Skip to content
This repository
Browse code

Merge pull request #562 from andrerod/dev

Sql Server Database wrappers
  • Loading branch information...
commit db8ff69bfc530ece7ee1383e1cde3571516bdc66 2 parents 799cf06 + aeeae1b
André Rodrigues authored January 28, 2013
33  lib/azure.js
@@ -98,6 +98,27 @@ exports.createServiceBusService = function (namespaceOrConnectionString, accessK
98 98
 };
99 99
 
100 100
 /**
  101
+* SqlService client exports.
  102
+*/
  103
+
  104
+var SqlService = require('./services/sqlAzure/sqlservice');
  105
+exports.SqlService = SqlService;
  106
+
  107
+/**
  108
+* Creates a new SqlManagementService object.
  109
+*
  110
+* @param {string} serverName                   The SQL server name.
  111
+* @param {string} administratorLogin           The SQL Server administrator login.
  112
+* @param {string} administratorLoginPassword   The SQL Server administrator login password.
  113
+* @param {string} [host]                       The host for the service.
  114
+* @param {string} [acsHost]                    The acs host.
  115
+* @param {object} [authenticationProvider]     The authentication provider.
  116
+*/
  117
+exports.createSqlService = function(serverName, administratorLogin, administratorLoginPassword, host, acsHost, authenticationProvider) {
  118
+  return new SqlService(serverName, administratorLogin, administratorLoginPassword, host, acsHost, authenticationProvider);
  119
+};
  120
+
  121
+/**
101 122
 * ServiceManagement client exports.
102 123
 */
103 124
 
@@ -127,14 +148,14 @@ exports.createServiceManagementService = function(subscriptionId, authentication
127 148
 };
128 149
 
129 150
 /**
130  
-* SqlDatabaseService client exports.
  151
+* SqlManagementService client exports.
131 152
 */
132 153
 
133  
-var SqlDatabaseService = require('./services/serviceManagement/sqldatabaseservice');
134  
-exports.SqlDatabaseService = SqlDatabaseService;
  154
+var SqlManagementService = require('./services/serviceManagement/sqlmanagementservice');
  155
+exports.SqlManagementService = SqlManagementService;
135 156
 
136 157
 /**
137  
-* Creates a new SqlDatabaseService object.
  158
+* Creates a new SqlManagementService object.
138 159
 *
139 160
 * @param {string} subscriptionId          The subscription ID for the account.
140 161
 * @param {string} authentication          The authentication object for the client.
@@ -151,8 +172,8 @@ exports.SqlDatabaseService = SqlDatabaseService;
151 172
 *                                            serializetype: 'XML'
152 173
 *                                         }
153 174
 */
