Incremental work towards service runtime.

This commit is contained in:
Andre Rodrigues 2012-03-12 18:10:28 -07:00
Родитель 581d6317fe
Коммит 8887fd37be
27 изменённых файлов: 2693 добавлений и 40 удалений

Просмотреть файл

@ -97,6 +97,12 @@ exports.createServiceBusService = function (namespace, accessKey, issuer, acsNam
return new ServiceBusService(namespace, accessKey, issuer, acsNamespace, host, authenticationProvider);
};
/**
* Service Runtime exports.
*/
exports.RoleEnvironment = require('./serviceruntime/roleenvironment');
/**
* Other exports.
*/

Просмотреть файл

@ -0,0 +1,48 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Module dependencies.
var fs = require('fs');
var xml2js = require('xml2js');
// Expose 'FileInputChannel'.
exports = module.exports = FileInputChannel;
function FileInputChannel() { }
FileInputChannel.prototype.readInputChannel = function (name, parseXml, callback) {
this.readData(name, function (error, data) {
if (!error) {
if (parseXml) {
var parser = new xml2js.Parser();
parser.on('error', function (e) { error = e; });
parser.parseString(data);
if (parser.resultObject) {
data = parser.resultObject;
}
}
callback(error, data);
} else {
callback(error);
}
});
};
FileInputChannel.prototype.readData = function(name, callback) {
var data = fs.readFileSync(name);
callback(undefined, data);
};

Просмотреть файл

@ -0,0 +1,32 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Module dependencies.
var XmlGoalStateDeserializer = require('./xmlgoalstatedeserializer');
// Expose 'GoalStateDeserializer'.
exports = module.exports = GoalStateDeserializer;
function GoalStateDeserializer() {
this.deserializer = new XmlGoalStateDeserializer();
}
GoalStateDeserializer.prototype.deserialize = function (xml) {
if (!xml) {
throw new Error('Invalid goal state');
}
return this.deserializer.deserialize(xml);
};

Просмотреть файл

@ -0,0 +1,69 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Module dependencies.
var net = require('net');
var xml2js = require('xml2js');
// Expose 'NamedPipeInputChannel'.
exports = module.exports = NamedPipeInputChannel;
function NamedPipeInputChannel() { }
NamedPipeInputChannel.prototype.readInputChannel = function (name, parseXml, callback) {
this.readData(name, function (error, data) {
if (!error) {
var parts = data.toString().split('\r\n');
var xml;
// If there is more than one part (and the \r\n wasnt the final marker).
if (parts.length > 1 && parts[1].length > 0) {
xml = parts[1];
} else {
xml = parts[0];
}
if (parseXml) {
var parser = new xml2js.Parser();
error = null;
parser.on('error', function (e) { error = e; });
parser.parseString(xml);
if (parser.resultObject) {
xml = parser.resultObject;
}
}
callback(error, xml);
} else {
callback(error);
}
});
};
NamedPipeInputChannel.prototype.readData = function(name, callback) {
var client = net.connect(name);
var data = '';
client.on('data', function(chunk) {
data += chunk;
client.end();
callback(undefined, data);
});
client.on('error', function(error) {
callback(error);
});
};

Просмотреть файл

@ -0,0 +1,29 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Module dependencies.
var net = require("net");
// Expose 'NamedPipeOutputChannel'.
exports = module.exports = NamedPipeOutputChannel;
function NamedPipeOutputChannel() { }
NamedPipeOutputChannel.prototype.writeOutputChannel = function (name, data, callback) {
var client = net.connect(name);
client.end(data);
callback();
};

Просмотреть файл

@ -0,0 +1,53 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Module dependencies.
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var Constants = require('../util/constants');
var ServiceRuntimeConstants = Constants.ServiceRuntimeConstants;
// Expose 'Protocol1RuntimeClient'.
exports = module.exports = Protocol1RuntimeClient;
function Protocol1RuntimeClient(goalStateClient, currentStateClient, endpoint) {
EventEmitter.call(this);
this.goalStateClient = goalStateClient;
this.currentStateClient = currentStateClient;
this.goalStateClient.endpoint = endpoint;
this.currentGoalState = null;
this.currentEnvironmentData = null;
}
util.inherits(Protocol1RuntimeClient, EventEmitter);
Protocol1RuntimeClient.prototype.getCurrentGoalState = function (callback) {
return this.goalStateClient.getCurrentGoalState(callback);
};
Protocol1RuntimeClient.prototype.getRoleEnvironmentData = function (callback) {
this.goalStateClient.on(ServiceRuntimeConstants.CHANGED, function (currentGoalState) {
self.emit(ServiceRuntimeConstants.CHANGED, currentGoalState);
});
return this.goalStateClient.getRoleEnvironmentData(callback);
};
Protocol1RuntimeClient.prototype.setCurrentState = function (state, callback) {
this.currentStateClient.setCurrentState(state, callback);
};

Просмотреть файл

@ -0,0 +1,28 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Expose 'Protocol1RuntimeCurrentStateClient'.
exports = module.exports = Protocol1RuntimeCurrentStateClient;
function Protocol1RuntimeCurrentStateClient(currentStateSerializer, outputChannel) {
this.currentStateSerializer = currentStateSerializer;
this.outputChannel = outputChannel;
this.endpoint = null;
}
Protocol1RuntimeCurrentStateClient.prototype.setCurrentState = function (state, callback) {
var serializedState = this.currentStateSerializer.serialize(state);
this.outputChannel.writeOutputChannel(serializedState, callback);
};

Просмотреть файл

@ -0,0 +1,85 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Module dependencies.
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var Constants = require('../util/constants');
var ServiceRuntimeConstants = Constants.ServiceRuntimeConstants;
// Expose 'Protocol1RuntimeGoalStateClient'.
exports = module.exports = Protocol1RuntimeGoalStateClient;
function Protocol1RuntimeGoalStateClient(currentStateClient, goalStateDeserializer, roleEnvironmentDataDeserializer, namedPipeInputChannel, fileInputChannel) {
EventEmitter.call(this);
this.currentStateClient = currentStateClient;
this.goalStateDeserializer = goalStateDeserializer;
this.roleEnvironmentDataDeserializer = roleEnvironmentDataDeserializer;
this.namedPipeInputChannel = namedPipeInputChannel;
this.fileInputChannel = fileInputChannel;
this.endpoint = null;
this.currentGoalState = null;
this.currentEnvironmentData = null;
}
util.inherits(Protocol1RuntimeGoalStateClient, EventEmitter);
Protocol1RuntimeGoalStateClient.prototype.getCurrentGoalState = function (callback) {
var self = this;
this.ensureGoalStateRetrieved(function (error) {
if (!error) {
callback(error, self.currentGoalState);
} else {
callback(error);
}
});
};
Protocol1RuntimeGoalStateClient.prototype.getRoleEnvironmentData = function (callback) {
var self = this;
this.ensureGoalStateRetrieved(function (error) {
if (!error) {
if (!self.currentEnvironmentData) {
self.fileInputChannel.readInputChannel(self.currentGoalState.roleEnvironmentPath, true, function (readError, data) {
self.currentEnvironmentData = self.roleEnvironmentDataDeserializer.deserialize(data);
callback(readError, self.currentEnvironmentData);
});
} else {
callback(undefined, self.currentEnvironmentData);
}
} else {
callback(error);
}
});
};
Protocol1RuntimeGoalStateClient.prototype.ensureGoalStateRetrieved = function (callback) {
var self = this;
if (!self.currentGoalState) {
self.namedPipeInputChannel.readInputChannel(self.endpoint, true, function (error, data) {
if (error) {
callback(error);
} else {
self.currentGoalState = self.goalStateDeserializer.deserialize(data);
callback();
}
});
} else {
callback();
}
};

Просмотреть файл

