Incremental work towards service runtime.
This commit is contained in:
Родитель
581d6317fe
Коммит
8887fd37be
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
77
package.json
77
package.json
|
@ -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();
|
||||
});
|
||||
});
|
Загрузка…
Ссылка в новой задаче