154  
-exports.createSqlDatabaseService = function(subscriptionId, authentication, hostOptions) {
155  
-  return new SqlDatabaseService(subscriptionId, authentication, hostOptions);
  175
+exports.createSqlManagementService = function(subscriptionId, authentication, hostOptions) {
  176
+  return new SqlManagementService(subscriptionId, authentication, hostOptions);
156 177
 };
157 178
 
158 179
 /**
1  lib/services/core/serviceclient.js
@@ -72,6 +72,7 @@ ServiceClient.CLOUD_TABLE_HOST = 'table.core.windows.net';
72 72
 ServiceClient.CLOUD_SERVICEBUS_HOST = 'servicebus.windows.net';
73 73
 ServiceClient.CLOUD_ACCESS_CONTROL_HOST = 'accesscontrol.windows.net';
74 74
 ServiceClient.CLOUD_SERVICE_MANAGEMENT_HOST = 'management.core.windows.net';
  75
+ServiceClient.CLOUD_DATABASE_HOST = 'database.windows.net';
75 76
 
76 77
 /**
77 78
 * The default service bus issuer.
2  lib/services/core/servicemanagementclient.js
@@ -41,7 +41,7 @@ ServiceManagementClient.DefaultAPIVersion = '2012-03-01';
41 41
 ServiceManagementClient.DefaultSerializeType = 'JSON';
42 42
 
43 43
 /**
44  
-* Creates a new ServiceClient object.
  44
+* Creates a new ServiceManagementClient object.
45 45
 *
46 46
 * @constructor
47 47
 * @param {string} hostOptions             The host options to override defaults.
125  lib/services/core/sqlserviceclient.js
... ...
@@ -0,0 +1,125 @@
  1
+/**
  2
+* Copyright (c) Microsoft.  All rights reserved.
  3
+*
  4
+* Licensed under the Apache License, Version 2.0 (the "License");
  5
+* you may not use this file except in compliance with the License.
  6
+* You may obtain a copy of the License at
  7
+*   http://www.apache.org/licenses/LICENSE-2.0
  8
+*
  9
+* Unless required by applicable law or agreed to in writing, software
  10
+* distributed under the License is distributed on an "AS IS" BASIS,
  11
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12
+* See the License for the specific language governing permissions and
  13
+* limitations under the License.
  14
+*/
  15
+
  16
+// Module dependencies.
  17
+var util = require('util');
  18
+var url = require('url');
  19
+
  20
+var azureutil = require('../../util/util');
  21
+
  22
+var ServiceClient = require('./serviceclient');
  23
+var SqlServerAcs = require('../sqlAzure/sqlserveracs');
  24
+var Constants = require('../../util/constants');
  25
+var HeaderConstants = Constants.HeaderConstants;
  26
+var QueryStringConstants = Constants.QueryStringConstants;
  27
+var HttpConstants = Constants.HttpConstants;
  28
+
  29
+// Expose 'SqlServiceClient'.
  30
+exports = module.exports = SqlServiceClient;
  31
+
  32
+/**
  33
+* Creates a new SqlServiceClient object.
  34
+*
  35
+* @constructor
  36
+* @param {string} serverName                   The SQL server name.
  37
+* @param {string} administratorLogin           The SQL Server administrator login.
  38
+* @param {string} administratorLoginPassword   The SQL Server administrator login password.
  39
+* @param {string} host                         The host for the service.
  40
+* @param {string} acsHost                      The acs host. Usually the same as the sb namespace with "-sb" suffix.
  41
+* @param {object} [authenticationProvider]     The authentication provider.
  42
+*/
  43
+function SqlServiceClient(serverName, administratorLogin, administratorLoginPassword, host, acsHost, authenticationProvider) {
  44
+  SqlServiceClient.super_.call(this, host, authenticationProvider);
  45
+
  46
+  this.authenticationProvider = authenticationProvider;
  47
+  if (!this.authenticationProvider) {
  48
+    this.authenticationProvider = new SqlServerAcs(acsHost, serverName, administratorLogin, administratorLoginPassword);
  49
+  }
  50
+}
  51
+
  52
+util.inherits(SqlServiceClient, ServiceClient);
  53
+
  54
+/**
  55
+* Builds the request options to be passed to the http.request method.
  56
+*
  57
+* @param {WebResource} webResource The webresource where to build the options from.
  58
+* @param {object}      options     The request options.
  59
+* @param {function(error, requestOptions)}  callback  The callback function.
  60
+*/
  61
+SqlServiceClient.prototype._buildRequestOptions = function (webResource, options, callback) {
  62
+  var self = this;
  63
+
  64
+  if (!webResource.headers || !webResource.headers[HeaderConstants.CONTENT_TYPE]) {
  65
+    webResource.addOptionalHeader(HeaderConstants.CONTENT_TYPE, '');
  66
+  }
  67
+
  68
+  if (!webResource.headers || !webResource.headers[HeaderConstants.CONTENT_LENGTH]) {
  69
+    webResource.addOptionalHeader(HeaderConstants.CONTENT_LENGTH, 0);
  70
+  }
  71
+
  72
+  webResource.addOptionalHeader(HeaderConstants.ACCEPT_CHARSET_HEADER, 'UTF-8');
  73
+  webResource.addOptionalHeader(HeaderConstants.HOST_HEADER, this.host + ':' + this.port);
  74
+
  75
+  // Sets the request url in the web resource.
  76
+  this._setRequestUrl(webResource);
  77
+
  78
+  // If wrap is used, make sure proxy settings are in sync
  79
+  if (this.useProxy &&
  80
+      this.authenticationProvider &&
  81
+      this.authenticationProvider.wrapTokenManager &&
  82
+      this.authenticationProvider.wrapTokenManager.wrapService) {
  83
+    this.authenticationProvider.wrapTokenManager.wrapService.setProxy(this.proxyUrl, this.proxyPort);
  84
+  }
  85
+
  86
+  // Now that the web request is finalized, sign it
  87
+  this.authenticationProvider.signRequest(webResource, function (error) {
  88
+    var requestOptions = null;
  89
+
  90
+    if (!error) {
  91
+      requestOptions = {
  92
+        url: url.format({
  93
+          protocol: self._isHttps() ? 'https:' : 'http:',
  94
+          hostname: self.host,
  95
+          port: self.port,
  96
+          pathname: webResource.path + webResource.getQueryString(true)
  97
+        }),
  98
+        method: webResource.httpVerb,
  99
+        headers: webResource.headers
  100
+      };
  101
+
  102
+      self._setRequestOptionsProxy(requestOptions);
  103
+    }
  104
+
  105
+    callback(error, requestOptions);
  106
+  });
  107
+};
  108
+
  109
+/**
  110
+* Retrieves the normalized path to be used in a request.
  111
+* It adds a leading "/" to the path in case
  112
+* it's not there before.
  113
+*
  114
+* @param {string} path The path to be normalized.
  115
+* @return {string} The normalized path.
  116
+*/
  117
+SqlServiceClient.prototype._getPath = function (path) {
  118
+  if (path === null || path === undefined) {
  119
+    path = '/';
  120
+  } else if (path.indexOf('/') !== 0) {
  121
+    path = '/' + path;
  122
+  }
  123
+
  124
+  return path;
  125
+};
26  lib/services/serviceBus/models/queueresult.js
@@ -37,19 +37,6 @@ QueueResult.serialize = function (path, queue) {
37 37
     }
38 38
   };
39 39
 
40  
-  var atomQueue = {
41  
-    'title': '',
42  
-    'updated': ISO8061Date.format(new Date()),
43  
-    'author': {
44  
-      name: ''
45  
-    },
46  
-    'id': '',
47  
-    'content': {
48  
-      '$': { type: 'application/xml' },
49  
-      QueueDescription: queueDescription
50  
-    }
51  
-  };
52  
-
53 40
   if (queue) {
54 41
     if (queue[ServiceBusConstants.LOCK_DURATION]) {
55 42
       queueDescription[ServiceBusConstants.LOCK_DURATION] = queue[ServiceBusConstants.LOCK_DURATION];
@@ -96,6 +83,19 @@ QueueResult.serialize = function (path, queue) {
96 83
     }
97 84
   }
98 85
 
  86
+  var atomQueue = {
  87
+    'title': '',
  88
+    'updated': ISO8061Date.format(new Date()),
  89
+    'author': {
  90
+      name: ''
  91
+    },
  92
+    'id': '',
  93
+    'content': {
  94
+      '$': { type: 'application/xml' },
  95
+      QueueDescription: queueDescription
  96
+    }
  97
+  };
  98
+
99 99
   var atomHandler = new AtomHandler(null, null);
100 100
   var xml = atomHandler.serialize(atomQueue);
101 101
 
30  lib/services/serviceBus/models/ruleresult.js
@@ -34,21 +34,6 @@ RuleResult.serialize = function (name, path, rule) {
34 34
     }
35 35
   };
36 36
 