@ -0,0 +1,476 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Module dependencies.
var events = require('events');
var uuid = require('node-uuid');
var RuntimeKernel = require('./runtimekernel');
var Constants = require('../util/constants');
var ServiceRuntimeConstants = Constants.ServiceRuntimeConstants;
RoleEnvironment.EnvironmentVariables = {
VersionEndpointEnvironmentName: 'WaRuntimeEndpoint'
};
RoleEnvironment.VersionEndpointFixedPath = '\\\\.\\pipe\\WindowsAzureRuntime';
// Expose 'RoleEnvironment'.
exports = module.exports = RoleEnvironment;
exports.clientId = uuid();
var runtimeClient = null;
var currentGoalState = null;
var currentEnvironmentData = null;
var lastState = null;
var maxDateTime = new Date('9999-12-31T23:59:59.9999999');
var eventEmitter = new events.EventEmitter();
function RoleEnvironment() { }
RoleEnvironment._initialize = function (callback) {
var getCurrentGoalState = function (error, rtClient) {
if (error) {
callback(error);
} else {
runtimeClient = rtClient;
currentGoalState = runtimeClient.getCurrentGoalState(getCurrentEnvironmentData);
}
};
var getCurrentEnvironmentData = function (error, goalState) {
if (error) {
callback(error);
} else {
currentGoalState = goalState;
runtimeClient.getRoleEnvironmentData(function (getRoleEnvironmentDataError, environmentData) {
if (getRoleEnvironmentDataError) {
callback(getRoleEnvironmentDataError);
} else {
currentEnvironmentData = environmentData;
runtimeClient.on(ServiceRuntimeConstants.CHANGED, function (newGoalState) {
switch (newGoalState.expectedState) {
case ServiceRuntimeConstants.STARTED:
if (newGoalState.incarnation > currentGoalState.incarnation) {
self._processGoalStateChange(newGoalState); // NOTE: do we need a callback here ?
}
break;
case ServiceRuntimeConstants.STOPPED:
/*
raiseStoppingEvent();
CurrentState stoppedState = new AcquireCurrentState(clientId,
newGoalState.getIncarnation(), CurrentStatus.STOPPED, maxDateTime);
runtimeClient.setCurrentState(stoppedState);*/
break;
}
});
callback();
}
});
}
};
if (!runtimeClient) {
var endpoint = process.env[RoleEnvironment.EnvironmentVariables.VersionEndpointEnvironmentName];
if (!endpoint) {
endpoint = RoleEnvironment.VersionEndpointFixedPath;
}
var kernel = RuntimeKernel.getKernel();
kernel.getRuntimeVersionManager().getRuntimeClient(endpoint, getCurrentGoalState);
} else {
getCurrentGoalState(undefined, runtimeClient);
}
};
/**
* Returns a RoleInstance object that represents the role instance
* in which this code is currently executing.
*
* @param {function(error, roleInstance)} callback The callback function.
*/
RoleEnvironment.getCurrentRoleInstance = function (callback) {
RoleEnvironment._initialize(function (error) {
var currentInstance = undefined;
if (!error) {
currentInstance = currentEnvironmentData.currentInstance;
}
callback(error, currentInstance);
});
};
/**
* Returns the deployment ID that uniquely identifies the deployment in
* which this role instance is running.
*
* @param {function(error, deploymentId)} callback The callback function.
*/
RoleEnvironment.getDeploymentId = function (callback) {
RoleEnvironment._initialize(function (error) {
var id = undefined;
if (!error) {
id = currentEnvironmentData.id;
}
callback(error, id);
});
};
/**
* Indicates whether the role instance is running in the Windows Azure
* environment.
*
* @param {function(error, isAvailable)} callback The callback function.
*/
RoleEnvironment.isAvailable = function (callback) {
try {
RoleEnvironment._initialize(function (initializeError) {
callback(initializeError, runtimeClient != null);
});
} catch (error) {
callback(error, false);
}
};
/**
* Indicates whether the role instance is running in the development fabric.
*
* @param {function(error, isEmulated)} callback The callback function.
*/
RoleEnvironment.isEmulated = function(callback) {
RoleEnvironment._initialize(function (error) {
var isEmulated = undefined;
if (!error) {
isEmulated = currentEnvironmentData.isEmulated;
}
callback(error, isEmulated);
});
};
/**
* Returns the set of Role objects defined for your service.
* Roles are defined in the service definition file.
*
* @param {function(error, roles)} callback The callback function.
*/
RoleEnvironment.getRoles = function (callback) {
RoleEnvironment._initialize(function (error) {
var roles = undefined;
if (!error) {
roles = currentEnvironmentData.roles;
}
callback(error, roles);
});
};
/**
* Retrieves the settings in the service configuration file.
* A role's configuration settings are defined in the service definition file. Values for configuration settings are
* set in the service configuration file.
*
* @param {function(error, configurationSettings)} callback The callback function.
*/
RoleEnvironment.getConfigurationSettings = function (callback) {
RoleEnvironment._initialize(function (error) {
var configurationSettings = undefined;
if (!error) {
configurationSettings = currentEnvironmentData.configurationSettings;
}
callback(error, configurationSettings);
});
};
/**
* Retrieves the set of named local storage resources.
*
* @param {function(error, localResources)} callback The callback function.
*/
RoleEnvironment.getLocalResources = function (callback) {
RoleEnvironment._initialize(function (error) {
var localResources = undefined;
if (!error) {
localResources = currentEnvironmentData.localResources;
}
callback(error, localResources);
});
};
/**
* Requests that the current role instance be stopped and restarted.
*
* Before the role instance is recycled, the Windows Azure load balancer takes the role instance out of rotation.
* This ensures that no new requests are routed to the instance while it is restarting.
*
* A call to <code>RequestRecycle</code> initiates the normal shutdown cycle. Windows Azure raises the
* <code>Stopping</code> event and calls the <code>OnStop</code> method so that you can run the necessary code to
* prepare the instance to be recycled.
*/
RoleEnvironment.requestRecycle = function (callback) {
RoleEnvironment._initialize(function (error) {
if (!error) {
var newState = {
clientId: exports.clientId,
incarnation: currentGoalState.incarnation,
status: ServiceRuntimeConstants.RoleStatus.RECYCLE,
expiration: maxDateTime
};
runtimeClient.setCurrentState(newState, callback);
} else {
callback(error);
}
});
};
/**
* Sets the status of the role instance.
*
* An instance may indicate that it is in one of two states: Ready or Busy. If an instance's state is Ready, it is
* prepared to receive requests from the load balancer. If the instance's state is Busy, it will not receive
* requests from the load balancer.
*
* @param {string} status A value that indicates whether the instance is ready or busy.
* @param {date} expiration_utc A date value that specifies the expiration date and time of the status.
*
*/
RoleEnvironment.setStatus = function (roleInstanceStatus, expirationUtc, callback) {
RoleEnvironment._initialize(function (error) {
if (!error) {
var currentStatus = ServiceRuntimeConstants.RoleStatus.STARTED;
switch (roleInstanceStatus) {
case ServiceRuntimeConstants.RoleInstanceStatus.BUSY:
currentStatus = ServiceRuntimeConstants.RoleStatus.BUSY;
break;
case ServiceRuntimeConstants.RoleInstanceStatus.READY:
currentStatus = ServiceRuntimeConstants.RoleStatus.STARTED;
break;
}
var newState = {
clientId: exports.clientId,
incarnation: currentGoalState.incarnation,
status: currentStatus,
expiration: expirationUtc
};
lastState = newState;
runtimeClient.setCurrentState(newState, callback);
} else {
callback(error);
}
});
};
/**
* Clears the status of the role instance.
* An instance may indicate that it has completed communicating status by calling this method.
*/
RoleEnvironment.clearStatus = function (callback) {
RoleEnvironment._initialize(function (error) {
if (!error) {
var newState = {
clientId: exports.clientId
};
lastState = newState;
runtimeClient.setCurrentState(newState, callback);
} else {
callback(error);
}
});
};
RoleEnvironment.on = function (event, callback) {
eventEmitter.on(event, callback);
};
RoleEnvironment._processGoalStateChange = function (newGoalState, callback) {
var self = this;
var last = lastState;
RoleEnvironment._calculateChanges(function (error, changes) {
if (!error) {
if (changes.length === 0) {
self._acceptLatestIncarnation(newGoalState, last);
} else {
eventEmitter.emit(ServiceRuntimeConstants.CHANGING, changes);
// TODO: check for canceled ?
RoleEnvironment._acceptLatestIncarnation(newGoalState, last);
runtimeClient.getRoleEnvironmentData(function (getRoleEnvironmentDataError, environmentData) {
if (getRoleEnvironmentDataError) {
callback(getRoleEnvironmentDataError);
} else {
currentEnvironmentData = environmentData;
eventEmitter.emit(ServiceRuntimeConstants.CHANGED, changes);
callback();
}
});
}
} else {
callback(error);
}
});
};
RoleEnvironment._acceptLatestIncarnation = function (newGoalState, last) {
// TODO: implement
};
RoleEnvironment._calculateChanges = function (callback) {
var changes = [];
var current = currentEnvironmentData;
var newData;
runtimeClient.getRoleEnvironmentData(function (getRoleEnvironmentDataError, environmentData) {
if (!getRoleEnvironmentDataError) {
newData = environmentData;
var currentConfig = current.configurationSettings;
var newConfig = newData.configurationSettings;
var currentRoles = current.roles;
var newRoles = newData.roles;
var setting;
for (setting in currentConfig) {
if (!newConfig[setting] ||
newConfig[setting] !== currentConfig[setting]) {
changes.push({ type: 'ConfigurationSettingChange', name: setting });
}
}
for (setting in newConfig) {
if (!currentConfig[setting]) {
changes.push({ type: 'ConfigurationSettingChange', name: setting });
}
}
var changedRoleSet = [];
var role;
var currentRole;
var newRole;
var instance;
var currentInstance;
var newInstance;
var endpoint;
var currentEndpoint;
var newEndpoint;
for (role in currentRoles) {
if (newRoles[role]) {
currentRole = currentRoles[role];
newRole = newRoles[role];
for (instance in currentRole) {
if (newRole[instance]) {
currentInstance = currentRole[instance];
newInstance = newRole[instance];
if (currentInstance['faultDomain'] === newInstance['faultDomain'] &&
currentInstance['updateDomain'] === currentInstance['updateDomain']) {
for (endpoint in currentInstance['endpoints']) {
if (newInstance['endpoints'][endpoint]) {
currentEndpoint = currentInstance['endpoints'][endpoint];
newEndpoint = newInstance['endpoints'][endpoint];
if (currentEndpoint['protocol'] !== newEndpoint['protocol'] ||
currentEndpoint['address'] !== newEndpoint['address'] ||
currentEndpoint['port'] !== newEndpoint['port']) {
changedRoleSet.push(role);
}
} else {
changedRoleSet.push(role);
}
}
} else {
changedRoleSet.push(role);
}
} else {
changedRoleSet.push(role);
}
}
} else {
changedRoleSet.push(role);
}
}
for (role in newRoles) {
if (currentRoles[role]) {
currentRole = currentRoles[role];
newRole = newRoles[role];
for (instance in newRole) {
if (currentRole[instance]) {
currentInstance = currentRole[instance];
newInstance = newRole[instance];
if (currentInstance['faultDomain'] === newInstance['faultDomain'] &&
currentInstance['updateDomain'] === currentInstance['updateDomain']) {
for (endpoint in newInstance['endpoints']) {
if (currentInstance['endpoints'][endpoint]) {
currentEndpoint = currentInstance['endpoints'][endpoint];
newEndpoint = newInstance['endpoints'][endpoint];
if (currentEndpoint['protocol'] !== newEndpoint['protocol'] ||
currentEndpoint['address'] !== newEndpoint['address'] ||
currentEndpoint['port'] !== newEndpoint['port']) {
changedRoleSet.push(role);
}
} else {
changedRoleSet.push(role);
}
}
} else {
changedRoleSet.push(role);
}
} else {
changedRoleSet.push(role);
}
}
} else {
changedRoleSet.push(role);
}
}
for (var changedRole in changedRoleSet) {
changes.push({ type: 'TopologyChange', name: changedRoleSet[changedRole] });
}
callback(undefined, changes);
} else {
callback(getRoleEnvironmentDataError);
}
});
};

Просмотреть файл

@ -0,0 +1,21 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Module dependencies.
// Expose 'RoleInstance'.
exports = module.exports = RoleInstance;
function RoleInstance() { }

Просмотреть файл

@ -0,0 +1,72 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Module dependencies.
var FileInputChannel = require('./fileinputchannel');
var NamedPipeInputChannel = require('./namedpipeinputchannel');
var NamedPipeOutputChannel = require('./namedpipeoutputchannel');
var Protocol1RuntimeCurrentStateClient = require('./protocol1runtimecurrentstateclient');
var Protocol1RuntimeGoalStateClient = require('./protocol1runtimegoalstateclient');
var RuntimeVersionProtocolClient = require('./runtimeversionprotocolclient');
var RuntimeVersionManager = require('./runtimeversionmanager');
var GoalStateDeserializer = require('./goalstatedeserializer');
var XmlRoleEnvironmentDataDeserializer = require('./xmlroleenvironmentdatadeserializer');
var XmlCurrentStateSerializer = require('./xmlcurrentstateserializer');
// Expose 'RuntimeKernel'.
exports = module.exports = RuntimeKernel;
var theKernel;
function RuntimeKernel() {
this.currentStateSerializer = new XmlCurrentStateSerializer();
this.goalStateDeserializer = new GoalStateDeserializer();
this.namedPipeOutputChannel = new NamedPipeOutputChannel();
this.namedPipeInputChannel = new NamedPipeInputChannel();
this.fileInputChannel = new FileInputChannel();
this.protocol1RuntimeCurrentStateClient = new Protocol1RuntimeCurrentStateClient(this.currentStateSerializer, this.namedPipeOutputChannel);
this.roleEnvironmentDataDeserializer = new XmlRoleEnvironmentDataDeserializer();
this.protocol1RuntimeGoalStateClient = new Protocol1RuntimeGoalStateClient(this.protocol1RuntimeCurrentStateClient,
this.goalStateDeserializer, this.roleEnvironmentDataDeserializer, this.namedPipeInputChannel, this.fileInputChannel);
this.runtimeVersionProtocolClient = new RuntimeVersionProtocolClient(this.namedPipeInputChannel);
this.runtimeVersionManager = new RuntimeVersionManager(this.runtimeVersionProtocolClient, this);
}
RuntimeKernel.getKernel = function () {
if (!theKernel) {
theKernel = new RuntimeKernel();
}
return theKernel;
};
RuntimeKernel.prototype.getGoalStateClient = function () {
return this.protocol1RuntimeGoalStateClient;
};
RuntimeKernel.prototype.getCurrentStateClient = function () {
return this.protocol1RuntimeCurrentStateClient;
};
RuntimeKernel.prototype.getRuntimeVersionManager = function () {
return this.runtimeVersionManager;
};

