Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #376 from andrerod/connectionStrings

Adding connection string parser.
  • Loading branch information...
commit a6830e10f419bb72ad8490ef6d318e5e2cbe588d 2 parents dd97c17 + 8b2ae41
@andrerod andrerod authored
View
53 lib/azure.js
@@ -26,13 +26,13 @@ exports.TableService = TableService;
* Creates a new TableService object.
* If no storageaccount or storageaccesskey are provided, the AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_ACCESS_KEY environment variables will be used.
*
-* @param {string} [storageAccount] The storage account.
-* @param {string} [storageAccessKey] The storage access key.
-* @param {string} [host] The host address.
-* @param {object} [authenticationProvider] The authentication provider.
+* @param {string} [storageAccountOrConnectionString] The storage account or the connection string.
+* @param {string} [storageAccessKey] The storage access key.
+* @param {string} [host] The host address.
+* @param {object} [authenticationProvider] The authentication provider.
*/
-exports.createTableService = function (storageAccount, storageAccessKey, host, authenticationProvider) {
- return new TableService(storageAccount, storageAccessKey, host, authenticationProvider);
+exports.createTableService = function (storageAccountOrConnectionString, storageAccessKey, host, authenticationProvider) {
+ return new TableService(storageAccountOrConnectionString, storageAccessKey, host, authenticationProvider);
};
/**
@@ -46,13 +46,13 @@ exports.BlobService = BlobService;
* Creates a new BlobService object.
* If no storageaccount or storageaccesskey are provided, the AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_ACCESS_KEY environment variables will be used.
*
-* @param {string} [storageAccount] The storage account.
-* @param {string} [storageAccessKey] The storage access key.
-* @param {string} [host] The host address.
-* @param {object} [authenticationProvider] The authentication provider.
+* @param {string} [storageAccountOrConnectionString] The storage account or the connection string.
+* @param {string} [storageAccessKey] The storage access key.
+* @param {string} [host] The host address.
+* @param {object} [authenticationProvider] The authentication provider.
*/
-exports.createBlobService = function (storageAccount, storageAccessKey, host, authenticationProvider) {
- return new BlobService(storageAccount, storageAccessKey, host, authenticationProvider);
+exports.createBlobService = function (storageAccountOrConnectionString, storageAccessKey, host, authenticationProvider) {
+ return new BlobService(storageAccountOrConnectionString, storageAccessKey, host, authenticationProvider);
};
/**
@@ -67,13 +67,13 @@ exports.QueueService = QueueService;
* If no storageAccount or storageAccessKey are provided, the AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_ACCESS_KEY
* environment variables will be used.
*
-* @param {string} [storageAccount] The storage account.
-* @param {string} [storageAccessKey] The storage access key.
-* @param {string} [host] The host address.
-* @param {object} [authenticationProvider] The authentication provider.
+* @param {string} [storageAccountOrConnectionString] The storage account or the connection string.
+* @param {string} [storageAccessKey] The storage access key.
+* @param {string} [host] The host address.
+* @param {object} [authenticationProvider] The authentication provider.
*/
-exports.createQueueService = function (storageAccount, storageAccessKey, host, authenticationProvider) {
- return new QueueService(storageAccount, storageAccessKey, host, authenticationProvider);
+exports.createQueueService = function (storageAccountOrConnectionString, storageAccessKey, host, authenticationProvider) {
+ return new QueueService(storageAccountOrConnectionString, storageAccessKey, host, authenticationProvider);
};
/**
@@ -86,15 +86,15 @@ exports.ServiceBusService = ServiceBusService;
/**
* Creates a new ServiceBusService object.
*
-* @param {string} [namespace] The service bus namespace.
-* @param {string} [accessKey] The password.
-* @param {string} [issuer] The issuer.
-* @param {string} [acsNamespace] The acs namespace. Usually the same as the sb namespace with "-sb" suffix.
-* @param {string} [host] The host address.
-* @param {object} [authenticationProvider] The authentication provider.
+* @param {string} [namespaceOrConnectionString] The service bus namespace.
+* @param {string} [accessKey] The password.
+* @param {string} [issuer] The issuer.
+* @param {string} [acsNamespace] The acs namespace. Usually the same as the sb namespace with "-sb" suffix.
+* @param {string} [host] The host address.
+* @param {object} [authenticationProvider] The authentication provider.
*/
-exports.createServiceBusService = function (namespace, accessKey, issuer, acsNamespace, host, authenticationProvider) {
- return new ServiceBusService(namespace, accessKey, issuer, acsNamespace, host, authenticationProvider);
+exports.createServiceBusService = function (namespaceOrConnectionString, accessKey, issuer, acsNamespace, host, authenticationProvider) {
+ return new ServiceBusService(namespaceOrConnectionString, accessKey, issuer, acsNamespace, host, authenticationProvider);
};
/**
@@ -149,6 +149,7 @@ exports.SharedKeyTable = require('./services/table/sharedkeytable');
exports.SharedKeyLiteTable = require('./services/table/sharedkeylitetable');
exports.ISO8061Date = require('./util/iso8061date');
exports.Logger = require('./diagnostics/logger');
+exports.ConnectionStringParser = require('./services/core/connectionstringparser');
/*
* Convenience functions.
View
12 lib/services/blob/blobservice.js
@@ -70,12 +70,12 @@ BlobService.incorrectEndByteOffsetErr = 'End byte offset must be a modulus of 51
* @constructor
* @extends {ServiceClient}
*
-* @param {string} [storageAccount] The storage account.
-* @param {string} [storageAccessKey] The storage access key.
-* @param {string} [host] The host address.
-* @param {object} [authenticationProvider] The authentication provider.
+* @param {string} [storageAccountOrConnectionString] The storage account or the connection string.
+* @param {string} [storageAccessKey] The storage access key.
+* @param {string} [host] The host address.
+* @param {object} [authenticationProvider] The authentication provider.
*/
-function BlobService(storageAccount, storageAccessKey, host, authenticationProvider) {
+function BlobService(storageAccountOrConnectionString, storageAccessKey, host, authenticationProvider) {
if (!host) {
if (ServiceClient.isEmulated()) {
host = ServiceClient.DEVSTORE_BLOB_HOST;
@@ -84,7 +84,7 @@ function BlobService(storageAccount, storageAccessKey, host, authenticationProvi
}
}
- BlobService.super_.call(this, host, storageAccount, storageAccessKey, authenticationProvider);
+ BlobService.super_.call(this, storageAccountOrConnectionString, storageAccessKey, host, authenticationProvider);
if (!this.authenticationProvider) {
this.authenticationProvider = new SharedKey(this.storageAccount, this.storageAccessKey, this.usePathStyleUri);
View
217 lib/services/core/connectionstringparser.js
@@ -0,0 +1,217 @@
+/**
+* Copyright (c) Microsoft. All rights reserved.
+*
+* 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 util = require('../../util/util');
+
+// Expose 'ConnectionStringParser'.
+exports = module.exports;
+
+/**
+* Creates a new 'ConnectionString' instance.
+*
+* @constructor
+* @param {string} connectionString The connection string to be parsed.
+*/
+function ConnectionStringParser(connectionString) {
+ this._value = connectionString;
+ this._pos = 0;
+ this._state = 'ExpectKey';
+}
+
+/**
+* Parses a connection string into an object.
+*
+* @return {object} The query string object.
+*/
+ConnectionStringParser.prototype._parse = function () {
+ var key = null;
+ var value = null;
+ var parsedConnectionString = { };
+
+ for (; ;) {
+ this._skipWhitespaces();
+
+ if (this._pos === this._value.length && this._state !== 'ExpectValue')
+ {
+ // Not stopping after the end has been reached and a value is expected
+ // results in creating an empty value, which we expect.
+ break;
+ }
+
+ switch (this._state) {
+ case 'ExpectKey':
+ key = this._extractKey();
+ this._state = 'ExpectAssignment';
+ break;
+
+ case 'ExpectAssignment':
+ this._skipOperator('=');
+ this._state = 'ExpectValue';
+ break;
+
+ case 'ExpectValue':
+ value = this._extractValue();
+ this._state = 'ExpectSeparator';
+ parsedConnectionString[key.toLowerCase()] = value;
+ key = null;
+ value = null;
+ break;
+
+ default:
+ this._skipOperator(';');
+ this._state = 'ExpectKey';
+ break;
+ }
+ }
+
+ if (this._state === 'ExpectAssignment') {
+ // Must end parsing in the valid state (expected key or separator)
+ throw new Error('Missing character "="');
+ }
+
+ return parsedConnectionString;
+};
+
+
+/**
+* Skips whitespaces at the current position.
+*/
+ConnectionStringParser.prototype._skipWhitespaces = function () {
+ while (this._pos < this._value.length && this._value[this._pos] === ' ')
+ {
+ this._pos++;
+ }
+};
+
+/**
+* Extracts key at the current position.
+*
+* @return {string} Key.
+*/
+ConnectionStringParser.prototype._extractKey = function () {
+ var key = null;
+ var firstPos = this._pos;
+ var ch = this._value[this._pos++];
+
+ if (ch === '"' || ch === '\'') {
+ key = this._extractString(ch);
+ } else if (ch === ';' || ch === '=') {
+ // Key name was expected.
+ throw new Error('Missing key');
+ } else {
+ while (this._pos < this._value.length) {
+ ch = this._value[this._pos];
+ if (ch === '=') {
+ break;
+ }
+ this._pos++;
+ }
+
+ key = this._value.substring(firstPos, this._pos);
+ }
+
+ if (key.length === 0) {
+ // Empty key name.
+ throw new Error('Empty key name');
+ }
+
+ return key;
+};
+
+/**
+* Extracts the string until the given quotation mark.
+*
+* @param {string} quote Quotation mark terminating the string.
+* @return {string} string.
+*/
+ConnectionStringParser.prototype._extractString = function (quote) {
+ var firstPos = this._pos;
+ while (this._pos < this._value.length && this._value[this._pos] !== quote)
+ {
+ this._pos++;
+ }
+
+ if (this._pos === this._value.length) {
+ // Runaway string.
+ throw new Error('Unterminated string starting at position ' + firstPos);
+ }
+
+ return this._value.substring(firstPos, this._pos++);
+};
+
+/**
+* Skips specified operator.
+*
+* @param {string} operatorChar The oeprator to skip.
+*/
+ConnectionStringParser.prototype._skipOperator = function (operatorChar) {
+ if (this._value[this._pos] != operatorChar) {
+ // Character was expected.
+ throw new Error('expecting ' + operatorChar + ' but instead got ' + currentChar + ' at position ' + this._pos);
+ }
+
+ this._pos++;
+};
+
+/**
+* Extracts key's value.
+*
+* @return {string} The key value.
+*/
+ConnectionStringParser.prototype._extractValue = function () {
+ var value = '';
+
+ if (this._pos < this._value.length) {
+ var ch = this._value[this._pos];
+
+ if (ch === '\'' || ch === '"') {
+ this._pos++;
+ value = this._extractString(ch);
+ } else {
+ var firstPos = this._pos;
+ var isFound = false;
+
+ while (this._pos < this._value.length && !isFound) {
+ ch = this._value[this._pos];
+
+ switch (ch) {
+ case ';':
+ isFound = true;
+ break;
+
+
+ default:
+ this._pos++;
+ break;
+ }
+ }
+
+ value = this._value.substring(firstPos, this._pos);
+ }
+ }
+
+ return value;
+};
+
+/**
+* Parses a connection string.
+*
+* @param {number} connectionString The connection string to be parsed.
+* @return {object} The query string object.
+*/
+exports.parse = function (connectionString) {
+ var connectionStringParser = new ConnectionStringParser(connectionString);
+ return connectionStringParser._parse();
+};
View
3  lib/services/core/servicebusserviceclient.js
@@ -33,12 +33,11 @@ exports = module.exports = ServiceBusServiceClient;
* Creates a new ServiceBusServiceClient object.
*
* @constructor
-* @param {string} host The host for the service.
+* @param {string} host The host for the service.
* @param {string} [namespace] The service bus namespace.
* @param {string} [accessKey] The password.
* @param {string} [issuer] The issuer.
* @param {string} [acsNamespace] The acs namespace. Usually the same as the sb namespace with "-sb" suffix.
-* @param {string} [host] The host address.
* @param {object} [authenticationProvider] The authentication provider.
*/
function ServiceBusServiceClient(host, namespace, accessKey, issuer, acsNamespace, authenticationProvider) {
View
6 lib/services/core/serviceclient.js
@@ -109,9 +109,11 @@ function ServiceClient(host, authenticationProvider) {
var parsedHost = this._parseHost(host);
this.host = parsedHost.hostname;
this.port = parsedHost.port;
- this.protocol = parsedHost.protocol + '//';
+ if (!this.protocol) {
+ this.protocol = parsedHost.protocol + '//';
+ }
}
- else {
+ else if (!this.protocol) {
this.protocol = ServiceClient.DEFAULT_PROTOCOL;
}
View
35 lib/services/core/storageserviceclient.js
@@ -23,6 +23,8 @@ var xml2js = require('xml2js');
var azureutil = require('../../util/util');
+var ConnectionStringParser = require('../core/connectionstringparser');
+
var ServiceClient = require('./serviceclient');
var Constants = require('../../util/constants');
var HeaderConstants = Constants.HeaderConstants;
@@ -41,12 +43,35 @@ StorageServiceClient.incorrectStorageAccessKeyErr = 'AccessKey must be a non emp
* Creates a new ServiceClient object.
*
* @constructor
-* @param {string} host The host for the service.
-* @param {string} storageAccount The storage account.
-* @param {string} storageAccessKey The storage access key.
-* @param {object} authenticationProvider The authentication provider object (e.g. sharedkey / sharedkeytable / sharedaccesssignature).
+* @param {string} storageAccountOrConnectionString The storage account or connection string.
+* @param {string} storageAccessKey The storage access key.
+* @param {string} host The host for the service.
+* @param {object} authenticationProvider The authentication provider object (e.g. sharedkey / sharedkeytable / sharedaccesssignature).
*/
-function StorageServiceClient(host, storageAccount, storageAccessKey, authenticationProvider) {
+function StorageServiceClient(storageAccountOrConnectionString, storageAccessKey, host, authenticationProvider) {
+ var storageAccount = storageAccountOrConnectionString;
+
+ if (storageAccountOrConnectionString && !storageAccessKey) {
+ // If namespaceOrConnectionString was passed and no accessKey was passed, assume connection string
+ var connectionString = ConnectionStringParser.parse(storageAccountOrConnectionString);
+ if (connectionString['accountname']) {
+ storageAccount = connectionString['accountname'];
+ }
+
+ if (connectionString['accountkey']) {
+ storageAccessKey = connectionString['accountkey'];
+ }
+
+ if (connectionString['defaultendpointsprotocol']) {
+ if (connectionString['defaultendpointsprotocol'] !== 'http' &&
+ connectionString['defaultendpointsprotocol'] !== 'https') {
+ throw new Error('Invalid protocol ' + connectionString['defaultendpointsprotocol']);
+ }
+
+ this.protocol = connectionString['defaultendpointsprotocol'] + '://';
+ }
+ }
+
this._setAccountCredentials(storageAccount, storageAccessKey);
this.apiVersion = HeaderConstants.TARGET_STORAGE_VERSION;
this.usePathStyleUri = ServiceClient.isEmulated(host);
View
12 lib/services/queue/queueservice.js
@@ -44,12 +44,12 @@ exports = module.exports = QueueService;
* @constructor
* @augments {ServiceClient}
*
-* @param {string} [storageAccount] The storage account.
-* @param {string} [storageAccessKey] The storage access key.
-* @param {string} [host] The host address.
-* @param {object} [authenticationProvider] The authentication provider.
+* @param {string} [storageAccountOrConnectionString] The storage account or the connection string.
+* @param {string} [storageAccessKey] The storage access key.
+* @param {string} [host] The host address.
+* @param {object} [authenticationProvider] The authentication provider.
*/
-function QueueService(storageAccount, storageAccessKey, host, authenticationProvider) {
+function QueueService(storageAccountOrConnectionString, storageAccessKey, host, authenticationProvider) {
if (!host) {
if (ServiceClient.isEmulated()) {
host = ServiceClient.DEVSTORE_QUEUE_HOST;
@@ -58,7 +58,7 @@ function QueueService(storageAccount, storageAccessKey, host, authenticationProv
}
}
- QueueService.super_.call(this, host, storageAccount, storageAccessKey, authenticationProvider);
+ QueueService.super_.call(this, storageAccountOrConnectionString, storageAccessKey, host, authenticationProvider);
if (!this.authenticationProvider) {
this.authenticationProvider = new SharedKey(this.storageAccount, this.storageAccessKey, this.usePathStyleUri);
View
41 lib/services/serviceBus/servicebusservice.js
@@ -15,6 +15,7 @@
// Module dependencies.
var util = require('util');
+var url = require('url');
var azureutil = require('../../util/util');
var RFC1123 = require('../../util/rfc1123date');
@@ -28,6 +29,8 @@ var QueryStringConstants = Constants.QueryStringConstants;
var HttpConstants = Constants.HttpConstants;
var HeaderConstants = Constants.HeaderConstants;
+var ConnectionStringParser = require('../core/connectionstringparser');
+
var QueueResult = require('./models/queueresult');
var QueueMessageResult = require('./models/queuemessageresult');
var TopicResult = require('./models/topicresult');
@@ -43,18 +46,42 @@ exports = module.exports = ServiceBusService;
* @constructor
* @augments {ServiceClient}
*
-* @param {string} [namespace] The service bus namespace.
-* @param {string} [accessKey] The password.
-* @param {string} [issuer] The issuer.
-* @param {string} [acsNamespace] The acs namespace. Usually the same as the sb namespace with "-sb" suffix.
-* @param {string} [host] The host address.
-* @param {object} [authenticationProvider] The authentication provider.
+* @param {string} [namespaceOrConnectionString] The service bus namespace or the connection string.
+* @param {string} [accessKey] The password.
+* @param {string} [issuer] The issuer.
+* @param {string} [acsNamespace] The acs namespace. Usually the same as the sb namespace with "-sb" suffix.
+* @param {string} [host] The host address.
+* @param {object} [authenticationProvider] The authentication provider.
*/
-function ServiceBusService(namespace, accessKey, issuer, acsNamespace, host, authenticationProvider) {
+function ServiceBusService(namespaceOrConnectionString, accessKey, issuer, acsNamespace, host, authenticationProvider) {
if (!host) {
host = ServiceClient.CLOUD_SERVICEBUS_HOST;
}
+ var namespace = namespaceOrConnectionString;
+ if (namespaceOrConnectionString && !accessKey) {
+ // If namespaceOrConnectionString was passed and no accessKey was passed, assume connection string
+ var connectionString = ConnectionStringParser.parse(namespaceOrConnectionString);
+ if (connectionString['endpoint']) {
+ var endpoint = url.parse(connectionString['endpoint']);
+ namespace = endpoint.host.split('.')[0];
+ host = endpoint.host.substring(namespace.length + 1);
+ }
+
+ if (connectionString['sharedsecretissuer']) {
+ issuer = connectionString['sharedsecretissuer'];
+ }
+
+ if (connectionString['sharedsecretvalue']) {
+ accessKey = connectionString['sharedsecretvalue'];
+ }
+
+ if (connectionString['stsendpoint']) {
+ var endpoint = url.parse(connectionString['stsendpoint']);
+ acsNamespace = endpoint.host.split('.')[0];
+ }
+ }
+
ServiceBusService.super_.call(this, host, namespace, accessKey, issuer, acsNamespace, authenticationProvider);
}
View
32 lib/services/serviceManagement/servicemanagementservice.js
@@ -31,24 +31,24 @@ exports = module.exports = ServiceManagementService;
* Creates a new ServiceManagementService object.
*
* @constructor
-* @param {string} subscriptionId The subscription ID for the account.
-* @param {string} authentication The authentication object for the client.
-* {
-* keyfile: 'path to .pem',
-* certfile: 'path to .pem',
-* keyvalue: privatekey value,
-* certvalue: public cert value
-* }
-* @param {string} hostOptions The host options to override defaults.
-* {
-* host: 'management.core.windows.net',
-* apiversion: '2012-03-01',
-* serializetype: 'XML'
-* }
+* @param {string} subscriptionIdOrConnectionString The subscription ID for the account or the connectionString.
+* @param {string} authentication The authentication object for the client.
+* {
+* keyfile: 'path to .pem',
+* certfile: 'path to .pem',
+* keyvalue: privatekey value,
+* certvalue: public cert value
+* }
+* @param {string} hostOptions The host options to override defaults.
+* {
+* host: 'management.core.windows.net',
+* apiversion: '2012-03-01',
+* serializetype: 'XML'
+* }
*/
-function ServiceManagementService(subscriptionId, authentication, hostOptions) {
+function ServiceManagementService(subscriptionIdOrConnectionString, authentication, hostOptions) {
if (typeof subscriptionId != 'string' || subscriptionId.length === 0) {
- throw new Error('SubscriptionId is required');
+ throw new Error('A subscriptionId or a connection string is required');
}
ServiceManagementService.super_.call(this, authentication, hostOptions);
View
12 lib/services/table/tableservice.js
@@ -54,12 +54,12 @@ TableService.incorrectPartitionErr = 'PartitionKey and RowKey must be specified
* @constructor
* @extends {ServiceClient}
*
-* @param {string} [storageAccount] The storage account.
-* @param {string} [storageAccessKey] The storage access key.
-* @param {string} [host] The host address.
-* @param {object} [authenticationProvider] The authentication provider.
+* @param {string} [storageAccountOrConnectionString] The storage account or the connection string.
+* @param {string} [storageAccessKey] The storage access key.
+* @param {string} [host] The host address.
+* @param {object} [authenticationProvider] The authentication provider.
*/
-function TableService(storageAccount, storageAccessKey, host, authenticationProvider) {
+function TableService(storageAccountOrConnectionString, storageAccessKey, host, authenticationProvider) {
if (!host) {
if (ServiceClient.isEmulated()) {
host = ServiceClient.DEVSTORE_TABLE_HOST;
@@ -68,7 +68,7 @@ function TableService(storageAccount, storageAccessKey, host, authenticationProv
}
}
- TableService.super_.call(this, host, storageAccount, storageAccessKey, authenticationProvider);
+ TableService.super_.call(this, storageAccountOrConnectionString, storageAccessKey, host, authenticationProvider);
if (!this.authenticationProvider) {
this.authenticationProvider = new SharedKeyTable(this.storageAccount, this.storageAccessKey, this.usePathStyleUri);
View
20 test/cli/commands/cli.account-tests.js
@@ -18,19 +18,15 @@ var cli = require('../cli');
var capture = require('../util').capture;
suite('cli', function(){
- suite('account', function() {
-
- suite('import', function() {
-
- test('should launch browser when there is no file name', function(done) {
+ suite('account', function() {
+ suite('import', function() {
+ test('should launch browser when there is no file name', function(done) {
+ capture(function() {
+ cli.parse('node cli.js account import data/account-credentials.publishsettings'.split(' '));
+ }, function (result) {
- var result = capture(function() {
- cli.parse('node cli.js account import'.split(' '));
- });
-
- done();
- });
-
+ done();
+ });
});
});
});
View
34 test/cli/commands/cli.site-tests.js
@@ -0,0 +1,34 @@
+/**
+* Copyright 2012 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.
+*/
+
+require('should');
+var cli = require('../cli');
+var capture = require('../util').capture;
+
+suite('cli', function(){
+ suite('site', function() {
+ suite('list', function() {
+ test('should list no sites', function(done) {
+ capture(function() {
+ cli.parse('node cli.js site list --json'.split(' '));
+ }, function (result) {
+ done();
+ });
+ });
+ });
+ });
+});
+
+
View
11 test/cli/data/account-credentials.publishsettings
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PublishData>
+ <PublishProfile
+ PublishMethod="AzureServiceManagementAPI"
+ Url="https://management.core.windows.net/"
+ ManagementCertificate="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">
+ <Subscription
+ Id="db1ab6f0-4769-4b27-930e-01e2ef9c123c"
+ Name="Account" />
+ </PublishProfile>
+</PublishData>
View
8 test/cli/util.js
@@ -17,7 +17,7 @@ exports = module.exports = {
capture: capture,
};
-function capture(action) {
+function capture(action, cb) {
var result = {
text: '',
}
@@ -26,11 +26,12 @@ function capture(action) {
var processExit = process.exit
process.stdout.write = function(data, encoding, fd) {
- result.text = result.text + data;
+ result.text += data;
};
process.exit = function(status) {
result.exitStatus = status;
- throw new Error('process exit');
+
+ return cb(result);
};
try {
@@ -41,5 +42,4 @@ function capture(action) {
}
process.stdout.write = processStdoutWrite;
process.exit = processExit;
- return result;
}
View
12 test/services/blob/blobservice-tests.js
@@ -1272,6 +1272,18 @@ suite('blobservice-tests', function () {
});
});
});
+
+ test('storageConnectionStrings', function (done) {
+ var connectionString = 'DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=mykey';
+ var blobService = azure.createBlobService(connectionString);
+
+ assert.equal(blobService.storageAccount, 'myaccount');
+ assert.equal(blobService.storageAccessKey, 'mykey');
+ assert.equal(blobService.protocol, 'https://');
+ assert.equal(blobService.host, 'blob.core.windows.net');
+
+ done();
+ });
});
function repeat(s, n) {
View
112 test/services/core/connectionstringparser-tests.js
@@ -0,0 +1,112 @@
+/**
+* Copyright (c) Microsoft. All rights reserved.
+*
+* 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');
+
+// Test includes
+var testutil = require('../../util/util');
+
+var azure = testutil.libRequire('azure');
+var ConnectionStringParser = azure.ConnectionStringParser;
+
+suite('connectionstringparser-tests', function () {
+ test('parseValid', function (done) {
+ var parsedConnectionString = ConnectionStringParser.parse('Endpoint=sb://ablal-martvue.servicebus.windows.net/;SharedSecretIssuer=owner;SharedSecretValue=value');
+ assert.equal(parsedConnectionString['endpoint'], 'sb://ablal-martvue.servicebus.windows.net/');
+ assert.equal(parsedConnectionString['sharedsecretissuer'], 'owner');
+ assert.equal(parsedConnectionString['sharedsecretvalue'], 'value');
+
+ done();
+ });
+
+ test('parseEmpty', function (done) {
+ // actual empty
+ var parsedConnectionString = ConnectionStringParser.parse('');
+ assert.equal(JSON.stringify(parsedConnectionString), '{}');
+
+ // Empty with spaces
+ var parsedConnectionString = ConnectionStringParser.parse(' ');
+ assert.equal(JSON.stringify(parsedConnectionString), '{}');
+
+ done();
+ });
+
+ test('parseInvalidAssignment', function (done) {
+ // no assignment
+ assert.throws(
+ function() {
+ var parsedConnectionString = ConnectionStringParser.parse('Endpoint');
+ },
+ function(err) {
+ if ((err instanceof Error) && err.message === 'Missing character "="') {
+ return true;
+ }
+ },
+ "unexpected error"
+ );
+
+ done();
+ });
+
+ test('parseInvalidKey', function (done) {
+ assert.throws(
+ function() {
+ var parsedConnectionString = ConnectionStringParser.parse('=value');
+ },
+ function(err) {
+ if ((err instanceof Error) && err.message === 'Missing key') {
+ return true;
+ }
+ },
+ "unexpected error"
+ );
+
+ assert.throws(
+ function() {
+ var parsedConnectionString = ConnectionStringParser.parse(' =value');
+ },
+ function(err) {
+ if ((err instanceof Error) && err.message === 'Missing key') {
+ return true;
+ }
+ },
+ "unexpected error"
+ );
+
+ done();
+ });
+
+ test('parseQuotedValues', function (done) {
+ var parsedConnectionString = ConnectionStringParser.parse('"test key"=\'value of test\'');
+ assert.equal(parsedConnectionString['test key'], 'value of test');
+
+ var parsedConnectionString = ConnectionStringParser.parse('\'test\'="value"');
+ assert.equal(parsedConnectionString['test'], 'value');
+
+ done();
+ });
+
+ test('connectionStringWithSpecialCharacters', function (done) {
+ var parsedConnectionString = ConnectionStringParser.parse('key1=qwdwdqdw=@#!@;key2=value2');
+ assert.equal(parsedConnectionString['key1'], 'qwdwdqdw=@#!@');
+ assert.equal(parsedConnectionString['key2'], 'value2');
+
+ var parsedConnectionString = ConnectionStringParser.parse('key1="qwd;wdqdw=@#!@";key2=value2');
+ assert.equal(parsedConnectionString['key1'], 'qwd;wdqdw=@#!@');
+ assert.equal(parsedConnectionString['key2'], 'value2');
+
+ done();
+ });
+});
View
11 test/services/queue/queueservice-tests.js
@@ -450,4 +450,15 @@ suite('queueservice-tests', function () {
done();
});
});
+
+ test('storageConnectionStrings', function (done) {
+ var connectionString = 'DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=mykey';
+ var queueService = azure.createQueueService(connectionString);
+
+ assert.equal(queueService.storageAccount, 'myaccount');
+ assert.equal(queueService.storageAccessKey, 'mykey');
+ assert.equal(queueService.protocol, 'https://');
+
+ done();
+ });
});
View
13 test/services/serviceBus/servicebusservice-tests.js
@@ -1606,4 +1606,17 @@ suite('servicebusservice-tests', function () {
});
});
});
+
+ test('connectionStrings', function (done) {
+ var connectionString = 'Endpoint=sb://ablal-martvue.servicebus.windows.net/;StsEndpoint=https://ablal-martvue-sb.accesscontrol.windows.net;SharedSecretIssuer=owner;SharedSecretValue=value';
+
+ var serviceBusService = azure.createServiceBusService(connectionString);
+ assert.equal(serviceBusService.host, 'servicebus.windows.net');
+ assert.equal(serviceBusService.namespace, 'ablal-martvue');
+ assert.equal(serviceBusService.issuer, 'owner');
+ assert.equal(serviceBusService.accessKey, 'value');
+ assert.equal(serviceBusService.acsNamespace, 'ablal-martvue-sb');
+
+ done();
+ });
});
View
11 test/services/table/tableservice-tests.js
@@ -766,4 +766,15 @@ suite('tableservice-tests', function () {
});
});
});
+
+ test('storageConnectionStrings', function (done) {
+ var connectionString = 'DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=mykey';
+ var tableService = azure.createTableService(connectionString);
+
+ assert.equal(tableService.storageAccount, 'myaccount');
+ assert.equal(tableService.storageAccessKey, 'mykey');
+ assert.equal(tableService.protocol, 'https://');
+
+ done();
+ });
});
View
1  test/testlist.txt
@@ -7,6 +7,7 @@ services/blob/sharedaccesssignature-tests.js
services/blob/sharedkey-tests.js
services/blob/sharedkeylite-tests.js
services/blob/filters-tests.js
+services/core/connectionstringparser-tests.js
services/core/serviceclient-tests.js
services/core/exponentialretrypolicyfilter-tests.js
services/core/linearretrypolicyfilter-tests.js
Please sign in to comment.
Something went wrong with that request. Please try again.