37  
-  var atomRule = {
38  
-    'title': {
39  
-      '$': {
40  
-        'type': 'text'
41  
-      },
42  
-      '_': name
43  
-    },
44  
-    'updated': ISO8061Date.format(new Date()),
45  
-    'id': '',
46  
-    'content': {
47  
-      '$': { type: 'application/xml' },
48  
-      RuleDescription: ruleDescription
49  
-    }
50  
-  };
51  
-
52 37
   if (rule) {
53 38
     var filters = [];
54 39
     if (rule.sqlExpressionFilter) {
@@ -122,6 +107,21 @@ RuleResult.serialize = function (name, path, rule) {
122 107
     }
123 108
   }
124 109
 
  110
+  var atomRule = {
  111
+    'title': {
  112
+      '$': {
  113
+        'type': 'text'
  114
+      },
  115
+      '_': name
  116
+    },
  117
+    'updated': ISO8061Date.format(new Date()),
  118
+    'id': '',
  119
+    'content': {
  120
+      '$': { type: 'application/xml' },
  121
+      RuleDescription: ruleDescription
  122
+    }
  123
+  };
  124
+
125 125
   var atomHandler = new AtomHandler(null, null);
126 126
   var xml = atomHandler.serialize(atomRule);
127 127
   return xml;
26  lib/services/serviceBus/models/subscriptionresult.js
@@ -35,19 +35,6 @@ SubscriptionResult.serialize = function (path, subscription) {
35 35
     }
36 36
   };
37 37
 
38  
-  var atomQueue = {
39  
-    'title': '',
40  
-    'updated': ISO8061Date.format(new Date()),
41  
-    'author': {
42  
-      name: ''
43  
-    },
44  
-    'id': '',
45  
-    'content': {
46  
-      '$': { type: 'application/xml' },
47  
-      SubscriptionDescription: subscriptionDescription
48  
-    }
49  
-  };
50  
-
51 38
   if (subscription) {
52 39
     if (subscription[ServiceBusConstants.LOCK_DURATION]) {
53 40
       subscriptionDescription[ServiceBusConstants.LOCK_DURATION] = subscription[ServiceBusConstants.LOCK_DURATION];
@@ -86,6 +73,19 @@ SubscriptionResult.serialize = function (path, subscription) {
86 73
     }
87 74
   }
88 75
 
  76
+  var atomQueue = {
  77
+    'title': '',
  78
+    'updated': ISO8061Date.format(new Date()),
  79
+    'author': {
  80
+      name: ''
  81
+    },
  82
+    'id': '',
  83
+    'content': {
  84
+      '$': { type: 'application/xml' },
  85
+      SubscriptionDescription: subscriptionDescription
  86
+    }
  87
+  };
  88
+
89 89
   var atomHandler = new AtomHandler(null, null);
90 90
   var xml = atomHandler.serialize(atomQueue);
91 91
 
26  lib/services/serviceBus/models/topicresult.js
@@ -35,19 +35,6 @@ TopicResult.serialize = function (path, topic) {
35 35
     }
36 36
   };
37 37
 