Просмотреть файл

@ -0,0 +1,62 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Module dependencies.
var Protocol1RuntimeClient = require('./protocol1runtimeclient');
// Expose 'RuntimeVersionManager'.
exports = module.exports = RuntimeVersionManager;
function RuntimeVersionManager(runtimeVersionProtocolClient, runtimeKernel) {
this.protocolClient = runtimeVersionProtocolClient;
this.runtimeKernel = runtimeKernel;
var self = this;
var runtimeClientFactory = {
getVersion: function () {
return '2011-03-08';
},
createRuntimeClient: function (path) {
return new Protocol1RuntimeClient(
self.runtimeKernel.getGoalStateClient(),
self.runtimeKernel.getCurrentStateClient(),
path);
}
};
this.supportedVersionList = [ runtimeClientFactory ];
}
RuntimeVersionManager.prototype.getRuntimeClient = function (versionEndpoint, callback) {
var self = this;
self.protocolClient.getVersionMap(versionEndpoint, function (error, versionMap) {
if (error) {
callback(error);
} else {
for (var i in self.supportedVersionList) {
var factory = self.supportedVersionList[i];
if (versionMap[factory.getVersion()]) {
callback(undefined, factory.createRuntimeClient(versionMap[factory.getVersion()]));
return;
}
}
callback('Server does not support any known protocol versions.');
}
});
};

Просмотреть файл

@ -0,0 +1,52 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Module dependencies.
var Constants = require('../util/constants');
var ServiceRuntimeConstants = Constants.ServiceRuntimeConstants;
// Expose 'RuntimeVersionProtocolClient'.
exports = module.exports = RuntimeVersionProtocolClient;
function RuntimeVersionProtocolClient(inputChannel) {
this.inputChannel = inputChannel;
}
RuntimeVersionProtocolClient.prototype.getVersionMap = function (connectionPath, callback) {
this.inputChannel.readInputChannel(connectionPath, true, function (error, data) {
if (error) {
callback(error);
} else {
var versions = {};
if (data[ServiceRuntimeConstants.RUNTIME_SERVER_ENDPOINTS] &&
data[ServiceRuntimeConstants.RUNTIME_SERVER_ENDPOINTS][ServiceRuntimeConstants.RUNTIME_SERVER_ENDPOINT]) {
var endpoints = data[ServiceRuntimeConstants.RUNTIME_SERVER_ENDPOINTS][ServiceRuntimeConstants.RUNTIME_SERVER_ENDPOINT];
if (!Array.isArray(endpoints)) {
endpoints = [endpoints];
}
for (var endpoint in endpoints) {
var currentEndpoint = endpoints[endpoint];
versions[currentEndpoint[Constants.ATOM_METADATA_MARKER].version] = currentEndpoint[Constants.ATOM_METADATA_MARKER].path;
}
}
callback(undefined, versions);
}
});
};

Просмотреть файл

@ -0,0 +1,48 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Module dependencies.
var js2xml = require('../util/js2xml');
var Constants = require('../util/constants');
var ServiceRuntimeConstants = Constants.ServiceRuntimeConstants;
// Expose 'XmlCurrentStateSerializer'.
exports = module.exports = XmlCurrentStateSerializer;
function XmlCurrentStateSerializer() { }
XmlCurrentStateSerializer.prototype.serialize = function (currentState) {
var currentStateXml = {};
currentStateXml[ServiceRuntimeConstants.CURRENT_STATE] = {};
currentStateXml[ServiceRuntimeConstants.CURRENT_STATE][ServiceRuntimeConstants.STATUS_LEASE] = {};
currentStateXml[ServiceRuntimeConstants.CURRENT_STATE][ServiceRuntimeConstants.STATUS_LEASE][Constants.ATOM_METADATA_MARKER] = {};
currentStateXml[ServiceRuntimeConstants.CURRENT_STATE][ServiceRuntimeConstants.STATUS_LEASE][Constants.ATOM_METADATA_MARKER][ServiceRuntimeConstants.CLIENT_ID] = currentState.clientId;
// If it is a request for a change of status
if (currentState.status) {
currentStateXml[ServiceRuntimeConstants.CURRENT_STATE][ServiceRuntimeConstants.STATUS_LEASE][ServiceRuntimeConstants.ACQUIRE] = {};
currentStateXml[ServiceRuntimeConstants.CURRENT_STATE][ServiceRuntimeConstants.STATUS_LEASE][ServiceRuntimeConstants.ACQUIRE][ServiceRuntimeConstants.EXPIRATION] = currentState.expiration;
currentStateXml[ServiceRuntimeConstants.CURRENT_STATE][ServiceRuntimeConstants.STATUS_LEASE][ServiceRuntimeConstants.ACQUIRE][ServiceRuntimeConstants.INCARNATION] = currentState.incarnation;
currentStateXml[ServiceRuntimeConstants.CURRENT_STATE][ServiceRuntimeConstants.STATUS_LEASE][ServiceRuntimeConstants.ACQUIRE][ServiceRuntimeConstants.STATUS] = currentState.status;
} else {
currentStateXml[ServiceRuntimeConstants.CURRENT_STATE][ServiceRuntimeConstants.STATUS_LEASE][ServiceRuntimeConstants.RELEASE] = {};
}
// Serialize JSON object to XML
var xml = js2xml.serialize(currentStateXml);
return xml;
};

Просмотреть файл

@ -0,0 +1,39 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Module dependencies.
var Constants = require('../util/constants');
var ServiceRuntimeConstants = Constants.ServiceRuntimeConstants;
// Expose 'XmlGoalStateDeserializer'.
exports = module.exports = XmlGoalStateDeserializer;
function XmlGoalStateDeserializer() { }
XmlGoalStateDeserializer.prototype.deserialize = function (xml) {
if (!xml) {
throw new Error('Invalid goal state');
}
var goalState = {};
goalState.incarnation = xml[ServiceRuntimeConstants.INCARNATION];
goalState.expectedState = xml[ServiceRuntimeConstants.EXPECTED_STATE];
goalState.roleEnvironmentPath = xml[ServiceRuntimeConstants.ROLE_ENVIRONMENT_PATH];
goalState.deadline = xml[ServiceRuntimeConstants.DEADLINE];
goalState.currentStateEndpoint = xml[ServiceRuntimeConstants.CURRENT_STATE_ENDPOINT];
return goalState;
};

Просмотреть файл