38  
-  var atomQueue = {
39  
-    'title': '',
40  
-    'updated': ISO8061Date.format(new Date()),
41  
-    'author': {
42  
-      name: ''
43  
-    },
44  
-    'id': '',
45  
-    'content': {
46  
-      '$': { type: 'application/xml' },
47  
-      TopicDescription: topicDescription
48  
-    }
49  
-  };
50  
-
51 38
   if (topic) {
52 39
     if (topic[ServiceBusConstants.DEFAULT_MESSAGE_TIME_TO_LIVE]) {
53 40
       topicDescription[ServiceBusConstants.DEFAULT_MESSAGE_TIME_TO_LIVE] = topic[ServiceBusConstants.DEFAULT_MESSAGE_TIME_TO_LIVE];
@@ -74,6 +61,19 @@ TopicResult.serialize = function (path, topic) {
74 61
     }
75 62
   }
76 63
 
  64
+  var atomQueue = {
  65
+    'title': '',
  66
+    'updated': ISO8061Date.format(new Date()),
  67
+    'author': {
  68
+      name: ''
  69
+    },
  70
+    'id': '',
  71
+    'content': {
  72
+      '$': { type: 'application/xml' },
  73
+      TopicDescription: topicDescription
  74
+    }
  75
+  };
  76
+
77 77
   var atomHandler = new AtomHandler(null, null);
78 78
   var xml = atomHandler.serialize(atomQueue);
79 79
   return xml;
28  lib/services/serviceManagement/sqldatabaseservice.js → ...ervices/serviceManagement/sqlmanagementservice.js
@@ -25,12 +25,12 @@ var parseserverresponse = require('./models/parseserverresponse');
25 25
 var Constants = require('../../util/constants');
26 26
 var HttpConstants = Constants.HttpConstants;
27 27
 
28  
-// Expose 'SqlDatabaseService'.
29  
-exports = module.exports = SqlDatabaseService;
  28
+// Expose 'SqlManagementService'.
  29
+exports = module.exports = SqlManagementService;
30 30
 
31 31
 /**
32 32
 *
33  
-* Creates a new SqlDatabaseService object
  33
+* Creates a new SqlManagementService object
34 34
 *
35 35
 * @constructor
36 36
 * @param {string} subscriptionId   Subscription ID for the account or the connection string
@@ -49,7 +49,7 @@ exports = module.exports = SqlDatabaseService;
49 49
 *                                                   }
50 50
 */
51 51
 
52  
-function SqlDatabaseService(subscriptionId, authentication, hostOptions) {
  52
+function SqlManagementService(subscriptionId, authentication, hostOptions) {
53 53
   if (typeof subscriptionId != 'string' || subscriptionId.length === 0) {
54 54
     throw new Error('A subscriptionId or a connection string is required');
55 55
   }
@@ -59,19 +59,19 @@ function SqlDatabaseService(subscriptionId, authentication, hostOptions) {
59 59
   }
60 60
 
61 61
   hostOptions.serializetype = 'XML';
62  
-  SqlDatabaseService.super_.call(this, authentication, hostOptions);
  62
+  SqlManagementService.super_.call(this, authentication, hostOptions);
63 63
 
64 64
   this.subscriptionId = subscriptionId;
65 65
 }
66 66
 
67  
-util.inherits(SqlDatabaseService, ServiceManagementClient);
  67
+util.inherits(SqlManagementService, ServiceManagementClient);
68 68
 
69 69
 /**
70 70
 * Lists the available SQL Servers.
71 71
 *
72 72
 * @param {function} callback function (err, results, response) The callback function called on completion. Required.
73 73
 */
74  
-SqlDatabaseService.prototype.listServers = function (callback) {
  74
+SqlManagementService.prototype.listServers = function (callback) {
75 75
   var path = this._makePath('servers');
76 76
   var webResource = WebResource.get(path);
77 77
   webResource.withOkCode(HttpConstants.HttpResponseCodes.OK_CODE, true);
@@ -98,7 +98,7 @@ SqlDatabaseService.prototype.listServers = function (callback) {
98 98
 * @param {string}   name                The SQL Server name.
99 99
 * @param {function} callback            function (err, response) The callback function called on completion. Required.
100 100
 */
101  
-SqlDatabaseService.prototype.deleteServer = function (name, callback) {
  101
+SqlManagementService.prototype.deleteServer = function (name, callback) {
102 102
   var path = this._makePath('servers') + '/' + name;
103 103
   var webResource = WebResource.del(path);
104 104
 
@@ -119,7 +119,7 @@ SqlDatabaseService.prototype.deleteServer = function (name, callback) {
119 119
 * @param {string}   location                    The server's location.
120 120
 * @param {function} callback                    function (err, server, response) The callback function called on completion. Required.
121 121
 */
122  
-SqlDatabaseService.prototype.createServer = function (administratorLogin, administratorLoginPassword, location, callback) {
  122
+SqlManagementService.prototype.createServer = function (administratorLogin, administratorLoginPassword, location, callback) {
123 123
   var path = this._makePath('servers');
124 124
   var webResource = WebResource.post(path);
125 125
 
@@ -159,7 +159,7 @@ SqlDatabaseService.prototype.createServer = function (administratorLogin, admini
159 159
 * @param {string}   serverName          The server name.
160 160
 * @param {function} callback            function (err, results, response) The callback function called on completion. Required.
161 161
 */
162  
-SqlDatabaseService.prototype.listServerFirewallRules = function (serverName, callback) {
  162
+SqlManagementService.prototype.listServerFirewallRules = function (serverName, callback) {
163 163
   var path = this._makePath('servers') + '/' + serverName + '/firewallrules';
164 164
   var webResource = WebResource.get(path);
165 165
   webResource.withOkCode(HttpConstants.HttpResponseCodes.OK_CODE, true);
@@ -188,7 +188,7 @@ SqlDatabaseService.prototype.listServerFirewallRules = function (serverName, cal
188 188
 * @param {string}   ruleName            The rule name.
189 189
 * @param {function} callback            function (err, response) The callback function called on completion. Required.
190 190
 */
191  
-SqlDatabaseService.prototype.deleteServerFirewallRule = function (serverName, ruleName, callback) {
  191
+SqlManagementService.prototype.deleteServerFirewallRule = function (serverName, ruleName, callback) {
192 192
   var path = this._makePath('servers') + '/' + serverName + '/firewallrules/' + ruleName;
193 193
   var webResource = WebResource.del(path);
194 194
 
@@ -210,7 +210,7 @@ SqlDatabaseService.prototype.deleteServerFirewallRule = function (serverName, ru
210 210
 * @param {string}   endIPAddress        The ending IP address for the rule.
211 211
 * @param {function} callback            function (err, rule, response) The callback function called on completion. Required.
212 212
 */
213  
-SqlDatabaseService.prototype.createServerFirewallRule = function (serverName, ruleName, startIPAddress, endIPAddress, callback) {
  213
+SqlManagementService.prototype.createServerFirewallRule = function (serverName, ruleName, startIPAddress, endIPAddress, callback) {
214 214
   var path = this._makePath('servers') + '/' + serverName + '/firewallrules';
215 215
   var webResource = WebResource.post(path);
216 216
 
@@ -254,7 +254,7 @@ SqlDatabaseService.prototype.createServerFirewallRule = function (serverName, ru
254 254
 * @param {string}   endIPAddress        The ending IP address for the rule.
255 255
 * @param {function} callback            function (err, rule, response) The callback function called on completion. Required.
256 256
 */
257  
-SqlDatabaseService.prototype.updateServerFirewallRule = function (serverName, ruleName, startIPAddress, endIPAddress, callback) {
  257
+SqlManagementService.prototype.updateServerFirewallRule = function (serverName, ruleName, startIPAddress, endIPAddress, callback) {
258 258
   var path = this._makePath('servers') + '/' + serverName + '/firewallrules/' + ruleName;
259 259
   var webResource = WebResource.put(path);
260 260
   webResource.withOkCode(HttpConstants.HttpResponseCodes.OK_CODE, true);
@@ -290,6 +290,6 @@ SqlDatabaseService.prototype.updateServerFirewallRule = function (serverName, ru
290 290
   });
291 291
 };
292 292
 
293  
-SqlDatabaseService.prototype._makePath = function (operationName) {
  293
+SqlManagementService.prototype._makePath = function (operationName) {
294 294
   return '/' + this.subscriptionId + '/services/sqlservers/' + operationName;
295 295
 };
81  lib/services/sqlAzure/models/databaseresult.js
... ...
@@ -0,0 +1,81 @@
  1
+/**
  2
+* Copyright (c) Microsoft.  All rights reserved.
  3
+*
  4
+* Licensed under the Apache License, Version 2.0 (the "License");
  5
+* you may not use this file except in compliance with the License.
  6
+* You may obtain a copy of the License at
  7
+*   http://www.apache.org/licenses/LICENSE-2.0
  8
+*
  9
+* Unless required by applicable law or agreed to in writing, software
  10
+* distributed under the License is distributed on an "AS IS" BASIS,
  11
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12
+* See the License for the specific language governing permissions and
  13
+* limitations under the License.
  14
+*/
  15
+
  16
+// Module dependencies.
  17
+var AtomHandler = require('../../../util/atomhandler');
  18
+var ISO8061Date = require('../../../util/iso8061date');
  19
+var Constants = require('../../../util/constants');
  20
+var ServiceBusConstants = Constants.ServiceBusConstants;
  21
+var HeaderConstants = Constants.HeaderConstants;
  22
+
  23
+// Expose 'DatabaseResult'.
  24
+exports = module.exports = DatabaseResult;
  25
+
  26
+function DatabaseResult() { }
  27
+
  28
+DatabaseResult.serialize = function (databaseName, collation, edition, maxSizeInGB) {
  29
+  var databaseDescription = { };
  30
+
  31
+  if (collation) {
  32
+    databaseDescription['d:CollationName'] = collation;
  33
+  } else {
  34
+    databaseDescription['d:CollationName'] = { '$': { 'm:null': 'true' } };
  35
+  }
  36
+
  37
+  databaseDescription['d:CreationDate'] = { '$': { 'm:type': 'Edm.DateTime' }, '_': '0001-01-01T00:00:00' };
  38
+
  39
+  if (edition) {
  40
+    databaseDescription['d:Edition'] = edition;
  41
+  } else {
  42
+    databaseDescription['d:Edition'] = { '$': { 'm:null': 'true' } };
  43
+  }
  44
+
  45
+  databaseDescription['d:Id'] = { '$': { 'm:type': 'Edm.Int32' }, '_': '0' };
  46
+  databaseDescription['d:IsFederationRoot'] = { '$': { 'm:type': 'Edm.Boolean', 'm:null': 'true' } };
  47
+  databaseDescription['d:IsReadonly'] = { '$': { 'm:type': 'Edm.Boolean' }, '_': 'false' };
  48
+  databaseDescription['d:IsRecursiveTriggersOn'] = { '$': { 'm:type': 'Edm.Boolean', 'm:null': 'true' } };
  49
+  databaseDescription['d:IsSystemObject'] = { '$': { 'm:type': 'Edm.Boolean' }, '_': 'false' };
  50
+
  51
+  if (maxSizeInGB) {
  52
+    databaseDescription['d:MaxSizeGB'] = { '$': { 'm:type': 'Edm.Int32' }, '_': maxSizeInGB };
  53
+  } else {
  54
+    databaseDescription['d:MaxSizeGB'] = { '$': { 'm:type': 'Edm.Int32', 'm:null': 'true' } };
  55
+  }
  56
+
  57
+  if (databaseName) {
  58
+    databaseDescription['d:Name'] = databaseName;
  59
+  }
  60
+
  61
+  databaseDescription['d:SizeMB'] = { '$': { 'm:type': 'Edm.Decimal' }, '_': '0' };
  62
+  databaseDescription['d:Status'] = { '$': { 'm:type': 'Edm.Int32' }, '_': '0' };
  63
+
  64
+  var atom = {
  65
+    'title': '',
  66
+    'updated': ISO8061Date.format(new Date(), false, 7),
  67
+    'author': {
  68
+      name: ''
  69
+    },
  70
+    'id': '',
  71
+    'content': {
  72
+      '$': { type: 'application/xml' },
  73
+      'm:properties': databaseDescription
  74
+    }
  75
+  };
  76
+
  77
+  var atomHandler = new AtomHandler();
  78
+  var xml = atomHandler.serialize(atom);
  79
+
  80
+  return xml;
  81
+};
135  lib/services/sqlAzure/sqlserveracs.js
... ...
@@ -0,0 +1,135 @@
  1
+/**
  2
+* Copyright (c) Microsoft.  All rights reserved.
  3
+*
  4
+* Licensed under the Apache License, Version 2.0 (the "License");
  5
+* you may not use this file except in compliance with the License.
  6
+* You may obtain a copy of the License at
  7
+*   http://www.apache.org/licenses/LICENSE-2.0
  8
+*
  9
+* Unless required by applicable law or agreed to in writing, software
  10
+* distributed under the License is distributed on an "AS IS" BASIS,
  11
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12
+* See the License for the specific language governing permissions and
  13
+* limitations under the License.
  14
+*/
  15
+
  16
+// Module dependencies.
  17
+var util = require('util');
  18
+var url = require('url');
  19
+var _ = require('underscore');
  20
+
  21
+var azureutil = require('../../util/util');
  22
+
  23
+var ServiceClient = require('../core/serviceclient');
  24
+
  25
+var WebResource = require('../../http/webresource');
  26
+var Constants = require('../../util/constants');
  27
+var QueryStringConstants = Constants.QueryStringConstants;
  28
+var HttpConstants = Constants.HttpConstants;
  29
+var HeaderConstants = Constants.HeaderConstants;
  30
+var SqlAzureConstants = Constants.SqlAzureConstants;
  31
+
  32
+// Expose 'SqlServerAcs'.
  33
+exports = module.exports = SqlServerAcs;
  34
+
  35
+/**
  36
+* Creates a new SqlServerAcs object.
  37
+*
  38
+* @param {string} acsHost                      The access control host.
  39
+* @param {string} serverName                   The SQL server name.
  40
+* @param {string} administratorLogin           The administrator login.
  41
+* @param {string} administratorLoginPassword   The administrator login password.
  42
+*/
  43
+function SqlServerAcs(acsHost, serverName, administratorLogin, administratorLoginPassword) {
  44
+  this.acsHost = acsHost;
  45
+  this.serverName = serverName;
  46
+  this.administratorLogin = administratorLogin;
  47
+  this.administratorLoginPassword = administratorLoginPassword;
  48
+
  49
+  SqlServerAcs.super_.call(this, acsHost);
  50
+}
  51
+
  52
+util.inherits(SqlServerAcs, ServiceClient);
  53
+
  54
+/**
  55
+* Signs a request with the Authentication header.
  56
+* 
  57
+* @param {WebResource} The webresource to be signed.
  58
+* @return {undefined}
  59
+*/
  60
+SqlServerAcs.prototype.signRequest = function (webResourceToSign, callback) {
  61
+  var escapedLogin = escapeConnectionCredentials(this.administratorLogin);
  62
+  var escapedLoginPassword = escapeConnectionCredentials(this.administratorLoginPassword);
  63
+
  64
+  var escapedCredentials = escapedLogin + ':' + escapedLoginPassword;
  65
+
  66
+  var encodedCredentials = 'Basic ' + (new Buffer(escapedCredentials).toString('base64'));
  67
+
  68
+  var webResource = WebResource.get('/v1/ManagementService.svc/GetAccessToken');
  69
+
  70
+  webResource.addOptionalHeader('sqlauthorization', encodedCredentials);
  71
+
  72
+  var processResponseCallback = function (responseObject, next) {
  73
+    if (!responseObject.error) {
  74
+      if (responseObject.response.headers['set-cookie']) {
  75
+        _.each(responseObject.response.headers['set-cookie'], function (cookie) {
  76
+          if (_.startsWith(cookie, SqlAzureConstants.SQL_SERVER_MANAGEMENT_COOKIE)) {
  77
+            webResourceToSign.addOptionalHeader('Cookie', cookie.split(';')[0]);
  78
+          }
  79
+        })
  80
+      }
  81
+
  82
+      webResourceToSign.addOptionalHeader('AccessToken', responseObject.response.body.string[Constants.XML_VALUE_MARKER]);
  83
+    }
  84
+
  85
+    var finalCallback = function (returnObject) {
  86
+      callback(returnObject.error);
  87
+    };
  88
+
  89
+    next(responseObject, finalCallback);
  90
+  };
  91
+
  92
+  this.performRequest(webResource, null, null, processResponseCallback);
  93
+};
  94
+
  95
+SqlServerAcs.prototype._buildRequestOptions = function (webResource, options, callback) {
  96
+  var self = this;
  97
+
  98
+  // Sets the request url in the web resource.
  99
+  this._setRequestUrl(webResource);
  100
+
  101
+  var requestOptions = {
  102
+    url: url.format({
  103
+      protocol: self._isHttps() ? 'https:' : 'http:',
  104
+      hostname: self.host,
  105
+      port: self.port,
  106
+      pathname: webResource.path + webResource.getQueryString(true)
  107
+    }),
  108
+    method: webResource.httpVerb,
  109
+    headers: webResource.headers
  110
+  };
  111
+
  112
+  callback(null, requestOptions);
  113
+};
  114
+
  115
+/**
  116
+* Retrieves the normalized path to be used in a request.
  117
+* It adds a leading "/" to the path in case
  118
+* it's not there before.
  119
+*
  120
+* @param {string} path The path to be normalized.
  121
+* @return {string} The normalized path.
  122
+*/
  123
+SqlServerAcs.prototype._getPath = function (path) {
  124
+  if (path === null || path === undefined) {
  125
+    path = '/';
  126
+  } else if (path.indexOf('/') !== 0) {
  127
+    path = '/' + path;
  128
+  }
  129
+
  130
+  return path;
  131
+};
  132
+
  133
+function escapeConnectionCredentials(value) {
  134
+  return value.replace(/\\/g, /\\\\/g).replace(/:/g, /\\:/g);
  135
+}
193  lib/services/sqlAzure/sqlservice.js
... ...
@@ -0,0 +1,193 @@
  1
+/**
  2
+* Copyright (c) Microsoft.  All rights reserved.
  3
+*
  4
+* Licensed under the Apache License, Version 2.0 (the "License");
  5
+* you may not use this file except in compliance with the License.
  6
+* You may obtain a copy of the License at
  7
+*   http://www.apache.org/licenses/LICENSE-2.0
  8
+*
  9
+* Unless required by applicable law or agreed to in writing, software
  10
+* distributed under the License is distributed on an "AS IS" BASIS,
  11
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12
+* See the License for the specific language governing permissions and
  13
+* limitations under the License.
  14
+*/
  15
+
  16
+// Module dependencies.
  17
+var util = require('util');
  18
+var xml2js = require('xml2js');
  19
+var url = require('url');
  20
+var _ = require('underscore');
  21
+
  22
+var SqlServiceClient = require('../core/sqlserviceclient');
  23
+var WebResource = require('../../http/webresource');
  24
+var ServiceClient = require('../core/serviceclient');
  25
+
  26
+var AtomHandler = require('../../util/atomhandler');
  27
+var DatabaseResult = require('./models/databaseresult');
  28
+
  29
+var Constants = require('../../util/constants');
  30
+var HttpConstants = Constants.HttpConstants;
  31
+var HeaderConstants = Constants.HeaderConstants;
  32
+var SqlAzureConstants = Constants.SqlAzureConstants;
  33
+
  34
+// Expose 'SqlService'.
  35
+exports = module.exports = SqlService;
  36
+
  37
+/**
  38
+*
  39
+* Creates a new SqlService object
  40
+*
  41
+* @constructor
  42
+* @param {string} serverName                   The SQL server name.
  43
+* @param {string} administratorLogin           The SQL Server administrator login.
  44
+* @param {string} administratorLoginPassword   The SQL Server administrator login password.
  45
+* @param {string} [host]                       The host for the service.
  46
+* @param {string} [acsHost]                    The acs host.
  47
+* @param {object} [authenticationProvider]     The authentication provider.
  48
+*/
  49
+
  50
+function SqlService(serverName, administratorLogin, administratorLoginPassword, host, acsHost, authenticationProvider) {
  51
+  this.serverName = serverName;
  52
+
  53
+  var endpoint = url.format({ protocol: 'https:', port: 443, hostname: serverName + '.' + ServiceClient.CLOUD_DATABASE_HOST });
  54
+  var acsEndpoint = url.format({ protocol: 'https:', port: 443, hostname: serverName + '.' + ServiceClient.CLOUD_DATABASE_HOST });
  55
+
  56
+  SqlService.super_.call(this,
  57
+    serverName,
  58
+    administratorLogin,
  59
+    administratorLoginPassword,
  60
+    endpoint,
  61
+    acsEndpoint,
  62
+    authenticationProvider);
  63
+}
  64
+
  65
+util.inherits(SqlService, SqlServiceClient);
  66
+
  67
+/**
  68
+* Creates a SQL Server database.
  69
+*
  70
+* @param {string}             databaseName                             The database name.
  71
+* @param {object|function}    [optionsOrCallback]                      The get options or callback function.
  72
+* @param {string}             [optionsOrCallback.collation]            The database collation to be used.
  73
+* @param {string}             [optionsOrCallback.edition]              The database edition to be used.
  74
+* @param {string}             [optionsOrCallback.maxSizeInGB]          The database maximum size in gigabytes.
  75
+* @param {function}           callback                                 function (err, response) The callback function called on completion. Required.
  76
+*/
  77
+SqlService.prototype.createServerDatabase = function (databaseName, optionsOrCallback, callback) {
  78
+  var options = null;
  79
+  if (typeof optionsOrCallback === 'function' && !callback) {
  80
+    callback = optionsOrCallback;
  81
+    options = { };
  82
+  } else {
  83
+    options = optionsOrCallback;
  84
+  }
  85
+
  86
+  validateCallback(callback);
  87
+
  88
+  var databaseXml = DatabaseResult.serialize(databaseName, options.collation, options.edition, options.maxSizeInGB);
  89
+
  90
+  var webResource = WebResource.post(SqlAzureConstants.MANAGEMENT_SERVICE_URI + 'Server2(\'' + this.serverName + '\')/Databases');
  91
+
  92
+  webResource.addOptionalHeader(HeaderConstants.CONTENT_TYPE, 'application/atom+xml;charset="utf-8"');
  93
+  webResource.addOptionalHeader(HeaderConstants.CONTENT_LENGTH, Buffer.byteLength(databaseXml, 'utf8'));
  94
+  webResource.addOptionalHeader('Expect', '100-continue');
  95
+
  96
+  var processResponseCallback = function (responseObject, next) {
  97
+    if (!responseObject.error && responseObject.response.body.entry) {
  98
+      var atomHandler = new AtomHandler();
  99
+      responseObject.database = atomHandler.parse(responseObject.response.body.entry)
  100
+    }
  101
+
  102
+    var finalCallback = function (returnObject) {
  103
+      callback(returnObject.error, returnObject.database, returnObject.response);
  104
+    };
  105
+
  106
+    next(responseObject, finalCallback);
  107
+  };
  108
+
  109
+  this._performRequestExtended(webResource, databaseXml, null, processResponseCallback);
  110
+};
  111
+
  112
+/**
  113
+* Deletes a SQL Server database.
  114
+*
  115
+* @param {string}   databaseId          The database identifier.
  116
+* @param {function} callback            function (err, response) The callback function called on completion. Required.
  117
+*/
  118
+SqlService.prototype.deleteServerDatabase = function (databaseId, callback) {
  119
+  validateCallback(callback);
  120
+
  121
+  var webResource = WebResource.del(SqlAzureConstants.MANAGEMENT_SERVICE_URI + 'Server2(\'' + this.serverName + '\')/Databases(' + databaseId + ')');
  122
+
  123
+  var processResponseCallback = function (responseObject, next) {
  124
+    var finalCallback = function (returnObject) {
  125
+      callback(returnObject.error, returnObject.response);
  126
+    };
  127
+
  128
+    next(responseObject, finalCallback);
  129
+  };
  130
+
  131
+  this._performRequestExtended(webResource, null, null, processResponseCallback);
  132
+};
  133
+
  134
+/**
  135
+* Lists the SQL Server databases.
  136
+*
  137
+* @param {function} callback            function (err, results, response) The callback function called on completion. Required.
  138
+*/
  139
+SqlService.prototype.listServerDatabases = function (callback) {
  140
+  validateCallback(callback);
  141
+
  142
+  var webResource = WebResource.get(SqlAzureConstants.MANAGEMENT_SERVICE_URI + 'Server2(\'' + this.serverName + '\')/Databases');
  143
+
  144
+  var processResponseCallback = function (responseObject, next) {
  145
+    if (!responseObject.error) {
  146
+      responseObject.databases = [];
  147
+
  148
+      var entries = [];
  149
+      if (responseObject.response.body.feed && responseObject.response.body.feed.entry) {
  150
+        entries = responseObject.response.body.feed.entry;
  151
+      } else if (responseObject.response.body.entry) {
  152
+        entries = [responseObject.response.body.entry];
  153
+      }
  154
+
  155
+      var atomHandler = new AtomHandler();
  156
+      _.each(entries, function (entry) {
  157
+        responseObject.databases.push(atomHandler.parse(entry));
  158
+      });
  159
+    }
  160
+
  161
+    var finalCallback = function (returnObject) {
  162
+      callback(returnObject.error, returnObject.databases, returnObject.response);
  163
+    };
  164
+
  165
+    next(responseObject, finalCallback);
  166
+  };
  167
+
  168
+  this._performRequestExtended(webResource, null, null, processResponseCallback);
  169
+};
  170
+
  171
+SqlService.prototype._performRequestExtended = function (webResource, rawData, options, callback) {
  172
+  if (!webResource.headers || !webResource.headers[HeaderConstants.DATA_SERVICE_VERSION]) {
  173
+    webResource.addOptionalHeader(HeaderConstants.DATA_SERVICE_VERSION, '1.0;NetFx');
  174
+  }
  175
+
  176
+  if (!webResource.headers || !webResource.headers[HeaderConstants.MAX_DATA_SERVICE_VERSION]) {
  177
+    webResource.addOptionalHeader(HeaderConstants.MAX_DATA_SERVICE_VERSION, '2.0;NetFx');
  178
+  }
  179
+
  180
+  this.performRequest(webResource, rawData, options, callback);
  181
+};
  182
+
  183
+/**
  184
+* Validates a callback function.
  185
+*
  186
+* @param {string} callback The callback function.
  187
+* @return {undefined}
  188
+*/
  189
+function validateCallback(callback) {
  190
+  if (!callback) {
  191
+    throw new Error(TableService.incorrectCallbackErr);
  192
+  }
  193
+}
1  lib/services/table/tableservice.js
@@ -24,7 +24,6 @@ var StorageServiceClient = require('../core/storageserviceclient');
24 24
 var BatchServiceClient = require('./batchserviceclient');
25 25
 var SharedKeyTable = require('./sharedkeytable');
26 26
 var TableQuery = require('./tablequery');
27  
-var AtomHandler = require('../../util/atomhandler');
28 27
 var ServiceClient = require('../core/serviceclient');
29 28
 var WebResource = require('../../http/webresource');
30 29
 var Constants = require('../../util/constants');
5  lib/util/constants.js
@@ -2511,6 +2511,11 @@ var Constants = {
2511 2511
     }
2512 2512
   },
2513 2513
 
  2514
+  SqlAzureConstants: {
  2515
+    SQL_SERVER_MANAGEMENT_COOKIE: '.SQLSERVERMANAGEMENT',
  2516
+    MANAGEMENT_SERVICE_URI: '/v1/ManagementService.svc/'
  2517
+  },
  2518
+
2514 2519
   BlobErrorCodeStrings: {
2515 2520
     INVALID_BLOCK_ID: 'InvalidBlockId',
2516 2521
     BLOB_NOT_FOUND: 'BlobNotFound',
2  ...ces/serviceManagement/sqldatabaseservice-tests.js → ...s/serviceManagement/sqlmanagementservice-tests.js
@@ -32,7 +32,7 @@ describe('SQL Server Management', function () {
32 32
   before(function () {
33 33
     var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID'];
34 34
     var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() };
35  
-    service = azure.createSqlDatabaseService(
  35
+    service = azure.createSqlManagementService(
36 36
       subscriptionId, auth,
37 37
       { serializetype: 'XML'});
38 38
   });
190  test/services/sqlAzure/sqlservice-tests.js
... ...
@@ -0,0 +1,190 @@
  1
+/**
  2
+* Copyright (c) Microsoft.  All rights reserved.
  3
+*
  4
+* Licensed under the Apache License, Version 2.0 (the "License");
  5
+* you may not use this file except in compliance with the License.
  6
+* You may obtain a copy of the License at
  7
+*   http://www.apache.org/licenses/LICENSE-2.0
  8
+*
  9
+* Unless required by applicable law or agreed to in writing, software
  10
+* distributed under the License is distributed on an "AS IS" BASIS,
  11
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12
+* See the License for the specific language governing permissions and
  13
+* limitations under the License.
  14
+*/
  15
+
  16
+var should = require('should');
  17
+var mocha = require('mocha');
  18
+var uuid = require('node-uuid');
  19
+
  20
+var testutil = require('../../util/util');
  21
+
  22
+var azure = testutil.libRequire('azure');
  23
+
  24
+var SERVER_ADMIN_USERNAME = 'azuresdk';
  25
+var SERVER_ADMIN_PASSWORD = 'PassWord!1';
  26
+var SERVER_LOCATION = 'West US';
  27
+
  28
+var DATABASE_NAME = 'mydatabase';
  29
+
  30
+describe('SQL Azure Database', function () {
  31
+  var serverName;
  32
+
  33
+  var service;
  34
+  var serviceManagement;
  35
+
  36
+  before(function (done) {
  37
+    var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID'];
  38
+    var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() };
  39
+    serviceManagement = azure.createSqlManagementService(
  40
+      subscriptionId, auth,
  41
+      { serializetype: 'XML'});
  42
+
  43
+    serviceManagement.createServer(SERVER_ADMIN_USERNAME, SERVER_ADMIN_PASSWORD, SERVER_LOCATION, function (err, name) {
  44
+      should.not.exist(err);
  45
+
  46
+      serverName = name;
  47
+
  48
+      // Create the SQL Azure service to test
  49
+      service = azure.createSqlService(serverName, SERVER_ADMIN_USERNAME, SERVER_ADMIN_PASSWORD);
  50
+
  51
+      // add firewall rule for all the ip range
  52
+      serviceManagement.createServerFirewallRule(serverName, 'rule1', '0.0.0.0', '255.255.255.255', function () {
  53
+
  54
+        // Wait for the firewall rule to be added (test different operations needed as it seems they dont go valid at the same time)
  55
+        var checkIfRuleAdded = function () {
  56
+          setTimeout(function () {
  57
+            var databaseId;
  58
+
  59
+            service.createServerDatabase(DATABASE_NAME, function (err, db) {
  60
+              if (err) {
  61
+                checkIfRuleAdded();
  62
+              } else {
  63
+                databaseId = db.Id;
  64
+
  65
+                var checkIfRuleDeleted = function () {
  66
+                  setTimeout(function () {
  67
+                    service.deleteServerDatabase(databaseId, function (err) {
  68
+                      if (err) {
  69
+                        checkIfRuleDeleted();
  70
+                      } else {
  71
+                        var checkIfRuleLists = function () {
  72
+                          setTimeout(function () {
  73
+                            service.listServerDatabases(function (err) {
  74
+                              if (err) {
  75
+                                checkIfRuleLists();
  76
+                              } else {
  77
+                                done();
  78
+                              }
  79
+                            })
  80
+                          }, 2000);
  81
+                        };
  82
+
  83
+                        checkIfRuleLists();
  84
+                      }
  85
+                    });
  86
+                  }, 2000);
  87
+                };
  88
+
  89
+                checkIfRuleDeleted();
  90
+              }
  91
+            });
  92
+          }, 2000);
  93
+        };
  94
+
  95
+        checkIfRuleAdded();
  96
+      });
  97
+    });
  98
+  });
  99
+
  100
+  after(function (done) {
  101
+    serviceManagement.deleteServer(serverName, done);
  102
+  });
  103
+
  104
+  describe('list SQL databases', function () {
  105
+    describe('when only master database is defined', function () {
  106
+      it('should return it', function (done) {
  107
+        service.listServerDatabases(function (err, databases) {
  108
+          should.not.exist(err);
  109
+          should.exist(databases);
  110
+          databases.should.have.length(1);
  111
+          databases[0].Name.should.equal('master');
  112
+          done(err);
  113
+        });
  114
+      });
  115
+    });
  116
+
  117
+    describe('when multiple databases are defined', function () {
  118
+      var databaseId;
  119
+
  120
+      before(function (done) {
  121
+        service.createServerDatabase(DATABASE_NAME, function (err, database) {
  122
+          should.not.exist(err);
  123
+          databaseId = database.Id;
  124
+
  125
+          done(err);
  126
+        });
  127
+      });
  128
+
  129
+      after(function (done) {
  130
+        service.deleteServerDatabase(databaseId, function (err) {
  131
+          done(err);
  132
+        });
  133
+      });
  134
+
  135
+      it('should return it', function (done) {
  136
+        service.listServerDatabases(function (err, databases) {
  137
+          should.not.exist(err);
  138
+          should.exist(databases);
  139
+          databases.should.have.length(2);
  140
+          should.exist(databases.filter(function (database) {
  141
+            return database.Name === DATABASE_NAME;
  142
+          })[0]);
  143
+
  144
+          done(err);
  145
+        });
  146
+      });
  147
+    });
  148
+  });
  149
+
  150
+  describe('Delete SQL databases', function () {