@ -0,0 +1,208 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Module dependencies.
var Constants = require('../util/constants');
var ServiceRuntimeConstants = Constants.ServiceRuntimeConstants;
// Expose 'XmlRoleEnvironmentDataDeserializer'.
exports = module.exports = XmlRoleEnvironmentDataDeserializer;
function XmlRoleEnvironmentDataDeserializer() { }
XmlRoleEnvironmentDataDeserializer.prototype.deserialize = function (xml) {
var configurationSettings = this._translateConfigurationSettings(xml);
var localResources = this._translateLocalResources(xml);
var currentInstance = this._translateCurrentInstance(xml);
var isEmulated = xml[ServiceRuntimeConstants.DEPLOYMENT][Constants.ATOM_METADATA_MARKER][ServiceRuntimeConstants.EMULATED] === 'true';
var deploymentId = xml[ServiceRuntimeConstants.DEPLOYMENT][Constants.ATOM_METADATA_MARKER][ServiceRuntimeConstants.DEPLOYMENT_ID];
var roles = this._translateRoles(xml, currentInstance, currentInstance.roleName);
var roleEnvironmentData = {
id: deploymentId,
isEmulated: isEmulated,
configurationSettings: configurationSettings,
localResources: localResources,
currentInstance: currentInstance,
roles: roles
};
return roleEnvironmentData;
};
XmlRoleEnvironmentDataDeserializer.prototype._translateConfigurationSettings = function (xml) {
var configurationSettingsMap = {};
if (xml[ServiceRuntimeConstants.CURRENT_INSTANCE] &&
xml[ServiceRuntimeConstants.CURRENT_INSTANCE][ServiceRuntimeConstants.CONFIGURATION_SETTINGS] &&
xml[ServiceRuntimeConstants.CURRENT_INSTANCE][ServiceRuntimeConstants.CONFIGURATION_SETTINGS][ServiceRuntimeConstants.CONFIGURATION_SETTING]) {
var configurationSettings = xml[ServiceRuntimeConstants.CURRENT_INSTANCE][ServiceRuntimeConstants.CONFIGURATION_SETTINGS][ServiceRuntimeConstants.CONFIGURATION_SETTING];
if (!Array.isArray(configurationSettings)) {
configurationSettings = [configurationSettings];
}
for (var configurationSetting in configurationSettings) {
var currentConfigurationSetting = configurationSettings[configurationSetting];
configurationSettingsMap[currentConfigurationSetting[Constants.ATOM_METADATA_MARKER]['name']] = currentConfigurationSetting[Constants.ATOM_METADATA_MARKER]['value'];
}
}
return configurationSettingsMap;
};
XmlRoleEnvironmentDataDeserializer.prototype._translateLocalResources = function (xml) {
var localResourcesMap = {};
if (xml[ServiceRuntimeConstants.CURRENT_INSTANCE] &&
xml[ServiceRuntimeConstants.CURRENT_INSTANCE][ServiceRuntimeConstants.LOCAL_RESOURCES] &&
xml[ServiceRuntimeConstants.CURRENT_INSTANCE][ServiceRuntimeConstants.LOCAL_RESOURCES][ServiceRuntimeConstants.LOCAL_RESOURCE]) {
var localResources = xml[ServiceRuntimeConstants.CURRENT_INSTANCE][ServiceRuntimeConstants.LOCAL_RESOURCES][ServiceRuntimeConstants.LOCAL_RESOURCE];
if (!Array.isArray(localResources)) {
localResources = [localResources];
}
for (var localResource in localResources) {
var currentLocalResource = localResources[localResource];
var currentLocalResourceName = currentLocalResource[Constants.ATOM_METADATA_MARKER]['name'];
delete currentLocalResource[Constants.ATOM_METADATA_MARKER]['name'];
localResourcesMap[currentLocalResourceName] = currentLocalResource[Constants.ATOM_METADATA_MARKER];
}
}
return localResourcesMap;
};
XmlRoleEnvironmentDataDeserializer.prototype._translateCurrentInstance = function (xml) {
var currentInstance = {};
currentInstance.id = xml[ServiceRuntimeConstants.CURRENT_INSTANCE][Constants.ATOM_METADATA_MARKER]['id'];
currentInstance.roleName = xml[ServiceRuntimeConstants.CURRENT_INSTANCE][Constants.ATOM_METADATA_MARKER]['roleName'];
currentInstance.faultDomain = xml[ServiceRuntimeConstants.CURRENT_INSTANCE][Constants.ATOM_METADATA_MARKER]['faultDomain'];
currentInstance.updateDomain = xml[ServiceRuntimeConstants.CURRENT_INSTANCE][Constants.ATOM_METADATA_MARKER]['updateDomain'];
currentInstance.endpoints = this._translateRoleInstanceEndpoints(xml);
return currentInstance;
};
XmlRoleEnvironmentDataDeserializer.prototype._translateRoleInstanceEndpoints = function(xml) {
var endpointsMap = { };
if (xml[ServiceRuntimeConstants.CURRENT_INSTANCE] &&
xml[ServiceRuntimeConstants.CURRENT_INSTANCE][ServiceRuntimeConstants.ENDPOINTS] &&
xml[ServiceRuntimeConstants.CURRENT_INSTANCE][ServiceRuntimeConstants.ENDPOINTS][ServiceRuntimeConstants.ENDPOINT]) {
var endpoints = xml[ServiceRuntimeConstants.CURRENT_INSTANCE][ServiceRuntimeConstants.ENDPOINTS][ServiceRuntimeConstants.ENDPOINT];
if (!Array.isArray(endpoints)) {
endpoints = [endpoints];
}
for (var endpoint in endpoints) {
var currentEndpoint = endpoints[endpoint];
var currentEndpointName = currentEndpoint[Constants.ATOM_METADATA_MARKER]['name'];
delete currentEndpoint[Constants.ATOM_METADATA_MARKER]['name'];
endpointsMap[currentEndpointName] = currentEndpoint[Constants.ATOM_METADATA_MARKER];
}
}
return endpointsMap;
};
XmlRoleEnvironmentDataDeserializer.prototype._translateRoles = function (xml, currentInstance, currentRole) {
var rolesMap = {};
var roleInstances;
if (xml[ServiceRuntimeConstants.ROLES] &&
xml[ServiceRuntimeConstants.ROLES][ServiceRuntimeConstants.ROLE]) {
var roles = xml[ServiceRuntimeConstants.ROLES][ServiceRuntimeConstants.ROLE];
if (!Array.isArray(roles)) {
roles = [roles];
}
for (var role in roles) {
var currentIterationRole = roles[role];
var currentIterationRoleName = currentIterationRole[Constants.ATOM_METADATA_MARKER]['name'];
roleInstances = this._translateRoleInstances(currentIterationRole);
if (currentIterationRoleName === currentRole) {
roleInstances[currentInstance.id] = currentInstance;
}
rolesMap[currentIterationRoleName] = roleInstances;
}
}
if (!rolesMap[currentRole]) {
roleInstances = {};
roleInstances[currentInstance.id] = currentInstance;
rolesMap[currentRole] = roleInstances;
}
return rolesMap;
};
XmlRoleEnvironmentDataDeserializer.prototype._translateRoleInstances = function (xml) {
var roleInstancesMap = {};
if (xml[ServiceRuntimeConstants.INSTANCES] &&
xml[ServiceRuntimeConstants.INSTANCES][ServiceRuntimeConstants.INSTANCE]) {
var instances = xml[ServiceRuntimeConstants.INSTANCES][ServiceRuntimeConstants.INSTANCE];
if (!Array.isArray(instances)) {
instances = [instances];
}
for (var instance in instances) {
var currentIterationInstance = instances[instance];
var currentIterationInstanceId = currentIterationInstance[Constants.ATOM_METADATA_MARKER]['id'];
delete currentIterationInstance[Constants.ATOM_METADATA_MARKER]['id'];
currentIterationInstance[Constants.ATOM_METADATA_MARKER].endpoints = this._translateRoleInstanceEndpoints(currentIterationInstance[ServiceRuntimeConstants.ENDPOINTS]);
roleInstancesMap[currentIterationInstanceId] = currentIterationInstance[Constants.ATOM_METADATA_MARKER];
}
}
return roleInstancesMap;
};
XmlRoleEnvironmentDataDeserializer.prototype._translateRoleInstanceEndpoints = function (endpointsXml) {
var endpointsMap = {};
if (endpointsXml &&
endpointsXml[ServiceRuntimeConstants.ENDPOINT]) {
var endpoints = endpointsXml[ServiceRuntimeConstants.ENDPOINT];
if (!Array.isArray(endpoints)) {
endpoints = [endpoints];
}
for (var endpoint in endpoints) {
var currentEndpoint = endpoints[endpoint];
var currentEndpointName = currentEndpoint[Constants.ATOM_METADATA_MARKER]['name'];
delete currentEndpoint[Constants.ATOM_METADATA_MARKER]['name'];
endpointsMap[currentEndpointName] = currentEndpoint[Constants.ATOM_METADATA_MARKER];
}
}
return endpointsMap;
};

Просмотреть файл

@ -1195,6 +1195,326 @@ var Constants = {
WRAP_ACCESS_TOKEN_EXPIRES_IN: 'wrap_access_token_expires_in'
},
/**
* Defines constants for use with Service Runtime.
*
* @const
* @type {string}
*/
ServiceRuntimeConstants: {
/**
* The runtime server endpoint element.
*
* @const
* @type {string}
*/
RUNTIME_SERVER_ENDPOINT: 'RuntimeServerEndpoint',
/**
* The runtime server endpoints element.
*
* @const
* @type {string}
*/
RUNTIME_SERVER_ENDPOINTS: 'RuntimeServerEndpoints',
/**
* The current instance element.
*
* @const
* @type {string}
*/
CURRENT_INSTANCE: 'CurrentInstance',
/**
* The configuration settings element.
*
* @const
* @type {string}
*/
CONFIGURATION_SETTINGS: 'ConfigurationSettings',
/**
* The configuration setting element.
*
* @const
* @type {string}
*/
CONFIGURATION_SETTING: 'ConfigurationSetting',
/**
* The local resources element.
*
* @const
* @type {string}
*/
LOCAL_RESOURCES: 'LocalResources',
/**
* The local resource element.
*
* @const
* @type {string}
*/
LOCAL_RESOURCE: 'LocalResource',
/**
* The deployment element.
*
* @const
* @type {string}
*/
DEPLOYMENT: 'Deployment',
/**
* The emulated element.
*
* @const
* @type {string}
*/
EMULATED: 'Emulated',
/**
* The id element.
*
* @const
* @type {string}
*/
DEPLOYMENT_ID: 'id',
/**
* The endpoints element.
*
* @const
* @type {string}
*/
ENDPOINTS: 'Endpoints',
/**
* The endpoint element.
*
* @const
* @type {string}
*/
ENDPOINT: 'Endpoint',
/**
* The roles element.
*
* @const
* @type {string}
*/
ROLES: 'Roles',
/**
* The role element.
*
* @const
* @type {string}
*/
ROLE: 'Role',
/**
* The instances element.
*
* @const
* @type {string}
*/
INSTANCES: 'Instances',
/**
* The instance element.
*
* @const
* @type {string}
*/
INSTANCE: 'Instance',
/**
* The role environment path element.
*
* @const
* @type {string}
*/
ROLE_ENVIRONMENT_PATH: 'RoleEnvironmentPath',
/**
* The role environment changed event.
*
* @const
* @type {string}
*/
CHANGED: 'changed',
/**
* The role environment changing event.
*
* @const
* @type {string}
*/
CHANGING: 'changing',
/**
* The ready event.
*
* @const
* @type {string}
*/
READY: 'ready',
/**
* The expected state element.
*
* @const
* @type {string}
*/
EXPECTED_STATE: 'ExpectedState',
/**
* The incarnation element.
*
* @const
* @type {string}
*/
INCARNATION: 'Incarnation',
/**
* The current state endpoint element.
*
* @const
* @type {string}
*/
CURRENT_STATE_ENDPOINT: 'CurrentStateEndpoint',
/**
* The deadline element.
*
* @const
* @type {string}
*/
DEADLINE: 'Deadline',
/**
* The current state element.
*
* @const
* @type {string}
*/
CURRENT_STATE: 'CurrentState',
/**
* The status lease element.
*
* @const
* @type {string}
*/
STATUS_LEASE: 'StatusLease',
/**
* The status lease element.
*
* @const
* @type {string}
*/
STATUS: 'Status',
/**
* The expiration element.
*
* @const
* @type {string}
*/
EXPIRATION: 'Expiration',
/**
* The client identifier element.
*
* @const
* @type {string}
*/
CLIENT_ID: 'ClientId',
/**
* The acquire element.
*
* @const
* @type {string}
*/
ACQUIRE: 'Acquire',
/**
* The release element.
*
* @const
* @type {string}
*/
RELEASE: 'Release',
/**
* The different role instance target statuses.
*
* @const
* @type {string}
*/
RoleInstanceStatus: {
/**
* The ready status.
*
* @const
* @type {string}
*/
READY: 'ready',
/**
* The busy status.
*
* @const
* @type {string}
*/
BUSY: 'busy'
},
/**
* The different role statuses.
*
* @const
* @type {string}
*/
RoleStatus: {
/**
* The started event.
*
* @const
* @type {string}
*/
STARTED: 'started',
/**
* The stopped event.
*
* @const
* @type {string}
*/
STOPPED: 'stopped',
/**
* The busy event.
*
* @const
* @type {string}
*/
BUSY: 'busy',
/**
* The recycle event.
*
* @const
* @type {string}
*/
RECYCLE: 'recycle'
}
},
/**
* Defines constants for use with HTTP headers.
*/

122
lib/util/js2xml.js Normal file
Просмотреть файл

@ -0,0 +1,122 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Module dependencies.
var xmlbuilder = require('xmlbuilder');
var azureutil = require('./util');
var Constants = require('./constants');
exports = module.exports;
exports.serialize = function (entity) {
if (azureutil.objectKeysLength(entity) !== 1) {
throw new Error('Invalid XML root element.');
}
var doc = xmlbuilder.create();
var rootElementName = azureutil.objectFirstKey(entity);
doc = doc.begin(rootElementName, { version: '1.0', encoding: 'utf-8', standalone: 'yes' });
if (entity[rootElementName][Constants.ATOM_METADATA_MARKER]) {
for (var metadata in entity[rootElementName][Constants.ATOM_METADATA_MARKER]) {
doc.att(metadata, entity[rootElementName][Constants.ATOM_METADATA_MARKER][metadata]);
}
}
for (var attribute in entity[rootElementName]) {
doc = _writeAtomEntryValue(doc, attribute, entity[rootElementName][attribute]);
}
doc = doc.doc();
return doc.toString();
};
/*
* Writes a single property for an entry or complex type.
*
* @param {object} parentElement Parent DOM element under which the property should be added.
* @param {string} name Property name.
* @param {object} value Property value.
* @return {object} The current DOM element.
*/
function _writeAtomEntryValue (parentElement, name, value) {
var ignored = false;
var propertyTagName = name;
if (!azureutil.stringIsEmpty(value) &&
typeof value === 'object' &&
!_isDate(value)) {
if (Array.isArray(value) && value.length > 0) {
for (var i in value) {
parentElement = _writeAtomEntryValue(parentElement, name, value[i]);
}
// For an array no element was actually added at this level, so skip uping level.
ignored = true;
} else if (typeof value === 'object') {
parentElement = parentElement.ele(propertyTagName);
for (var propertyName in value) {
if (propertyName !== Constants.ATOM_METADATA_MARKER) {
parentElement = _writeAtomEntryValue(parentElement, propertyName, value[propertyName]);
}
}
} else {
// Ignoring complex elements
ignored = true;
}
} else {
parentElement = parentElement.ele(propertyTagName);
if (!azureutil.stringIsEmpty(value)) {
parentElement = parentElement.txt(formatToString(value));
}
}
if (value && value[Constants.ATOM_METADATA_MARKER]) {
// include the metadata
var attributeList = value[Constants.ATOM_METADATA_MARKER];
for (var attribute in attributeList) {
parentElement = parentElement.att(attribute, attributeList[attribute]);
}
}
if (!ignored) {
parentElement = parentElement.up();
}
return parentElement;
};
/*
* Checks whether the specified value is a Date object.
* @param {string} value Value to check.
* @return {bool} true if the value is a Date object; false otherwise.
*/
function _isDate (value) {
return Object.prototype.toString.call(value) === "[object Date]";
};
/**
* Formats a value by invoking .toString() on it.
* @param {object} value Value to format.
* @return {string} The formatted text.
*/
function formatToString(value) {
return value.toString();
}

Просмотреть файл

@ -31,6 +31,33 @@ exports.encodeUri = function (uri) {
.replace(/\*/g, '%2A');
};
/**
* Returns the number of keys (properties) in an object.
*
* @param {object} value The object which keys are to be counted.
* @return {number} The number of keys in the object.
*/
exports.objectKeysLength = function (value) {
return _.keys(value).length;
};
/**
* Returns the name of the first property in an object.
*
* @param {object} value The object which key is to be returned.
* @return {number} The name of the first key in the object.
*/
exports.objectFirstKey = function (value) {
if (value) {
for (var key in value) {
return key;
}
}
// Object has no properties
return null;
};
/**
* Checks if a value is null or undefined.
*

Просмотреть файл

@ -1,39 +1,40 @@
{
"name": "azure",
"author": "Microsoft Corporation",
"version": "0.5.2",
"description": "Windows Azure Client Library for node",
"tags" : ["azure", "sdk"],
"keywords": [ "node", "azure" ],
"main": "./lib/azure.js",
"engines": { "node": ">= 0.4.7" },
"licenses": [ { "type": "Apache", "url": "http://www.apache.org/licenses/LICENSE-2.0" } ],
"dependencies": {
"xml2js" : ">= 0.1.11",
"sax": ">= 0.1.1",
"qs": ">= 0.3.1",
"log": ">= 1.2.0",
"xmlbuilder": ">= 0.3.1",
"mime": ">= 1.2.4",
"dateformat": "1.0.2-1.2.3",
"underscore": ">= 1.3.1",
"underscore.string": ">= 2.0.0"
},
"devDependencies": {
"mocha": "*",
"jshint": "*"
},
"homepage": "http://github.com/WindowsAzure/azure-sdk-for-node",
"repository": {
"type": "git",
"url": "git@github.com:WindowsAzure/azure-sdk-for-node.git"
},
"bugs" : {
"url" : "http://github.com/WindowsAzure/azure-sdk-for-node/issues"
},
"scripts": {
"test": "node test/runtests.js",
"jshint": "node test/runjshint.js",
"extendedtests": "node test/runextendedtests.js"
}
}
"name": "azure",
"author": "Microsoft Corporation",
"version": "0.5.2",
"description": "Windows Azure Client Library for node",
"tags" : ["azure", "sdk"],
"keywords": [ "node", "azure" ],
"main": "./lib/azure.js",
"engines": { "node": ">= 0.4.7" },
"licenses": [ { "type": "Apache", "url": "http://www.apache.org/licenses/LICENSE-2.0" } ],
"dependencies": {
"xml2js" : ">= 0.1.11",
"sax": ">= 0.1.1",
"qs": ">= 0.3.1",
"log": ">= 1.2.0",
"xmlbuilder": ">= 0.3.1",
"mime": ">= 1.2.4",
"dateformat": "1.0.2-1.2.3",
"underscore": ">= 1.3.1",
"underscore.string": ">= 2.0.0",
"node-uuid": "> = 1.2.0"
},
"devDependencies": {
"mocha": "*",
"jshint": "*"
},
"homepage": "http://github.com/WindowsAzure/azure-sdk-for-node",
"repository": {
"type": "git",
"url": "git@github.com:WindowsAzure/azure-sdk-for-node.git"
},
"bugs" : {
"url" : "http://github.com/WindowsAzure/azure-sdk-for-node/issues"
},
"scripts": {
"test": "node test/runtests.js",
"jshint": "node test/runjshint.js",
"extendedtests": "node test/runextendedtests.js"
}
}

Просмотреть файл

@ -117,6 +117,51 @@
<Content Include="..\..\lib\http\webresource.js">
<Link>lib\http\webresource.js</Link>
</Content>
<Content Include="..\..\lib\serviceruntime\fileinputchannel.js">
<Link>lib\serviceruntime\fileinputchannel.js</Link>
</Content>
<Content Include="..\..\lib\serviceruntime\goalstatedeserializer.js">
<Link>lib\serviceruntime\goalstatedeserializer.js</Link>
</Content>
<Content Include="..\..\lib\serviceruntime\namedpipeinputchannel.js">
<Link>lib\serviceruntime\namedpipeinputchannel.js</Link>
</Content>
<Content Include="..\..\lib\serviceruntime\namedpipeoutputchannel.js">
<Link>lib\serviceruntime\namedpipeoutputchannel.js</Link>
</Content>
<Content Include="..\..\lib\serviceruntime\protocol1runtimeclient.js">
<Link>lib\serviceruntime\protocol1runtimeclient.js</Link>
</Content>
<Content Include="..\..\lib\serviceruntime\protocol1runtimecurrentstateclient.js">
<Link>lib\serviceruntime\protocol1runtimecurrentstateclient.js</Link>
</Content>
<Content Include="..\..\lib\serviceruntime\protocol1runtimegoalstateclient.js">
<Link>lib\serviceruntime\protocol1runtimegoalstateclient.js</Link>
</Content>
<Content Include="..\..\lib\serviceruntime\roleenvironment.js">
<Link>lib\serviceruntime\roleenvironment.js</Link>
</Content>
<Content Include="..\..\lib\serviceruntime\roleinstance.js">
<Link>lib\serviceruntime\roleinstance.js</Link>
</Content>
<Content Include="..\..\lib\serviceruntime\runtimekernel.js">
<Link>lib\serviceruntime\runtimekernel.js</Link>
</Content>
<Content Include="..\..\lib\serviceruntime\runtimeversionmanager.js">
<Link>lib\serviceruntime\runtimeversionmanager.js</Link>
</Content>
<Content Include="..\..\lib\serviceruntime\runtimeversionprotocolclient.js">
<Link>lib\serviceruntime\runtimeversionprotocolclient.js</Link>
</Content>
<Content Include="..\..\lib\serviceruntime\xmlcurrentstateserializer.js">
<Link>lib\serviceruntime\xmlcurrentstateserializer.js</Link>
</Content>
<Content Include="..\..\lib\serviceruntime\xmlgoalstatedeserializer.js">
<Link>lib\serviceruntime\xmlgoalstatedeserializer.js</Link>
</Content>
<Content Include="..\..\lib\serviceruntime\xmlroleenvironmentdatadeserializer.js">
<Link>lib\serviceruntime\xmlroleenvironmentdatadeserializer.js</Link>
</Content>
<Content Include="..\..\lib\services\blob\blobservice.js">
<Link>lib\services\blob\blobservice.js</Link>
</Content>
@ -255,6 +300,9 @@
<Content Include="..\..\lib\util\iso8061date.js">
<Link>lib\util\iso8061date.js</Link>
</Content>
<Content Include="..\..\lib\util\js2xml.js">
<Link>lib\util\js2xml.js</Link>
</Content>
<Content Include="..\..\lib\util\rfc1123date.js">
<Link>lib\util\rfc1123date.js</Link>
</Content>
@ -288,6 +336,15 @@
<Content Include="..\..\test\runtests.js">
<Link>test\runtests.js</Link>
</Content>
<Content Include="..\..\test\serviceruntime\roleenvironment-tests.js">
<Link>test\serviceruntime\roleenvironment-tests.js</Link>
</Content>
<Content Include="..\..\test\serviceruntime\runtimeversionmanager-tests.js">
<Link>test\serviceruntime\runtimeversionmanager-tests.js</Link>
</Content>
<Content Include="..\..\test\serviceruntime\runtimeversionprotocolclient-tests.js">
<Link>test\serviceruntime\runtimeversionprotocolclient-tests.js</Link>
</Content>
<Content Include="..\..\test\services\blob\blobservice-longrunning-tests.js">
<Link>test\services\blob\blobservice-longrunning-tests.js</Link>
</Content>

Просмотреть файл

@ -0,0 +1,655 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var assert = require('assert');
var RuntimeKernel = require('../../lib/serviceruntime/runtimekernel');
var NamedPipeInputChannel = require('../../lib/serviceruntime/namedpipeinputchannel');
var RuntimeVersionProtocolClient = require('../../lib/serviceruntime/runtimeversionprotocolclient');
var RuntimeVersionManager = require('../../lib/serviceruntime/runtimeversionmanager');
var Constants = require('../../lib/util/constants');
var ServiceRuntimeConstants = Constants.ServiceRuntimeConstants;
var azure = require('../../lib/azure');
suite('roleenvironment-tests', function () {
test('IsAvailable', function (done) {
azure.RoleEnvironment.isAvailable(function (error1, isAvailable1) {
assert.notEqual(error1, null);
assert.equal(isAvailable1, false);
var runtimeKernel = RuntimeKernel.getKernel();
var originalNamedPipeInputChannelReadData = runtimeKernel.namedPipeInputChannel.readData;
runtimeKernel.namedPipeInputChannel.readData = function (name, callback) {
if (name === '\\\\.\\pipe\\WindowsAzureRuntime') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RuntimeServerDiscovery xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<RuntimeServerEndpoints>" +
"<RuntimeServerEndpoint version=\"2011-03-08\" path=\"SomePath.GoalState\" />" +
"</RuntimeServerEndpoints>" +
"</RuntimeServerDiscovery>");
} else if (name === 'SomePath.GoalState') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<GoalState xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Incarnation>1</Incarnation>" +
"<ExpectedState>Started</ExpectedState>" +
"<RoleEnvironmentPath>C:\\file.xml</RoleEnvironmentPath>" +
"<CurrentStateEndpoint>\\.\pipe\WindowsAzureRuntime.CurrentState</CurrentStateEndpoint>" +
"<Deadline>9999-12-31T23:59:59.9999999</Deadline>" +
"</GoalState>");
} else {
callback('wrong file');
}
};
var originalFileInputChannelReadData = runtimeKernel.fileInputChannel.readData;
runtimeKernel.fileInputChannel.readData = function (name, callback) {
if (name === 'C:\\file.xml') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RoleEnvironment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Deployment id=\"92f5cd71a4c048ed94e1b130bd0c4639\" emulated=\"false\" />" +
"<CurrentInstance id=\"geophotoapp_IN_0\" roleName=\"geophotoapp\" faultDomain=\"0\" updateDomain=\"0\">" +
"<ConfigurationSettings />" +
"<LocalResources>" +
"<LocalResource name=\"DiagnosticStore\" path=\"somepath.DiagnosticStore\" sizeInMB=\"4096\" />" +
"</LocalResources>" +
"<Endpoints>" +
"<Endpoint name=\"HttpIn\" address=\"10.114.250.21\" port=\"80\" protocol=\"tcp\" />" +
"</Endpoints>" +
"</CurrentInstance>" +
"<Roles />" +
"</RoleEnvironment>");
} else {
callback('wrong file');
}
};
azure.RoleEnvironment.isAvailable(function (error2, isAvailable2) {
assert.equal(error2, null);
assert.equal(isAvailable2, true);
runtimeKernel.namedPipeInputChannel.readData = originalNamedPipeInputChannelReadData;
runtimeKernel.fileInputChannel.readData = originalFileInputChannelReadData;
runtimeKernel.protocol1RuntimeGoalStateClient.currentGoalState = null;
runtimeKernel.protocol1RuntimeGoalStateClient.currentEnvironmentData = null;
done();
});
});
});
test('GetLocalResourcesNoGoalStateNamedPipe', function (done) {
assert.throws(
azure.RoleEnvironment.getLocalResources(function () { }),
Error
);
done();
});
test('GetDeploymentId', function (done) {
var runtimeKernel = RuntimeKernel.getKernel();
var originalNamedPipeInputChannelReadData = runtimeKernel.namedPipeInputChannel.readData;
runtimeKernel.namedPipeInputChannel.readData = function (name, callback) {
if (name === '\\\\.\\pipe\\WindowsAzureRuntime') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RuntimeServerDiscovery xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<RuntimeServerEndpoints>" +
"<RuntimeServerEndpoint version=\"2011-03-08\" path=\"SomePath.GoalState\" />" +
"</RuntimeServerEndpoints>" +
"</RuntimeServerDiscovery>");
} else if (name === 'SomePath.GoalState') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<GoalState xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Incarnation>1</Incarnation>" +
"<ExpectedState>Started</ExpectedState>" +
"<RoleEnvironmentPath>C:\\file.xml</RoleEnvironmentPath>" +
"<CurrentStateEndpoint>\\.\pipe\WindowsAzureRuntime.CurrentState</CurrentStateEndpoint>" +
"<Deadline>9999-12-31T23:59:59.9999999</Deadline>" +
"</GoalState>");
} else {
callback('wrong file');
}
};
var originalFileInputChannelReadData = runtimeKernel.fileInputChannel.readData;
runtimeKernel.fileInputChannel.readData = function (name, callback) {
if (name === 'C:\\file.xml') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RoleEnvironment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Deployment id=\"mydeploymentid\" emulated=\"false\" />" +
"<CurrentInstance id=\"geophotoapp_IN_0\" roleName=\"geophotoapp\" faultDomain=\"0\" updateDomain=\"0\">" +
"<ConfigurationSettings />" +
"<LocalResources>" +
"<LocalResource name=\"DiagnosticStore\" path=\"somepath.DiagnosticStore\" sizeInMB=\"4096\" />" +
"</LocalResources>" +
"<Endpoints>" +
"<Endpoint name=\"HttpIn\" address=\"10.114.250.21\" port=\"80\" protocol=\"tcp\" />" +
"</Endpoints>" +
"</CurrentInstance>" +
"<Roles />" +
"</RoleEnvironment>");
} else {
callback('wrong file');
}
};
azure.RoleEnvironment.getDeploymentId(function (error, id) {
assert.equal(error, null);
assert.equal(id, 'mydeploymentid');
runtimeKernel.namedPipeInputChannel.readData = originalNamedPipeInputChannelReadData;
runtimeKernel.fileInputChannel.readData = originalFileInputChannelReadData;
runtimeKernel.protocol1RuntimeGoalStateClient.currentGoalState = null;
runtimeKernel.protocol1RuntimeGoalStateClient.currentEnvironmentData = null;
done();
});
});
test('GetLocalResources', function (done) {
var runtimeKernel = RuntimeKernel.getKernel();
var originalNamedPipeInputChannelReadData = runtimeKernel.namedPipeInputChannel.readData;
runtimeKernel.namedPipeInputChannel.readData = function (name, callback) {
if (name === '\\\\.\\pipe\\WindowsAzureRuntime') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RuntimeServerDiscovery xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<RuntimeServerEndpoints>" +
"<RuntimeServerEndpoint version=\"2011-03-08\" path=\"SomePath.GoalState\" />" +
"</RuntimeServerEndpoints>" +
"</RuntimeServerDiscovery>");
} else if (name === 'SomePath.GoalState') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<GoalState xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Incarnation>1</Incarnation>" +
"<ExpectedState>Started</ExpectedState>" +
"<RoleEnvironmentPath>C:\\file.xml</RoleEnvironmentPath>" +
"<CurrentStateEndpoint>\\.\pipe\WindowsAzureRuntime.CurrentState</CurrentStateEndpoint>" +
"<Deadline>9999-12-31T23:59:59.9999999</Deadline>" +
"</GoalState>");
} else {
callback('wrong file');
}
};
var originalFileInputChannelReadData = runtimeKernel.fileInputChannel.readData;
runtimeKernel.fileInputChannel.readData = function (name, callback) {
if (name === 'C:\\file.xml') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RoleEnvironment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Deployment id=\"92f5cd71a4c048ed94e1b130bd0c4639\" emulated=\"false\" />" +
"<CurrentInstance id=\"geophotoapp_IN_0\" roleName=\"geophotoapp\" faultDomain=\"0\" updateDomain=\"0\">" +
"<ConfigurationSettings />" +
"<LocalResources>" +
"<LocalResource name=\"DiagnosticStore\" path=\"somepath.DiagnosticStore\" sizeInMB=\"4096\" />" +
"</LocalResources>" +
"<Endpoints>" +
"<Endpoint name=\"HttpIn\" address=\"10.114.250.21\" port=\"80\" protocol=\"tcp\" />" +
"</Endpoints>" +
"</CurrentInstance>" +
"<Roles />" +
"</RoleEnvironment>");
} else {
callback('wrong file');
}
};
azure.RoleEnvironment.getLocalResources(function (error, localResources) {
assert.equal(error, null);
assert.notEqual(localResources, null);
assert.notEqual(localResources['DiagnosticStore'], null);
assert.notEqual(localResources['DiagnosticStore']['path'], null);
assert.notEqual(localResources['DiagnosticStore']['sizeInMB'], null);
runtimeKernel.namedPipeInputChannel.readData = originalNamedPipeInputChannelReadData;
runtimeKernel.fileInputChannel.readData = originalFileInputChannelReadData;
runtimeKernel.protocol1RuntimeGoalStateClient.currentGoalState = null;
runtimeKernel.protocol1RuntimeGoalStateClient.currentEnvironmentData = null;
done();
});
});
test('GetRoles', function (done) {
var runtimeKernel = RuntimeKernel.getKernel();
var originalNamedPipeInputChannelReadData = runtimeKernel.namedPipeInputChannel.readData;
runtimeKernel.namedPipeInputChannel.readData = function (name, callback) {
if (name === '\\\\.\\pipe\\WindowsAzureRuntime') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RuntimeServerDiscovery xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<RuntimeServerEndpoints>" +
"<RuntimeServerEndpoint version=\"2011-03-08\" path=\"SomePath.GoalState\" />" +
"</RuntimeServerEndpoints>" +
"</RuntimeServerDiscovery>");
} else if (name === 'SomePath.GoalState') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<GoalState xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Incarnation>1</Incarnation>" +
"<ExpectedState>Started</ExpectedState>" +
"<RoleEnvironmentPath>C:\\file.xml</RoleEnvironmentPath>" +
"<CurrentStateEndpoint>\\.\pipe\WindowsAzureRuntime.CurrentState</CurrentStateEndpoint>" +
"<Deadline>9999-12-31T23:59:59.9999999</Deadline>" +
"</GoalState>");
} else {
callback('wrong file');
}
};
var originalFileInputChannelReadData = runtimeKernel.fileInputChannel.readData;
runtimeKernel.fileInputChannel.readData = function (name, callback) {
if (name === 'C:\\file.xml') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RoleEnvironment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Deployment id=\"92f5cd71a4c048ed94e1b130bd0c4639\" emulated=\"false\" />" +
"<CurrentInstance id=\"geophotoapp_IN_0\" roleName=\"role1\" faultDomain=\"0\" updateDomain=\"0\">" +
"<ConfigurationSettings />" +
"<LocalResources />" +
"<Endpoints>" +
"<Endpoint name=\"HttpIn\" address=\"10.114.250.21\" port=\"80\" protocol=\"tcp\" />" +
"</Endpoints>" +
"</CurrentInstance>" +
"<Roles>" +
"<Role name=\"role1\">" +
"<Instances>" +
"<Instance id=\"deployment16(191).test.role1_IN_0\" faultDomain=\"0\" updateDomain=\"0\">" +
"<Endpoints>" +
"<Endpoint name=\"MyInternalEndpoint1\" address=\"127.255.0.0\" port=\"20000\" protocol=\"tcp\" />" +
"</Endpoints>" +
"</Instance>" +
"</Instances>" +
"</Role>" +
"<Role name=\"role2\">" +
"<Instances>" +
"<Instance id=\"deployment16(191).test.role2_IN_0\" faultDomain=\"0\" updateDomain=\"0\">" +
"<Endpoints>" +
"<Endpoint name=\"MyInternalEndpoint2\" address=\"127.255.0.2\" port=\"20002\" protocol=\"tcp\" />" +
"</Endpoints>" +
"</Instance>" +
"<Instance id=\"deployment16(191).test.role2_IN_1\" faultDomain=\"0\" updateDomain=\"0\">" +
"<Endpoints>" +
"<Endpoint name=\"MyInternalEndpoint3\" address=\"127.255.0.3\" port=\"20002\" protocol=\"tcp\" />" +
"<Endpoint name=\"MyInternalEndpoint4\" address=\"127.255.0.3\" port=\"20004\" protocol=\"tcp\" />" +
"</Endpoints>" +
"</Instance>" +
"</Instances>" +
"</Role>" +
"</Roles>" +
"</RoleEnvironment>");
} else {
callback('wrong file');
}
};
azure.RoleEnvironment.getRoles(function (error, roles) {
assert.equal(error, null);
assert.notEqual(roles, null);
assert.notEqual(roles['role1'], null);
assert.notEqual(roles['role1']['deployment16(191).test.role1_IN_0'], null);
assert.notEqual(roles['role1']['geophotoapp_IN_0'], null);
assert.notEqual(roles['role2'], null);
assert.notEqual(roles['role2']['deployment16(191).test.role2_IN_0'], null);
assert.notEqual(roles['role2']['deployment16(191).test.role2_IN_1'], null);
runtimeKernel.namedPipeInputChannel.readData = originalNamedPipeInputChannelReadData;
runtimeKernel.fileInputChannel.readData = originalFileInputChannelReadData;
runtimeKernel.protocol1RuntimeGoalStateClient.currentGoalState = null;
runtimeKernel.protocol1RuntimeGoalStateClient.currentEnvironmentData = null;
done();
});
});
test('CalculateChanges', function (done) {
var runtimeKernel = RuntimeKernel.getKernel();
var originalNamedPipeInputChannelReadData = runtimeKernel.namedPipeInputChannel.readData;
runtimeKernel.namedPipeInputChannel.readData = function (name, callback) {
if (name === '\\\\.\\pipe\\WindowsAzureRuntime') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RuntimeServerDiscovery xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<RuntimeServerEndpoints>" +
"<RuntimeServerEndpoint version=\"2011-03-08\" path=\"SomePath.GoalState\" />" +
"</RuntimeServerEndpoints>" +
"</RuntimeServerDiscovery>");
} else if (name === 'SomePath.GoalState') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<GoalState xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Incarnation>1</Incarnation>" +
"<ExpectedState>Started</ExpectedState>" +
"<RoleEnvironmentPath>C:\\file.xml</RoleEnvironmentPath>" +
"<CurrentStateEndpoint>\\.\pipe\WindowsAzureRuntime.CurrentState</CurrentStateEndpoint>" +
"<Deadline>9999-12-31T23:59:59.9999999</Deadline>" +
"</GoalState>");
} else {
callback('wrong file');
}
};
var originalFileInputChannelReadData = runtimeKernel.fileInputChannel.readData;
runtimeKernel.fileInputChannel.readData = function (name, callback) {
if (name === 'C:\\file.xml') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RoleEnvironment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Deployment id=\"92f5cd71a4c048ed94e1b130bd0c4639\" emulated=\"false\" />" +
"<CurrentInstance id=\"geophotoapp_IN_0\" roleName=\"role1\" faultDomain=\"0\" updateDomain=\"0\">" +
"<ConfigurationSettings />" +
"<LocalResources />" +
"<Endpoints>" +
"<Endpoint name=\"HttpIn\" address=\"10.114.250.21\" port=\"80\" protocol=\"tcp\" />" +
"</Endpoints>" +
"</CurrentInstance>" +
"<Roles>" +
"<Role name=\"role1\">" +
"<Instances>" +
"<Instance id=\"deployment16(191).test.role1_IN_0\" faultDomain=\"0\" updateDomain=\"0\">" +
"<Endpoints>" +
"<Endpoint name=\"MyInternalEndpoint1\" address=\"127.255.0.0\" port=\"20000\" protocol=\"tcp\" />" +
"</Endpoints>" +
"</Instance>" +
"</Instances>" +
"</Role>" +
"<Role name=\"role2\">" +
"<Instances>" +
"<Instance id=\"deployment16(191).test.role2_IN_0\" faultDomain=\"0\" updateDomain=\"0\">" +
"<Endpoints>" +
"<Endpoint name=\"MyInternalEndpoint2\" address=\"127.255.0.2\" port=\"20002\" protocol=\"tcp\" />" +
"</Endpoints>" +
"</Instance>" +
"<Instance id=\"deployment16(191).test.role2_IN_1\" faultDomain=\"0\" updateDomain=\"0\">" +
"<Endpoints>" +
"<Endpoint name=\"MyInternalEndpoint3\" address=\"127.255.0.3\" port=\"20002\" protocol=\"tcp\" />" +
"<Endpoint name=\"MyInternalEndpoint4\" address=\"127.255.0.3\" port=\"20004\" protocol=\"tcp\" />" +
"</Endpoints>" +
"</Instance>" +
"</Instances>" +
"</Role>" +
"</Roles>" +
"</RoleEnvironment>");
} else {
callback('wrong file');
}
};
// do first call to get environment data
azure.RoleEnvironment.getRoles(function (error, roles) {
assert.equal(error, null);
assert.notEqual(roles, null);
// explicitly call calculate changes to reread and compare to previous environment data
azure.RoleEnvironment._calculateChanges(function (calculateChangesError, changes) {
assert.equal(calculateChangesError, null);
assert.notEqual(changes, null);
assert.equal(changes.length, 0);
runtimeKernel.namedPipeInputChannel.readData = originalNamedPipeInputChannelReadData;
runtimeKernel.fileInputChannel.readData = originalFileInputChannelReadData;
runtimeKernel.protocol1RuntimeGoalStateClient.currentGoalState = null;
runtimeKernel.protocol1RuntimeGoalStateClient.currentEnvironmentData = null;
done();
});
});
});
test('testRequestRecycle', function (done) {
var runtimeKernel = RuntimeKernel.getKernel();
var originalNamedPipeInputChannelReadData = runtimeKernel.namedPipeInputChannel.readData;
runtimeKernel.namedPipeInputChannel.readData = function (name, callback) {
if (name === '\\\\.\\pipe\\WindowsAzureRuntime') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RuntimeServerDiscovery xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<RuntimeServerEndpoints>" +
"<RuntimeServerEndpoint version=\"2011-03-08\" path=\"SomePath.GoalState\" />" +
"</RuntimeServerEndpoints>" +
"</RuntimeServerDiscovery>");
} else if (name === 'SomePath.GoalState') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<GoalState xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Incarnation>1</Incarnation>" +
"<ExpectedState>Started</ExpectedState>" +
"<RoleEnvironmentPath>C:\\file.xml</RoleEnvironmentPath>" +
"<CurrentStateEndpoint>\\.\pipe\WindowsAzureRuntime.CurrentState</CurrentStateEndpoint>" +
"<Deadline>9999-12-31T23:59:59.9999999</Deadline>" +
"</GoalState>");
} else {
callback('wrong file');
}
};
var originalFileInputChannelReadData = runtimeKernel.fileInputChannel.readData;
runtimeKernel.fileInputChannel.readData = function (name, callback) {
if (name === 'C:\\file.xml') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RoleEnvironment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Deployment id=\"deploymentId\" emulated=\"false\" />" +
"<CurrentInstance id=\"test\" roleName=\"test\" faultDomain=\"0\" updateDomain=\"0\">" +
"<ConfigurationSettings />" +
"<LocalResources />" +
"<Endpoints />" +
"</CurrentInstance>" +
"<Roles />" +
"</RoleEnvironment>");
} else {
callback('wrong file');
}
};
var originalNamedPipeOutputChannelWriteOutputChannel = runtimeKernel.namedPipeOutputChannel.writeOutputChannel;
var writtenData;
runtimeKernel.namedPipeOutputChannel.writeOutputChannel = function (data, callback) {
writtenData = data;
callback();
};
azure.RoleEnvironment.requestRecycle(function (error) {
assert.equal(error, null);
assert.equal(writtenData, '<?xml version="1.0" encoding="utf-8" standalone="yes"?><CurrentState><StatusLease ClientId="' + azure.RoleEnvironment.clientId + '"><Acquire><Expiration>Fri Dec 31 9999 15:59:59 GMT-0800 (Pacific Standard Time)</Expiration><Incarnation>1</Incarnation><Status>recycle</Status></Acquire></StatusLease></CurrentState>');
runtimeKernel.namedPipeInputChannel.readData = originalNamedPipeInputChannelReadData;
runtimeKernel.fileInputChannel.readData = originalFileInputChannelReadData;
runtimeKernel.protocol1RuntimeGoalStateClient.currentGoalState = null;
runtimeKernel.protocol1RuntimeGoalStateClient.currentEnvironmentData = null;
runtimeKernel.namedPipeOutputChannel.writeOutputChannel = originalNamedPipeOutputChannelWriteOutputChannel;
done();
});
});
test('testClearStatus', function (done) {
var runtimeKernel = RuntimeKernel.getKernel();
var originalNamedPipeInputChannelReadData = runtimeKernel.namedPipeInputChannel.readData;
runtimeKernel.namedPipeInputChannel.readData = function (name, callback) {
if (name === '\\\\.\\pipe\\WindowsAzureRuntime') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RuntimeServerDiscovery xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<RuntimeServerEndpoints>" +
"<RuntimeServerEndpoint version=\"2011-03-08\" path=\"SomePath.GoalState\" />" +
"</RuntimeServerEndpoints>" +
"</RuntimeServerDiscovery>");
} else if (name === 'SomePath.GoalState') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<GoalState xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Incarnation>1</Incarnation>" +
"<ExpectedState>Started</ExpectedState>" +
"<RoleEnvironmentPath>C:\\file.xml</RoleEnvironmentPath>" +
"<CurrentStateEndpoint>\\.\pipe\WindowsAzureRuntime.CurrentState</CurrentStateEndpoint>" +
"<Deadline>9999-12-31T23:59:59.9999999</Deadline>" +
"</GoalState>");
} else {
callback('wrong file');
}
};
var originalFileInputChannelReadData = runtimeKernel.fileInputChannel.readData;
runtimeKernel.fileInputChannel.readData = function (name, callback) {
if (name === 'C:\\file.xml') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RoleEnvironment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Deployment id=\"deploymentId\" emulated=\"false\" />" +
"<CurrentInstance id=\"test\" roleName=\"test\" faultDomain=\"0\" updateDomain=\"0\">" +
"<ConfigurationSettings />" +
"<LocalResources />" +
"<Endpoints />" +
"</CurrentInstance>" +
"<Roles />" +
"</RoleEnvironment>");
} else {
callback('wrong file');
}
};
var originalNamedPipeOutputChannelWriteOutputChannel = runtimeKernel.namedPipeOutputChannel.writeOutputChannel;
var writtenData;
runtimeKernel.namedPipeOutputChannel.writeOutputChannel = function (data, callback) {
writtenData = data;
callback();
};
azure.RoleEnvironment.clearStatus(function (error) {
assert.equal(error, null);
assert.equal(writtenData, '<?xml version="1.0" encoding="utf-8" standalone="yes"?><CurrentState><StatusLease ClientId="' + azure.RoleEnvironment.clientId + '"><Release/></StatusLease></CurrentState>');
runtimeKernel.namedPipeInputChannel.readData = originalNamedPipeInputChannelReadData;
runtimeKernel.fileInputChannel.readData = originalFileInputChannelReadData;
runtimeKernel.protocol1RuntimeGoalStateClient.currentGoalState = null;
runtimeKernel.protocol1RuntimeGoalStateClient.currentEnvironmentData = null;
runtimeKernel.namedPipeOutputChannel.writeOutputChannel = originalNamedPipeOutputChannelWriteOutputChannel;
done();
});
});
test('testSetStatus', function (done) {
var runtimeKernel = RuntimeKernel.getKernel();
var originalNamedPipeInputChannelReadData = runtimeKernel.namedPipeInputChannel.readData;
runtimeKernel.namedPipeInputChannel.readData = function (name, callback) {
if (name === '\\\\.\\pipe\\WindowsAzureRuntime') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RuntimeServerDiscovery xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<RuntimeServerEndpoints>" +
"<RuntimeServerEndpoint version=\"2011-03-08\" path=\"SomePath.GoalState\" />" +
"</RuntimeServerEndpoints>" +
"</RuntimeServerDiscovery>");
} else if (name === 'SomePath.GoalState') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<GoalState xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Incarnation>1</Incarnation>" +
"<ExpectedState>Started</ExpectedState>" +
"<RoleEnvironmentPath>C:\\file.xml</RoleEnvironmentPath>" +
"<CurrentStateEndpoint>\\.\pipe\WindowsAzureRuntime.CurrentState</CurrentStateEndpoint>" +
"<Deadline>9999-12-31T23:59:59.9999999</Deadline>" +
"</GoalState>");
} else {
callback('wrong file');
}
};
var originalFileInputChannelReadData = runtimeKernel.fileInputChannel.readData;
runtimeKernel.fileInputChannel.readData = function (name, callback) {
if (name === 'C:\\file.xml') {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RoleEnvironment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Deployment id=\"deploymentId\" emulated=\"false\" />" +
"<CurrentInstance id=\"test\" roleName=\"test\" faultDomain=\"0\" updateDomain=\"0\">" +
"<ConfigurationSettings />" +
"<LocalResources />" +
"<Endpoints />" +
"</CurrentInstance>" +
"<Roles />" +
"</RoleEnvironment>");
} else {
callback('wrong file');
}
};
var originalNamedPipeOutputChannelWriteOutputChannel = runtimeKernel.namedPipeOutputChannel.writeOutputChannel;
var writtenData;
runtimeKernel.namedPipeOutputChannel.writeOutputChannel = function (data, callback) {
writtenData = data;
callback();
};
azure.RoleEnvironment.setStatus(ServiceRuntimeConstants.RoleInstanceStatus.READY, new Date(2012, 1, 1, 12, 10, 10, 0), function (error1) {
assert.equal(error1, null);
assert.equal(writtenData, '<?xml version="1.0" encoding="utf-8" standalone="yes"?><CurrentState><StatusLease ClientId="' + azure.RoleEnvironment.clientId + '"><Acquire><Expiration>Wed Feb 01 2012 12:10:10 GMT-0800 (Pacific Standard Time)</Expiration><Incarnation>1</Incarnation><Status>started</Status></Acquire></StatusLease></CurrentState>');
azure.RoleEnvironment.setStatus(ServiceRuntimeConstants.RoleInstanceStatus.BUSY, new Date(2012, 1, 1, 10, 10, 10, 0), function (error2) {
assert.equal(error2, null);
assert.equal(writtenData, '<?xml version="1.0" encoding="utf-8" standalone="yes"?><CurrentState><StatusLease ClientId="' + azure.RoleEnvironment.clientId + '"><Acquire><Expiration>Wed Feb 01 2012 10:10:10 GMT-0800 (Pacific Standard Time)</Expiration><Incarnation>1</Incarnation><Status>busy</Status></Acquire></StatusLease></CurrentState>');
runtimeKernel.namedPipeInputChannel.readData = originalNamedPipeInputChannelReadData;
runtimeKernel.fileInputChannel.readData = originalFileInputChannelReadData;
runtimeKernel.protocol1RuntimeGoalStateClient.currentGoalState = null;
runtimeKernel.protocol1RuntimeGoalStateClient.currentEnvironmentData = null;
runtimeKernel.namedPipeOutputChannel.writeOutputChannel = originalNamedPipeOutputChannelWriteOutputChannel;
done();
});
});
});
});

Просмотреть файл

@ -0,0 +1,51 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var assert = require('assert');
var NamedPipeInputChannel = require('../../lib/serviceruntime/namedpipeinputchannel');
var RuntimeVersionProtocolClient = require('../../lib/serviceruntime/runtimeversionprotocolclient');
var RuntimeVersionManager = require('../../lib/serviceruntime/runtimeversionmanager');
suite('runtimeversionmanager-tests', function () {
test('GetRuntimeClient', function (done) {
var inputChannel = new NamedPipeInputChannel();
inputChannel.readData = function (name, callback) {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RuntimeServerDiscovery xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<RuntimeServerEndpoints>" +
"<RuntimeServerEndpoint version=\"2011-03-08\" path=\"SomePath.GoalState\" />" +
"</RuntimeServerEndpoints>" +
"</RuntimeServerDiscovery>");
};
var runtimeVersionProtocolClient = new RuntimeVersionProtocolClient(inputChannel);
var runtimeKernel = {
getGoalStateClient: function () { return {}; },
getCurrentStateClient: function () { return {}; }
};
var runtimeVersionManager = new RuntimeVersionManager(runtimeVersionProtocolClient, runtimeKernel);
runtimeVersionManager.getRuntimeClient('', function (error, runtimeClient) {
assert.equal(error, undefined);
assert.notEqual(runtimeClient, null);
done();
});
});
});

Просмотреть файл

@ -0,0 +1,69 @@
/**
* Copyright 2011 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var assert = require('assert');
var NamedPipeInputChannel = require('../../lib/serviceruntime/namedpipeinputchannel');
var RuntimeVersionProtocolClient = require('../../lib/serviceruntime/runtimeversionprotocolclient');
suite('runtimeversionprotocolclient-tests', function () {
test('GetVersionMapSingle', function (done) {
var inputChannel = new NamedPipeInputChannel();
inputChannel.readData = function (name, callback) {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RuntimeServerDiscovery xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<RuntimeServerEndpoints>" +
"<RuntimeServerEndpoint version=\"2011-03-08\" path=\"SomePath.GoalState\" />" +
"</RuntimeServerEndpoints>" +
"</RuntimeServerDiscovery>");
};
var runtimeVersionProtocolClient = new RuntimeVersionProtocolClient(inputChannel);
runtimeVersionProtocolClient.getVersionMap('', function (error, versions) {
assert.equal(error, null);
assert.notEqual(versions, null);
assert.equal(versions["2011-03-08"], "SomePath.GoalState");
done();
});
});
test('GetVersionMapArray', function (done) {
var inputChannel = new NamedPipeInputChannel();
inputChannel.readData = function (name, callback) {
callback(undefined,
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<RuntimeServerDiscovery xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<RuntimeServerEndpoints>" +
"<RuntimeServerEndpoint version=\"2011-03-08\" path=\"SomePath.GoalState\" />" +
"<RuntimeServerEndpoint version=\"2011-08-08\" path=\"SomeOtherPath.GoalState\" />" +
"</RuntimeServerEndpoints>" +
"</RuntimeServerDiscovery>");
};
var runtimeVersionProtocolClient = new RuntimeVersionProtocolClient(inputChannel);
runtimeVersionProtocolClient.getVersionMap('', function (error, versions) {
assert.equal(error, null);
assert.notEqual(versions, null);
assert.equal(versions["2011-03-08"], "SomePath.GoalState");
assert.equal(versions["2011-08-08"], "SomeOtherPath.GoalState");
done();
});
});
});

Просмотреть файл

@ -40,13 +40,13 @@ var mockServerClient;
var currentTestName;
suite('blobservice-longrunning-tests', function () {
setup: function (done) {
setup(function (done) {
blobService = azure.createBlobService(ServiceClient.DEVSTORE_STORAGE_ACCOUNT, ServiceClient.DEVSTORE_STORAGE_ACCESS_KEY, ServiceClient.DEVSTORE_BLOB_HOST);
done();
});
teardown: function (done) {
teardown(function (done) {
var deleteFiles = function () {
// delete test files
var list = fs.readdirSync('./');

Просмотреть файл

@ -1,3 +1,6 @@
serviceruntime/roleenvironment-tests.js
serviceruntime/runtimeversionmanager-tests.js
serviceruntime/runtimeversionprotocolclient-tests.js
services/blob/blobservice-tests.js
services/blob/sharedaccesssignature-tests.js
services/blob/sharedkey-tests.js

Просмотреть файл

@ -142,4 +142,24 @@ suite('util-tests', function() {
done();
});
test('keys counting works', function (done) {
// int positives
assert.equal(util.objectKeysLength({ }), 0);
assert.equal(util.objectKeysLength(null), 0);
assert.equal(util.objectKeysLength({ prop1: 1 }), 1);
assert.equal(util.objectKeysLength({ prop1: 1, prop2: 2 }), 2);
done();
});
test('first key works', function (done) {
// int positives
assert.equal(util.objectFirstKey({}), null);
assert.equal(util.objectFirstKey(null), null);
assert.equal(util.objectFirstKey({ prop1: 1 }), 'prop1');
assert.equal(util.objectFirstKey({ prop1: 1, prop2: 2 }), 'prop1');
done();
});
});