From f05854345598a2be3978557d41c39e34c3f61b65 Mon Sep 17 00:00:00 2001 From: Qinyuan Wan Date: Tue, 22 Mar 2016 16:47:05 -0700 Subject: [PATCH 01/29] fix async patch and post run --- .../ms-rest-azure/lib/azureServiceClient.js | 201 ++++++++---------- .../NodeJS/ms-rest-azure/lib/pollingState.js | 65 +++--- 2 files changed, 128 insertions(+), 138 deletions(-) diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js index ae1798dc5e56a..4b967ca5cd373 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js @@ -32,15 +32,15 @@ function AzureServiceClient(credentials, options) { if (!credentials) { throw new Error('Azure clients require credentials.'); } - + AzureServiceClient['super_'].call(this, credentials, options); - + this.acceptLanguage = 'en-US'; this.generateClientRequestId = true; this.longRunningOperationRetryTimeout = 30; if (!options) options = {}; - + if (options.acceptLanguage !== null && options.acceptLanguage !== undefined) { this.acceptLanguage = options.acceptLanguage; } @@ -62,68 +62,73 @@ util.inherits(AzureServiceClient, msRest.ServiceClient); * @param {object} [options] * @param {object} [options.customHeaders] headers that will be added to request */ -AzureServiceClient.prototype.getPutOrPatchOperationResult = function (resultOfInitialRequest, options, callback) { +AzureServiceClient.prototype.getPutOrPatchOperationResult = function(resultOfInitialRequest, options, callback) { var self = this; - if(!callback && typeof options === 'function') { + if (!callback && typeof options === 'function') { callback = options; options = null; } if (!callback) { throw new Error('Missing callback'); } - + if (!resultOfInitialRequest) { return callback(new Error('Missing resultOfInitialRequest parameter')); } - + + if (!resultOfInitialRequest.response) { + return callback(new Error('Missing resultOfInitialRequest.response')); + } + if (resultOfInitialRequest.response.statusCode !== 200 && - resultOfInitialRequest.response.statusCode !== 201 && - resultOfInitialRequest.response.statusCode !== 202) { - return callback(new Error(util.format('Unexpected polling status code from long running operation \'%s\'', + resultOfInitialRequest.response.statusCode !== 201 && + resultOfInitialRequest.response.statusCode !== 202 && + resultOfInitialRequest.response.statusCode !== 204) { + return callback(new Error(util.format('Unexpected polling status code from long running operation \'%s\'', resultOfInitialRequest.response.statusCode))); } + var pollingState = null; try { pollingState = new PollingState(resultOfInitialRequest, this.longRunningOperationRetryTimeout); } catch (error) { callback(error); } - var resourceUrl = resultOfInitialRequest.request.url; this._options = options; - + async.whilst( - //while condition - function () { - var finished = [LroStates.Succeeded, LroStates.Failed, LroStates.Canceled].some(function (e) { - return pollingState.status === e; + function() { + var finished = [LroStates.Succeeded, LroStates.Failed, LroStates.Canceled].some(function(e) { + return e === pollingState.status; }); return !finished; }, - //while loop body - function (callback) { - setTimeout(function () { + function(callback) { + setTimeout(function() { if (pollingState.azureAsyncOperationHeaderLink) { - self._updateStateFromAzureAsyncOperationHeader(pollingState, false, function (err) { + self._updateStateFromAzureAsyncOperationHeader(pollingState, true, function(err) { return callback(err); }); } else if (pollingState.locationHeaderLink) { - self._updateStateFromLocationHeaderOnPut(pollingState, function (err) { + self._updateStateFromLocationHeader(pollingState, function(err) { return callback(err); }); - } else { - self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function (err) { + } else if (resultOfInitialRequest.request.method === "PUT") { + self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { return callback(err); }); + } else { + return callback(new Error('Location header is missing from long running operation.')); } }, pollingState.getTimeout()); }, //when done - function (err) { + function(err) { if (pollingState.status === LroStates.Succeeded) { - if (!pollingState.resource) { - self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function (err) { + if ((pollingState.azureAsyncOperationHeaderLink || !pollingState.resource) && resultOfInitialRequest.request.method !== "DELETE" && resultOfInitialRequest.request.method !== "POST") { + self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { return callback(err, pollingState.getOperationResponse()); }); } else { @@ -142,9 +147,9 @@ AzureServiceClient.prototype.getPutOrPatchOperationResult = function (resultOfIn * @param {object} [options] * @param {object} [options.customHeaders] headers that will be added to request */ -AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOfInitialRequest, options, callback) { +AzureServiceClient.prototype.getPostOrDeleteOperationResult = function(resultOfInitialRequest, options, callback) { var self = this; - + if (!callback && typeof options === 'function') { callback = options; options = null; @@ -152,45 +157,52 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOf if (!callback) { throw new Error('Missing callback'); } - + if (!resultOfInitialRequest) { return callback(new Error('Missing resultOfInitialRequest parameter')); } - + if (!resultOfInitialRequest.response) { return callback(new Error('Missing resultOfInitialRequest.response')); } - + if (resultOfInitialRequest.response.statusCode !== 200 && - resultOfInitialRequest.response.statusCode !== 202 && - resultOfInitialRequest.response.statusCode !== 204) { - return callback(new Error(util.format('Unexpected polling status code from long running operation \'%s\'', + resultOfInitialRequest.response.statusCode !== 201 && + resultOfInitialRequest.response.statusCode !== 202 && + resultOfInitialRequest.response.statusCode !== 204) { + return callback(new Error(util.format('Unexpected polling status code from long running operation \'%s\'', resultOfInitialRequest.response.statusCode))); } - + var pollingState = null; try { pollingState = new PollingState(resultOfInitialRequest, this.longRunningOperationRetryTimeout); } catch (error) { callback(error); } + + var resourceUrl = resultOfInitialRequest.request.url; this._options = options; async.whilst( - function () { - var finished = [LroStates.Succeeded, LroStates.Failed, LroStates.Canceled].some(function (e) { + function() { + var finished = [LroStates.Succeeded, LroStates.Failed, LroStates.Canceled].some(function(e) { return e === pollingState.status; }); return !finished; }, - function (callback) { - setTimeout(function () { + function(callback) { + setTimeout(function() { if (pollingState.azureAsyncOperationHeaderLink) { - self._updateStateFromAzureAsyncOperationHeader(pollingState, true, function (err) { + self._updateStateFromAzureAsyncOperationHeader(pollingState, true, function(err) { return callback(err); }); } else if (pollingState.locationHeaderLink) { - self._updateStateFromLocationHeaderOnPostOrDelete(pollingState, function (err) { + self._updateStateFromLocationHeader(pollingState, function(err) { + return callback(err); + }); + } else if (resultOfInitialRequest.request.method === "PUT") { + self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { return callback(err); }); } else { @@ -198,9 +210,16 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOf } }, pollingState.getTimeout()); }, - function (err) { - if (pollingState.status === LroStates.Succeeded ) { - return callback(null, pollingState.getOperationResponse()); + //when done + function(err) { + if (pollingState.status === LroStates.Succeeded) { + if ((pollingState.azureAsyncOperationHeaderLink || !pollingState.resource) && resultOfInitialRequest.request.method !== "DELETE" && resultOfInitialRequest.request.method !== "POST") { + self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { + return callback(err, pollingState.getOperationResponse()); + }); + } else { + return callback(null, pollingState.getOperationResponse()); + } } else { return callback(pollingState.getCloudError(err)); } @@ -212,14 +231,14 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOf * @param {object} [pollingState] - The object to persist current operation state. * @param {boolean} [inPostOrDelete] - Invoked by Post Or Delete operation. */ -AzureServiceClient.prototype._updateStateFromAzureAsyncOperationHeader = function (pollingState, inPostOrDelete, callback) { - this._getStatus(pollingState.azureAsyncOperationHeaderLink, function (err, result) { +AzureServiceClient.prototype._updateStateFromAzureAsyncOperationHeader = function(pollingState, inPostOrDelete, callback) { + this._getStatus(pollingState.azureAsyncOperationHeaderLink, function(err, result) { if (err) return callback(err); - + if (!result.body || !result.body.status) { return callback(new Error('The response from long running operation does not contain a body.')); } - + pollingState.status = result.body.status; pollingState.error = result.body.error; pollingState.response = result.response; @@ -233,36 +252,25 @@ AzureServiceClient.prototype._updateStateFromAzureAsyncOperationHeader = functio }; /** - * Retrieve PUT operation status by polling from 'location' header. + * Retrieve PUT/POST/PATCH/DELETE operation status by polling from 'location' header. * @param {object} [pollingState] - The object to persist current operation state. */ -AzureServiceClient.prototype._updateStateFromLocationHeaderOnPut = function (pollingState, callback) { - this._getStatus(pollingState.locationHeaderLink, function (err, result) { +AzureServiceClient.prototype._updateStateFromLocationHeader = function(pollingState, callback) { + this._getStatus(pollingState.locationHeaderLink, function(err, result) { if (err) return callback(err); - + pollingState.updateResponse(result.response); pollingState.request = result.request; - + var statusCode = result.response.statusCode; if (statusCode === 202) { pollingState.status = LroStates.InProgress; - } - else if (statusCode === 200 || - statusCode === 201) { - - if (!result.body) { - return callback(new Error('The response from long running operation does not contain a body.')); - } - - // In 202 pattern on PUT ProvisioningState may not be present in - // the response. In that case the assumption is the status is Succeeded. - if (result.body.properties && result.body.properties.provisioningState) { - pollingState.status = result.body.properties.provisioningState; - } - else { - pollingState.status = LroStates.Succeeded; - } - + } else if (statusCode === 200 || + statusCode === 201 || + statusCode === 204) { + + pollingState.status = LroStates.Succeeded; + pollingState.error = { code: pollingState.Status, message: util.format('Long running operation failed with status \'%s\'.', pollingState.status) @@ -273,59 +281,34 @@ AzureServiceClient.prototype._updateStateFromLocationHeaderOnPut = function (pol }); }; -/** - * Retrieve POST or DELETE operation status by polling from 'location' header. - * @param {object} [pollingState] - The object to persist current operation state. - */ -AzureServiceClient.prototype._updateStateFromLocationHeaderOnPostOrDelete = function (pollingState, callback) { - this._getStatus(pollingState.locationHeaderLink, function (err, result) { - if (err) return callback(err); - - pollingState.updateResponse(result.response); - pollingState.request = result.request; - - var statusCode = result.response.statusCode; - if (statusCode === 202) { - pollingState.status = LroStates.InProgress; - } - else if (statusCode === 200 || - statusCode === 201 || - statusCode === 204) { - pollingState.status = LroStates.Succeeded; - pollingState.resource = result.body; - } - callback(null); - }); -}; - /** * Polling for resource status. * @param {function} [resourceUrl] - The url of resource. * @param {object} [pollingState] - The object to persist current operation state. */ -AzureServiceClient.prototype._updateStateFromGetResourceOperation = function (resourceUrl, pollingState, callback) { - this._getStatus(resourceUrl, function (err, result) { +AzureServiceClient.prototype._updateStateFromGetResourceOperation = function(resourceUrl, pollingState, callback) { + this._getStatus(resourceUrl, function(err, result) { if (err) return callback(err); if (!result.body) { return callback(new Error('The response from long running operation does not contain a body.')); } - + if (result.body.properties && result.body.properties.provisioningState) { pollingState.status = result.body.properties.provisioningState; } else { pollingState.status = LroStates.Succeeded; } - + //we might not throw an error, but initialize here just in case. pollingState.error = { code: pollingState.status, message: util.format('Long running operation failed with status \'%s\'.', pollingState.status) }; - + pollingState.updateResponse(result.response); pollingState.request = result.request; pollingState.resource = result.body; - + //nothing to return, the 'pollingState' has all the info we care. callback(null); }); @@ -335,21 +318,21 @@ AzureServiceClient.prototype._updateStateFromGetResourceOperation = function (re * Retrieve operation status by querying the operation URL. * @param {string} [operationUrl] - URL used to poll operation result. */ -AzureServiceClient.prototype._getStatus = function (operationUrl, callback) { +AzureServiceClient.prototype._getStatus = function(operationUrl, callback) { var self = this; if (!operationUrl) { return callback(new Error('operationUrl cannot be null.')); } - + // Construct URL var requestUrl = operationUrl.replace(' ', '%20'); - + // Create HTTP transport objects var httpRequest = new WebResource(); httpRequest.method = 'GET'; httpRequest.headers = {}; httpRequest.url = requestUrl; - if(this._options) { + if (this._options) { for (var headerName in this._options['customHeaders']) { if (this._options['customHeaders'].hasOwnProperty(headerName)) { httpRequest.headers[headerName] = this._options['customHeaders'][headerName]; @@ -357,13 +340,13 @@ AzureServiceClient.prototype._getStatus = function (operationUrl, callback) { } } // Send Request - return self.pipeline(httpRequest, function (err, response, responseBody) { + return self.pipeline(httpRequest, function(err, response, responseBody) { if (err) { return callback(err); } var statusCode = response.statusCode; if (statusCode !== 200 && statusCode !== 201 && statusCode !== 202 && statusCode !== 204) { - var error = new Error(util.format('Invalid status code with response body "%s" occurred ' + + var error = new Error(util.format('Invalid status code with response body "%s" occurred ' + 'when polling for operation status.', responseBody)); error.statusCode = response.statusCode; error.request = msRest.stripRequest(httpRequest); @@ -388,8 +371,8 @@ AzureServiceClient.prototype._getStatus = function (operationUrl, callback) { try { result.body = JSON.parse(responseBody); } catch (deserializationError) { - var parseError = new Error(util.format('Error "%s" occurred in deserializing the response body - "%s" -' + - ' when polling for operation status.', deserializationError, responseBody)); + var parseError = new Error(util.format('Error "%s" occurred in deserializing the response body - "%s" -' + + ' when polling for operation status.', deserializationError, responseBody)); parseError.request = msRest.stripRequest(httpRequest); parseError.response = msRest.stripResponse(response); parseError.body = responseBody; diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/lib/pollingState.js b/ClientRuntimes/NodeJS/ms-rest-azure/lib/pollingState.js index 87a68bf6dfc25..0d7c48fd1df0b 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/lib/pollingState.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/lib/pollingState.js @@ -25,39 +25,46 @@ function PollingState(resultOfInitialRequest, retryTimeout) { this.request = resultOfInitialRequest.request; //Parse response.body & assign it as the resource try { - if (resultOfInitialRequest.body && - typeof resultOfInitialRequest.body.valueOf() === 'string' && - resultOfInitialRequest.body.length > 0) { + if (resultOfInitialRequest.body && + typeof resultOfInitialRequest.body.valueOf() === 'string' && + resultOfInitialRequest.body.length > 0) { this.resource = JSON.parse(resultOfInitialRequest.body); } else { this.resource = resultOfInitialRequest.body; - } + } } catch (error) { - var deserializationError = new Error(util.format('Error "%s" occurred in parsing the responseBody ' + + var deserializationError = new Error(util.format('Error "%s" occurred in parsing the responseBody ' + 'while creating the PollingState for Long Running Operation- "%s"', error, resultOfInitialRequest.body)); deserializationError.request = resultOfInitialRequest.request; deserializationError.response = resultOfInitialRequest.response; throw deserializationError; } - - if (this.resource && this.resource.properties && this.resource.properties.provisioningState) { - this.status = this.resource.properties.provisioningState; - } else { - switch (this.response.statusCode) { - case 202: - this.status = LroStates.InProgress; - break; - case 204: - case 201: - case 200: - this.status = LroStates.Succeeded; - break; + switch (this.response.statusCode) { + case 202: + this.status = LroStates.InProgress; + break; - default: - this.status = LroStates.Failed; - break; - } + case 204: + this.status = LroStates.Succeeded; + break; + case 201: + if (this.resource && this.resource.properties && this.resource.properties.provisioningState) { + this.status = this.resource.properties.provisioningState; + } else { + this.status = LroStates.InProgress; + } + break; + case 200: + if (this.resource && this.resource.properties && this.resource.properties.provisioningState) { + this.status = this.resource.properties.provisioningState; + } else { + this.status = LroStates.Succeeded; + } + break; + default: + this.status = LroStates.Failed; + break; } } @@ -65,7 +72,7 @@ function PollingState(resultOfInitialRequest, retryTimeout) { * Gets timeout in milliseconds. * @returns {number} timeout */ -PollingState.prototype.getTimeout = function () { +PollingState.prototype.getTimeout = function() { if (this._retryTimeout || this._retryTimeout === 0) { return this._retryTimeout * 1000; } @@ -79,13 +86,13 @@ PollingState.prototype.getTimeout = function () { * Update cached data using the provided response object * @param {object} [response] - provider response object. */ -PollingState.prototype.updateResponse = function (response) { +PollingState.prototype.updateResponse = function(response) { this.response = response; if (response && response.headers) { if (response.headers['azure-asyncoperation']) { this.azureAsyncOperationHeaderLink = response.headers['azure-asyncoperation']; } - + if (response.headers['location']) { this.locationHeaderLink = response.headers['location']; } @@ -96,7 +103,7 @@ PollingState.prototype.updateResponse = function (response) { * Returns long running operation result. * @returns {object} HttpOperationResponse */ -PollingState.prototype.getOperationResponse = function () { +PollingState.prototype.getOperationResponse = function() { var result = new msRest.HttpOperationResponse(); result.request = this.request; result.response = this.response; @@ -112,7 +119,7 @@ PollingState.prototype.getOperationResponse = function () { * Returns an Error on operation failure. * @returns {object} Error */ -PollingState.prototype.getCloudError = function (err) { +PollingState.prototype.getCloudError = function(err) { var errMsg; var errCode; @@ -126,11 +133,11 @@ PollingState.prototype.getCloudError = function (err) { parsedResponse = JSON.parse(this.response.body); } } catch (err) { - error.message = util.format('Error "%s" occurred while deserializing the error ' + + error.message = util.format('Error "%s" occurred while deserializing the error ' + 'message "%s" for long running operation.', err.message, this.response.body); return error; } - + if (err && err.message) { errMsg = util.format('Long running operation failed with error: \'%s\'.', err.message); } else { From b789377b723611732d63266140f6592fd817d837 Mon Sep 17 00:00:00 2001 From: Qinyuan Wan Date: Wed, 23 Mar 2016 10:43:45 -0700 Subject: [PATCH 02/29] add test for fixing the post/patch async operation --- .../ms-rest-azure/lib/azureServiceClient.js | 8 +-- .../test/azureServiceClientTests.js | 50 ++++++++++++++++++- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js index 4b967ca5cd373..4a7ce94cf713a 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js @@ -115,7 +115,7 @@ AzureServiceClient.prototype.getPutOrPatchOperationResult = function(resultOfIni self._updateStateFromLocationHeader(pollingState, function(err) { return callback(err); }); - } else if (resultOfInitialRequest.request.method === "PUT") { + } else if (resultOfInitialRequest.request.method === 'PUT') { self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { return callback(err); }); @@ -127,7 +127,7 @@ AzureServiceClient.prototype.getPutOrPatchOperationResult = function(resultOfIni //when done function(err) { if (pollingState.status === LroStates.Succeeded) { - if ((pollingState.azureAsyncOperationHeaderLink || !pollingState.resource) && resultOfInitialRequest.request.method !== "DELETE" && resultOfInitialRequest.request.method !== "POST") { + if ((pollingState.azureAsyncOperationHeaderLink || !pollingState.resource) && resultOfInitialRequest.request.method !== 'DELETE' && resultOfInitialRequest.request.method !== 'POST') { self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { return callback(err, pollingState.getOperationResponse()); }); @@ -201,7 +201,7 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function(resultOfI self._updateStateFromLocationHeader(pollingState, function(err) { return callback(err); }); - } else if (resultOfInitialRequest.request.method === "PUT") { + } else if (resultOfInitialRequest.request.method === 'PUT') { self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { return callback(err); }); @@ -213,7 +213,7 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function(resultOfI //when done function(err) { if (pollingState.status === LroStates.Succeeded) { - if ((pollingState.azureAsyncOperationHeaderLink || !pollingState.resource) && resultOfInitialRequest.request.method !== "DELETE" && resultOfInitialRequest.request.method !== "POST") { + if ((pollingState.azureAsyncOperationHeaderLink || !pollingState.resource) && resultOfInitialRequest.request.method !== 'DELETE' && resultOfInitialRequest.request.method !== 'POST') { self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { return callback(err, pollingState.getOperationResponse()); }); diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js b/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js index e28f44bf5ad68..bab92dc1e627c 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js @@ -156,11 +156,56 @@ describe('AzureServiceClient', function () { }); }); + describe('Patch', function () { + resultOfInitialRequest.response.statusCode = 202; + resultOfInitialRequest.body.properties.provisioningState = LroStates.Succeeded; + + it('works by polling from azure-asyncoperation header', function (done) { + resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; + resultOfInitialRequest.response.headers['location'] = urlFromLocationHeader_Return200; + client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + should.not.exist(err); + JSON.parse(result.body).name.should.equal(testResourceName); + should.exist(result.response.randomFieldFromPollLocationHeader); + done(); + }); + }); + + it('works by polling from location header', function (done) { + resultOfInitialRequest.response.headers['azure-asyncoperation'] = urlFromAzureAsyncOPHeader_Return200; + resultOfInitialRequest.response.headers['location'] = ''; + client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + should.not.exist(err); + JSON.parse(result.body).name.should.equal(testResourceName); + done(); + }); + }); + + it('returns error if failed to poll from the azure-asyncoperation header', function (done) { + resultOfInitialRequest.response.headers['azure-asyncoperation'] = url_ReturnError; + resultOfInitialRequest.response.headers['location'] = ''; + client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + err.message.should.containEql(testError); + done(); + }); + }); + + it('returns error if failed to poll from the location header', function (done) { + resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; + resultOfInitialRequest.response.headers['location'] = url_ReturnError; + client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + err.message.should.containEql(testError); + done(); + }); + }); + }); + describe('Post-or-Delete', function () { resultOfInitialRequest.response.statusCode = 202; - + resultOfInitialRequest.body.properties.provisioningState = LroStates.Succeeded; + it('throw on not Lro related status code', function (done) { - client.getPostOrDeleteOperationResult({ response: { statusCode: 201 } }, function (err, result) { + client.getPostOrDeleteOperationResult({ response: { statusCode: 203 }, request: {url: url_resource}}, function (err, result) { err.message.should.containEql('Unexpected polling status code from long running operation'); done(); }); @@ -169,6 +214,7 @@ describe('AzureServiceClient', function () { it('works by polling from the azure-asyncoperation header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = urlFromAzureAsyncOPHeader_Return200; resultOfInitialRequest.response.headers['location'] = ''; + resultOfInitialRequest.request.method = 'POST'; client.getPostOrDeleteOperationResult(resultOfInitialRequest, function (err, result) { should.not.exist(err); should.exist(result.response.randomFieldFromPollAsyncOpHeader); From 9c7e28b27cdc5b49900ce005b1c4c6a06290264c Mon Sep 17 00:00:00 2001 From: Qinyuan Wan Date: Thu, 24 Mar 2016 10:09:33 -0700 Subject: [PATCH 03/29] code revise --- .../ms-rest-azure/lib/azureServiceClient.js | 83 ++++++++++--------- .../NodeJS/ms-rest-azure/lib/pollingState.js | 26 +++--- .../test/azureServiceClientTests.js | 4 +- 3 files changed, 60 insertions(+), 53 deletions(-) diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js index 4a7ce94cf713a..dabedd8d3217c 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js @@ -32,15 +32,15 @@ function AzureServiceClient(credentials, options) { if (!credentials) { throw new Error('Azure clients require credentials.'); } - + AzureServiceClient['super_'].call(this, credentials, options); - + this.acceptLanguage = 'en-US'; this.generateClientRequestId = true; this.longRunningOperationRetryTimeout = 30; if (!options) options = {}; - + if (options.acceptLanguage !== null && options.acceptLanguage !== undefined) { this.acceptLanguage = options.acceptLanguage; } @@ -62,7 +62,7 @@ util.inherits(AzureServiceClient, msRest.ServiceClient); * @param {object} [options] * @param {object} [options.customHeaders] headers that will be added to request */ -AzureServiceClient.prototype.getPutOrPatchOperationResult = function(resultOfInitialRequest, options, callback) { +AzureServiceClient.prototype.getPutOrPatchOperationResult = function (resultOfInitialRequest, options, callback) { var self = this; if (!callback && typeof options === 'function') { @@ -81,12 +81,10 @@ AzureServiceClient.prototype.getPutOrPatchOperationResult = function(resultOfIni return callback(new Error('Missing resultOfInitialRequest.response')); } - if (resultOfInitialRequest.response.statusCode !== 200 && - resultOfInitialRequest.response.statusCode !== 201 && - resultOfInitialRequest.response.statusCode !== 202 && - resultOfInitialRequest.response.statusCode !== 204) { - return callback(new Error(util.format('Unexpected polling status code from long running operation \'%s\'', - resultOfInitialRequest.response.statusCode))); + if (this._checkInitialRequestResponseStatusCodeFailed(resultOfInitialRequest)) { + return callback(new Error(util.format('Unexpected polling status code from long running operation \'%s\' for method \'%s\'', + resultOfInitialRequest.response.statusCode, + resultOfInitialRequest.request.method))); } var pollingState = null; @@ -147,7 +145,7 @@ AzureServiceClient.prototype.getPutOrPatchOperationResult = function(resultOfIni * @param {object} [options] * @param {object} [options.customHeaders] headers that will be added to request */ -AzureServiceClient.prototype.getPostOrDeleteOperationResult = function(resultOfInitialRequest, options, callback) { +AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOfInitialRequest, options, callback) { var self = this; if (!callback && typeof options === 'function') { @@ -166,12 +164,10 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function(resultOfI return callback(new Error('Missing resultOfInitialRequest.response')); } - if (resultOfInitialRequest.response.statusCode !== 200 && - resultOfInitialRequest.response.statusCode !== 201 && - resultOfInitialRequest.response.statusCode !== 202 && - resultOfInitialRequest.response.statusCode !== 204) { - return callback(new Error(util.format('Unexpected polling status code from long running operation \'%s\'', - resultOfInitialRequest.response.statusCode))); + if (this._checkInitialRequestResponseStatusCodeFailed(resultOfInitialRequest)) { + return callback(new Error(util.format('Unexpected polling status code from long running operation \'%s\' for method \'%s\'', + resultOfInitialRequest.response.statusCode, + resultOfInitialRequest.request.method))); } var pollingState = null; @@ -180,7 +176,6 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function(resultOfI } catch (error) { callback(error); } - var resourceUrl = resultOfInitialRequest.request.url; this._options = options; @@ -226,19 +221,31 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function(resultOfI }); }; +AzureServiceClient.prototype._checkInitialRequestResponseStatusCodeFailed = function (initialRequest) { + if (initialRequest.response.statusCode === 200 || + initialRequest.response.statusCode === 202 || + (initialRequest.response.statusCode === 201 && initialRequest.request.method === 'PUT') || + (initialRequest.response.statusCode === 204 && initialRequest.request.method === 'DELETE')) { + return false; + } else { + return true; + } +}; + + /** * Retrieve operation status by polling from 'azure-asyncoperation' header. * @param {object} [pollingState] - The object to persist current operation state. * @param {boolean} [inPostOrDelete] - Invoked by Post Or Delete operation. */ -AzureServiceClient.prototype._updateStateFromAzureAsyncOperationHeader = function(pollingState, inPostOrDelete, callback) { - this._getStatus(pollingState.azureAsyncOperationHeaderLink, function(err, result) { +AzureServiceClient.prototype._updateStateFromAzureAsyncOperationHeader = function (pollingState, inPostOrDelete, callback) { + this._getStatus(pollingState.azureAsyncOperationHeaderLink, function (err, result) { if (err) return callback(err); - + if (!result.body || !result.body.status) { return callback(new Error('The response from long running operation does not contain a body.')); } - + pollingState.status = result.body.status; pollingState.error = result.body.error; pollingState.response = result.response; @@ -252,10 +259,10 @@ AzureServiceClient.prototype._updateStateFromAzureAsyncOperationHeader = functio }; /** - * Retrieve PUT/POST/PATCH/DELETE operation status by polling from 'location' header. + * Retrieve PUT operation status by polling from 'location' header. * @param {object} [pollingState] - The object to persist current operation state. */ -AzureServiceClient.prototype._updateStateFromLocationHeader = function(pollingState, callback) { +AzureServiceClient.prototype._updateStateFromLocationHeader = function (pollingState, callback) { this._getStatus(pollingState.locationHeaderLink, function(err, result) { if (err) return callback(err); @@ -286,29 +293,29 @@ AzureServiceClient.prototype._updateStateFromLocationHeader = function(pollingSt * @param {function} [resourceUrl] - The url of resource. * @param {object} [pollingState] - The object to persist current operation state. */ -AzureServiceClient.prototype._updateStateFromGetResourceOperation = function(resourceUrl, pollingState, callback) { - this._getStatus(resourceUrl, function(err, result) { +AzureServiceClient.prototype._updateStateFromGetResourceOperation = function (resourceUrl, pollingState, callback) { + this._getStatus(resourceUrl, function (err, result) { if (err) return callback(err); if (!result.body) { return callback(new Error('The response from long running operation does not contain a body.')); } - + if (result.body.properties && result.body.properties.provisioningState) { pollingState.status = result.body.properties.provisioningState; } else { pollingState.status = LroStates.Succeeded; } - + //we might not throw an error, but initialize here just in case. pollingState.error = { code: pollingState.status, message: util.format('Long running operation failed with status \'%s\'.', pollingState.status) }; - + pollingState.updateResponse(result.response); pollingState.request = result.request; pollingState.resource = result.body; - + //nothing to return, the 'pollingState' has all the info we care. callback(null); }); @@ -318,21 +325,21 @@ AzureServiceClient.prototype._updateStateFromGetResourceOperation = function(res * Retrieve operation status by querying the operation URL. * @param {string} [operationUrl] - URL used to poll operation result. */ -AzureServiceClient.prototype._getStatus = function(operationUrl, callback) { +AzureServiceClient.prototype._getStatus = function (operationUrl, callback) { var self = this; if (!operationUrl) { return callback(new Error('operationUrl cannot be null.')); } - + // Construct URL var requestUrl = operationUrl.replace(' ', '%20'); - + // Create HTTP transport objects var httpRequest = new WebResource(); httpRequest.method = 'GET'; httpRequest.headers = {}; httpRequest.url = requestUrl; - if (this._options) { + if(this._options) { for (var headerName in this._options['customHeaders']) { if (this._options['customHeaders'].hasOwnProperty(headerName)) { httpRequest.headers[headerName] = this._options['customHeaders'][headerName]; @@ -340,13 +347,13 @@ AzureServiceClient.prototype._getStatus = function(operationUrl, callback) { } } // Send Request - return self.pipeline(httpRequest, function(err, response, responseBody) { + return self.pipeline(httpRequest, function (err, response, responseBody) { if (err) { return callback(err); } var statusCode = response.statusCode; if (statusCode !== 200 && statusCode !== 201 && statusCode !== 202 && statusCode !== 204) { - var error = new Error(util.format('Invalid status code with response body "%s" occurred ' + + var error = new Error(util.format('Invalid status code with response body "%s" occurred ' + 'when polling for operation status.', responseBody)); error.statusCode = response.statusCode; error.request = msRest.stripRequest(httpRequest); @@ -371,8 +378,8 @@ AzureServiceClient.prototype._getStatus = function(operationUrl, callback) { try { result.body = JSON.parse(responseBody); } catch (deserializationError) { - var parseError = new Error(util.format('Error "%s" occurred in deserializing the response body - "%s" -' + - ' when polling for operation status.', deserializationError, responseBody)); + var parseError = new Error(util.format('Error "%s" occurred in deserializing the response body - "%s" -' + + ' when polling for operation status.', deserializationError, responseBody)); parseError.request = msRest.stripRequest(httpRequest); parseError.response = msRest.stripResponse(response); parseError.body = responseBody; diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/lib/pollingState.js b/ClientRuntimes/NodeJS/ms-rest-azure/lib/pollingState.js index 0d7c48fd1df0b..114eedf25c573 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/lib/pollingState.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/lib/pollingState.js @@ -25,21 +25,21 @@ function PollingState(resultOfInitialRequest, retryTimeout) { this.request = resultOfInitialRequest.request; //Parse response.body & assign it as the resource try { - if (resultOfInitialRequest.body && - typeof resultOfInitialRequest.body.valueOf() === 'string' && - resultOfInitialRequest.body.length > 0) { + if (resultOfInitialRequest.body && + typeof resultOfInitialRequest.body.valueOf() === 'string' && + resultOfInitialRequest.body.length > 0) { this.resource = JSON.parse(resultOfInitialRequest.body); } else { this.resource = resultOfInitialRequest.body; - } + } } catch (error) { - var deserializationError = new Error(util.format('Error "%s" occurred in parsing the responseBody ' + + var deserializationError = new Error(util.format('Error "%s" occurred in parsing the responseBody ' + 'while creating the PollingState for Long Running Operation- "%s"', error, resultOfInitialRequest.body)); deserializationError.request = resultOfInitialRequest.request; deserializationError.response = resultOfInitialRequest.response; throw deserializationError; } - + switch (this.response.statusCode) { case 202: this.status = LroStates.InProgress; @@ -72,7 +72,7 @@ function PollingState(resultOfInitialRequest, retryTimeout) { * Gets timeout in milliseconds. * @returns {number} timeout */ -PollingState.prototype.getTimeout = function() { +PollingState.prototype.getTimeout = function () { if (this._retryTimeout || this._retryTimeout === 0) { return this._retryTimeout * 1000; } @@ -86,13 +86,13 @@ PollingState.prototype.getTimeout = function() { * Update cached data using the provided response object * @param {object} [response] - provider response object. */ -PollingState.prototype.updateResponse = function(response) { +PollingState.prototype.updateResponse = function (response) { this.response = response; if (response && response.headers) { if (response.headers['azure-asyncoperation']) { this.azureAsyncOperationHeaderLink = response.headers['azure-asyncoperation']; } - + if (response.headers['location']) { this.locationHeaderLink = response.headers['location']; } @@ -103,7 +103,7 @@ PollingState.prototype.updateResponse = function(response) { * Returns long running operation result. * @returns {object} HttpOperationResponse */ -PollingState.prototype.getOperationResponse = function() { +PollingState.prototype.getOperationResponse = function () { var result = new msRest.HttpOperationResponse(); result.request = this.request; result.response = this.response; @@ -119,7 +119,7 @@ PollingState.prototype.getOperationResponse = function() { * Returns an Error on operation failure. * @returns {object} Error */ -PollingState.prototype.getCloudError = function(err) { +PollingState.prototype.getCloudError = function (err) { var errMsg; var errCode; @@ -133,11 +133,11 @@ PollingState.prototype.getCloudError = function(err) { parsedResponse = JSON.parse(this.response.body); } } catch (err) { - error.message = util.format('Error "%s" occurred while deserializing the error ' + + error.message = util.format('Error "%s" occurred while deserializing the error ' + 'message "%s" for long running operation.', err.message, this.response.body); return error; } - + if (err && err.message) { errMsg = util.format('Long running operation failed with error: \'%s\'.', err.message); } else { diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js b/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js index bab92dc1e627c..f358540bb6aae 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js @@ -92,7 +92,7 @@ describe('AzureServiceClient', function () { describe('Put', function () { resultOfInitialRequest.response.statusCode = 201; - + it('throw on not Lro related status code', function (done) { client.getPutOrPatchOperationResult({ response: {statusCode: 10000}, request: { url:"http://foo" }}, function (err, result) { err.message.should.containEql('Unexpected polling status code from long running operation'); @@ -205,7 +205,7 @@ describe('AzureServiceClient', function () { resultOfInitialRequest.body.properties.provisioningState = LroStates.Succeeded; it('throw on not Lro related status code', function (done) { - client.getPostOrDeleteOperationResult({ response: { statusCode: 203 }, request: {url: url_resource}}, function (err, result) { + client.getPostOrDeleteOperationResult({ response: { statusCode: 201 }, request: {url: url_resource, method: 'POST'}}, function (err, result) { err.message.should.containEql('Unexpected polling status code from long running operation'); done(); }); From 6e478d4e7c98b1a625715aeebf6809116e297110 Mon Sep 17 00:00:00 2001 From: Qinyuan Wan Date: Tue, 22 Mar 2016 16:47:05 -0700 Subject: [PATCH 04/29] fix async patch and post run --- .../ms-rest-azure/lib/azureServiceClient.js | 168 ++++++++---------- .../NodeJS/ms-rest-azure/lib/pollingState.js | 39 ++-- .../test/azureServiceClientTests.js | 52 +++++- 3 files changed, 151 insertions(+), 108 deletions(-) diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js index ae1798dc5e56a..dabedd8d3217c 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js @@ -65,65 +65,68 @@ util.inherits(AzureServiceClient, msRest.ServiceClient); AzureServiceClient.prototype.getPutOrPatchOperationResult = function (resultOfInitialRequest, options, callback) { var self = this; - if(!callback && typeof options === 'function') { + if (!callback && typeof options === 'function') { callback = options; options = null; } if (!callback) { throw new Error('Missing callback'); } - + if (!resultOfInitialRequest) { return callback(new Error('Missing resultOfInitialRequest parameter')); } - - if (resultOfInitialRequest.response.statusCode !== 200 && - resultOfInitialRequest.response.statusCode !== 201 && - resultOfInitialRequest.response.statusCode !== 202) { - return callback(new Error(util.format('Unexpected polling status code from long running operation \'%s\'', - resultOfInitialRequest.response.statusCode))); + + if (!resultOfInitialRequest.response) { + return callback(new Error('Missing resultOfInitialRequest.response')); + } + + if (this._checkInitialRequestResponseStatusCodeFailed(resultOfInitialRequest)) { + return callback(new Error(util.format('Unexpected polling status code from long running operation \'%s\' for method \'%s\'', + resultOfInitialRequest.response.statusCode, + resultOfInitialRequest.request.method))); } + var pollingState = null; try { pollingState = new PollingState(resultOfInitialRequest, this.longRunningOperationRetryTimeout); } catch (error) { callback(error); } - var resourceUrl = resultOfInitialRequest.request.url; this._options = options; - + async.whilst( - //while condition - function () { - var finished = [LroStates.Succeeded, LroStates.Failed, LroStates.Canceled].some(function (e) { - return pollingState.status === e; + function() { + var finished = [LroStates.Succeeded, LroStates.Failed, LroStates.Canceled].some(function(e) { + return e === pollingState.status; }); return !finished; }, - //while loop body - function (callback) { - setTimeout(function () { + function(callback) { + setTimeout(function() { if (pollingState.azureAsyncOperationHeaderLink) { - self._updateStateFromAzureAsyncOperationHeader(pollingState, false, function (err) { + self._updateStateFromAzureAsyncOperationHeader(pollingState, true, function(err) { return callback(err); }); } else if (pollingState.locationHeaderLink) { - self._updateStateFromLocationHeaderOnPut(pollingState, function (err) { + self._updateStateFromLocationHeader(pollingState, function(err) { return callback(err); }); - } else { - self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function (err) { + } else if (resultOfInitialRequest.request.method === 'PUT') { + self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { return callback(err); }); + } else { + return callback(new Error('Location header is missing from long running operation.')); } }, pollingState.getTimeout()); }, //when done - function (err) { + function(err) { if (pollingState.status === LroStates.Succeeded) { - if (!pollingState.resource) { - self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function (err) { + if ((pollingState.azureAsyncOperationHeaderLink || !pollingState.resource) && resultOfInitialRequest.request.method !== 'DELETE' && resultOfInitialRequest.request.method !== 'POST') { + self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { return callback(err, pollingState.getOperationResponse()); }); } else { @@ -144,7 +147,7 @@ AzureServiceClient.prototype.getPutOrPatchOperationResult = function (resultOfIn */ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOfInitialRequest, options, callback) { var self = this; - + if (!callback && typeof options === 'function') { callback = options; options = null; @@ -152,45 +155,49 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOf if (!callback) { throw new Error('Missing callback'); } - + if (!resultOfInitialRequest) { return callback(new Error('Missing resultOfInitialRequest parameter')); } - + if (!resultOfInitialRequest.response) { return callback(new Error('Missing resultOfInitialRequest.response')); } - - if (resultOfInitialRequest.response.statusCode !== 200 && - resultOfInitialRequest.response.statusCode !== 202 && - resultOfInitialRequest.response.statusCode !== 204) { - return callback(new Error(util.format('Unexpected polling status code from long running operation \'%s\'', - resultOfInitialRequest.response.statusCode))); + + if (this._checkInitialRequestResponseStatusCodeFailed(resultOfInitialRequest)) { + return callback(new Error(util.format('Unexpected polling status code from long running operation \'%s\' for method \'%s\'', + resultOfInitialRequest.response.statusCode, + resultOfInitialRequest.request.method))); } - + var pollingState = null; try { pollingState = new PollingState(resultOfInitialRequest, this.longRunningOperationRetryTimeout); } catch (error) { callback(error); } + var resourceUrl = resultOfInitialRequest.request.url; this._options = options; async.whilst( - function () { - var finished = [LroStates.Succeeded, LroStates.Failed, LroStates.Canceled].some(function (e) { + function() { + var finished = [LroStates.Succeeded, LroStates.Failed, LroStates.Canceled].some(function(e) { return e === pollingState.status; }); return !finished; }, - function (callback) { - setTimeout(function () { + function(callback) { + setTimeout(function() { if (pollingState.azureAsyncOperationHeaderLink) { - self._updateStateFromAzureAsyncOperationHeader(pollingState, true, function (err) { + self._updateStateFromAzureAsyncOperationHeader(pollingState, true, function(err) { return callback(err); }); } else if (pollingState.locationHeaderLink) { - self._updateStateFromLocationHeaderOnPostOrDelete(pollingState, function (err) { + self._updateStateFromLocationHeader(pollingState, function(err) { + return callback(err); + }); + } else if (resultOfInitialRequest.request.method === 'PUT') { + self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { return callback(err); }); } else { @@ -198,15 +205,34 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOf } }, pollingState.getTimeout()); }, - function (err) { - if (pollingState.status === LroStates.Succeeded ) { - return callback(null, pollingState.getOperationResponse()); + //when done + function(err) { + if (pollingState.status === LroStates.Succeeded) { + if ((pollingState.azureAsyncOperationHeaderLink || !pollingState.resource) && resultOfInitialRequest.request.method !== 'DELETE' && resultOfInitialRequest.request.method !== 'POST') { + self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { + return callback(err, pollingState.getOperationResponse()); + }); + } else { + return callback(null, pollingState.getOperationResponse()); + } } else { return callback(pollingState.getCloudError(err)); } }); }; +AzureServiceClient.prototype._checkInitialRequestResponseStatusCodeFailed = function (initialRequest) { + if (initialRequest.response.statusCode === 200 || + initialRequest.response.statusCode === 202 || + (initialRequest.response.statusCode === 201 && initialRequest.request.method === 'PUT') || + (initialRequest.response.statusCode === 204 && initialRequest.request.method === 'DELETE')) { + return false; + } else { + return true; + } +}; + + /** * Retrieve operation status by polling from 'azure-asyncoperation' header. * @param {object} [pollingState] - The object to persist current operation state. @@ -236,33 +262,22 @@ AzureServiceClient.prototype._updateStateFromAzureAsyncOperationHeader = functio * Retrieve PUT operation status by polling from 'location' header. * @param {object} [pollingState] - The object to persist current operation state. */ -AzureServiceClient.prototype._updateStateFromLocationHeaderOnPut = function (pollingState, callback) { - this._getStatus(pollingState.locationHeaderLink, function (err, result) { +AzureServiceClient.prototype._updateStateFromLocationHeader = function (pollingState, callback) { + this._getStatus(pollingState.locationHeaderLink, function(err, result) { if (err) return callback(err); - + pollingState.updateResponse(result.response); pollingState.request = result.request; - + var statusCode = result.response.statusCode; if (statusCode === 202) { pollingState.status = LroStates.InProgress; - } - else if (statusCode === 200 || - statusCode === 201) { - - if (!result.body) { - return callback(new Error('The response from long running operation does not contain a body.')); - } - - // In 202 pattern on PUT ProvisioningState may not be present in - // the response. In that case the assumption is the status is Succeeded. - if (result.body.properties && result.body.properties.provisioningState) { - pollingState.status = result.body.properties.provisioningState; - } - else { - pollingState.status = LroStates.Succeeded; - } - + } else if (statusCode === 200 || + statusCode === 201 || + statusCode === 204) { + + pollingState.status = LroStates.Succeeded; + pollingState.error = { code: pollingState.Status, message: util.format('Long running operation failed with status \'%s\'.', pollingState.status) @@ -273,31 +288,6 @@ AzureServiceClient.prototype._updateStateFromLocationHeaderOnPut = function (pol }); }; -/** - * Retrieve POST or DELETE operation status by polling from 'location' header. - * @param {object} [pollingState] - The object to persist current operation state. - */ -AzureServiceClient.prototype._updateStateFromLocationHeaderOnPostOrDelete = function (pollingState, callback) { - this._getStatus(pollingState.locationHeaderLink, function (err, result) { - if (err) return callback(err); - - pollingState.updateResponse(result.response); - pollingState.request = result.request; - - var statusCode = result.response.statusCode; - if (statusCode === 202) { - pollingState.status = LroStates.InProgress; - } - else if (statusCode === 200 || - statusCode === 201 || - statusCode === 204) { - pollingState.status = LroStates.Succeeded; - pollingState.resource = result.body; - } - callback(null); - }); -}; - /** * Polling for resource status. * @param {function} [resourceUrl] - The url of resource. diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/lib/pollingState.js b/ClientRuntimes/NodeJS/ms-rest-azure/lib/pollingState.js index 87a68bf6dfc25..114eedf25c573 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/lib/pollingState.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/lib/pollingState.js @@ -40,24 +40,31 @@ function PollingState(resultOfInitialRequest, retryTimeout) { throw deserializationError; } - if (this.resource && this.resource.properties && this.resource.properties.provisioningState) { - this.status = this.resource.properties.provisioningState; - } else { - switch (this.response.statusCode) { - case 202: - this.status = LroStates.InProgress; - break; + switch (this.response.statusCode) { + case 202: + this.status = LroStates.InProgress; + break; - case 204: - case 201: - case 200: + case 204: + this.status = LroStates.Succeeded; + break; + case 201: + if (this.resource && this.resource.properties && this.resource.properties.provisioningState) { + this.status = this.resource.properties.provisioningState; + } else { + this.status = LroStates.InProgress; + } + break; + case 200: + if (this.resource && this.resource.properties && this.resource.properties.provisioningState) { + this.status = this.resource.properties.provisioningState; + } else { this.status = LroStates.Succeeded; - break; - - default: - this.status = LroStates.Failed; - break; - } + } + break; + default: + this.status = LroStates.Failed; + break; } } diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js b/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js index e28f44bf5ad68..f358540bb6aae 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js @@ -92,7 +92,7 @@ describe('AzureServiceClient', function () { describe('Put', function () { resultOfInitialRequest.response.statusCode = 201; - + it('throw on not Lro related status code', function (done) { client.getPutOrPatchOperationResult({ response: {statusCode: 10000}, request: { url:"http://foo" }}, function (err, result) { err.message.should.containEql('Unexpected polling status code from long running operation'); @@ -156,11 +156,56 @@ describe('AzureServiceClient', function () { }); }); + describe('Patch', function () { + resultOfInitialRequest.response.statusCode = 202; + resultOfInitialRequest.body.properties.provisioningState = LroStates.Succeeded; + + it('works by polling from azure-asyncoperation header', function (done) { + resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; + resultOfInitialRequest.response.headers['location'] = urlFromLocationHeader_Return200; + client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + should.not.exist(err); + JSON.parse(result.body).name.should.equal(testResourceName); + should.exist(result.response.randomFieldFromPollLocationHeader); + done(); + }); + }); + + it('works by polling from location header', function (done) { + resultOfInitialRequest.response.headers['azure-asyncoperation'] = urlFromAzureAsyncOPHeader_Return200; + resultOfInitialRequest.response.headers['location'] = ''; + client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + should.not.exist(err); + JSON.parse(result.body).name.should.equal(testResourceName); + done(); + }); + }); + + it('returns error if failed to poll from the azure-asyncoperation header', function (done) { + resultOfInitialRequest.response.headers['azure-asyncoperation'] = url_ReturnError; + resultOfInitialRequest.response.headers['location'] = ''; + client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + err.message.should.containEql(testError); + done(); + }); + }); + + it('returns error if failed to poll from the location header', function (done) { + resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; + resultOfInitialRequest.response.headers['location'] = url_ReturnError; + client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + err.message.should.containEql(testError); + done(); + }); + }); + }); + describe('Post-or-Delete', function () { resultOfInitialRequest.response.statusCode = 202; - + resultOfInitialRequest.body.properties.provisioningState = LroStates.Succeeded; + it('throw on not Lro related status code', function (done) { - client.getPostOrDeleteOperationResult({ response: { statusCode: 201 } }, function (err, result) { + client.getPostOrDeleteOperationResult({ response: { statusCode: 201 }, request: {url: url_resource, method: 'POST'}}, function (err, result) { err.message.should.containEql('Unexpected polling status code from long running operation'); done(); }); @@ -169,6 +214,7 @@ describe('AzureServiceClient', function () { it('works by polling from the azure-asyncoperation header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = urlFromAzureAsyncOPHeader_Return200; resultOfInitialRequest.response.headers['location'] = ''; + resultOfInitialRequest.request.method = 'POST'; client.getPostOrDeleteOperationResult(resultOfInitialRequest, function (err, result) { should.not.exist(err); should.exist(result.response.randomFieldFromPollAsyncOpHeader); From 4ab8892519dfbb10ce902be4471ea9f45ca83ef4 Mon Sep 17 00:00:00 2001 From: Qinyuan Wan Date: Thu, 24 Mar 2016 10:21:36 -0700 Subject: [PATCH 05/29] style change --- .../ms-rest-azure/lib/azureServiceClient.js | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js index dabedd8d3217c..fa2e530176f81 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js @@ -65,7 +65,7 @@ util.inherits(AzureServiceClient, msRest.ServiceClient); AzureServiceClient.prototype.getPutOrPatchOperationResult = function (resultOfInitialRequest, options, callback) { var self = this; - if (!callback && typeof options === 'function') { + if(!callback && typeof options === 'function') { callback = options; options = null; } @@ -86,13 +86,14 @@ AzureServiceClient.prototype.getPutOrPatchOperationResult = function (resultOfIn resultOfInitialRequest.response.statusCode, resultOfInitialRequest.request.method))); } - + var pollingState = null; try { pollingState = new PollingState(resultOfInitialRequest, this.longRunningOperationRetryTimeout); } catch (error) { callback(error); } + var resourceUrl = resultOfInitialRequest.request.url; this._options = options; @@ -123,7 +124,7 @@ AzureServiceClient.prototype.getPutOrPatchOperationResult = function (resultOfIn }, pollingState.getTimeout()); }, //when done - function(err) { + function (err) { if (pollingState.status === LroStates.Succeeded) { if ((pollingState.azureAsyncOperationHeaderLink || !pollingState.resource) && resultOfInitialRequest.request.method !== 'DELETE' && resultOfInitialRequest.request.method !== 'POST') { self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { @@ -147,7 +148,7 @@ AzureServiceClient.prototype.getPutOrPatchOperationResult = function (resultOfIn */ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOfInitialRequest, options, callback) { var self = this; - + if (!callback && typeof options === 'function') { callback = options; options = null; @@ -159,7 +160,7 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOf if (!resultOfInitialRequest) { return callback(new Error('Missing resultOfInitialRequest parameter')); } - + if (!resultOfInitialRequest.response) { return callback(new Error('Missing resultOfInitialRequest.response')); } @@ -169,7 +170,7 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOf resultOfInitialRequest.response.statusCode, resultOfInitialRequest.request.method))); } - + var pollingState = null; try { pollingState = new PollingState(resultOfInitialRequest, this.longRunningOperationRetryTimeout); @@ -186,7 +187,7 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOf }); return !finished; }, - function(callback) { + function (callback) { setTimeout(function() { if (pollingState.azureAsyncOperationHeaderLink) { self._updateStateFromAzureAsyncOperationHeader(pollingState, true, function(err) { @@ -206,7 +207,7 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOf }, pollingState.getTimeout()); }, //when done - function(err) { + function (err) { if (pollingState.status === LroStates.Succeeded) { if ((pollingState.azureAsyncOperationHeaderLink || !pollingState.resource) && resultOfInitialRequest.request.method !== 'DELETE' && resultOfInitialRequest.request.method !== 'POST') { self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { @@ -265,10 +266,10 @@ AzureServiceClient.prototype._updateStateFromAzureAsyncOperationHeader = functio AzureServiceClient.prototype._updateStateFromLocationHeader = function (pollingState, callback) { this._getStatus(pollingState.locationHeaderLink, function(err, result) { if (err) return callback(err); - + pollingState.updateResponse(result.response); pollingState.request = result.request; - + var statusCode = result.response.statusCode; if (statusCode === 202) { pollingState.status = LroStates.InProgress; From 39b4b190dfe0098bdb93c3075b93b651ba554d7d Mon Sep 17 00:00:00 2001 From: Qinyuan Wan Date: Wed, 6 Apr 2016 15:54:30 -0700 Subject: [PATCH 06/29] code revise --- .../NodeJS/ms-rest-azure/lib/azureServiceClient.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js index fa2e530176f81..5d462e43b35c8 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js @@ -229,7 +229,7 @@ AzureServiceClient.prototype._checkInitialRequestResponseStatusCodeFailed = func (initialRequest.response.statusCode === 204 && initialRequest.request.method === 'DELETE')) { return false; } else { - return true; + return true; } }; @@ -274,8 +274,8 @@ AzureServiceClient.prototype._updateStateFromLocationHeader = function (pollingS if (statusCode === 202) { pollingState.status = LroStates.InProgress; } else if (statusCode === 200 || - statusCode === 201 || - statusCode === 204) { + (initialRequest.response.statusCode === 201 && initialRequest.request.method === 'PUT') || + (initialRequest.response.statusCode === 204 && initialRequest.request.method === 'DELETE')) { pollingState.status = LroStates.Succeeded; From d1ff9419ecaa9313a8bc33c20ff7b7cd03b9846e Mon Sep 17 00:00:00 2001 From: Qinyuan Wan Date: Wed, 6 Apr 2016 15:57:47 -0700 Subject: [PATCH 07/29] fix the naming issue in azure serviceClientTest --- .../NodeJS/ms-rest-azure/test/azureServiceClientTests.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js b/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js index f358540bb6aae..98c1e78c2d474 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js @@ -160,7 +160,7 @@ describe('AzureServiceClient', function () { resultOfInitialRequest.response.statusCode = 202; resultOfInitialRequest.body.properties.provisioningState = LroStates.Succeeded; - it('works by polling from azure-asyncoperation header', function (done) { + it('works by polling from location header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; resultOfInitialRequest.response.headers['location'] = urlFromLocationHeader_Return200; client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { @@ -171,7 +171,7 @@ describe('AzureServiceClient', function () { }); }); - it('works by polling from location header', function (done) { + it('works by polling from azure-asyncoperation header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = urlFromAzureAsyncOPHeader_Return200; resultOfInitialRequest.response.headers['location'] = ''; client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { From 9573dee1b9fe3d1cbf7c8dc03b7c4957048691e0 Mon Sep 17 00:00:00 2001 From: Qinyuan Wan Date: Wed, 6 Apr 2016 16:16:25 -0700 Subject: [PATCH 08/29] code revise --- ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js index 5d462e43b35c8..c81827aa1906b 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js @@ -274,8 +274,8 @@ AzureServiceClient.prototype._updateStateFromLocationHeader = function (pollingS if (statusCode === 202) { pollingState.status = LroStates.InProgress; } else if (statusCode === 200 || - (initialRequest.response.statusCode === 201 && initialRequest.request.method === 'PUT') || - (initialRequest.response.statusCode === 204 && initialRequest.request.method === 'DELETE')) { + (statusCode === 201 && pollingState.request.method === 'PUT') || + (statusCode === 204 && pollingState.request.method === 'DELETE')) { pollingState.status = LroStates.Succeeded; From b9d642d3a779a9fe980717263ce357b1b4de2fbc Mon Sep 17 00:00:00 2001 From: Qinyuan Wan Date: Wed, 6 Apr 2016 17:37:27 -0700 Subject: [PATCH 09/29] add 204 poll state for post --- .../ms-rest-azure/lib/azureServiceClient.js | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js index c81827aa1906b..7e07c3aea86a5 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js @@ -111,7 +111,7 @@ AzureServiceClient.prototype.getPutOrPatchOperationResult = function (resultOfIn return callback(err); }); } else if (pollingState.locationHeaderLink) { - self._updateStateFromLocationHeader(pollingState, function(err) { + self._updateStateFromLocationHeader(resultOfInitialRequest.request.method, pollingState, function(err) { return callback(err); }); } else if (resultOfInitialRequest.request.method === 'PUT') { @@ -194,7 +194,7 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOf return callback(err); }); } else if (pollingState.locationHeaderLink) { - self._updateStateFromLocationHeader(pollingState, function(err) { + self._updateStateFromLocationHeader(resultOfInitialRequest.request.method, pollingState, function(err) { return callback(err); }); } else if (resultOfInitialRequest.request.method === 'PUT') { @@ -223,10 +223,11 @@ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOf }; AzureServiceClient.prototype._checkInitialRequestResponseStatusCodeFailed = function (initialRequest) { - if (initialRequest.response.statusCode === 200 || - initialRequest.response.statusCode === 202 || - (initialRequest.response.statusCode === 201 && initialRequest.request.method === 'PUT') || - (initialRequest.response.statusCode === 204 && initialRequest.request.method === 'DELETE')) { + var statusCode = initialRequest.response.statusCode; + var method = initialRequest.request.method; + if (statusCode === 200 || statusCode === 202 || + (statusCode === 201 && method === 'PUT') || + (statusCode === 204 && (method === 'DELETE' || method === 'POST'))) { return false; } else { return true; @@ -263,7 +264,7 @@ AzureServiceClient.prototype._updateStateFromAzureAsyncOperationHeader = functio * Retrieve PUT operation status by polling from 'location' header. * @param {object} [pollingState] - The object to persist current operation state. */ -AzureServiceClient.prototype._updateStateFromLocationHeader = function (pollingState, callback) { +AzureServiceClient.prototype._updateStateFromLocationHeader = function (method, pollingState, callback) { this._getStatus(pollingState.locationHeaderLink, function(err, result) { if (err) return callback(err); @@ -274,8 +275,8 @@ AzureServiceClient.prototype._updateStateFromLocationHeader = function (pollingS if (statusCode === 202) { pollingState.status = LroStates.InProgress; } else if (statusCode === 200 || - (statusCode === 201 && pollingState.request.method === 'PUT') || - (statusCode === 204 && pollingState.request.method === 'DELETE')) { + (statusCode === 201 && method === 'PUT') || + (statusCode === 204 && (method === 'DELETE' || method === 'POST'))) { pollingState.status = LroStates.Succeeded; @@ -284,7 +285,9 @@ AzureServiceClient.prototype._updateStateFromLocationHeader = function (pollingS message: util.format('Long running operation failed with status \'%s\'.', pollingState.status) }; pollingState.resource = result.body; - } + } else { + return callback(new Error('The response from long running operation does not have a valid status code.')); + } callback(null); }); }; From 5b4ca29a393a30f1f452436996d952e0aa868c3a Mon Sep 17 00:00:00 2001 From: Qinyuan Wan Date: Thu, 7 Apr 2016 14:13:09 -0700 Subject: [PATCH 10/29] change code gen in node js to merge LRO operations into one method --- .../Lro/operations/lRORetrys.js | 14 +-- .../AcceptanceTests/Lro/operations/lROSADs.js | 50 +++++------ .../AcceptanceTests/Lro/operations/lROs.js | 72 +++++++-------- .../Lro/operations/lROsCustomHeader.js | 8 +- .../AzureMethodTemplateModel.cs | 9 +- .../ms-rest-azure/lib/azureServiceClient.js | 88 +------------------ .../test/azureServiceClientTests.js | 36 ++++---- 7 files changed, 93 insertions(+), 184 deletions(-) diff --git a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lRORetrys.js b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lRORetrys.js index f3cb1fecfb34b..bacca9fd614ab 100644 --- a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lRORetrys.js +++ b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lRORetrys.js @@ -81,7 +81,7 @@ LRORetrys.prototype.put201CreatingSucceeded200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -334,7 +334,7 @@ LRORetrys.prototype.putAsyncRelativeRetrySucceeded = function (options, callback initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -562,7 +562,7 @@ LRORetrys.prototype.deleteProvisioning202Accepted200Succeeded = function (option initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -782,7 +782,7 @@ LRORetrys.prototype.delete202Retry200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -952,7 +952,7 @@ LRORetrys.prototype.deleteAsyncRelativeRetrySucceeded = function (options, callb initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1130,7 +1130,7 @@ LRORetrys.prototype.post202Retry200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1332,7 +1332,7 @@ LRORetrys.prototype.postAsyncRelativeRetrySucceeded = function (options, callbac initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result diff --git a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROSADs.js b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROSADs.js index 33fff6078369c..850509ad638ea 100644 --- a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROSADs.js +++ b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROSADs.js @@ -78,7 +78,7 @@ LROSADs.prototype.putNonRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -326,7 +326,7 @@ LROSADs.prototype.putNonRetry201Creating400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -576,7 +576,7 @@ LROSADs.prototype.putAsyncRelativeRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -799,7 +799,7 @@ LROSADs.prototype.deleteNonRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -965,7 +965,7 @@ LROSADs.prototype.delete202NonRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1133,7 +1133,7 @@ LROSADs.prototype.deleteAsyncRelativeRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1309,7 +1309,7 @@ LROSADs.prototype.postNonRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1506,7 +1506,7 @@ LROSADs.prototype.post202NonRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1705,7 +1705,7 @@ LROSADs.prototype.postAsyncRelativeRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1906,7 +1906,7 @@ LROSADs.prototype.putError201NoProvisioningStatePayload = function (options, cal initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2156,7 +2156,7 @@ LROSADs.prototype.putAsyncRelativeRetryNoStatus = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2390,7 +2390,7 @@ LROSADs.prototype.putAsyncRelativeRetryNoStatusPayload = function (options, call initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2614,7 +2614,7 @@ LROSADs.prototype.delete204Succeeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2783,7 +2783,7 @@ LROSADs.prototype.deleteAsyncRelativeRetryNoStatus = function (options, callback initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2960,7 +2960,7 @@ LROSADs.prototype.post202NoLocation = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3160,7 +3160,7 @@ LROSADs.prototype.postAsyncRelativeRetryNoPayload = function (options, callback) initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3361,7 +3361,7 @@ LROSADs.prototype.put200InvalidJson = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3594,7 +3594,7 @@ LROSADs.prototype.putAsyncRelativeRetryInvalidHeader = function (options, callba initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3828,7 +3828,7 @@ LROSADs.prototype.putAsyncRelativeRetryInvalidJsonPolling = function (options, c initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4052,7 +4052,7 @@ LROSADs.prototype.delete202RetryInvalidHeader = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4220,7 +4220,7 @@ LROSADs.prototype.deleteAsyncRelativeRetryInvalidHeader = function (options, cal initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4389,7 +4389,7 @@ LROSADs.prototype.deleteAsyncRelativeRetryInvalidJsonPolling = function (options initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4566,7 +4566,7 @@ LROSADs.prototype.post202RetryInvalidHeader = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4766,7 +4766,7 @@ LROSADs.prototype.postAsyncRelativeRetryInvalidHeader = function (options, callb initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4967,7 +4967,7 @@ LROSADs.prototype.postAsyncRelativeRetryInvalidJsonPolling = function (options, initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result diff --git a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROs.js b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROs.js index b0cc6a272fd58..f403121e6dfec 100644 --- a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROs.js +++ b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROs.js @@ -79,7 +79,7 @@ LROs.prototype.put200Succeeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -311,7 +311,7 @@ LROs.prototype.put200SucceededNoState = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -544,7 +544,7 @@ LROs.prototype.put202Retry200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -779,7 +779,7 @@ LROs.prototype.put201CreatingSucceeded200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1032,7 +1032,7 @@ LROs.prototype.put200UpdatingSucceeded204 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1268,7 +1268,7 @@ LROs.prototype.put201CreatingFailed200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1521,7 +1521,7 @@ LROs.prototype.put200Acceptedcanceled200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1756,7 +1756,7 @@ LROs.prototype.putNoHeaderInRetry = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1990,7 +1990,7 @@ LROs.prototype.putAsyncRetrySucceeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2224,7 +2224,7 @@ LROs.prototype.putAsyncNoRetrySucceeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2458,7 +2458,7 @@ LROs.prototype.putAsyncRetryFailed = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2692,7 +2692,7 @@ LROs.prototype.putAsyncNoRetrycanceled = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2926,7 +2926,7 @@ LROs.prototype.putAsyncNoHeaderInRetry = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3156,7 +3156,7 @@ LROs.prototype.putNonResource = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3382,7 +3382,7 @@ LROs.prototype.putAsyncNonResource = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3606,7 +3606,7 @@ LROs.prototype.putSubResource = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3828,7 +3828,7 @@ LROs.prototype.putAsyncSubResource = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4049,7 +4049,7 @@ LROs.prototype.deleteProvisioning202Accepted200Succeeded = function (options, ca initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4271,7 +4271,7 @@ LROs.prototype.deleteProvisioning202DeletingFailed200 = function (options, callb initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4493,7 +4493,7 @@ LROs.prototype.deleteProvisioning202Deletingcanceled200 = function (options, cal initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4711,7 +4711,7 @@ LROs.prototype.delete204Succeeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4880,7 +4880,7 @@ LROs.prototype.delete202Retry200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -5083,7 +5083,7 @@ LROs.prototype.delete202NoRetry204 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -5285,7 +5285,7 @@ LROs.prototype.deleteNoHeaderInRetry = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -5455,7 +5455,7 @@ LROs.prototype.deleteAsyncNoHeaderInRetry = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -5625,7 +5625,7 @@ LROs.prototype.deleteAsyncRetrySucceeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -5795,7 +5795,7 @@ LROs.prototype.deleteAsyncNoRetrySucceeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -5965,7 +5965,7 @@ LROs.prototype.deleteAsyncRetryFailed = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -6135,7 +6135,7 @@ LROs.prototype.deleteAsyncRetrycanceled = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -6306,7 +6306,7 @@ LROs.prototype.post200WithPayload = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -6533,7 +6533,7 @@ LROs.prototype.post202Retry200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -6734,7 +6734,7 @@ LROs.prototype.post202NoRetry204 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -6967,7 +6967,7 @@ LROs.prototype.postAsyncRetrySucceeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -7201,7 +7201,7 @@ LROs.prototype.postAsyncNoRetrySucceeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -7434,7 +7434,7 @@ LROs.prototype.postAsyncRetryFailed = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -7635,7 +7635,7 @@ LROs.prototype.postAsyncRetrycanceled = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result diff --git a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROsCustomHeader.js b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROsCustomHeader.js index 9dc6656111ba1..3d4d296e68aaa 100644 --- a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROsCustomHeader.js +++ b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROsCustomHeader.js @@ -82,7 +82,7 @@ LROsCustomHeader.prototype.putAsyncRetrySucceeded = function (options, callback) initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -320,7 +320,7 @@ LROsCustomHeader.prototype.put201CreatingSucceeded200 = function (options, callb initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -573,7 +573,7 @@ LROsCustomHeader.prototype.post202Retry200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -777,7 +777,7 @@ LROsCustomHeader.prototype.postAsyncRetrySucceeded = function (options, callback initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { + client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result diff --git a/AutoRest/Generators/NodeJS/Azure.NodeJS/TemplateModels/AzureMethodTemplateModel.cs b/AutoRest/Generators/NodeJS/Azure.NodeJS/TemplateModels/AzureMethodTemplateModel.cs index 95a519d366c9d..a6fbcc9e356e9 100644 --- a/AutoRest/Generators/NodeJS/Azure.NodeJS/TemplateModels/AzureMethodTemplateModel.cs +++ b/AutoRest/Generators/NodeJS/Azure.NodeJS/TemplateModels/AzureMethodTemplateModel.cs @@ -86,14 +86,7 @@ public string LongRunningOperationMethodNameInRuntime string result = null; if (this.IsLongRunningOperation) { - if (HttpMethod == HttpMethod.Post || HttpMethod == HttpMethod.Delete) - { - result = "getPostOrDeleteOperationResult"; - } - else if (HttpMethod == HttpMethod.Put || HttpMethod == HttpMethod.Patch) - { - result = "getPutOrPatchOperationResult"; - } + result = "getLongRunningOperationResult"; } return result; } diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js index 7e07c3aea86a5..e0207511c4c34 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js @@ -57,96 +57,12 @@ function AzureServiceClient(credentials, options) { util.inherits(AzureServiceClient, msRest.ServiceClient); /** - * Poll Azure long running PUT operation. - * @param {object} [resultOfInitialRequest] - Response of the initial request for the long running operation. - * @param {object} [options] - * @param {object} [options.customHeaders] headers that will be added to request - */ -AzureServiceClient.prototype.getPutOrPatchOperationResult = function (resultOfInitialRequest, options, callback) { - var self = this; - - if(!callback && typeof options === 'function') { - callback = options; - options = null; - } - if (!callback) { - throw new Error('Missing callback'); - } - - if (!resultOfInitialRequest) { - return callback(new Error('Missing resultOfInitialRequest parameter')); - } - - if (!resultOfInitialRequest.response) { - return callback(new Error('Missing resultOfInitialRequest.response')); - } - - if (this._checkInitialRequestResponseStatusCodeFailed(resultOfInitialRequest)) { - return callback(new Error(util.format('Unexpected polling status code from long running operation \'%s\' for method \'%s\'', - resultOfInitialRequest.response.statusCode, - resultOfInitialRequest.request.method))); - } - - var pollingState = null; - try { - pollingState = new PollingState(resultOfInitialRequest, this.longRunningOperationRetryTimeout); - } catch (error) { - callback(error); - } - - var resourceUrl = resultOfInitialRequest.request.url; - this._options = options; - - async.whilst( - function() { - var finished = [LroStates.Succeeded, LroStates.Failed, LroStates.Canceled].some(function(e) { - return e === pollingState.status; - }); - return !finished; - }, - function(callback) { - setTimeout(function() { - if (pollingState.azureAsyncOperationHeaderLink) { - self._updateStateFromAzureAsyncOperationHeader(pollingState, true, function(err) { - return callback(err); - }); - } else if (pollingState.locationHeaderLink) { - self._updateStateFromLocationHeader(resultOfInitialRequest.request.method, pollingState, function(err) { - return callback(err); - }); - } else if (resultOfInitialRequest.request.method === 'PUT') { - self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { - return callback(err); - }); - } else { - return callback(new Error('Location header is missing from long running operation.')); - } - }, pollingState.getTimeout()); - }, - //when done - function (err) { - if (pollingState.status === LroStates.Succeeded) { - if ((pollingState.azureAsyncOperationHeaderLink || !pollingState.resource) && resultOfInitialRequest.request.method !== 'DELETE' && resultOfInitialRequest.request.method !== 'POST') { - self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { - return callback(err, pollingState.getOperationResponse()); - }); - } else { - return callback(null, pollingState.getOperationResponse()); - } - } else { - return callback(pollingState.getCloudError(err)); - } - }); -}; - - -/** - * Poll Azure long running POST or DELETE operations. + * Poll Azure long running GET, PATCH, POST or DELETE operations. * @param {object} [resultOfInitialRequest] - result of the initial request. * @param {object} [options] * @param {object} [options.customHeaders] headers that will be added to request */ -AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOfInitialRequest, options, callback) { +AzureServiceClient.prototype.getLongRunningOperationResult = function (resultOfInitialRequest, options, callback) { var self = this; if (!callback && typeof options === 'function') { diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js b/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js index 98c1e78c2d474..3a56e378e4d9c 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js @@ -94,7 +94,7 @@ describe('AzureServiceClient', function () { resultOfInitialRequest.response.statusCode = 201; it('throw on not Lro related status code', function (done) { - client.getPutOrPatchOperationResult({ response: {statusCode: 10000}, request: { url:"http://foo" }}, function (err, result) { + client.getLongRunningOperationResult({ response: {statusCode: 10000}, request: { url:"http://foo" }}, function (err, result) { err.message.should.containEql('Unexpected polling status code from long running operation'); done(); }); @@ -103,7 +103,7 @@ describe('AzureServiceClient', function () { it('works by polling from the azure-asyncoperation header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = urlFromAzureAsyncOPHeader_Return200; resultOfInitialRequest.response.headers['location'] = ''; - client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { should.not.exist(err); JSON.parse(result.body).name.should.equal(testResourceName); done(); @@ -118,7 +118,7 @@ describe('AzureServiceClient', function () { 'testCustomField': testCustomFieldValue } }; - client.getPutOrPatchOperationResult(resultOfInitialRequest, options, function (err, result) { + client.getLongRunningOperationResult(resultOfInitialRequest, options, function (err, result) { should.not.exist(err); JSON.parse(result.body).name.should.equal(testResourceName); result.response.testCustomField.should.equal(testCustomFieldValue); @@ -129,7 +129,7 @@ describe('AzureServiceClient', function () { it('works by polling from the location header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; resultOfInitialRequest.response.headers['location'] = urlFromLocationHeader_Return200; - client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { should.not.exist(err); JSON.parse(result.body).name.should.equal(testResourceName); should.exist(result.response.randomFieldFromPollLocationHeader); @@ -140,7 +140,7 @@ describe('AzureServiceClient', function () { it('returns error if failed to poll from the azure-asyncoperation header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = url_ReturnError; resultOfInitialRequest.response.headers['location'] = ''; - client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { err.message.should.containEql(testError); done(); }); @@ -149,7 +149,7 @@ describe('AzureServiceClient', function () { it('returns error if failed to poll from the location header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; resultOfInitialRequest.response.headers['location'] = url_ReturnError; - client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { err.message.should.containEql(testError); done(); }); @@ -163,7 +163,7 @@ describe('AzureServiceClient', function () { it('works by polling from location header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; resultOfInitialRequest.response.headers['location'] = urlFromLocationHeader_Return200; - client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { should.not.exist(err); JSON.parse(result.body).name.should.equal(testResourceName); should.exist(result.response.randomFieldFromPollLocationHeader); @@ -174,7 +174,7 @@ describe('AzureServiceClient', function () { it('works by polling from azure-asyncoperation header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = urlFromAzureAsyncOPHeader_Return200; resultOfInitialRequest.response.headers['location'] = ''; - client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { should.not.exist(err); JSON.parse(result.body).name.should.equal(testResourceName); done(); @@ -184,7 +184,7 @@ describe('AzureServiceClient', function () { it('returns error if failed to poll from the azure-asyncoperation header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = url_ReturnError; resultOfInitialRequest.response.headers['location'] = ''; - client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { err.message.should.containEql(testError); done(); }); @@ -193,7 +193,7 @@ describe('AzureServiceClient', function () { it('returns error if failed to poll from the location header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; resultOfInitialRequest.response.headers['location'] = url_ReturnError; - client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { err.message.should.containEql(testError); done(); }); @@ -205,7 +205,7 @@ describe('AzureServiceClient', function () { resultOfInitialRequest.body.properties.provisioningState = LroStates.Succeeded; it('throw on not Lro related status code', function (done) { - client.getPostOrDeleteOperationResult({ response: { statusCode: 201 }, request: {url: url_resource, method: 'POST'}}, function (err, result) { + client.getLongRunningOperationResult({ response: { statusCode: 201 }, request: {url: url_resource, method: 'POST'}}, function (err, result) { err.message.should.containEql('Unexpected polling status code from long running operation'); done(); }); @@ -215,7 +215,7 @@ describe('AzureServiceClient', function () { resultOfInitialRequest.response.headers['azure-asyncoperation'] = urlFromAzureAsyncOPHeader_Return200; resultOfInitialRequest.response.headers['location'] = ''; resultOfInitialRequest.request.method = 'POST'; - client.getPostOrDeleteOperationResult(resultOfInitialRequest, function (err, result) { + client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { should.not.exist(err); should.exist(result.response.randomFieldFromPollAsyncOpHeader); done(); @@ -225,7 +225,7 @@ describe('AzureServiceClient', function () { it('works by polling from the location header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; resultOfInitialRequest.response.headers['location'] = urlFromLocationHeader_Return200; - client.getPostOrDeleteOperationResult(resultOfInitialRequest, function (err, result) { + client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { should.not.exist(err); should.exist(result.response.randomFieldFromPollLocationHeader); JSON.parse(result.body).name.should.equal(testResourceName); @@ -236,7 +236,7 @@ describe('AzureServiceClient', function () { it('returns error if failed to poll from the azure-asyncoperation header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = url_ReturnError; resultOfInitialRequest.response.headers['location'] = ''; - client.getPostOrDeleteOperationResult(resultOfInitialRequest, function (err, result) { + client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { err.message.should.containEql(testError); done(); }); @@ -245,7 +245,7 @@ describe('AzureServiceClient', function () { it('returns error if failed to poll from the location header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; resultOfInitialRequest.response.headers['location'] = url_ReturnError; - client.getPostOrDeleteOperationResult(resultOfInitialRequest, function (err, result) { + client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { err.message.should.containEql(testError); done(); }); @@ -265,7 +265,7 @@ describe('AzureServiceClient', function () { negativeClient.addFilter(mockFilter({ statusCode: 200, body: badResponseBody }, badResponseBody)); resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; resultOfInitialRequest.response.headers['location'] = urlFromLocationHeader_Return200; - negativeClient.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + negativeClient.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { should.exist(err); should.exist(err.response); should.exist(err.message); @@ -280,7 +280,7 @@ describe('AzureServiceClient', function () { negativeClient.addFilter(mockFilter({ statusCode: 200, body: badResponseBody }, badResponseBody)); resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; resultOfInitialRequest.response.headers['location'] = urlFromLocationHeader_Return200; - negativeClient.getPutOrPatchOperationResult(resultOfInitialRequest, negativeClient._getStatus, function (err, result) { + negativeClient.getLongRunningOperationResult(resultOfInitialRequest, negativeClient._getStatus, function (err, result) { should.exist(err); should.exist(err.response); should.exist(err.message); @@ -295,7 +295,7 @@ describe('AzureServiceClient', function () { negativeClient.addFilter(mockFilter({ statusCode: 203, body: badResponseBody }, badResponseBody)); resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; resultOfInitialRequest.response.headers['location'] = urlFromLocationHeader_Return200; - negativeClient.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { + negativeClient.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { should.exist(err); should.exist(err.response); should.exist(err.message); From 8b015ac266ddb655991927ac6a14c454d9e31b1d Mon Sep 17 00:00:00 2001 From: John-Hart Date: Thu, 14 Apr 2016 13:05:37 -0700 Subject: [PATCH 11/29] Captured the JSONException that may occur on a Non-Success StatusCode when attempting to Deserialize the HTTPResponse.Content when it is not JSON --- .../AzureClientExtensions.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure/AzureClientExtensions.cs b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure/AzureClientExtensions.cs index 57bbd064b95c2..0d8505210fd5e 100644 --- a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure/AzureClientExtensions.cs +++ b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure/AzureClientExtensions.cs @@ -599,7 +599,16 @@ private static async Task> GetRawAsync( statusCode != HttpStatusCode.Created && statusCode != HttpStatusCode.NoContent) { - CloudError errorBody = SafeJsonConvert.DeserializeObject(responseContent, client.DeserializationSettings); + CloudError errorBody = null; + try + { + errorBody = SafeJsonConvert.DeserializeObject(responseContent, client.DeserializationSettings); + } + catch (JsonException) + { + // failed to deserialize, return empty body + } + throw new CloudException(string.Format(CultureInfo.InvariantCulture, Resources.LongRunningOperationFailed, statusCode)) { From 3622e2bc43b1b387b4c89a9b9b0a7d8a89622e8f Mon Sep 17 00:00:00 2001 From: John-Hart Date: Thu, 14 Apr 2016 13:12:05 -0700 Subject: [PATCH 12/29] Added a new LongRunningOperations test to verify that a CloudException is thrown even when a JSONException occurs Deserializing the HTTPResponse.Content --- .../LongRunningOperationsTest.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/LongRunningOperationsTest.cs b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/LongRunningOperationsTest.cs index bf999fe9f7c1b..1d0bb2069f1bf 100644 --- a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/LongRunningOperationsTest.cs +++ b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/LongRunningOperationsTest.cs @@ -104,6 +104,19 @@ public void TestAsyncOperationWithMissingProvisioningState() Assert.Equal("100", resource.Id); } + [Fact] + public void TestAsyncOperationWithNonSuccessStatusAndInvalidResponseContent() + { + var tokenCredentials = new TokenCredentials("123", "abc"); + var handler = new PlaybackTestHandler(MockAsyncOperaionWithNonSuccessStatusAndInvalidResponseContent()); + var fakeClient = new RedisManagementClient(tokenCredentials, handler); + fakeClient.LongRunningOperationInitialTimeout = fakeClient.LongRunningOperationRetryTimeout = 0; + var error = Assert.Throws(() => + fakeClient.RedisOperations.Delete("rg", "redis", "1234")); + Assert.Equal("Long running operation failed with status 'BadRequest'.", error.Message); + Assert.Null(error.Body); + } + [Fact] public void TestPutOperationWithoutProvisioningState() { @@ -737,6 +750,22 @@ private IEnumerable MockAsyncOperaionWithMissingProvisionin yield return response3; } + private IEnumerable MockAsyncOperaionWithNonSuccessStatusAndInvalidResponseContent() + { + var response1 = new HttpResponseMessage(HttpStatusCode.Accepted) + { + Content = new StringContent("") + }; + response1.Headers.Add("Location", "http://custom/status"); + yield return response1; + + var response2 = new HttpResponseMessage(HttpStatusCode.BadRequest) + { + Content = new StringContent("<") + }; + yield return response2; + } + private IEnumerable MockPutOperaionWithoutProvisioningStateInResponse() { var response1 = new HttpResponseMessage(HttpStatusCode.Created) From d41d44c1d80f10460a8cc8d4d4811f971407ead2 Mon Sep 17 00:00:00 2001 From: John-Hart Date: Tue, 19 Apr 2016 13:12:02 -0700 Subject: [PATCH 13/29] Added a LRO acceptance test to verify that a CloudException is thrown when a JSONException occurs during Deserialization of the response content --- .../Azure.CSharp.Tests/AcceptanceTests.cs | 4 + .../AcceptanceTests/Lro/ILROSADsOperations.cs | 28 +++ .../AcceptanceTests/Lro/LROSADsOperations.cs | 203 ++++++++++++++++++ .../Lro/LROSADsOperationsExtensions.cs | 72 +++++++ AutoRest/TestServer/server/routes/lros.js | 10 + AutoRest/TestServer/swagger/lro.json | 40 ++++ 6 files changed, 357 insertions(+) diff --git a/AutoRest/Generators/CSharp/Azure.CSharp.Tests/AcceptanceTests.cs b/AutoRest/Generators/CSharp/Azure.CSharp.Tests/AcceptanceTests.cs index d04c712fd1c96..46078380b3b9a 100644 --- a/AutoRest/Generators/CSharp/Azure.CSharp.Tests/AcceptanceTests.cs +++ b/AutoRest/Generators/CSharp/Azure.CSharp.Tests/AcceptanceTests.cs @@ -274,6 +274,10 @@ public void LroSadPathTests() Assert.Equal("Error from the server", exception.Body.Message); Assert.NotNull(exception.Request); Assert.NotNull(exception.Response); + exception = + Assert.Throws(() => client.LROSADs.PutNonRetry201Creating400InvalidJson(new Product { Location = "West US" })); + Assert.Null(exception.Body); + Assert.Equal("Long running operation failed with status 'BadRequest'.", exception.Message); exception = Assert.Throws( () => client.LROSADs.PutAsyncRelativeRetry400(new Product {Location = "West US"})); diff --git a/AutoRest/Generators/CSharp/Azure.CSharp.Tests/Expected/AcceptanceTests/Lro/ILROSADsOperations.cs b/AutoRest/Generators/CSharp/Azure.CSharp.Tests/Expected/AcceptanceTests/Lro/ILROSADsOperations.cs index 60ac71a045d3e..5717f7f8f64e8 100644 --- a/AutoRest/Generators/CSharp/Azure.CSharp.Tests/Expected/AcceptanceTests/Lro/ILROSADsOperations.cs +++ b/AutoRest/Generators/CSharp/Azure.CSharp.Tests/Expected/AcceptanceTests/Lro/ILROSADsOperations.cs @@ -79,6 +79,34 @@ public partial interface ILROSADsOperations /// Task> BeginPutNonRetry201Creating400WithHttpMessagesAsync(Product product = default(Product), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); /// + /// Long running put request, service returns a Product with + /// 'ProvisioningState' = 'Creating' and 201 response code + /// + /// + /// Product to put + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + Task> PutNonRetry201Creating400InvalidJsonWithHttpMessagesAsync(Product product = default(Product), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Long running put request, service returns a Product with + /// 'ProvisioningState' = 'Creating' and 201 response code + /// + /// + /// Product to put + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + Task> BeginPutNonRetry201Creating400InvalidJsonWithHttpMessagesAsync(Product product = default(Product), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + /// /// Long running put request, service returns a 200 with /// ProvisioningState=’Creating’. Poll the endpoint indicated in the /// Azure-AsyncOperation header for operation status diff --git a/AutoRest/Generators/CSharp/Azure.CSharp.Tests/Expected/AcceptanceTests/Lro/LROSADsOperations.cs b/AutoRest/Generators/CSharp/Azure.CSharp.Tests/Expected/AcceptanceTests/Lro/LROSADsOperations.cs index 7b0662de0c29e..cbd54f78112ae 100644 --- a/AutoRest/Generators/CSharp/Azure.CSharp.Tests/Expected/AcceptanceTests/Lro/LROSADsOperations.cs +++ b/AutoRest/Generators/CSharp/Azure.CSharp.Tests/Expected/AcceptanceTests/Lro/LROSADsOperations.cs @@ -453,6 +453,209 @@ internal LROSADsOperations(AutoRestLongRunningOperationTestService client) return _result; } + /// + /// Long running put request, service returns a Product with + /// 'ProvisioningState' = 'Creating' and 201 response code + /// + /// + /// Product to put + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + public async Task> PutNonRetry201Creating400InvalidJsonWithHttpMessagesAsync(Product product = default(Product), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Send Request + AzureOperationResponse _response = await BeginPutNonRetry201Creating400InvalidJsonWithHttpMessagesAsync( + product, customHeaders, cancellationToken); + return await this.Client.GetPutOrPatchOperationResultAsync(_response, + customHeaders, + cancellationToken); + } + + /// + /// Long running put request, service returns a Product with + /// 'ProvisioningState' = 'Creating' and 201 response code + /// + /// + /// Product to put + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> BeginPutNonRetry201Creating400InvalidJsonWithHttpMessagesAsync(Product product = default(Product), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("product", product); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "BeginPutNonRetry201Creating400InvalidJson", tracingParameters); + } + // Construct URL + var _baseUrl = this.Client.BaseUri.AbsoluteUri; + var _url = new Uri(new Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "lro/nonretryerror/put/201/creating/400/invalidjson").ToString(); + List _queryParameters = new List(); + if (_queryParameters.Count > 0) + { + _url += "?" + string.Join("&", _queryParameters); + } + // Create HTTP transport objects + HttpRequestMessage _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("PUT"); + _httpRequest.RequestUri = new Uri(_url); + // Set Headers + if (this.Client.GenerateClientRequestId != null && this.Client.GenerateClientRequestId.Value) + { + _httpRequest.Headers.TryAddWithoutValidation("x-ms-client-request-id", Guid.NewGuid().ToString()); + } + if (this.Client.AcceptLanguage != null) + { + if (_httpRequest.Headers.Contains("accept-language")) + { + _httpRequest.Headers.Remove("accept-language"); + } + _httpRequest.Headers.TryAddWithoutValidation("accept-language", this.Client.AcceptLanguage); + } + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + if(product != null) + { + _requestContent = SafeJsonConvert.SerializeObject(product, this.Client.SerializationSettings); + _httpRequest.Content = new StringContent(_requestContent, Encoding.UTF8); + _httpRequest.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); + } + // Set Credentials + if (this.Client.Credentials != null) + { + cancellationToken.ThrowIfCancellationRequested(); + await this.Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + } + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await this.Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 200 && (int)_statusCode != 201) + { + var ex = new CloudException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + try + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + CloudError _errorBody = SafeJsonConvert.DeserializeObject(_responseContent, this.Client.DeserializationSettings); + if (_errorBody != null) + { + ex = new CloudException(_errorBody.Message); + ex.Body = _errorBody; + } + } + catch (JsonException) + { + // Ignore the exception + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_httpResponse.Headers.Contains("x-ms-request-id")) + { + ex.RequestId = _httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault(); + } + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new AzureOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_httpResponse.Headers.Contains("x-ms-request-id")) + { + _result.RequestId = _httpResponse.Headers.GetValues("x-ms-request-id").FirstOrDefault(); + } + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, this.Client.DeserializationSettings); + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + // Deserialize Response + if ((int)_statusCode == 201) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, this.Client.DeserializationSettings); + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + /// /// Long running put request, service returns a 200 with /// ProvisioningState=’Creating’. Poll the endpoint indicated in the diff --git a/AutoRest/Generators/CSharp/Azure.CSharp.Tests/Expected/AcceptanceTests/Lro/LROSADsOperationsExtensions.cs b/AutoRest/Generators/CSharp/Azure.CSharp.Tests/Expected/AcceptanceTests/Lro/LROSADsOperationsExtensions.cs index 86b6c1b083fc9..dc7d177cbe402 100644 --- a/AutoRest/Generators/CSharp/Azure.CSharp.Tests/Expected/AcceptanceTests/Lro/LROSADsOperationsExtensions.cs +++ b/AutoRest/Generators/CSharp/Azure.CSharp.Tests/Expected/AcceptanceTests/Lro/LROSADsOperationsExtensions.cs @@ -162,6 +162,78 @@ public static partial class LROSADsOperationsExtensions } } + /// + /// Long running put request, service returns a Product with + /// 'ProvisioningState' = 'Creating' and 201 response code + /// + /// + /// The operations group for this extension method. + /// + /// + /// Product to put + /// + public static Product PutNonRetry201Creating400InvalidJson(this ILROSADsOperations operations, Product product = default(Product)) + { + return Task.Factory.StartNew(s => ((ILROSADsOperations)s).PutNonRetry201Creating400InvalidJsonAsync(product), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult(); + } + + /// + /// Long running put request, service returns a Product with + /// 'ProvisioningState' = 'Creating' and 201 response code + /// + /// + /// The operations group for this extension method. + /// + /// + /// Product to put + /// + /// + /// The cancellation token. + /// + public static async Task PutNonRetry201Creating400InvalidJsonAsync(this ILROSADsOperations operations, Product product = default(Product), CancellationToken cancellationToken = default(CancellationToken)) + { + using (var _result = await operations.PutNonRetry201Creating400InvalidJsonWithHttpMessagesAsync(product, null, cancellationToken).ConfigureAwait(false)) + { + return _result.Body; + } + } + + /// + /// Long running put request, service returns a Product with + /// 'ProvisioningState' = 'Creating' and 201 response code + /// + /// + /// The operations group for this extension method. + /// + /// + /// Product to put + /// + public static Product BeginPutNonRetry201Creating400InvalidJson(this ILROSADsOperations operations, Product product = default(Product)) + { + return Task.Factory.StartNew(s => ((ILROSADsOperations)s).BeginPutNonRetry201Creating400InvalidJsonAsync(product), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult(); + } + + /// + /// Long running put request, service returns a Product with + /// 'ProvisioningState' = 'Creating' and 201 response code + /// + /// + /// The operations group for this extension method. + /// + /// + /// Product to put + /// + /// + /// The cancellation token. + /// + public static async Task BeginPutNonRetry201Creating400InvalidJsonAsync(this ILROSADsOperations operations, Product product = default(Product), CancellationToken cancellationToken = default(CancellationToken)) + { + using (var _result = await operations.BeginPutNonRetry201Creating400InvalidJsonWithHttpMessagesAsync(product, null, cancellationToken).ConfigureAwait(false)) + { + return _result.Body; + } + } + /// /// Long running put request, service returns a 200 with /// ProvisioningState=’Creating’. Poll the endpoint indicated in the diff --git a/AutoRest/TestServer/server/routes/lros.js b/AutoRest/TestServer/server/routes/lros.js index 9d9dc540e16aa..1f896de2765cd 100644 --- a/AutoRest/TestServer/server/routes/lros.js +++ b/AutoRest/TestServer/server/routes/lros.js @@ -940,6 +940,16 @@ var lros = function (coverage) { res.status(400).end('{ "message" : "Error from the server" }'); }); + coverage['LRONonRetryPut201Creating400InvalidJson'] = 0; + router.put('/nonretryerror/put/201/creating/400/invalidjson', function (req, res, next) { + res.status(201).end('{ "properties": { "provisioningState": "Creating"}, "id": "100", "name": "foo" }'); + }); + + router.get('/nonretryerror/put/201/creating/400/invalidjson', function (req, res, next) { + coverage['LRONonRetryPut201Creating400InvalidJson']++; + res.status(400).end('<{ "message" : "Error from the server" }'); + }); + coverage['LRONonRetryPutAsyncRetry400'] = 0; router.put('/nonretryerror/putasync/retry/400', function (req, res, next) { var pollingUri = 'http://localhost.:' + utils.getPort() + '/lro/nonretryerror/putasync/retry/failed/operationResults/400'; diff --git a/AutoRest/TestServer/swagger/lro.json b/AutoRest/TestServer/swagger/lro.json index b064ce8c3aa2d..9f9bba0c26759 100644 --- a/AutoRest/TestServer/swagger/lro.json +++ b/AutoRest/TestServer/swagger/lro.json @@ -1772,6 +1772,46 @@ } } } + }, + "/lro/nonretryerror/put/201/creating/400/invalidjson": { + "put": { + "x-ms-long-running-operation": true, + "operationId": "LROSADs_putNonRetry201Creating400InvalidJson", + "description": "Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code", + "tags": [ + "LROSAD Operations" + ], + "parameters": [ + { + "name": "product", + "description": "Product to put", + "in": "body", + "schema": { + "$ref": "#/definitions/Product" + } + } + ], + "responses": { + "200": { + "description": "Response after completion, with ProvisioningState='Succeeded'", + "schema": { + "$ref": "#/definitions/Product" + } + }, + "201": { + "description": "Initial response, with ProvisioningState = 'Creating'", + "schema": { + "$ref": "#/definitions/Product" + } + }, + "default": { + "description": "Unexpected error", + "schema": { + "$ref": "#/definitions/CloudError" + } + } + } + } }, "/lro/nonretryerror/putasync/retry/400": { "put": { From 16b8f29cfba5ff953897b641680844c3c98928af Mon Sep 17 00:00:00 2001 From: John-Hart Date: Tue, 19 Apr 2016 17:13:11 -0700 Subject: [PATCH 14/29] Set the intial coverage for the LRONonRetryPut201Creating400InvalidJson to 1 --- AutoRest/TestServer/server/routes/lros.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AutoRest/TestServer/server/routes/lros.js b/AutoRest/TestServer/server/routes/lros.js index 1f896de2765cd..ca11fa50082be 100644 --- a/AutoRest/TestServer/server/routes/lros.js +++ b/AutoRest/TestServer/server/routes/lros.js @@ -940,7 +940,8 @@ var lros = function (coverage) { res.status(400).end('{ "message" : "Error from the server" }'); }); - coverage['LRONonRetryPut201Creating400InvalidJson'] = 0; + /* TODO: only C# has implemented this test. Exclude it from code coverage until it is implemented in other languages */ + coverage['LRONonRetryPut201Creating400InvalidJson'] = 1; router.put('/nonretryerror/put/201/creating/400/invalidjson', function (req, res, next) { res.status(201).end('{ "properties": { "provisioningState": "Creating"}, "id": "100", "name": "foo" }'); }); From 08bd3364fd6760a056d439fcf590baaa27373578 Mon Sep 17 00:00:00 2001 From: tbombach Date: Fri, 22 Apr 2016 13:31:24 -0700 Subject: [PATCH 15/29] Adding documentation for instructions on writing tests in AutoRest --- Documentation/README.md | 3 +- Documentation/writing-tests.md | 52 ++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 Documentation/writing-tests.md diff --git a/Documentation/README.md b/Documentation/README.md index 890f11b09d4bf..6b77f525787bb 100644 --- a/Documentation/README.md +++ b/Documentation/README.md @@ -18,6 +18,7 @@ - Code Generators - Modelers 5. [Building AutoRest](building-code.md) -6. Contributing to the code +6. [Writing Tests](writing-tests.md) +7. Contributing to the code [Swagger2.0]:https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md diff --git a/Documentation/writing-tests.md b/Documentation/writing-tests.md new file mode 100644 index 0000000000000..7712f32f74753 --- /dev/null +++ b/Documentation/writing-tests.md @@ -0,0 +1,52 @@ +# Writing Tests + +## Build Prerequisites +To test AutoRest in each language, you must set up your machine according to the requirements on the [Building Code](building-code.md) page. + +## Architecture +Tests are split into unit and acceptance tests. Unit tests validate the AutoRest application itself and how it interprets Swagger documents. Acceptance tests validate the generated code in each language and are written in those languages. + +### Unit tests +Unit tests need to be updated when core parts of AutoRest change, not when the language-specific generator code changes. Unit tests are located in: +
+
\AutoRest\AutoRest.Core.Tests
+
These need to be updated when the command-line AutoRest application itself changes
+
\AutoRest\Modelers\Swagger.Tests
+ \AutoRest\Modelers\Swagger.Composite.Tests
+
These need to be updated when there are changes to how AutoRest processes Swagger files
+
+ +### Acceptance tests (and test server) +Acceptance tests are run against a Node.js test server (which uses [Express framework](http://expressjs.com/)). The code for the test server is checked in to the [\\AutoRest\\TestServer](../AutoRest/TestServer/) folder in the repository. + +There are two main components to the test server: the Swagger definitions that describe the server and the code that handles requests to the server and responds with the appropriate status code, payload, etc. if the request is constructed correctly. + +## How to add acceptance tests for scenarios +1. Add your scenarios to the Swagger files that describe the test server (located in the [\\AutoRest\\TestServer\\swagger](../AutoRest/TestServer/swagger/) folder). +2. Update the test server + - Update the routes to generate appropriate responses for your scenarios at paths specified in the Swagger files in step 1. This code is located in the [\\AutoRest\\TestServer\\server\\routes\\*.js](../AutoRest/TestServer/server/routes) files. + - For each scenario, the `coverage` dictionary needs to be incremented for the name of your scenario. This name will be used in the test report coverage. + - Update the `coverage` dictionary in [\\AutoRest\\TestServer\\server\\app.js](../AutoRest/TestServer/server/app.js) to include the names of your new scenarios. This lets the final test report include your scenarios when reporting on the coverage for each language. +3. Regenerate the expected code using `gulp regenerate` (this will use the Swagger files to generate client libraries for the test server). +4. In each language, write tests that cover your scenarios (for example, in C#, you must update [\\AutoRest\\Generators\\CSharp\CSharp.Tests\\AcceptanceTests.cs](../AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs) or [\\AutoRest\\Generators\\CSharp\\Azure.CSharp.Tests\\AcceptanceTests.cs](../AutoRest/Generators/CSharp/Azure.CSharp.Tests/AcceptanceTests.cs)). You will make calls to the test server using the generated code from step 3. +5. [Run the tests](#running-tests) + +## Running Tests +When you run tests, the test server is automatically started and the code that is generated for the test server Swagger files will correctly target this new instance. + +### Command Line +Tests can be run with `gulp test`. You can run tests for each language individually with `gulp:test:[language name]`. Use `gulp -T` to find the correct names. + +### Visual Studio +In Visual Studio, you can run tests for all languages using Task Runner Explorer. C# tests can also be run and debugged in Test Explorer. + +## Debugging the test server +When updating the test server code to return the appropriate responses for your scenarios, it can be useful to debug the code to make sure the test code calls the paths that you are expecting. + +### Visual Studio +1. Install [Node.js Tools for Visual Studio](https://www.visualstudio.com/en-us/features/node-js-vs.aspx) solution. +2. Open the [\\AutoRest\\TestServer\\server\\SwaggerBATServer.sln](../AutoRest/TestServer/server/SwaggerBATServer.sln). +3. Run the [SwaggerBATServer project](../AutoRest/TestServer/server/SwaggerBATServer.njsproj). +4. Make sure that the port that the test server is using matches the port that is used by the tests when you run them. + - For Node.js, this is straightforward because the server and tests both use port 3000 by default. + - For C#, the infrastructure is set up to use a random port to avoid conflicts. You must change the logic in [\\AutoRest\\Generators\\CSharp\\CSharp.Tests\\Utilities\\ServiceController.cs](../AutoRest/Generators/CSharp/CSharp.Tests/Utilities/ServiceController.cs).`GetRandomPort()` to use the same port as the test server. \ No newline at end of file From a7b6eb94049bae8e7eaa69b066791e7ed40dc2f8 Mon Sep 17 00:00:00 2001 From: John Hart Date: Fri, 22 Apr 2016 15:01:03 -0700 Subject: [PATCH 16/29] Added an ExitCode to Autorest.exe (#966) --- AutoRest/AutoRest/AutoRest.csproj | 3 ++- AutoRest/AutoRest/ExitCode.cs | 14 ++++++++++++++ AutoRest/AutoRest/Program.cs | 6 +++++- 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 AutoRest/AutoRest/ExitCode.cs diff --git a/AutoRest/AutoRest/AutoRest.csproj b/AutoRest/AutoRest/AutoRest.csproj index 8bd5ec84e97dd..7c578e0980acb 100644 --- a/AutoRest/AutoRest/AutoRest.csproj +++ b/AutoRest/AutoRest/AutoRest.csproj @@ -31,6 +31,7 @@ Properties\AssemblyVersionInfo.cs + @@ -70,4 +71,4 @@ - + \ No newline at end of file diff --git a/AutoRest/AutoRest/ExitCode.cs b/AutoRest/AutoRest/ExitCode.cs new file mode 100644 index 0000000000000..fe09a82b44c21 --- /dev/null +++ b/AutoRest/AutoRest/ExitCode.cs @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +namespace Microsoft.Rest.Generator.Cli +{ + /// + /// Available exit codes. + /// + public enum ExitCode : int + { + Success = 0, + Error = 1 + } +} diff --git a/AutoRest/AutoRest/Program.cs b/AutoRest/AutoRest/Program.cs index b0c4aa7abea2b..f7bdf406b1066 100644 --- a/AutoRest/AutoRest/Program.cs +++ b/AutoRest/AutoRest/Program.cs @@ -12,8 +12,10 @@ namespace Microsoft.Rest.Generator.Cli { internal class Program { - private static void Main(string[] args) + private static int Main(string[] args) { + int exitCode = (int)ExitCode.Error; + try { Settings settings = null; @@ -69,6 +71,7 @@ private static void Main(string[] args) { Console.WriteLine(Resources.GenerationComplete, settings.CodeGenerator, settings.Input); + exitCode = (int)ExitCode.Success; } } @@ -91,6 +94,7 @@ private static void Main(string[] args) Console.Error.WriteLine(Resources.ConsoleErrorMessage, exception.Message); Console.Error.WriteLine(Resources.ConsoleErrorStackTrace, exception.StackTrace); } + return exitCode; } /// From 1e0252d4e3d0ff5d67fae439010a32a9dd90fcb2 Mon Sep 17 00:00:00 2001 From: Hovsep Date: Fri, 22 Apr 2016 16:35:14 -0700 Subject: [PATCH 17/29] Revert "Escape data strings for odata queries." --- .../Azure.CSharp.Tests/AcceptanceTests.cs | 3 +-- .../ODataTests.cs | 21 +++++++------------ .../OData/ODataQuery.cs | 6 +++--- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/AutoRest/Generators/CSharp/Azure.CSharp.Tests/AcceptanceTests.cs b/AutoRest/Generators/CSharp/Azure.CSharp.Tests/AcceptanceTests.cs index d04c712fd1c96..ec21cdd514493 100644 --- a/AutoRest/Generators/CSharp/Azure.CSharp.Tests/AcceptanceTests.cs +++ b/AutoRest/Generators/CSharp/Azure.CSharp.Tests/AcceptanceTests.cs @@ -527,8 +527,7 @@ public void AzureODataTests() Top = 10, OrderBy = "id" }; - var filterString = Uri.EscapeDataString("id gt 5 and name eq 'foo'"); - Assert.Equal(string.Format("$filter={0}&$orderby=id&$top=10", filterString), filter.ToString()); + Assert.Equal("$filter=id gt 5 and name eq 'foo'&$orderby=id&$top=10", filter.ToString()); client.Odata.GetWithFilter(filter); } } diff --git a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/ODataTests.cs b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/ODataTests.cs index 639023af44855..c651bbdc33621 100644 --- a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/ODataTests.cs +++ b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/ODataTests.cs @@ -227,7 +227,6 @@ public void EncodingTheParameters() [Fact] public void ODataQuerySupportsAllParameters() { - var queryString = "foo eq 'bar'"; var query = new ODataQuery(p => p.Foo == "bar") { Expand = "param1", @@ -235,7 +234,7 @@ public void ODataQuerySupportsAllParameters() Skip = 10, Top = 100 }; - Assert.Equal(string.Format("$filter={0}&$orderby=d&$expand=param1&$top=100&$skip=10", Uri.EscapeDataString(queryString)), query.ToString()); + Assert.Equal("$filter=foo eq 'bar'&$orderby=d&$expand=param1&$top=100&$skip=10", query.ToString()); } [Fact] @@ -260,38 +259,34 @@ public void ODataQuerySupportsEmptyState() [Fact] public void ODataQuerySupportsPartialState() { - var queryString = "foo eq 'bar'"; var query = new ODataQuery(p => p.Foo == "bar") { Top = 100 }; - Assert.Equal(string.Format("$filter={0}&$top=100", Uri.EscapeDataString(queryString)), query.ToString()); + Assert.Equal("$filter=foo eq 'bar'&$top=100", query.ToString()); } [Fact] public void ODataQuerySupportsImplicitConversionFromFilterString() { - var queryString = "foo eq 'bar'"; - ODataQuery query = queryString; + ODataQuery query = "foo eq 'bar'"; query.Top = 100; - Assert.Equal(string.Format("$filter={0}&$top=100", Uri.EscapeDataString(queryString)), query.ToString()); + Assert.Equal("$filter=foo eq 'bar'&$top=100", query.ToString()); } [Fact] public void ODataQuerySupportsImplicitConversionFromFullFilterString() { - var queryString = "foo eq 'bar'"; - ODataQuery query = string.Format("$filter={0}", queryString); + ODataQuery query = "$filter=foo eq 'bar'"; query.Top = 100; - Assert.Equal(string.Format("$filter={0}&$top=100", Uri.EscapeDataString(queryString)), query.ToString()); + Assert.Equal("$filter=foo eq 'bar'&$top=100", query.ToString()); } [Fact] public void ODataQuerySupportsImplicitConversionFromQueryString() { - var queryString = "foo eq 'bar'"; - ODataQuery query = string.Format("$filter={0}&$top=100", queryString); - Assert.Equal(string.Format("$filter={0}&$top=100", Uri.EscapeDataString(queryString)), query.ToString()); + ODataQuery query = "$filter=foo eq 'bar'&$top=100"; + Assert.Equal("$filter=foo eq 'bar'&$top=100", query.ToString()); } [Fact] diff --git a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure/OData/ODataQuery.cs b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure/OData/ODataQuery.cs index 99fed407ca114..252c7739db668 100644 --- a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure/OData/ODataQuery.cs +++ b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure/OData/ODataQuery.cs @@ -146,17 +146,17 @@ public override string ToString() if (!string.IsNullOrEmpty(Filter)) { queryStringList.Add(string.Format(CultureInfo.InvariantCulture, - "$filter={0}", Uri.EscapeDataString(Filter))); + "$filter={0}", Filter)); } if (!string.IsNullOrEmpty(OrderBy)) { queryStringList.Add(string.Format(CultureInfo.InvariantCulture, - "$orderby={0}", Uri.EscapeDataString(OrderBy))); + "$orderby={0}", OrderBy)); } if (!string.IsNullOrEmpty(Expand)) { queryStringList.Add(string.Format(CultureInfo.InvariantCulture, - "$expand={0}", Uri.EscapeDataString(Expand))); + "$expand={0}", Expand)); } if (Top != null) { From 72ba2d63344acd09252ba06b58cbf4df82b7c516 Mon Sep 17 00:00:00 2001 From: Hovsep Mkrtchyan Date: Fri, 22 Apr 2016 17:23:18 -0700 Subject: [PATCH 18/29] Added tests to Odata filter generation --- .../ODataTests.cs | 47 ++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/ODataTests.cs b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/ODataTests.cs index c651bbdc33621..7c6829b301d14 100644 --- a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/ODataTests.cs +++ b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/ODataTests.cs @@ -7,6 +7,7 @@ using Microsoft.Rest.Azure.OData; using Newtonsoft.Json; using Xunit; +using System.Collections.Generic; namespace Microsoft.Rest.ClientRuntime.Azure.Test { @@ -248,14 +249,43 @@ public void ODataQuerySupportsEmptyState() { Value = null }; + var paramEncoded = new InputParam1 + { + Value = "bar/car" + }; query = new ODataQuery(p => p.Foo == param.Value); Assert.Equal("", query.ToString()); query = new ODataQuery(p => p.Foo == param.Value && p.AssignedTo(param.Value)); Assert.Equal("", query.ToString()); query = new ODataQuery(p => p.AssignedTo(param.Value)); Assert.Equal("", query.ToString()); + query = new ODataQuery(p => p.AssignedTo(paramEncoded.Value)); + Assert.Equal("$filter=assignedTo('bar%2Fcar')", query.ToString()); + } + + [Fact] + public void ODataQuerySupportsCustomDateTimeOffsetFilter() + { + var param = new Param1 + { + SubmitTime = DateTimeOffset.Parse("2016-03-28T08:15:00.0971693+00:00"), + State = "Ended" + + }; + + var filter = new List(); + filter.Add(string.Format("submitTime lt datetimeoffset'{0}'", Uri.EscapeDataString(param.SubmitTime.Value.ToString("O")))); + var filterString = string.Join(" and ", filter.ToArray()); + + + var query = new ODataQuery + { + Filter = filterString + }; + Assert.Equal("$filter=submitTime lt datetimeoffset'2016-03-28T08%3A15%3A00.0971693%2B00%3A00'' and state ne 'Ended'", query.ToString()); } + [Fact] public void ODataQuerySupportsPartialState() { @@ -266,6 +296,17 @@ public void ODataQuerySupportsPartialState() Assert.Equal("$filter=foo eq 'bar'&$top=100", query.ToString()); } + [Fact] + public void ODataQuerySupportsPartialStateWithSlashes() + { + var queryString = "$filter=foo eq 'bar%2Fclub'&$top=100"; + var query = new ODataQuery(p => p.Foo == "bar/club") + { + Top = 100 + }; + Assert.Equal(queryString, query.ToString()); + } + [Fact] public void ODataQuerySupportsImplicitConversionFromFilterString() { @@ -318,7 +359,7 @@ public void ODataQuerySupportsMethod() var filterString = FilterString.Generate(parameters => parameters.AtScope() && parameters.AssignedTo(param.Value)); - Assert.Equal(filterString, "atScope() and assignedTo('Microsoft.Web%2Fsites')"); + Assert.Equal("atScope() and assignedTo('Microsoft.Web%2Fsites')", filterString); } } @@ -356,6 +397,10 @@ public class Param1 [JsonProperty("d")] public DateTime Date { get; set; } public DateTime Date2 { get; set; } + [JsonProperty("submitTime")] + public DateTimeOffset? SubmitTime { get; set; } + [JsonProperty("state")] + public string State { get; set; } [JsonProperty("vals")] public string[] Values { get; set; } [JsonProperty("param2")] From af6fa32b56c6b08589aa558f71dfee6eb9dbb841 Mon Sep 17 00:00:00 2001 From: Hovsep Mkrtchyan Date: Fri, 22 Apr 2016 18:15:07 -0700 Subject: [PATCH 19/29] Fixed the test --- .../Microsoft.Rest.ClientRuntime.Azure.Tests/ODataTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/ODataTests.cs b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/ODataTests.cs index 7c6829b301d14..e267142696404 100644 --- a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/ODataTests.cs +++ b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure.Tests/ODataTests.cs @@ -275,6 +275,7 @@ public void ODataQuerySupportsCustomDateTimeOffsetFilter() var filter = new List(); filter.Add(string.Format("submitTime lt datetimeoffset'{0}'", Uri.EscapeDataString(param.SubmitTime.Value.ToString("O")))); + filter.Add(string.Format("state ne '{0}'", param.State)); var filterString = string.Join(" and ", filter.ToArray()); @@ -282,7 +283,7 @@ public void ODataQuerySupportsCustomDateTimeOffsetFilter() { Filter = filterString }; - Assert.Equal("$filter=submitTime lt datetimeoffset'2016-03-28T08%3A15%3A00.0971693%2B00%3A00'' and state ne 'Ended'", query.ToString()); + Assert.Equal("$filter=submitTime lt datetimeoffset'2016-03-28T08%3A15%3A00.0971693%2B00%3A00' and state ne 'Ended'", query.ToString()); } From 2f7d3e4680f2688e3fa237b72b1e50db0e53593a Mon Sep 17 00:00:00 2001 From: Qinyuan Wan Date: Tue, 26 Apr 2016 17:42:57 -0700 Subject: [PATCH 20/29] Deprecate two old functions --- .../Lro/operations/lRORetrys.js | 16 ++-- .../AcceptanceTests/Lro/operations/lROSADs.js | 52 ++++++------- .../AcceptanceTests/Lro/operations/lROs.js | 74 +++++++++---------- .../Lro/operations/lROsCustomHeader.js | 10 +-- .../ms-rest-azure/lib/azureServiceClient.js | 46 ++++++++++-- .../test/azureServiceClientTests.js | 22 +++--- 6 files changed, 126 insertions(+), 94 deletions(-) diff --git a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lRORetrys.js b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lRORetrys.js index bacca9fd614ab..91416004b938f 100644 --- a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lRORetrys.js +++ b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lRORetrys.js @@ -81,7 +81,7 @@ LRORetrys.prototype.put201CreatingSucceeded200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -334,7 +334,7 @@ LRORetrys.prototype.putAsyncRelativeRetrySucceeded = function (options, callback initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -562,7 +562,7 @@ LRORetrys.prototype.deleteProvisioning202Accepted200Succeeded = function (option initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -782,7 +782,7 @@ LRORetrys.prototype.delete202Retry200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -952,7 +952,7 @@ LRORetrys.prototype.deleteAsyncRelativeRetrySucceeded = function (options, callb initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1130,7 +1130,7 @@ LRORetrys.prototype.post202Retry200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1332,7 +1332,7 @@ LRORetrys.prototype.postAsyncRelativeRetrySucceeded = function (options, callbac initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1485,4 +1485,4 @@ LRORetrys.prototype.beginPostAsyncRelativeRetrySucceeded = function (options, ca }; -module.exports = LRORetrys; +module.exports = LRORetrys; \ No newline at end of file diff --git a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROSADs.js b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROSADs.js index 850509ad638ea..44a7ef1d9e6fc 100644 --- a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROSADs.js +++ b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROSADs.js @@ -78,7 +78,7 @@ LROSADs.prototype.putNonRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -326,7 +326,7 @@ LROSADs.prototype.putNonRetry201Creating400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -576,7 +576,7 @@ LROSADs.prototype.putAsyncRelativeRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -799,7 +799,7 @@ LROSADs.prototype.deleteNonRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -965,7 +965,7 @@ LROSADs.prototype.delete202NonRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1133,7 +1133,7 @@ LROSADs.prototype.deleteAsyncRelativeRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1309,7 +1309,7 @@ LROSADs.prototype.postNonRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1506,7 +1506,7 @@ LROSADs.prototype.post202NonRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1705,7 +1705,7 @@ LROSADs.prototype.postAsyncRelativeRetry400 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1906,7 +1906,7 @@ LROSADs.prototype.putError201NoProvisioningStatePayload = function (options, cal initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2156,7 +2156,7 @@ LROSADs.prototype.putAsyncRelativeRetryNoStatus = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2390,7 +2390,7 @@ LROSADs.prototype.putAsyncRelativeRetryNoStatusPayload = function (options, call initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2614,7 +2614,7 @@ LROSADs.prototype.delete204Succeeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2783,7 +2783,7 @@ LROSADs.prototype.deleteAsyncRelativeRetryNoStatus = function (options, callback initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2960,7 +2960,7 @@ LROSADs.prototype.post202NoLocation = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3160,7 +3160,7 @@ LROSADs.prototype.postAsyncRelativeRetryNoPayload = function (options, callback) initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3361,7 +3361,7 @@ LROSADs.prototype.put200InvalidJson = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3594,7 +3594,7 @@ LROSADs.prototype.putAsyncRelativeRetryInvalidHeader = function (options, callba initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3828,7 +3828,7 @@ LROSADs.prototype.putAsyncRelativeRetryInvalidJsonPolling = function (options, c initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4052,7 +4052,7 @@ LROSADs.prototype.delete202RetryInvalidHeader = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4220,7 +4220,7 @@ LROSADs.prototype.deleteAsyncRelativeRetryInvalidHeader = function (options, cal initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4389,7 +4389,7 @@ LROSADs.prototype.deleteAsyncRelativeRetryInvalidJsonPolling = function (options initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4566,7 +4566,7 @@ LROSADs.prototype.post202RetryInvalidHeader = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4766,7 +4766,7 @@ LROSADs.prototype.postAsyncRelativeRetryInvalidHeader = function (options, callb initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4967,7 +4967,7 @@ LROSADs.prototype.postAsyncRelativeRetryInvalidJsonPolling = function (options, initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -5119,4 +5119,4 @@ LROSADs.prototype.beginPostAsyncRelativeRetryInvalidJsonPolling = function (opti }; -module.exports = LROSADs; +module.exports = LROSADs; \ No newline at end of file diff --git a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROs.js b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROs.js index f403121e6dfec..7655fc4191aa2 100644 --- a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROs.js +++ b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROs.js @@ -79,7 +79,7 @@ LROs.prototype.put200Succeeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -311,7 +311,7 @@ LROs.prototype.put200SucceededNoState = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -544,7 +544,7 @@ LROs.prototype.put202Retry200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -779,7 +779,7 @@ LROs.prototype.put201CreatingSucceeded200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1032,7 +1032,7 @@ LROs.prototype.put200UpdatingSucceeded204 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1268,7 +1268,7 @@ LROs.prototype.put201CreatingFailed200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1521,7 +1521,7 @@ LROs.prototype.put200Acceptedcanceled200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1756,7 +1756,7 @@ LROs.prototype.putNoHeaderInRetry = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -1990,7 +1990,7 @@ LROs.prototype.putAsyncRetrySucceeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2224,7 +2224,7 @@ LROs.prototype.putAsyncNoRetrySucceeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2458,7 +2458,7 @@ LROs.prototype.putAsyncRetryFailed = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2692,7 +2692,7 @@ LROs.prototype.putAsyncNoRetrycanceled = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -2926,7 +2926,7 @@ LROs.prototype.putAsyncNoHeaderInRetry = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3156,7 +3156,7 @@ LROs.prototype.putNonResource = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3382,7 +3382,7 @@ LROs.prototype.putAsyncNonResource = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3606,7 +3606,7 @@ LROs.prototype.putSubResource = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -3828,7 +3828,7 @@ LROs.prototype.putAsyncSubResource = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4049,7 +4049,7 @@ LROs.prototype.deleteProvisioning202Accepted200Succeeded = function (options, ca initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4271,7 +4271,7 @@ LROs.prototype.deleteProvisioning202DeletingFailed200 = function (options, callb initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4493,7 +4493,7 @@ LROs.prototype.deleteProvisioning202Deletingcanceled200 = function (options, cal initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4711,7 +4711,7 @@ LROs.prototype.delete204Succeeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -4880,7 +4880,7 @@ LROs.prototype.delete202Retry200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -5083,7 +5083,7 @@ LROs.prototype.delete202NoRetry204 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -5285,7 +5285,7 @@ LROs.prototype.deleteNoHeaderInRetry = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -5455,7 +5455,7 @@ LROs.prototype.deleteAsyncNoHeaderInRetry = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -5625,7 +5625,7 @@ LROs.prototype.deleteAsyncRetrySucceeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -5795,7 +5795,7 @@ LROs.prototype.deleteAsyncNoRetrySucceeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -5965,7 +5965,7 @@ LROs.prototype.deleteAsyncRetryFailed = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -6135,7 +6135,7 @@ LROs.prototype.deleteAsyncRetrycanceled = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -6306,7 +6306,7 @@ LROs.prototype.post200WithPayload = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -6533,7 +6533,7 @@ LROs.prototype.post202Retry200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -6734,7 +6734,7 @@ LROs.prototype.post202NoRetry204 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -6967,7 +6967,7 @@ LROs.prototype.postAsyncRetrySucceeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -7201,7 +7201,7 @@ LROs.prototype.postAsyncNoRetrySucceeded = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -7434,7 +7434,7 @@ LROs.prototype.postAsyncRetryFailed = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -7635,7 +7635,7 @@ LROs.prototype.postAsyncRetrycanceled = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -7787,4 +7787,4 @@ LROs.prototype.beginPostAsyncRetrycanceled = function (options, callback) { }; -module.exports = LROs; +module.exports = LROs; \ No newline at end of file diff --git a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROsCustomHeader.js b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROsCustomHeader.js index 3d4d296e68aaa..0c25e2df3bb0c 100644 --- a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROsCustomHeader.js +++ b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROsCustomHeader.js @@ -82,7 +82,7 @@ LROsCustomHeader.prototype.putAsyncRetrySucceeded = function (options, callback) initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -320,7 +320,7 @@ LROsCustomHeader.prototype.put201CreatingSucceeded200 = function (options, callb initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -573,7 +573,7 @@ LROsCustomHeader.prototype.post202Retry200 = function (options, callback) { initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -777,7 +777,7 @@ LROsCustomHeader.prototype.postAsyncRetrySucceeded = function (options, callback initialResult.request = httpRequest; initialResult.response = response; initialResult.body = response.body; - client.getLongRunningOperationResult(initialResult, options, function (err, pollingResult) { + client.getPostOrDeleteOperationResult(initialResult, options, function (err, pollingResult) { if (err) return callback(err); // Create Result @@ -931,4 +931,4 @@ LROsCustomHeader.prototype.beginPostAsyncRetrySucceeded = function (options, cal }; -module.exports = LROsCustomHeader; +module.exports = LROsCustomHeader; \ No newline at end of file diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js index e0207511c4c34..fcc09299d1c03 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js @@ -57,7 +57,27 @@ function AzureServiceClient(credentials, options) { util.inherits(AzureServiceClient, msRest.ServiceClient); /** - * Poll Azure long running GET, PATCH, POST or DELETE operations. + * Poll Azure long running PUT or PATCH operation. (Deprecated, new version of the code-gen will generate code to call getLongRunningOperationResult) + * @param {object} [resultOfInitialRequest] - Response of the initial request for the long running operation. + * @param {object} [options] + * @param {object} [options.customHeaders] headers that will be added to request + */ +AzureServiceClient.prototype.getPutOrPatchOperationResult = function (resultOfInitialRequest, options, callback) { + return this.getLongRunningOperationResult(resultOfInitialRequest, options, callback); +} + +/** + * Poll Azure long running POST or DELETE operations. (Deprecated, new version of the code-gen will generate code to call getLongRunningOperationResult) + * @param {object} [resultOfInitialRequest] - result of the initial request. + * @param {object} [options] + * @param {object} [options.customHeaders] headers that will be added to request + */ +AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOfInitialRequest, options, callback) { + return this.getLongRunningOperationResult(resultOfInitialRequest, options, callback); +} + +/** + * Poll Azure long running PUT, PATCH, POST or DELETE operations. * @param {object} [resultOfInitialRequest] - result of the initial request. * @param {object} [options] * @param {object} [options.customHeaders] headers that will be added to request @@ -80,14 +100,25 @@ AzureServiceClient.prototype.getLongRunningOperationResult = function (resultOfI if (!resultOfInitialRequest.response) { return callback(new Error('Missing resultOfInitialRequest.response')); } + + if (!resultOfInitialRequest.request) { + return callback(new Error('Missing resultOfInitialRequest.request')); + } + + if (!resultOfInitialRequest.request.method) { + return callback(new Error('Missing resultOfInitialRequest.request.method')); + } - if (this._checkInitialRequestResponseStatusCodeFailed(resultOfInitialRequest)) { + var initialRequestMethod = resultOfInitialRequest.request.method; + + if (this._checkResponseStatusCodeFailed(resultOfInitialRequest)) { return callback(new Error(util.format('Unexpected polling status code from long running operation \'%s\' for method \'%s\'', resultOfInitialRequest.response.statusCode, - resultOfInitialRequest.request.method))); + initialRequestMethod))); } var pollingState = null; + try { pollingState = new PollingState(resultOfInitialRequest, this.longRunningOperationRetryTimeout); } catch (error) { @@ -110,10 +141,10 @@ AzureServiceClient.prototype.getLongRunningOperationResult = function (resultOfI return callback(err); }); } else if (pollingState.locationHeaderLink) { - self._updateStateFromLocationHeader(resultOfInitialRequest.request.method, pollingState, function(err) { + self._updateStateFromLocationHeader(initialRequestMethod, pollingState, function(err) { return callback(err); }); - } else if (resultOfInitialRequest.request.method === 'PUT') { + } else if (initialRequestMethod === 'PUT') { self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { return callback(err); }); @@ -125,7 +156,8 @@ AzureServiceClient.prototype.getLongRunningOperationResult = function (resultOfI //when done function (err) { if (pollingState.status === LroStates.Succeeded) { - if ((pollingState.azureAsyncOperationHeaderLink || !pollingState.resource) && resultOfInitialRequest.request.method !== 'DELETE' && resultOfInitialRequest.request.method !== 'POST') { + if ((pollingState.azureAsyncOperationHeaderLink || !pollingState.resource) + && (initialRequestMethod === 'PUT' || initialRequestMethod === 'PATCH')) { self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { return callback(err, pollingState.getOperationResponse()); }); @@ -138,7 +170,7 @@ AzureServiceClient.prototype.getLongRunningOperationResult = function (resultOfI }); }; -AzureServiceClient.prototype._checkInitialRequestResponseStatusCodeFailed = function (initialRequest) { +AzureServiceClient.prototype._checkResponseStatusCodeFailed = function (initialRequest) { var statusCode = initialRequest.response.statusCode; var method = initialRequest.request.method; if (statusCode === 200 || statusCode === 202 || diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js b/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js index 3a56e378e4d9c..954032749dcfd 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js @@ -94,7 +94,7 @@ describe('AzureServiceClient', function () { resultOfInitialRequest.response.statusCode = 201; it('throw on not Lro related status code', function (done) { - client.getLongRunningOperationResult({ response: {statusCode: 10000}, request: { url:"http://foo" }}, function (err, result) { + client.getPutOrPatchOperationResult({ response: {statusCode: 10000}, request: { url:"http://foo" }}, function (err, result) { err.message.should.containEql('Unexpected polling status code from long running operation'); done(); }); @@ -103,7 +103,7 @@ describe('AzureServiceClient', function () { it('works by polling from the azure-asyncoperation header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = urlFromAzureAsyncOPHeader_Return200; resultOfInitialRequest.response.headers['location'] = ''; - client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { + client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { should.not.exist(err); JSON.parse(result.body).name.should.equal(testResourceName); done(); @@ -118,7 +118,7 @@ describe('AzureServiceClient', function () { 'testCustomField': testCustomFieldValue } }; - client.getLongRunningOperationResult(resultOfInitialRequest, options, function (err, result) { + client.getPutOrPatchOperationResult(resultOfInitialRequest, options, function (err, result) { should.not.exist(err); JSON.parse(result.body).name.should.equal(testResourceName); result.response.testCustomField.should.equal(testCustomFieldValue); @@ -129,7 +129,7 @@ describe('AzureServiceClient', function () { it('works by polling from the location header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; resultOfInitialRequest.response.headers['location'] = urlFromLocationHeader_Return200; - client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { + client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { should.not.exist(err); JSON.parse(result.body).name.should.equal(testResourceName); should.exist(result.response.randomFieldFromPollLocationHeader); @@ -140,7 +140,7 @@ describe('AzureServiceClient', function () { it('returns error if failed to poll from the azure-asyncoperation header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = url_ReturnError; resultOfInitialRequest.response.headers['location'] = ''; - client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { + client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { err.message.should.containEql(testError); done(); }); @@ -149,7 +149,7 @@ describe('AzureServiceClient', function () { it('returns error if failed to poll from the location header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; resultOfInitialRequest.response.headers['location'] = url_ReturnError; - client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { + client.getPutOrPatchOperationResult(resultOfInitialRequest, function (err, result) { err.message.should.containEql(testError); done(); }); @@ -205,7 +205,7 @@ describe('AzureServiceClient', function () { resultOfInitialRequest.body.properties.provisioningState = LroStates.Succeeded; it('throw on not Lro related status code', function (done) { - client.getLongRunningOperationResult({ response: { statusCode: 201 }, request: {url: url_resource, method: 'POST'}}, function (err, result) { + client.getPostOrDeleteOperationResult({ response: { statusCode: 201 }, request: {url: url_resource, method: 'POST'}}, function (err, result) { err.message.should.containEql('Unexpected polling status code from long running operation'); done(); }); @@ -215,7 +215,7 @@ describe('AzureServiceClient', function () { resultOfInitialRequest.response.headers['azure-asyncoperation'] = urlFromAzureAsyncOPHeader_Return200; resultOfInitialRequest.response.headers['location'] = ''; resultOfInitialRequest.request.method = 'POST'; - client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { + client.getPostOrDeleteOperationResult(resultOfInitialRequest, function (err, result) { should.not.exist(err); should.exist(result.response.randomFieldFromPollAsyncOpHeader); done(); @@ -225,7 +225,7 @@ describe('AzureServiceClient', function () { it('works by polling from the location header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; resultOfInitialRequest.response.headers['location'] = urlFromLocationHeader_Return200; - client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { + client.getPostOrDeleteOperationResult(resultOfInitialRequest, function (err, result) { should.not.exist(err); should.exist(result.response.randomFieldFromPollLocationHeader); JSON.parse(result.body).name.should.equal(testResourceName); @@ -236,7 +236,7 @@ describe('AzureServiceClient', function () { it('returns error if failed to poll from the azure-asyncoperation header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = url_ReturnError; resultOfInitialRequest.response.headers['location'] = ''; - client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { + client.getPostOrDeleteOperationResult(resultOfInitialRequest, function (err, result) { err.message.should.containEql(testError); done(); }); @@ -245,7 +245,7 @@ describe('AzureServiceClient', function () { it('returns error if failed to poll from the location header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; resultOfInitialRequest.response.headers['location'] = url_ReturnError; - client.getLongRunningOperationResult(resultOfInitialRequest, function (err, result) { + client.getPostOrDeleteOperationResult(resultOfInitialRequest, function (err, result) { err.message.should.containEql(testError); done(); }); From 1a6bf4e79d9daa64ecf3fc4d6e9492ab7cc57b44 Mon Sep 17 00:00:00 2001 From: Qinyuan Wan Date: Wed, 27 Apr 2016 10:36:56 -0700 Subject: [PATCH 21/29] code revise --- .../NodeJS/ms-rest-azure/lib/azureServiceClient.js | 8 ++++---- .../NodeJS/ms-rest-azure/test/azureServiceClientTests.js | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js index fcc09299d1c03..ca4413b85a00b 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/lib/azureServiceClient.js @@ -64,7 +64,7 @@ util.inherits(AzureServiceClient, msRest.ServiceClient); */ AzureServiceClient.prototype.getPutOrPatchOperationResult = function (resultOfInitialRequest, options, callback) { return this.getLongRunningOperationResult(resultOfInitialRequest, options, callback); -} +}; /** * Poll Azure long running POST or DELETE operations. (Deprecated, new version of the code-gen will generate code to call getLongRunningOperationResult) @@ -74,7 +74,7 @@ AzureServiceClient.prototype.getPutOrPatchOperationResult = function (resultOfIn */ AzureServiceClient.prototype.getPostOrDeleteOperationResult = function (resultOfInitialRequest, options, callback) { return this.getLongRunningOperationResult(resultOfInitialRequest, options, callback); -} +}; /** * Poll Azure long running PUT, PATCH, POST or DELETE operations. @@ -156,8 +156,8 @@ AzureServiceClient.prototype.getLongRunningOperationResult = function (resultOfI //when done function (err) { if (pollingState.status === LroStates.Succeeded) { - if ((pollingState.azureAsyncOperationHeaderLink || !pollingState.resource) - && (initialRequestMethod === 'PUT' || initialRequestMethod === 'PATCH')) { + if ((pollingState.azureAsyncOperationHeaderLink || !pollingState.resource) && + (initialRequestMethod === 'PUT' || initialRequestMethod === 'PATCH')) { self._updateStateFromGetResourceOperation(resourceUrl, pollingState, function(err) { return callback(err, pollingState.getOperationResponse()); }); diff --git a/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js b/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js index 954032749dcfd..8e11e689690b7 100644 --- a/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js +++ b/ClientRuntimes/NodeJS/ms-rest-azure/test/azureServiceClientTests.js @@ -92,9 +92,10 @@ describe('AzureServiceClient', function () { describe('Put', function () { resultOfInitialRequest.response.statusCode = 201; + resultOfInitialRequest.request.method = 'PUT'; it('throw on not Lro related status code', function (done) { - client.getPutOrPatchOperationResult({ response: {statusCode: 10000}, request: { url:"http://foo" }}, function (err, result) { + client.getPutOrPatchOperationResult({ response: {statusCode: 10000}, request: { url:"http://foo", method:'PUT' }}, function (err, result) { err.message.should.containEql('Unexpected polling status code from long running operation'); done(); }); @@ -159,6 +160,7 @@ describe('AzureServiceClient', function () { describe('Patch', function () { resultOfInitialRequest.response.statusCode = 202; resultOfInitialRequest.body.properties.provisioningState = LroStates.Succeeded; + resultOfInitialRequest.request.method = 'PATCH'; it('works by polling from location header', function (done) { resultOfInitialRequest.response.headers['azure-asyncoperation'] = ''; From 651b1021b1728fe21bfa793c95e6de1e2db26833 Mon Sep 17 00:00:00 2001 From: Amar Zavery Date: Thu, 28 Apr 2016 14:03:32 -0700 Subject: [PATCH 22/29] fixed setting default value for a complex object containing constant properties (#985) * Enhancement to x-ms-parameterized-host extension * positionInOperation defaults to first * fixed setting default value for a complex object containing constant properties. * result of executing gulp regenerate:expected * Fixed fxcop warnings * remove null check validation for unixtime as they are treated as long in java --- .../java/fixtures/lro/LROSADsOperations.java | 76 +++ .../fixtures/lro/LROSADsOperationsImpl.java | 181 +++++++ .../fixtures/bodyinteger/IntOperations.java | 74 +++ .../bodyinteger/IntOperationsImpl.java | 198 ++++++++ .../java/fixtures/url/PathsOperations.java | 20 + .../fixtures/url/PathsOperationsImpl.java | 51 ++ .../TemplateModels/MethodTemplateModel.cs | 1 + .../AcceptanceTests/Lro/operations/index.d.ts | 46 ++ .../AcceptanceTests/Lro/operations/lROSADs.js | 249 ++++++++++ .../BodyInteger/operations/index.d.ts | 58 +++ .../BodyInteger/operations/intModel.js | 463 ++++++++++++++++++ .../operations/index.d.ts | 58 +++ .../operations/intModel.js | 463 ++++++++++++++++++ .../ModelFlattening/models/simpleProduct.js | 1 - .../AcceptanceTests/Url/operations/index.d.ts | 16 + .../AcceptanceTests/Url/operations/paths.js | 102 ++++ .../Validation/models/childProduct.js | 1 - .../Validation/models/constantProduct.js | 1 - .../Validation/models/product.js | 1 - .../NodeJS/NodeJS/ClientModelExtensions.cs | 16 +- .../NodeJS/NodeJS/GlobalSuppressions.cs | 2 + .../operations/lrosa_ds_operations.py | 86 ++++ .../operations/int_model.py | 175 +++++++ .../operations/paths.py | 43 ++ 24 files changed, 2371 insertions(+), 11 deletions(-) diff --git a/AutoRest/Generators/Java/Azure.Java.Tests/src/main/java/fixtures/lro/LROSADsOperations.java b/AutoRest/Generators/Java/Azure.Java.Tests/src/main/java/fixtures/lro/LROSADsOperations.java index 67695190d0b37..7fdc2cc170dd2 100644 --- a/AutoRest/Generators/Java/Azure.Java.Tests/src/main/java/fixtures/lro/LROSADsOperations.java +++ b/AutoRest/Generators/Java/Azure.Java.Tests/src/main/java/fixtures/lro/LROSADsOperations.java @@ -195,6 +195,82 @@ public interface LROSADsOperations { */ ServiceCall beginPutNonRetry201Creating400Async(Product product, final ServiceCallback serviceCallback) throws IllegalArgumentException; + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @throws CloudException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @throws InterruptedException exception thrown when long running operation is interrupted + * @return the Product object wrapped in {@link ServiceResponse} if successful. + */ + ServiceResponse putNonRetry201Creating400InvalidJson() throws CloudException, IOException, InterruptedException; + + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link ServiceCall} object + */ + ServiceCall putNonRetry201Creating400InvalidJsonAsync(final ServiceCallback serviceCallback) throws IllegalArgumentException; + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @param product Product to put + * @throws CloudException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @throws InterruptedException exception thrown when long running operation is interrupted + * @return the Product object wrapped in {@link ServiceResponse} if successful. + */ + ServiceResponse putNonRetry201Creating400InvalidJson(Product product) throws CloudException, IOException, InterruptedException; + + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @param product Product to put + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link ServiceCall} object + */ + ServiceCall putNonRetry201Creating400InvalidJsonAsync(Product product, final ServiceCallback serviceCallback) throws IllegalArgumentException; + + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @throws CloudException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @return the Product object wrapped in {@link ServiceResponse} if successful. + */ + ServiceResponse beginPutNonRetry201Creating400InvalidJson() throws CloudException, IOException; + + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link ServiceCall} object + */ + ServiceCall beginPutNonRetry201Creating400InvalidJsonAsync(final ServiceCallback serviceCallback) throws IllegalArgumentException; + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @param product Product to put + * @throws CloudException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @return the Product object wrapped in {@link ServiceResponse} if successful. + */ + ServiceResponse beginPutNonRetry201Creating400InvalidJson(Product product) throws CloudException, IOException; + + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @param product Product to put + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link ServiceCall} object + */ + ServiceCall beginPutNonRetry201Creating400InvalidJsonAsync(Product product, final ServiceCallback serviceCallback) throws IllegalArgumentException; + /** * Long running put request, service returns a 200 with ProvisioningState=’Creating’. Poll the endpoint indicated in the Azure-AsyncOperation header for operation status. * diff --git a/AutoRest/Generators/Java/Azure.Java.Tests/src/main/java/fixtures/lro/LROSADsOperationsImpl.java b/AutoRest/Generators/Java/Azure.Java.Tests/src/main/java/fixtures/lro/LROSADsOperationsImpl.java index a00b4293ab132..2f3623d834f8d 100644 --- a/AutoRest/Generators/Java/Azure.Java.Tests/src/main/java/fixtures/lro/LROSADsOperationsImpl.java +++ b/AutoRest/Generators/Java/Azure.Java.Tests/src/main/java/fixtures/lro/LROSADsOperationsImpl.java @@ -95,6 +95,14 @@ interface LROSADsService { @PUT("lro/nonretryerror/put/201/creating/400") Call beginPutNonRetry201Creating400(@Body Product product, @Header("accept-language") String acceptLanguage); + @Headers("Content-Type: application/json; charset=utf-8") + @PUT("lro/nonretryerror/put/201/creating/400/invalidjson") + Call putNonRetry201Creating400InvalidJson(@Body Product product, @Header("accept-language") String acceptLanguage); + + @Headers("Content-Type: application/json; charset=utf-8") + @PUT("lro/nonretryerror/put/201/creating/400/invalidjson") + Call beginPutNonRetry201Creating400InvalidJson(@Body Product product, @Header("accept-language") String acceptLanguage); + @Headers("Content-Type: application/json; charset=utf-8") @PUT("lro/nonretryerror/putasync/retry/400") Call putAsyncRelativeRetry400(@Body Product product, @Header("accept-language") String acceptLanguage); @@ -627,6 +635,179 @@ private ServiceResponse beginPutNonRetry201Creating400Delegate(Response .build(response); } + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @throws CloudException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @throws InterruptedException exception thrown when long running operation is interrupted + * @return the Product object wrapped in ServiceResponse if successful. + */ + public ServiceResponse putNonRetry201Creating400InvalidJson() throws CloudException, IOException, InterruptedException { + final Product product = null; + Response result = service.putNonRetry201Creating400InvalidJson(product, this.client.getAcceptLanguage()).execute(); + return client.getAzureClient().getPutOrPatchResult(result, new TypeToken() { }.getType()); + } + + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link ServiceCall} object + */ + public ServiceCall putNonRetry201Creating400InvalidJsonAsync(final ServiceCallback serviceCallback) throws IllegalArgumentException { + if (serviceCallback == null) { + throw new IllegalArgumentException("ServiceCallback is required for async calls."); + } + final Product product = null; + Call call = service.putNonRetry201Creating400InvalidJson(product, this.client.getAcceptLanguage()); + final ServiceCall serviceCall = new ServiceCall(call); + call.enqueue(new Callback() { + @Override + public void onFailure(Call call, Throwable t) { + serviceCallback.failure(t); + } + @Override + public void onResponse(Call call, Response response) { + client.getAzureClient().getPutOrPatchResultAsync(response, new TypeToken() { }.getType(), serviceCall, serviceCallback); + } + }); + return serviceCall; + } + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @param product Product to put + * @throws CloudException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @throws InterruptedException exception thrown when long running operation is interrupted + * @return the Product object wrapped in ServiceResponse if successful. + */ + public ServiceResponse putNonRetry201Creating400InvalidJson(Product product) throws CloudException, IOException, InterruptedException { + Validator.validate(product); + Response result = service.putNonRetry201Creating400InvalidJson(product, this.client.getAcceptLanguage()).execute(); + return client.getAzureClient().getPutOrPatchResult(result, new TypeToken() { }.getType()); + } + + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @param product Product to put + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link ServiceCall} object + */ + public ServiceCall putNonRetry201Creating400InvalidJsonAsync(Product product, final ServiceCallback serviceCallback) throws IllegalArgumentException { + if (serviceCallback == null) { + throw new IllegalArgumentException("ServiceCallback is required for async calls."); + } + Validator.validate(product, serviceCallback); + Call call = service.putNonRetry201Creating400InvalidJson(product, this.client.getAcceptLanguage()); + final ServiceCall serviceCall = new ServiceCall(call); + call.enqueue(new Callback() { + @Override + public void onFailure(Call call, Throwable t) { + serviceCallback.failure(t); + } + @Override + public void onResponse(Call call, Response response) { + client.getAzureClient().getPutOrPatchResultAsync(response, new TypeToken() { }.getType(), serviceCall, serviceCallback); + } + }); + return serviceCall; + } + + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @throws CloudException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @return the Product object wrapped in {@link ServiceResponse} if successful. + */ + public ServiceResponse beginPutNonRetry201Creating400InvalidJson() throws CloudException, IOException { + final Product product = null; + Call call = service.beginPutNonRetry201Creating400InvalidJson(product, this.client.getAcceptLanguage()); + return beginPutNonRetry201Creating400InvalidJsonDelegate(call.execute()); + } + + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link Call} object + */ + public ServiceCall beginPutNonRetry201Creating400InvalidJsonAsync(final ServiceCallback serviceCallback) throws IllegalArgumentException { + if (serviceCallback == null) { + throw new IllegalArgumentException("ServiceCallback is required for async calls."); + } + final Product product = null; + Call call = service.beginPutNonRetry201Creating400InvalidJson(product, this.client.getAcceptLanguage()); + final ServiceCall serviceCall = new ServiceCall(call); + call.enqueue(new ServiceResponseCallback(serviceCallback) { + @Override + public void onResponse(Call call, Response response) { + try { + serviceCallback.success(beginPutNonRetry201Creating400InvalidJsonDelegate(response)); + } catch (CloudException | IOException exception) { + serviceCallback.failure(exception); + } + } + }); + return serviceCall; + } + + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @param product Product to put + * @throws CloudException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @return the Product object wrapped in {@link ServiceResponse} if successful. + */ + public ServiceResponse beginPutNonRetry201Creating400InvalidJson(Product product) throws CloudException, IOException { + Validator.validate(product); + Call call = service.beginPutNonRetry201Creating400InvalidJson(product, this.client.getAcceptLanguage()); + return beginPutNonRetry201Creating400InvalidJsonDelegate(call.execute()); + } + + /** + * Long running put request, service returns a Product with 'ProvisioningState' = 'Creating' and 201 response code. + * + * @param product Product to put + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link Call} object + */ + public ServiceCall beginPutNonRetry201Creating400InvalidJsonAsync(Product product, final ServiceCallback serviceCallback) throws IllegalArgumentException { + if (serviceCallback == null) { + throw new IllegalArgumentException("ServiceCallback is required for async calls."); + } + Validator.validate(product, serviceCallback); + Call call = service.beginPutNonRetry201Creating400InvalidJson(product, this.client.getAcceptLanguage()); + final ServiceCall serviceCall = new ServiceCall(call); + call.enqueue(new ServiceResponseCallback(serviceCallback) { + @Override + public void onResponse(Call call, Response response) { + try { + serviceCallback.success(beginPutNonRetry201Creating400InvalidJsonDelegate(response)); + } catch (CloudException | IOException exception) { + serviceCallback.failure(exception); + } + } + }); + return serviceCall; + } + + private ServiceResponse beginPutNonRetry201Creating400InvalidJsonDelegate(Response response) throws CloudException, IOException { + return new AzureServiceResponseBuilder(this.client.getMapperAdapter()) + .register(200, new TypeToken() { }.getType()) + .register(201, new TypeToken() { }.getType()) + .registerError(CloudException.class) + .build(response); + } + /** * Long running put request, service returns a 200 with ProvisioningState=’Creating’. Poll the endpoint indicated in the Azure-AsyncOperation header for operation status. * diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/bodyinteger/IntOperations.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/bodyinteger/IntOperations.java index 2f705c55d8129..9710c80eabe31 100644 --- a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/bodyinteger/IntOperations.java +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/bodyinteger/IntOperations.java @@ -209,4 +209,78 @@ public interface IntOperations { */ ServiceCall putMin64Async(long intBody, final ServiceCallback serviceCallback) throws IllegalArgumentException; + /** + * Get datetime encoded as Unix time value. + * + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @return the long object wrapped in {@link ServiceResponse} if successful. + */ + ServiceResponse getUnixTime() throws ErrorException, IOException; + + /** + * Get datetime encoded as Unix time value. + * + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link ServiceCall} object + */ + ServiceCall getUnixTimeAsync(final ServiceCallback serviceCallback) throws IllegalArgumentException; + + /** + * Put datetime encoded as Unix time. + * + * @param intBody the long value + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @return the {@link ServiceResponse} object if successful. + */ + ServiceResponse putUnixTimeDate(long intBody) throws ErrorException, IOException; + + /** + * Put datetime encoded as Unix time. + * + * @param intBody the long value + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link ServiceCall} object + */ + ServiceCall putUnixTimeDateAsync(long intBody, final ServiceCallback serviceCallback) throws IllegalArgumentException; + + /** + * Get invalid Unix time value. + * + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @return the long object wrapped in {@link ServiceResponse} if successful. + */ + ServiceResponse getInvalidUnixTime() throws ErrorException, IOException; + + /** + * Get invalid Unix time value. + * + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link ServiceCall} object + */ + ServiceCall getInvalidUnixTimeAsync(final ServiceCallback serviceCallback) throws IllegalArgumentException; + + /** + * Get null Unix time value. + * + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @return the long object wrapped in {@link ServiceResponse} if successful. + */ + ServiceResponse getNullUnixTime() throws ErrorException, IOException; + + /** + * Get null Unix time value. + * + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link ServiceCall} object + */ + ServiceCall getNullUnixTimeAsync(final ServiceCallback serviceCallback) throws IllegalArgumentException; + } diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/bodyinteger/IntOperationsImpl.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/bodyinteger/IntOperationsImpl.java index 8e9325c0caf42..134ce02e57ae8 100644 --- a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/bodyinteger/IntOperationsImpl.java +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/bodyinteger/IntOperationsImpl.java @@ -93,6 +93,22 @@ interface IntService { @PUT("int/min/64") Call putMin64(@Body long intBody); + @Headers("Content-Type: application/json; charset=utf-8") + @GET("int/unixtime") + Call getUnixTime(); + + @Headers("Content-Type: application/json; charset=utf-8") + @PUT("int/unixtime") + Call putUnixTimeDate(@Body long intBody); + + @Headers("Content-Type: application/json; charset=utf-8") + @GET("int/invalidunixtime") + Call getInvalidUnixTime(); + + @Headers("Content-Type: application/json; charset=utf-8") + @GET("int/nullunixtime") + Call getNullUnixTime(); + } /** @@ -553,4 +569,186 @@ private ServiceResponse putMin64Delegate(Response response) .build(response); } + /** + * Get datetime encoded as Unix time value. + * + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @return the long object wrapped in {@link ServiceResponse} if successful. + */ + public ServiceResponse getUnixTime() throws ErrorException, IOException { + Call call = service.getUnixTime(); + return getUnixTimeDelegate(call.execute()); + } + + /** + * Get datetime encoded as Unix time value. + * + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link Call} object + */ + public ServiceCall getUnixTimeAsync(final ServiceCallback serviceCallback) throws IllegalArgumentException { + if (serviceCallback == null) { + throw new IllegalArgumentException("ServiceCallback is required for async calls."); + } + Call call = service.getUnixTime(); + final ServiceCall serviceCall = new ServiceCall(call); + call.enqueue(new ServiceResponseCallback(serviceCallback) { + @Override + public void onResponse(Call call, Response response) { + try { + serviceCallback.success(getUnixTimeDelegate(response)); + } catch (ErrorException | IOException exception) { + serviceCallback.failure(exception); + } + } + }); + return serviceCall; + } + + private ServiceResponse getUnixTimeDelegate(Response response) throws ErrorException, IOException { + return new ServiceResponseBuilder(this.client.getMapperAdapter()) + .register(200, new TypeToken() { }.getType()) + .registerError(ErrorException.class) + .build(response); + } + + /** + * Put datetime encoded as Unix time. + * + * @param intBody the long value + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @return the {@link ServiceResponse} object if successful. + */ + public ServiceResponse putUnixTimeDate(long intBody) throws ErrorException, IOException { + Call call = service.putUnixTimeDate(intBody); + return putUnixTimeDateDelegate(call.execute()); + } + + /** + * Put datetime encoded as Unix time. + * + * @param intBody the long value + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link Call} object + */ + public ServiceCall putUnixTimeDateAsync(long intBody, final ServiceCallback serviceCallback) throws IllegalArgumentException { + if (serviceCallback == null) { + throw new IllegalArgumentException("ServiceCallback is required for async calls."); + } + Call call = service.putUnixTimeDate(intBody); + final ServiceCall serviceCall = new ServiceCall(call); + call.enqueue(new ServiceResponseCallback(serviceCallback) { + @Override + public void onResponse(Call call, Response response) { + try { + serviceCallback.success(putUnixTimeDateDelegate(response)); + } catch (ErrorException | IOException exception) { + serviceCallback.failure(exception); + } + } + }); + return serviceCall; + } + + private ServiceResponse putUnixTimeDateDelegate(Response response) throws ErrorException, IOException { + return new ServiceResponseBuilder(this.client.getMapperAdapter()) + .register(200, new TypeToken() { }.getType()) + .registerError(ErrorException.class) + .build(response); + } + + /** + * Get invalid Unix time value. + * + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @return the long object wrapped in {@link ServiceResponse} if successful. + */ + public ServiceResponse getInvalidUnixTime() throws ErrorException, IOException { + Call call = service.getInvalidUnixTime(); + return getInvalidUnixTimeDelegate(call.execute()); + } + + /** + * Get invalid Unix time value. + * + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link Call} object + */ + public ServiceCall getInvalidUnixTimeAsync(final ServiceCallback serviceCallback) throws IllegalArgumentException { + if (serviceCallback == null) { + throw new IllegalArgumentException("ServiceCallback is required for async calls."); + } + Call call = service.getInvalidUnixTime(); + final ServiceCall serviceCall = new ServiceCall(call); + call.enqueue(new ServiceResponseCallback(serviceCallback) { + @Override + public void onResponse(Call call, Response response) { + try { + serviceCallback.success(getInvalidUnixTimeDelegate(response)); + } catch (ErrorException | IOException exception) { + serviceCallback.failure(exception); + } + } + }); + return serviceCall; + } + + private ServiceResponse getInvalidUnixTimeDelegate(Response response) throws ErrorException, IOException { + return new ServiceResponseBuilder(this.client.getMapperAdapter()) + .register(200, new TypeToken() { }.getType()) + .registerError(ErrorException.class) + .build(response); + } + + /** + * Get null Unix time value. + * + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @return the long object wrapped in {@link ServiceResponse} if successful. + */ + public ServiceResponse getNullUnixTime() throws ErrorException, IOException { + Call call = service.getNullUnixTime(); + return getNullUnixTimeDelegate(call.execute()); + } + + /** + * Get null Unix time value. + * + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link Call} object + */ + public ServiceCall getNullUnixTimeAsync(final ServiceCallback serviceCallback) throws IllegalArgumentException { + if (serviceCallback == null) { + throw new IllegalArgumentException("ServiceCallback is required for async calls."); + } + Call call = service.getNullUnixTime(); + final ServiceCall serviceCall = new ServiceCall(call); + call.enqueue(new ServiceResponseCallback(serviceCallback) { + @Override + public void onResponse(Call call, Response response) { + try { + serviceCallback.success(getNullUnixTimeDelegate(response)); + } catch (ErrorException | IOException exception) { + serviceCallback.failure(exception); + } + } + }); + return serviceCall; + } + + private ServiceResponse getNullUnixTimeDelegate(Response response) throws ErrorException, IOException { + return new ServiceResponseBuilder(this.client.getMapperAdapter()) + .register(200, new TypeToken() { }.getType()) + .registerError(ErrorException.class) + .build(response); + } + } diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/url/PathsOperations.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/url/PathsOperations.java index f7676a65a59a3..1ccd08f952b57 100644 --- a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/url/PathsOperations.java +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/url/PathsOperations.java @@ -502,4 +502,24 @@ public interface PathsOperations { */ ServiceCall arrayCsvInPathAsync(List arrayPath, final ServiceCallback serviceCallback) throws IllegalArgumentException; + /** + * Get the date 2016-04-13 encoded value as '1460505600' (Unix time). + * + * @param unixTimeUrlPath Unix time encoded value + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @return the {@link ServiceResponse} object if successful. + */ + ServiceResponse unixTimeUrl(long unixTimeUrlPath) throws ErrorException, IOException; + + /** + * Get the date 2016-04-13 encoded value as '1460505600' (Unix time). + * + * @param unixTimeUrlPath Unix time encoded value + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link ServiceCall} object + */ + ServiceCall unixTimeUrlAsync(long unixTimeUrlPath, final ServiceCallback serviceCallback) throws IllegalArgumentException; + } diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/url/PathsOperationsImpl.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/url/PathsOperationsImpl.java index b32c2fcbd2471..31942e3ce28cb 100644 --- a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/url/PathsOperationsImpl.java +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/url/PathsOperationsImpl.java @@ -159,6 +159,10 @@ interface PathsService { @GET("paths/array/ArrayPath1%2cbegin%21%2A%27%28%29%3B%3A%40%20%26%3D%2B%24%2C%2F%3F%23%5B%5Dend%2c%2c/{arrayPath:commaSeparated}") Call arrayCsvInPath(@Path("arrayPath") String arrayPath); + @Headers("Content-Type: application/json; charset=utf-8") + @GET("paths/int/1460505600/{unixTimeUrlPath}") + Call unixTimeUrl(@Path("unixTimeUrlPath") long unixTimeUrlPath); + } /** @@ -1418,4 +1422,51 @@ private ServiceResponse arrayCsvInPathDelegate(Response resp .build(response); } + /** + * Get the date 2016-04-13 encoded value as '1460505600' (Unix time). + * + * @param unixTimeUrlPath Unix time encoded value + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @return the {@link ServiceResponse} object if successful. + */ + public ServiceResponse unixTimeUrl(long unixTimeUrlPath) throws ErrorException, IOException { + Call call = service.unixTimeUrl(unixTimeUrlPath); + return unixTimeUrlDelegate(call.execute()); + } + + /** + * Get the date 2016-04-13 encoded value as '1460505600' (Unix time). + * + * @param unixTimeUrlPath Unix time encoded value + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link Call} object + */ + public ServiceCall unixTimeUrlAsync(long unixTimeUrlPath, final ServiceCallback serviceCallback) throws IllegalArgumentException { + if (serviceCallback == null) { + throw new IllegalArgumentException("ServiceCallback is required for async calls."); + } + Call call = service.unixTimeUrl(unixTimeUrlPath); + final ServiceCall serviceCall = new ServiceCall(call); + call.enqueue(new ServiceResponseCallback(serviceCallback) { + @Override + public void onResponse(Call call, Response response) { + try { + serviceCallback.success(unixTimeUrlDelegate(response)); + } catch (ErrorException | IOException exception) { + serviceCallback.failure(exception); + } + } + }); + return serviceCall; + } + + private ServiceResponse unixTimeUrlDelegate(Response response) throws ErrorException, IOException { + return new ServiceResponseBuilder(this.client.getMapperAdapter()) + .register(200, new TypeToken() { }.getType()) + .registerError(ErrorException.class) + .build(response); + } + } diff --git a/AutoRest/Generators/Java/Java/TemplateModels/MethodTemplateModel.cs b/AutoRest/Generators/Java/Java/TemplateModels/MethodTemplateModel.cs index c9f8bc6faf9fa..7b9afbb821d68 100644 --- a/AutoRest/Generators/Java/Java/TemplateModels/MethodTemplateModel.cs +++ b/AutoRest/Generators/Java/Java/TemplateModels/MethodTemplateModel.cs @@ -363,6 +363,7 @@ public IEnumerable RequiredNullableParameters !param.Type.IsPrimaryType(KnownPrimaryType.Double) && !param.Type.IsPrimaryType(KnownPrimaryType.Boolean) && !param.Type.IsPrimaryType(KnownPrimaryType.Long) && + !param.Type.IsPrimaryType(KnownPrimaryType.UnixTime) && !param.IsConstant && param.IsRequired) { yield return param; diff --git a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/index.d.ts b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/index.d.ts index ec051455be3e0..01c453943187e 100644 --- a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/index.d.ts +++ b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/index.d.ts @@ -1908,6 +1908,52 @@ export interface LROSADs { beginPutNonRetry201Creating400(options: { product? : models.Product, customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; beginPutNonRetry201Creating400(callback: ServiceCallback): void; + /** + * Long running put request, service returns a Product with + * 'ProvisioningState' = 'Creating' and 201 response code + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.product] Product to put + * + * @param {string} [options.product.provisioningState] + * + * @param {object} [options.product.tags] + * + * @param {string} [options.product.location] Resource Location + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {ServiceCallback} [callback] callback function; see ServiceCallback + * doc in ms-rest index.d.ts for details + */ + putNonRetry201Creating400InvalidJson(options: { product? : models.Product, customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + putNonRetry201Creating400InvalidJson(callback: ServiceCallback): void; + + /** + * Long running put request, service returns a Product with + * 'ProvisioningState' = 'Creating' and 201 response code + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.product] Product to put + * + * @param {string} [options.product.provisioningState] + * + * @param {object} [options.product.tags] + * + * @param {string} [options.product.location] Resource Location + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {ServiceCallback} [callback] callback function; see ServiceCallback + * doc in ms-rest index.d.ts for details + */ + beginPutNonRetry201Creating400InvalidJson(options: { product? : models.Product, customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + beginPutNonRetry201Creating400InvalidJson(callback: ServiceCallback): void; + /** * Long running put request, service returns a 200 with * ProvisioningState=’Creating’. Poll the endpoint indicated in the diff --git a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROSADs.js b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROSADs.js index 33fff6078369c..b82dd78f09140 100644 --- a/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROSADs.js +++ b/AutoRest/Generators/NodeJS/Azure.NodeJS.Tests/Expected/AcceptanceTests/Lro/operations/lROSADs.js @@ -525,6 +525,255 @@ LROSADs.prototype.beginPutNonRetry201Creating400 = function (options, callback) }); }; +/** + * + * Long running put request, service returns a Product with + * 'ProvisioningState' = 'Creating' and 201 response code + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.product] Product to put + * + * @param {string} [options.product.provisioningState] + * + * @param {object} [options.product.tags] + * + * @param {string} [options.product.location] Resource Location + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {function} callback + * + * @returns {function} callback(err, result, request, response) + * + * {Error} err - The Error object if an error occurred, null otherwise. + * + * {object} [result] - The deserialized result object. + * See {@link Product} for more information. + * + * {object} [request] - The HTTP Request object if an error did not occur. + * + * {stream} [response] - The HTTP Response stream if an error did not occur. + */ +LROSADs.prototype.putNonRetry201Creating400InvalidJson = function (options, callback) { + var client = this.client; + if(!callback && typeof options === 'function') { + callback = options; + options = null; + } + + if (!callback) { + throw new Error('callback cannot be null.'); + } + + // Send request + this.beginPutNonRetry201Creating400InvalidJson(options, function (err, parsedResult, httpRequest, response){ + if (err) return callback(err); + + var initialResult = new msRest.HttpOperationResponse(); + initialResult.request = httpRequest; + initialResult.response = response; + initialResult.body = response.body; + client.getPutOrPatchOperationResult(initialResult, options, function (err, pollingResult) { + if (err) return callback(err); + + // Create Result + var result = null; + httpRequest = pollingResult.request; + response = pollingResult.response; + var responseBody = pollingResult.body; + if (responseBody === '') responseBody = null; + + // Deserialize Response + var parsedResponse = null; + try { + parsedResponse = JSON.parse(responseBody); + result = JSON.parse(responseBody); + if (parsedResponse !== null && parsedResponse !== undefined) { + var resultMapper = new client.models['Product']().mapper(); + result = client.deserialize(resultMapper, parsedResponse, 'result'); + } + } catch (error) { + var deserializationError = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody)); + deserializationError.request = msRest.stripRequest(httpRequest); + deserializationError.response = msRest.stripResponse(response); + return callback(deserializationError); + } + + return callback(null, result, httpRequest, response); + }); + }); +}; + +/** + * Long running put request, service returns a Product with + * 'ProvisioningState' = 'Creating' and 201 response code + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.product] Product to put + * + * @param {string} [options.product.provisioningState] + * + * @param {object} [options.product.tags] + * + * @param {string} [options.product.location] Resource Location + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {function} callback + * + * @returns {function} callback(err, result, request, response) + * + * {Error} err - The Error object if an error occurred, null otherwise. + * + * {object} [result] - The deserialized result object. + * See {@link Product} for more information. + * + * {object} [request] - The HTTP Request object if an error did not occur. + * + * {stream} [response] - The HTTP Response stream if an error did not occur. + */ +LROSADs.prototype.beginPutNonRetry201Creating400InvalidJson = function (options, callback) { + var client = this.client; + if(!callback && typeof options === 'function') { + callback = options; + options = null; + } + if (!callback) { + throw new Error('callback cannot be null.'); + } + var product = (options && options.product !== undefined) ? options.product : undefined; + // Validate + try { + if (this.client.acceptLanguage !== null && this.client.acceptLanguage !== undefined && typeof this.client.acceptLanguage.valueOf() !== 'string') { + throw new Error('this.client.acceptLanguage must be of type string.'); + } + } catch (error) { + return callback(error); + } + + // Construct URL + var requestUrl = this.client.baseUri + + '//lro/nonretryerror/put/201/creating/400/invalidjson'; + var queryParameters = []; + if (queryParameters.length > 0) { + requestUrl += '?' + queryParameters.join('&'); + } + // trim all duplicate forward slashes in the url + var regex = /([^:]\/)\/+/gi; + requestUrl = requestUrl.replace(regex, '$1'); + + // Create HTTP transport objects + var httpRequest = new WebResource(); + httpRequest.method = 'PUT'; + httpRequest.headers = {}; + httpRequest.url = requestUrl; + // Set Headers + if (this.client.generateClientRequestId) { + httpRequest.headers['x-ms-client-request-id'] = msRestAzure.generateUuid(); + } + if (this.client.acceptLanguage !== undefined && this.client.acceptLanguage !== null) { + httpRequest.headers['accept-language'] = this.client.acceptLanguage; + } + if(options) { + for(var headerName in options['customHeaders']) { + if (options['customHeaders'].hasOwnProperty(headerName)) { + httpRequest.headers[headerName] = options['customHeaders'][headerName]; + } + } + } + httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8'; + // Serialize Request + var requestContent = null; + var requestModel = null; + try { + if (product !== null && product !== undefined) { + var requestModelMapper = new client.models['Product']().mapper(); + requestModel = client.serialize(requestModelMapper, product, 'product'); + requestContent = JSON.stringify(requestModel); + } + } catch (error) { + var serializationError = new Error(util.format('Error "%s" occurred in serializing the ' + + 'payload - "%s"', error.message, util.inspect(product, {depth: null}))); + return callback(serializationError); + } + httpRequest.body = requestContent; + // Send Request + return client.pipeline(httpRequest, function (err, response, responseBody) { + if (err) { + return callback(err); + } + var statusCode = response.statusCode; + if (statusCode !== 200 && statusCode !== 201) { + var error = new Error(responseBody); + error.statusCode = response.statusCode; + error.request = msRest.stripRequest(httpRequest); + error.response = msRest.stripResponse(response); + if (responseBody === '') responseBody = null; + var parsedErrorResponse; + try { + parsedErrorResponse = JSON.parse(responseBody); + if (parsedErrorResponse) { + if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error; + if (parsedErrorResponse.code) error.code = parsedErrorResponse.code; + if (parsedErrorResponse.message) error.message = parsedErrorResponse.message; + } + if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) { + var resultMapper = new client.models['CloudError']().mapper(); + error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body'); + } + } catch (defaultError) { + error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + + '- "%s" for the default response.', defaultError.message, responseBody); + return callback(error); + } + return callback(error); + } + // Create Result + var result = null; + if (responseBody === '') responseBody = null; + // Deserialize Response + if (statusCode === 200) { + var parsedResponse = null; + try { + parsedResponse = JSON.parse(responseBody); + result = JSON.parse(responseBody); + if (parsedResponse !== null && parsedResponse !== undefined) { + var resultMapper = new client.models['Product']().mapper(); + result = client.deserialize(resultMapper, parsedResponse, 'result'); + } + } catch (error) { + var deserializationError = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody)); + deserializationError.request = msRest.stripRequest(httpRequest); + deserializationError.response = msRest.stripResponse(response); + return callback(deserializationError); + } + } + // Deserialize Response + if (statusCode === 201) { + var parsedResponse = null; + try { + parsedResponse = JSON.parse(responseBody); + result = JSON.parse(responseBody); + if (parsedResponse !== null && parsedResponse !== undefined) { + var resultMapper = new client.models['Product']().mapper(); + result = client.deserialize(resultMapper, parsedResponse, 'result'); + } + } catch (error) { + var deserializationError1 = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody)); + deserializationError1.request = msRest.stripRequest(httpRequest); + deserializationError1.response = msRest.stripResponse(response); + return callback(deserializationError1); + } + } + + return callback(null, result, httpRequest, response); + }); +}; + /** * * Long running put request, service returns a 200 with diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/index.d.ts b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/index.d.ts index 26ce14eb339ea..1b00b43d81429 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/index.d.ts +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/index.d.ts @@ -167,4 +167,62 @@ export interface IntModel { */ putMin64(intBody: number, options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; putMin64(intBody: number, callback: ServiceCallback): void; + + /** + * Get datetime encoded as Unix time value + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {ServiceCallback} [callback] callback function; see ServiceCallback + * doc in ms-rest index.d.ts for details + */ + getUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + getUnixTime(callback: ServiceCallback): void; + + /** + * Put datetime encoded as Unix time + * + * @param {number} intBody + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {ServiceCallback} [callback] callback function; see ServiceCallback + * doc in ms-rest index.d.ts for details + */ + putUnixTimeDate(intBody: number, options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + putUnixTimeDate(intBody: number, callback: ServiceCallback): void; + + /** + * Get invalid Unix time value + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {ServiceCallback} [callback] callback function; see ServiceCallback + * doc in ms-rest index.d.ts for details + */ + getInvalidUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + getInvalidUnixTime(callback: ServiceCallback): void; + + /** + * Get null Unix time value + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {ServiceCallback} [callback] callback function; see ServiceCallback + * doc in ms-rest index.d.ts for details + */ + getNullUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + getNullUnixTime(callback: ServiceCallback): void; } diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/intModel.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/intModel.js index 81595128f8a57..b1ed3fbf470cf 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/intModel.js +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/intModel.js @@ -1196,5 +1196,468 @@ IntModel.prototype.putMin64 = function (intBody, options, callback) { }); }; +/** + * Get datetime encoded as Unix time value + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {function} callback + * + * @returns {function} callback(err, result, request, response) + * + * {Error} err - The Error object if an error occurred, null otherwise. + * + * {number} [result] - The deserialized result object. + * + * {object} [request] - The HTTP Request object if an error did not occur. + * + * {stream} [response] - The HTTP Response stream if an error did not occur. + */ +IntModel.prototype.getUnixTime = function (options, callback) { + var client = this.client; + if(!callback && typeof options === 'function') { + callback = options; + options = null; + } + if (!callback) { + throw new Error('callback cannot be null.'); + } + + // Construct URL + var requestUrl = this.client.baseUri + + '//int/unixtime'; + // trim all duplicate forward slashes in the url + var regex = /([^:]\/)\/+/gi; + requestUrl = requestUrl.replace(regex, '$1'); + + // Create HTTP transport objects + var httpRequest = new WebResource(); + httpRequest.method = 'GET'; + httpRequest.headers = {}; + httpRequest.url = requestUrl; + // Set Headers + if(options) { + for(var headerName in options['customHeaders']) { + if (options['customHeaders'].hasOwnProperty(headerName)) { + httpRequest.headers[headerName] = options['customHeaders'][headerName]; + } + } + } + httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8'; + httpRequest.body = null; + // Send Request + return client.pipeline(httpRequest, function (err, response, responseBody) { + if (err) { + return callback(err); + } + var statusCode = response.statusCode; + if (statusCode !== 200) { + var error = new Error(responseBody); + error.statusCode = response.statusCode; + error.request = msRest.stripRequest(httpRequest); + error.response = msRest.stripResponse(response); + if (responseBody === '') responseBody = null; + var parsedErrorResponse; + try { + parsedErrorResponse = JSON.parse(responseBody); + if (parsedErrorResponse) { + if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error; + if (parsedErrorResponse.code) error.code = parsedErrorResponse.code; + if (parsedErrorResponse.message) error.message = parsedErrorResponse.message; + } + if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) { + var resultMapper = new client.models['ErrorModel']().mapper(); + error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body'); + } + } catch (defaultError) { + error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + + '- "%s" for the default response.', defaultError.message, responseBody); + return callback(error); + } + return callback(error); + } + // Create Result + var result = null; + if (responseBody === '') responseBody = null; + // Deserialize Response + if (statusCode === 200) { + var parsedResponse = null; + try { + parsedResponse = JSON.parse(responseBody); + result = JSON.parse(responseBody); + if (parsedResponse !== null && parsedResponse !== undefined) { + var resultMapper = { + required: false, + serializedName: 'parsedResponse', + type: { + name: 'Number' + } + }; + result = client.deserialize(resultMapper, parsedResponse, 'result'); + } + } catch (error) { + var deserializationError = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody)); + deserializationError.request = msRest.stripRequest(httpRequest); + deserializationError.response = msRest.stripResponse(response); + return callback(deserializationError); + } + } + + return callback(null, result, httpRequest, response); + }); +}; + +/** + * Put datetime encoded as Unix time + * + * @param {number} intBody + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {function} callback + * + * @returns {function} callback(err, result, request, response) + * + * {Error} err - The Error object if an error occurred, null otherwise. + * + * {null} [result] - The deserialized result object. + * + * {object} [request] - The HTTP Request object if an error did not occur. + * + * {stream} [response] - The HTTP Response stream if an error did not occur. + */ +IntModel.prototype.putUnixTimeDate = function (intBody, options, callback) { + var client = this.client; + if(!callback && typeof options === 'function') { + callback = options; + options = null; + } + if (!callback) { + throw new Error('callback cannot be null.'); + } + // Validate + try { + if (intBody === null || intBody === undefined || typeof intBody !== 'number') { + throw new Error('intBody cannot be null or undefined and it must be of type number.'); + } + } catch (error) { + return callback(error); + } + + // Construct URL + var requestUrl = this.client.baseUri + + '//int/unixtime'; + // trim all duplicate forward slashes in the url + var regex = /([^:]\/)\/+/gi; + requestUrl = requestUrl.replace(regex, '$1'); + + // Create HTTP transport objects + var httpRequest = new WebResource(); + httpRequest.method = 'PUT'; + httpRequest.headers = {}; + httpRequest.url = requestUrl; + // Set Headers + if(options) { + for(var headerName in options['customHeaders']) { + if (options['customHeaders'].hasOwnProperty(headerName)) { + httpRequest.headers[headerName] = options['customHeaders'][headerName]; + } + } + } + httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8'; + // Serialize Request + var requestContent = null; + var requestModel = null; + try { + if (intBody !== null && intBody !== undefined) { + var requestModelMapper = { + required: true, + serializedName: 'intBody', + type: { + name: 'Number' + } + }; + requestModel = client.serialize(requestModelMapper, intBody, 'intBody'); + requestContent = JSON.stringify(requestModel); + } + } catch (error) { + var serializationError = new Error(util.format('Error "%s" occurred in serializing the ' + + 'payload - "%s"', error.message, util.inspect(intBody, {depth: null}))); + return callback(serializationError); + } + httpRequest.body = requestContent; + // Send Request + return client.pipeline(httpRequest, function (err, response, responseBody) { + if (err) { + return callback(err); + } + var statusCode = response.statusCode; + if (statusCode !== 200) { + var error = new Error(responseBody); + error.statusCode = response.statusCode; + error.request = msRest.stripRequest(httpRequest); + error.response = msRest.stripResponse(response); + if (responseBody === '') responseBody = null; + var parsedErrorResponse; + try { + parsedErrorResponse = JSON.parse(responseBody); + if (parsedErrorResponse) { + if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error; + if (parsedErrorResponse.code) error.code = parsedErrorResponse.code; + if (parsedErrorResponse.message) error.message = parsedErrorResponse.message; + } + if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) { + var resultMapper = new client.models['ErrorModel']().mapper(); + error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body'); + } + } catch (defaultError) { + error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + + '- "%s" for the default response.', defaultError.message, responseBody); + return callback(error); + } + return callback(error); + } + // Create Result + var result = null; + if (responseBody === '') responseBody = null; + + return callback(null, result, httpRequest, response); + }); +}; + +/** + * Get invalid Unix time value + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {function} callback + * + * @returns {function} callback(err, result, request, response) + * + * {Error} err - The Error object if an error occurred, null otherwise. + * + * {number} [result] - The deserialized result object. + * + * {object} [request] - The HTTP Request object if an error did not occur. + * + * {stream} [response] - The HTTP Response stream if an error did not occur. + */ +IntModel.prototype.getInvalidUnixTime = function (options, callback) { + var client = this.client; + if(!callback && typeof options === 'function') { + callback = options; + options = null; + } + if (!callback) { + throw new Error('callback cannot be null.'); + } + + // Construct URL + var requestUrl = this.client.baseUri + + '//int/invalidunixtime'; + // trim all duplicate forward slashes in the url + var regex = /([^:]\/)\/+/gi; + requestUrl = requestUrl.replace(regex, '$1'); + + // Create HTTP transport objects + var httpRequest = new WebResource(); + httpRequest.method = 'GET'; + httpRequest.headers = {}; + httpRequest.url = requestUrl; + // Set Headers + if(options) { + for(var headerName in options['customHeaders']) { + if (options['customHeaders'].hasOwnProperty(headerName)) { + httpRequest.headers[headerName] = options['customHeaders'][headerName]; + } + } + } + httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8'; + httpRequest.body = null; + // Send Request + return client.pipeline(httpRequest, function (err, response, responseBody) { + if (err) { + return callback(err); + } + var statusCode = response.statusCode; + if (statusCode !== 200) { + var error = new Error(responseBody); + error.statusCode = response.statusCode; + error.request = msRest.stripRequest(httpRequest); + error.response = msRest.stripResponse(response); + if (responseBody === '') responseBody = null; + var parsedErrorResponse; + try { + parsedErrorResponse = JSON.parse(responseBody); + if (parsedErrorResponse) { + if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error; + if (parsedErrorResponse.code) error.code = parsedErrorResponse.code; + if (parsedErrorResponse.message) error.message = parsedErrorResponse.message; + } + if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) { + var resultMapper = new client.models['ErrorModel']().mapper(); + error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body'); + } + } catch (defaultError) { + error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + + '- "%s" for the default response.', defaultError.message, responseBody); + return callback(error); + } + return callback(error); + } + // Create Result + var result = null; + if (responseBody === '') responseBody = null; + // Deserialize Response + if (statusCode === 200) { + var parsedResponse = null; + try { + parsedResponse = JSON.parse(responseBody); + result = JSON.parse(responseBody); + if (parsedResponse !== null && parsedResponse !== undefined) { + var resultMapper = { + required: false, + serializedName: 'parsedResponse', + type: { + name: 'Number' + } + }; + result = client.deserialize(resultMapper, parsedResponse, 'result'); + } + } catch (error) { + var deserializationError = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody)); + deserializationError.request = msRest.stripRequest(httpRequest); + deserializationError.response = msRest.stripResponse(response); + return callback(deserializationError); + } + } + + return callback(null, result, httpRequest, response); + }); +}; + +/** + * Get null Unix time value + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {function} callback + * + * @returns {function} callback(err, result, request, response) + * + * {Error} err - The Error object if an error occurred, null otherwise. + * + * {number} [result] - The deserialized result object. + * + * {object} [request] - The HTTP Request object if an error did not occur. + * + * {stream} [response] - The HTTP Response stream if an error did not occur. + */ +IntModel.prototype.getNullUnixTime = function (options, callback) { + var client = this.client; + if(!callback && typeof options === 'function') { + callback = options; + options = null; + } + if (!callback) { + throw new Error('callback cannot be null.'); + } + + // Construct URL + var requestUrl = this.client.baseUri + + '//int/nullunixtime'; + // trim all duplicate forward slashes in the url + var regex = /([^:]\/)\/+/gi; + requestUrl = requestUrl.replace(regex, '$1'); + + // Create HTTP transport objects + var httpRequest = new WebResource(); + httpRequest.method = 'GET'; + httpRequest.headers = {}; + httpRequest.url = requestUrl; + // Set Headers + if(options) { + for(var headerName in options['customHeaders']) { + if (options['customHeaders'].hasOwnProperty(headerName)) { + httpRequest.headers[headerName] = options['customHeaders'][headerName]; + } + } + } + httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8'; + httpRequest.body = null; + // Send Request + return client.pipeline(httpRequest, function (err, response, responseBody) { + if (err) { + return callback(err); + } + var statusCode = response.statusCode; + if (statusCode !== 200) { + var error = new Error(responseBody); + error.statusCode = response.statusCode; + error.request = msRest.stripRequest(httpRequest); + error.response = msRest.stripResponse(response); + if (responseBody === '') responseBody = null; + var parsedErrorResponse; + try { + parsedErrorResponse = JSON.parse(responseBody); + if (parsedErrorResponse) { + if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error; + if (parsedErrorResponse.code) error.code = parsedErrorResponse.code; + if (parsedErrorResponse.message) error.message = parsedErrorResponse.message; + } + if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) { + var resultMapper = new client.models['ErrorModel']().mapper(); + error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body'); + } + } catch (defaultError) { + error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + + '- "%s" for the default response.', defaultError.message, responseBody); + return callback(error); + } + return callback(error); + } + // Create Result + var result = null; + if (responseBody === '') responseBody = null; + // Deserialize Response + if (statusCode === 200) { + var parsedResponse = null; + try { + parsedResponse = JSON.parse(responseBody); + result = JSON.parse(responseBody); + if (parsedResponse !== null && parsedResponse !== undefined) { + var resultMapper = { + required: false, + serializedName: 'parsedResponse', + type: { + name: 'Number' + } + }; + result = client.deserialize(resultMapper, parsedResponse, 'result'); + } + } catch (error) { + var deserializationError = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody)); + deserializationError.request = msRest.stripRequest(httpRequest); + deserializationError.response = msRest.stripResponse(response); + return callback(deserializationError); + } + } + + return callback(null, result, httpRequest, response); + }); +}; + module.exports = IntModel; diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/index.d.ts b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/index.d.ts index 8238ac41b5170..ac60442293ccf 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/index.d.ts +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/index.d.ts @@ -264,4 +264,62 @@ export interface IntModel { */ putMin64(intBody: number, options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; putMin64(intBody: number, callback: ServiceCallback): void; + + /** + * Get datetime encoded as Unix time value + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {ServiceCallback} [callback] callback function; see ServiceCallback + * doc in ms-rest index.d.ts for details + */ + getUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + getUnixTime(callback: ServiceCallback): void; + + /** + * Put datetime encoded as Unix time + * + * @param {number} intBody + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {ServiceCallback} [callback] callback function; see ServiceCallback + * doc in ms-rest index.d.ts for details + */ + putUnixTimeDate(intBody: number, options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + putUnixTimeDate(intBody: number, callback: ServiceCallback): void; + + /** + * Get invalid Unix time value + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {ServiceCallback} [callback] callback function; see ServiceCallback + * doc in ms-rest index.d.ts for details + */ + getInvalidUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + getInvalidUnixTime(callback: ServiceCallback): void; + + /** + * Get null Unix time value + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {ServiceCallback} [callback] callback function; see ServiceCallback + * doc in ms-rest index.d.ts for details + */ + getNullUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + getNullUnixTime(callback: ServiceCallback): void; } diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/intModel.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/intModel.js index e7c05cfad0073..42f1d72ab3f7f 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/intModel.js +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/intModel.js @@ -1196,5 +1196,468 @@ IntModel.prototype.putMin64 = function (intBody, options, callback) { }); }; +/** + * Get datetime encoded as Unix time value + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {function} callback + * + * @returns {function} callback(err, result, request, response) + * + * {Error} err - The Error object if an error occurred, null otherwise. + * + * {number} [result] - The deserialized result object. + * + * {object} [request] - The HTTP Request object if an error did not occur. + * + * {stream} [response] - The HTTP Response stream if an error did not occur. + */ +IntModel.prototype.getUnixTime = function (options, callback) { + var client = this.client; + if(!callback && typeof options === 'function') { + callback = options; + options = null; + } + if (!callback) { + throw new Error('callback cannot be null.'); + } + + // Construct URL + var requestUrl = this.client.baseUri + + '//int/unixtime'; + // trim all duplicate forward slashes in the url + var regex = /([^:]\/)\/+/gi; + requestUrl = requestUrl.replace(regex, '$1'); + + // Create HTTP transport objects + var httpRequest = new WebResource(); + httpRequest.method = 'GET'; + httpRequest.headers = {}; + httpRequest.url = requestUrl; + // Set Headers + if(options) { + for(var headerName in options['customHeaders']) { + if (options['customHeaders'].hasOwnProperty(headerName)) { + httpRequest.headers[headerName] = options['customHeaders'][headerName]; + } + } + } + httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8'; + httpRequest.body = null; + // Send Request + return client.pipeline(httpRequest, function (err, response, responseBody) { + if (err) { + return callback(err); + } + var statusCode = response.statusCode; + if (statusCode !== 200) { + var error = new Error(responseBody); + error.statusCode = response.statusCode; + error.request = msRest.stripRequest(httpRequest); + error.response = msRest.stripResponse(response); + if (responseBody === '') responseBody = null; + var parsedErrorResponse; + try { + parsedErrorResponse = JSON.parse(responseBody); + if (parsedErrorResponse) { + if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error; + if (parsedErrorResponse.code) error.code = parsedErrorResponse.code; + if (parsedErrorResponse.message) error.message = parsedErrorResponse.message; + } + if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) { + var resultMapper = new client.models['ErrorModel']().mapper(); + error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body'); + } + } catch (defaultError) { + error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + + '- "%s" for the default response.', defaultError.message, responseBody); + return callback(error); + } + return callback(error); + } + // Create Result + var result = null; + if (responseBody === '') responseBody = null; + // Deserialize Response + if (statusCode === 200) { + var parsedResponse = null; + try { + parsedResponse = JSON.parse(responseBody); + result = JSON.parse(responseBody); + if (parsedResponse !== null && parsedResponse !== undefined) { + var resultMapper = { + required: false, + serializedName: 'parsedResponse', + type: { + name: 'Number' + } + }; + result = client.deserialize(resultMapper, parsedResponse, 'result'); + } + } catch (error) { + var deserializationError = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody)); + deserializationError.request = msRest.stripRequest(httpRequest); + deserializationError.response = msRest.stripResponse(response); + return callback(deserializationError); + } + } + + return callback(null, result, httpRequest, response); + }); +}; + +/** + * Put datetime encoded as Unix time + * + * @param {number} intBody + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {function} callback + * + * @returns {function} callback(err, result, request, response) + * + * {Error} err - The Error object if an error occurred, null otherwise. + * + * {null} [result] - The deserialized result object. + * + * {object} [request] - The HTTP Request object if an error did not occur. + * + * {stream} [response] - The HTTP Response stream if an error did not occur. + */ +IntModel.prototype.putUnixTimeDate = function (intBody, options, callback) { + var client = this.client; + if(!callback && typeof options === 'function') { + callback = options; + options = null; + } + if (!callback) { + throw new Error('callback cannot be null.'); + } + // Validate + try { + if (intBody === null || intBody === undefined || typeof intBody !== 'number') { + throw new Error('intBody cannot be null or undefined and it must be of type number.'); + } + } catch (error) { + return callback(error); + } + + // Construct URL + var requestUrl = this.client.baseUri + + '//int/unixtime'; + // trim all duplicate forward slashes in the url + var regex = /([^:]\/)\/+/gi; + requestUrl = requestUrl.replace(regex, '$1'); + + // Create HTTP transport objects + var httpRequest = new WebResource(); + httpRequest.method = 'PUT'; + httpRequest.headers = {}; + httpRequest.url = requestUrl; + // Set Headers + if(options) { + for(var headerName in options['customHeaders']) { + if (options['customHeaders'].hasOwnProperty(headerName)) { + httpRequest.headers[headerName] = options['customHeaders'][headerName]; + } + } + } + httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8'; + // Serialize Request + var requestContent = null; + var requestModel = null; + try { + if (intBody !== null && intBody !== undefined) { + var requestModelMapper = { + required: true, + serializedName: 'intBody', + type: { + name: 'Number' + } + }; + requestModel = client.serialize(requestModelMapper, intBody, 'intBody'); + requestContent = JSON.stringify(requestModel); + } + } catch (error) { + var serializationError = new Error(util.format('Error "%s" occurred in serializing the ' + + 'payload - "%s"', error.message, util.inspect(intBody, {depth: null}))); + return callback(serializationError); + } + httpRequest.body = requestContent; + // Send Request + return client.pipeline(httpRequest, function (err, response, responseBody) { + if (err) { + return callback(err); + } + var statusCode = response.statusCode; + if (statusCode !== 200) { + var error = new Error(responseBody); + error.statusCode = response.statusCode; + error.request = msRest.stripRequest(httpRequest); + error.response = msRest.stripResponse(response); + if (responseBody === '') responseBody = null; + var parsedErrorResponse; + try { + parsedErrorResponse = JSON.parse(responseBody); + if (parsedErrorResponse) { + if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error; + if (parsedErrorResponse.code) error.code = parsedErrorResponse.code; + if (parsedErrorResponse.message) error.message = parsedErrorResponse.message; + } + if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) { + var resultMapper = new client.models['ErrorModel']().mapper(); + error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body'); + } + } catch (defaultError) { + error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + + '- "%s" for the default response.', defaultError.message, responseBody); + return callback(error); + } + return callback(error); + } + // Create Result + var result = null; + if (responseBody === '') responseBody = null; + + return callback(null, result, httpRequest, response); + }); +}; + +/** + * Get invalid Unix time value + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {function} callback + * + * @returns {function} callback(err, result, request, response) + * + * {Error} err - The Error object if an error occurred, null otherwise. + * + * {number} [result] - The deserialized result object. + * + * {object} [request] - The HTTP Request object if an error did not occur. + * + * {stream} [response] - The HTTP Response stream if an error did not occur. + */ +IntModel.prototype.getInvalidUnixTime = function (options, callback) { + var client = this.client; + if(!callback && typeof options === 'function') { + callback = options; + options = null; + } + if (!callback) { + throw new Error('callback cannot be null.'); + } + + // Construct URL + var requestUrl = this.client.baseUri + + '//int/invalidunixtime'; + // trim all duplicate forward slashes in the url + var regex = /([^:]\/)\/+/gi; + requestUrl = requestUrl.replace(regex, '$1'); + + // Create HTTP transport objects + var httpRequest = new WebResource(); + httpRequest.method = 'GET'; + httpRequest.headers = {}; + httpRequest.url = requestUrl; + // Set Headers + if(options) { + for(var headerName in options['customHeaders']) { + if (options['customHeaders'].hasOwnProperty(headerName)) { + httpRequest.headers[headerName] = options['customHeaders'][headerName]; + } + } + } + httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8'; + httpRequest.body = null; + // Send Request + return client.pipeline(httpRequest, function (err, response, responseBody) { + if (err) { + return callback(err); + } + var statusCode = response.statusCode; + if (statusCode !== 200) { + var error = new Error(responseBody); + error.statusCode = response.statusCode; + error.request = msRest.stripRequest(httpRequest); + error.response = msRest.stripResponse(response); + if (responseBody === '') responseBody = null; + var parsedErrorResponse; + try { + parsedErrorResponse = JSON.parse(responseBody); + if (parsedErrorResponse) { + if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error; + if (parsedErrorResponse.code) error.code = parsedErrorResponse.code; + if (parsedErrorResponse.message) error.message = parsedErrorResponse.message; + } + if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) { + var resultMapper = new client.models['ErrorModel']().mapper(); + error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body'); + } + } catch (defaultError) { + error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + + '- "%s" for the default response.', defaultError.message, responseBody); + return callback(error); + } + return callback(error); + } + // Create Result + var result = null; + if (responseBody === '') responseBody = null; + // Deserialize Response + if (statusCode === 200) { + var parsedResponse = null; + try { + parsedResponse = JSON.parse(responseBody); + result = JSON.parse(responseBody); + if (parsedResponse !== null && parsedResponse !== undefined) { + var resultMapper = { + required: false, + serializedName: 'parsedResponse', + type: { + name: 'Number' + } + }; + result = client.deserialize(resultMapper, parsedResponse, 'result'); + } + } catch (error) { + var deserializationError = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody)); + deserializationError.request = msRest.stripRequest(httpRequest); + deserializationError.response = msRest.stripResponse(response); + return callback(deserializationError); + } + } + + return callback(null, result, httpRequest, response); + }); +}; + +/** + * Get null Unix time value + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {function} callback + * + * @returns {function} callback(err, result, request, response) + * + * {Error} err - The Error object if an error occurred, null otherwise. + * + * {number} [result] - The deserialized result object. + * + * {object} [request] - The HTTP Request object if an error did not occur. + * + * {stream} [response] - The HTTP Response stream if an error did not occur. + */ +IntModel.prototype.getNullUnixTime = function (options, callback) { + var client = this.client; + if(!callback && typeof options === 'function') { + callback = options; + options = null; + } + if (!callback) { + throw new Error('callback cannot be null.'); + } + + // Construct URL + var requestUrl = this.client.baseUri + + '//int/nullunixtime'; + // trim all duplicate forward slashes in the url + var regex = /([^:]\/)\/+/gi; + requestUrl = requestUrl.replace(regex, '$1'); + + // Create HTTP transport objects + var httpRequest = new WebResource(); + httpRequest.method = 'GET'; + httpRequest.headers = {}; + httpRequest.url = requestUrl; + // Set Headers + if(options) { + for(var headerName in options['customHeaders']) { + if (options['customHeaders'].hasOwnProperty(headerName)) { + httpRequest.headers[headerName] = options['customHeaders'][headerName]; + } + } + } + httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8'; + httpRequest.body = null; + // Send Request + return client.pipeline(httpRequest, function (err, response, responseBody) { + if (err) { + return callback(err); + } + var statusCode = response.statusCode; + if (statusCode !== 200) { + var error = new Error(responseBody); + error.statusCode = response.statusCode; + error.request = msRest.stripRequest(httpRequest); + error.response = msRest.stripResponse(response); + if (responseBody === '') responseBody = null; + var parsedErrorResponse; + try { + parsedErrorResponse = JSON.parse(responseBody); + if (parsedErrorResponse) { + if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error; + if (parsedErrorResponse.code) error.code = parsedErrorResponse.code; + if (parsedErrorResponse.message) error.message = parsedErrorResponse.message; + } + if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) { + var resultMapper = new client.models['ErrorModel']().mapper(); + error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body'); + } + } catch (defaultError) { + error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + + '- "%s" for the default response.', defaultError.message, responseBody); + return callback(error); + } + return callback(error); + } + // Create Result + var result = null; + if (responseBody === '') responseBody = null; + // Deserialize Response + if (statusCode === 200) { + var parsedResponse = null; + try { + parsedResponse = JSON.parse(responseBody); + result = JSON.parse(responseBody); + if (parsedResponse !== null && parsedResponse !== undefined) { + var resultMapper = { + required: false, + serializedName: 'parsedResponse', + type: { + name: 'Number' + } + }; + result = client.deserialize(resultMapper, parsedResponse, 'result'); + } + } catch (error) { + var deserializationError = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody)); + deserializationError.request = msRest.stripRequest(httpRequest); + deserializationError.response = msRest.stripResponse(response); + return callback(deserializationError); + } + } + + return callback(null, result, httpRequest, response); + }); +}; + module.exports = IntModel; diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/ModelFlattening/models/simpleProduct.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/ModelFlattening/models/simpleProduct.js index 3e66a747ff5a0..cca28edbd8eda 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/ModelFlattening/models/simpleProduct.js +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/ModelFlattening/models/simpleProduct.js @@ -42,7 +42,6 @@ SimpleProduct.prototype.mapper = function () { return { required: false, serializedName: 'SimpleProduct', - defaultValue: {}, type: { name: 'Composite', className: 'SimpleProduct', diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/index.d.ts b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/index.d.ts index 3d9f5f55e7f91..3f5e24643883c 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/index.d.ts +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/index.d.ts @@ -394,6 +394,22 @@ export interface Paths { */ arrayCsvInPath(arrayPath: string[], options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; arrayCsvInPath(arrayPath: string[], callback: ServiceCallback): void; + + /** + * Get the date 2016-04-13 encoded value as '1460505600' (Unix time) + * + * @param {number} unixTimeUrlPath Unix time encoded value + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {ServiceCallback} [callback] callback function; see ServiceCallback + * doc in ms-rest index.d.ts for details + */ + unixTimeUrl(unixTimeUrlPath: number, options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + unixTimeUrl(unixTimeUrlPath: number, callback: ServiceCallback): void; } /** diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/paths.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/paths.js index ac14e44e195cb..4039b0ce9664a 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/paths.js +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/paths.js @@ -2458,5 +2458,107 @@ Paths.prototype.arrayCsvInPath = function (arrayPath, options, callback) { }); }; +/** + * Get the date 2016-04-13 encoded value as '1460505600' (Unix time) + * + * @param {number} unixTimeUrlPath Unix time encoded value + * + * @param {object} [options] Optional Parameters. + * + * @param {object} [options.customHeaders] Headers that will be added to the + * request + * + * @param {function} callback + * + * @returns {function} callback(err, result, request, response) + * + * {Error} err - The Error object if an error occurred, null otherwise. + * + * {null} [result] - The deserialized result object. + * + * {object} [request] - The HTTP Request object if an error did not occur. + * + * {stream} [response] - The HTTP Response stream if an error did not occur. + */ +Paths.prototype.unixTimeUrl = function (unixTimeUrlPath, options, callback) { + var client = this.client; + if(!callback && typeof options === 'function') { + callback = options; + options = null; + } + if (!callback) { + throw new Error('callback cannot be null.'); + } + // Validate + try { + if (unixTimeUrlPath === null || unixTimeUrlPath === undefined || typeof unixTimeUrlPath !== 'number') { + throw new Error('unixTimeUrlPath cannot be null or undefined and it must be of type number.'); + } + } catch (error) { + return callback(error); + } + + // Construct URL + var requestUrl = this.client.baseUri + + '//paths/int/1460505600/{unixTimeUrlPath}'; + requestUrl = requestUrl.replace('{unixTimeUrlPath}', encodeURIComponent(unixTimeUrlPath.toString())); + // trim all duplicate forward slashes in the url + var regex = /([^:]\/)\/+/gi; + requestUrl = requestUrl.replace(regex, '$1'); + + // Create HTTP transport objects + var httpRequest = new WebResource(); + httpRequest.method = 'GET'; + httpRequest.headers = {}; + httpRequest.url = requestUrl; + // Set Headers + if(options) { + for(var headerName in options['customHeaders']) { + if (options['customHeaders'].hasOwnProperty(headerName)) { + httpRequest.headers[headerName] = options['customHeaders'][headerName]; + } + } + } + httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8'; + httpRequest.body = null; + // Send Request + return client.pipeline(httpRequest, function (err, response, responseBody) { + if (err) { + return callback(err); + } + var statusCode = response.statusCode; + if (statusCode !== 200) { + var error = new Error(responseBody); + error.statusCode = response.statusCode; + error.request = msRest.stripRequest(httpRequest); + error.response = msRest.stripResponse(response); + if (responseBody === '') responseBody = null; + var parsedErrorResponse; + try { + parsedErrorResponse = JSON.parse(responseBody); + if (parsedErrorResponse) { + if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error; + if (parsedErrorResponse.code) error.code = parsedErrorResponse.code; + if (parsedErrorResponse.message) error.message = parsedErrorResponse.message; + } + if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) { + var resultMapper = new client.models['ErrorModel']().mapper(); + error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body'); + } + } catch (defaultError) { + error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + + '- "%s" for the default response.', defaultError.message, responseBody); + return callback(error); + } + return callback(error); + } + // Create Result + var result = null; + if (responseBody === '') responseBody = null; + + return callback(null, result, httpRequest, response); + }); +}; + module.exports = Paths; diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Validation/models/childProduct.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Validation/models/childProduct.js index 212a2c646ec44..14cb8cf926118 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Validation/models/childProduct.js +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Validation/models/childProduct.js @@ -31,7 +31,6 @@ ChildProduct.prototype.mapper = function () { return { required: false, serializedName: 'ChildProduct', - defaultValue: {}, type: { name: 'Composite', className: 'ChildProduct', diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Validation/models/constantProduct.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Validation/models/constantProduct.js index e79e409278475..cd97a2c9285e5 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Validation/models/constantProduct.js +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Validation/models/constantProduct.js @@ -29,7 +29,6 @@ ConstantProduct.prototype.mapper = function () { return { required: false, serializedName: 'ConstantProduct', - defaultValue: {}, type: { name: 'Composite', className: 'ConstantProduct', diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Validation/models/product.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Validation/models/product.js index 6af3595ad51bb..ee09ede6f6cac 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Validation/models/product.js +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Validation/models/product.js @@ -47,7 +47,6 @@ Product.prototype.mapper = function () { return { required: false, serializedName: 'Product', - defaultValue: {}, type: { name: 'Composite', className: 'Product', diff --git a/AutoRest/Generators/NodeJS/NodeJS/ClientModelExtensions.cs b/AutoRest/Generators/NodeJS/NodeJS/ClientModelExtensions.cs index c842b28b3280b..8f36adeec8742 100644 --- a/AutoRest/Generators/NodeJS/NodeJS/ClientModelExtensions.cs +++ b/AutoRest/Generators/NodeJS/NodeJS/ClientModelExtensions.cs @@ -195,7 +195,8 @@ private static string ValidatePrimaryType(this PrimaryType primary, IScopeProvid primary.Type == KnownPrimaryType.Decimal || primary.Type == KnownPrimaryType.Int || primary.Type == KnownPrimaryType.Long || - primary.Type == KnownPrimaryType.Object) + primary.Type == KnownPrimaryType.Object || + primary.Type == KnownPrimaryType.UnixTime) { if (isRequired) { @@ -302,7 +303,7 @@ private static string PrimaryTSType(this PrimaryType primary) if (primary.Type == KnownPrimaryType.Boolean) return "boolean"; - else if (primary.Type == KnownPrimaryType.Double || primary.Type == KnownPrimaryType.Decimal || primary.Type == KnownPrimaryType.Int || primary.Type == KnownPrimaryType.Long) + else if (primary.Type == KnownPrimaryType.Double || primary.Type == KnownPrimaryType.Decimal || primary.Type == KnownPrimaryType.Int || primary.Type == KnownPrimaryType.Long || primary.Type == KnownPrimaryType.UnixTime) return "number"; else if (primary.Type == KnownPrimaryType.String || primary.Type == KnownPrimaryType.Uuid) return "string"; @@ -666,9 +667,9 @@ public static IndentedStringBuilder AppendConstraintValidations(this IType type, public static string ConstructMapper(this IType type, string serializedName, IParameter parameter, bool isPageable, bool expandComposite) { var builder = new IndentedStringBuilder(" "); - string defaultValue = null; - bool isRequired = false; - bool isConstant = false; + string defaultValue = null; + bool isRequired = false; + bool isConstant = false; bool isReadOnly = false; Dictionary constraints = null; var property = parameter as Property; @@ -684,7 +685,7 @@ public static string ConstructMapper(this IType type, string serializedName, IPa isReadOnly = property.IsReadOnly; } CompositeType composite = type as CompositeType; - if (composite != null && composite.ContainsConstantProperties) + if (composite != null && composite.ContainsConstantProperties && (parameter != null && parameter.IsRequired)) { defaultValue = "{}"; } @@ -746,7 +747,8 @@ public static string ConstructMapper(this IType type, string serializedName, IPa { builder.AppendLine("type: {").Indent().AppendLine("name: 'Boolean'").Outdent().AppendLine("}"); } - else if(primary.Type == KnownPrimaryType.Int || primary.Type == KnownPrimaryType.Long || primary.Type == KnownPrimaryType.Decimal || primary.Type == KnownPrimaryType.Double) + else if(primary.Type == KnownPrimaryType.Int || primary.Type == KnownPrimaryType.Long || primary.Type == KnownPrimaryType.Decimal || + primary.Type == KnownPrimaryType.Double || primary.Type == KnownPrimaryType.UnixTime) { builder.AppendLine("type: {").Indent().AppendLine("name: 'Number'").Outdent().AppendLine("}"); } diff --git a/AutoRest/Generators/NodeJS/NodeJS/GlobalSuppressions.cs b/AutoRest/Generators/NodeJS/NodeJS/GlobalSuppressions.cs index dd0050ebae502..a0c9b570f4d8c 100644 --- a/AutoRest/Generators/NodeJS/NodeJS/GlobalSuppressions.cs +++ b/AutoRest/Generators/NodeJS/NodeJS/GlobalSuppressions.cs @@ -191,4 +191,6 @@ [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Rest.Generator.NodeJS.TemplateModels.ClientModelExtensions.#ConstructMapper(Microsoft.Rest.Generator.ClientModel.IType,System.String,Microsoft.Rest.Generator.ClientModel.IParameter,System.Boolean,System.Boolean)")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Scope = "member", Target = "Microsoft.Rest.Generator.NodeJS.NodeJsCodeNamer.#EscapeDefaultValue(System.String,Microsoft.Rest.Generator.ClientModel.IType)")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "readOnly", Scope = "member", Target = "Microsoft.Rest.Generator.NodeJS.TemplateModels.ClientModelExtensions.#ConstructMapper(Microsoft.Rest.Generator.ClientModel.IType,System.String,Microsoft.Rest.Generator.ClientModel.IParameter,System.Boolean,System.Boolean)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Rest.Generator.NodeJS.TemplateModels.ClientModelExtensions.#ValidatePrimaryType(Microsoft.Rest.Generator.ClientModel.PrimaryType,Microsoft.Rest.Generator.Utilities.IScopeProvider,System.String,System.Boolean)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "Microsoft.Rest.Generator.NodeJS.TemplateModels.ClientModelExtensions.#ConstructMapper(Microsoft.Rest.Generator.ClientModel.IType,System.String,Microsoft.Rest.Generator.ClientModel.IParameter,System.Boolean,System.Boolean)")] diff --git a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Lro/autorestlongrunningoperationtestservice/operations/lrosa_ds_operations.py b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Lro/autorestlongrunningoperationtestservice/operations/lrosa_ds_operations.py index f4bb777cedec5..a211b6975e70d 100644 --- a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Lro/autorestlongrunningoperationtestservice/operations/lrosa_ds_operations.py +++ b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Lro/autorestlongrunningoperationtestservice/operations/lrosa_ds_operations.py @@ -205,6 +205,92 @@ def get_long_running_output(response): long_running_send, get_long_running_output, get_long_running_status, long_running_operation_timeout) + def put_non_retry201_creating400_invalid_json( + self, product=None, custom_headers={}, raw=False, **operation_config): + """ + Long running put request, service returns a Product with + 'ProvisioningState' = 'Creating' and 201 response code + + :param product: Product to put + :type product: :class:`Product + ` + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :rtype: + :class:`AzureOperationPoller` + instance that returns :class:`Product + ` + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/lro/nonretryerror/put/201/creating/400/invalidjson' + + # Construct parameters + query_parameters = {} + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if self.config.generate_client_request_id: + header_parameters['x-ms-client-request-id'] = str(uuid.uuid1()) + if custom_headers: + header_parameters.update(custom_headers) + if self.config.accept_language is not None: + header_parameters['accept-language'] = self._serialize.header("self.config.accept_language", self.config.accept_language, 'str') + + # Construct body + if product is not None: + body_content = self._serialize.body(product, 'Product') + else: + body_content = None + + # Construct and send request + def long_running_send(): + + request = self._client.put(url, query_parameters) + return self._client.send( + request, header_parameters, body_content, **operation_config) + + def get_long_running_status(status_link, headers={}): + + request = self._client.get(status_link) + request.headers.update(headers) + return self._client.send( + request, header_parameters, **operation_config) + + def get_long_running_output(response): + + if response.status_code not in [200, 201]: + exp = CloudError(response) + exp.request_id = response.headers.get('x-ms-request-id') + raise exp + + deserialized = None + + if response.status_code == 200: + deserialized = self._deserialize('Product', response) + if response.status_code == 201: + deserialized = self._deserialize('Product', response) + + if raw: + client_raw_response = ClientRawResponse(deserialized, response) + return client_raw_response + + return deserialized + + if raw: + response = long_running_send() + return get_long_running_output(response) + + long_running_operation_timeout = operation_config.get( + 'long_running_operation_timeout', + self.config.long_running_operation_timeout) + return AzureOperationPoller( + long_running_send, get_long_running_output, + get_long_running_status, long_running_operation_timeout) + def put_async_relative_retry400( self, product=None, custom_headers={}, raw=False, **operation_config): """ diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyInteger/autorestintegertestservice/operations/int_model.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyInteger/autorestintegertestservice/operations/int_model.py index 45d9ed146e114..a2b06061ed5cb 100644 --- a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyInteger/autorestintegertestservice/operations/int_model.py +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyInteger/autorestintegertestservice/operations/int_model.py @@ -466,3 +466,178 @@ def put_min64( if raw: client_raw_response = ClientRawResponse(None, response) return client_raw_response + + def get_unix_time( + self, custom_headers={}, raw=False, **operation_config): + """ + Get datetime encoded as Unix time value + + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: long + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/int/unixtime' + + # Construct parameters + query_parameters = {} + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if custom_headers: + header_parameters.update(custom_headers) + + # Construct and send request + request = self._client.get(url, query_parameters) + response = self._client.send(request, header_parameters, **operation_config) + + if response.status_code not in [200]: + raise models.ErrorException(self._deserialize, response) + + deserialized = None + + if response.status_code == 200: + deserialized = self._deserialize('long', response) + + if raw: + client_raw_response = ClientRawResponse(deserialized, response) + return client_raw_response + + return deserialized + + def put_unix_time_date( + self, int_body, custom_headers={}, raw=False, **operation_config): + """ + Put datetime encoded as Unix time + + :param int_body: + :type int_body: long + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: None + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/int/unixtime' + + # Construct parameters + query_parameters = {} + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if custom_headers: + header_parameters.update(custom_headers) + + # Construct body + body_content = self._serialize.body(int_body, 'long') + + # Construct and send request + request = self._client.put(url, query_parameters) + response = self._client.send( + request, header_parameters, body_content, **operation_config) + + if response.status_code not in [200]: + raise models.ErrorException(self._deserialize, response) + + if raw: + client_raw_response = ClientRawResponse(None, response) + return client_raw_response + + def get_invalid_unix_time( + self, custom_headers={}, raw=False, **operation_config): + """ + Get invalid Unix time value + + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: long + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/int/invalidunixtime' + + # Construct parameters + query_parameters = {} + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if custom_headers: + header_parameters.update(custom_headers) + + # Construct and send request + request = self._client.get(url, query_parameters) + response = self._client.send(request, header_parameters, **operation_config) + + if response.status_code not in [200]: + raise models.ErrorException(self._deserialize, response) + + deserialized = None + + if response.status_code == 200: + deserialized = self._deserialize('long', response) + + if raw: + client_raw_response = ClientRawResponse(deserialized, response) + return client_raw_response + + return deserialized + + def get_null_unix_time( + self, custom_headers={}, raw=False, **operation_config): + """ + Get null Unix time value + + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: long + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/int/nullunixtime' + + # Construct parameters + query_parameters = {} + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if custom_headers: + header_parameters.update(custom_headers) + + # Construct and send request + request = self._client.get(url, query_parameters) + response = self._client.send(request, header_parameters, **operation_config) + + if response.status_code not in [200]: + raise models.ErrorException(self._deserialize, response) + + deserialized = None + + if response.status_code == 200: + deserialized = self._deserialize('long', response) + + if raw: + client_raw_response = ClientRawResponse(deserialized, response) + return client_raw_response + + return deserialized diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/operations/paths.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/operations/paths.py index 97cd8878c0e6a..c419d607826a2 100644 --- a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/operations/paths.py +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/operations/paths.py @@ -1114,3 +1114,46 @@ def array_csv_in_path( if raw: client_raw_response = ClientRawResponse(None, response) return client_raw_response + + def unix_time_url( + self, unix_time_url_path, custom_headers={}, raw=False, **operation_config): + """ + Get the date 2016-04-13 encoded value as '1460505600' (Unix time) + + :param unix_time_url_path: Unix time encoded value + :type unix_time_url_path: long + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: None + :rtype: :class:`ClientRawResponse` + if raw=true + """ + # Construct URL + url = '/paths/int/1460505600/{unixTimeUrlPath}' + path_format_arguments = { + 'unixTimeUrlPath': self._serialize.url("unix_time_url_path", unix_time_url_path, 'long') + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} + + # Construct headers + header_parameters = {} + header_parameters['Content-Type'] = 'application/json; charset=utf-8' + if custom_headers: + header_parameters.update(custom_headers) + + # Construct and send request + request = self._client.get(url, query_parameters) + response = self._client.send(request, header_parameters, **operation_config) + + if response.status_code not in [200]: + raise models.ErrorException(self._deserialize, response) + + if raw: + client_raw_response = ClientRawResponse(None, response) + return client_raw_response From 37a536990d655307b3deb44d4f3de78eee4935de Mon Sep 17 00:00:00 2001 From: Amar Zavery Date: Fri, 29 Apr 2016 16:51:42 -0700 Subject: [PATCH 23/29] UnixTime in node.js (#987) * Enhancement to x-ms-parameterized-host extension * positionInOperation defaults to first * fixed setting default value for a complex object containing constant properties. * result of executing gulp regenerate:expected * Fixed fxcop warnings * remove null check validation for unixtime as they are treated as long in java * unixTime in node.js * modification * UnixTime tests * FxCop warnings --- .../AcceptanceTests/acceptanceTests.ts | 30 +++++++++++++++++++ .../BodyInteger/operations/index.d.ts | 18 +++++------ .../BodyInteger/operations/intModel.js | 23 +++++++------- .../operations/index.d.ts | 18 +++++------ .../operations/intModel.js | 23 +++++++------- .../AcceptanceTests/Url/operations/index.d.ts | 6 ++-- .../AcceptanceTests/Url/operations/paths.js | 11 +++---- .../NodeJS/NodeJS/ClientModelExtensions.cs | 26 +++++++++++----- .../NodeJS/NodeJS/GlobalSuppressions.cs | 1 + .../NodeJS/NodeJS/NodeJsCodeNamer.cs | 8 ++--- ClientRuntimes/NodeJS/ms-rest/README.md | 3 +- .../NodeJS/ms-rest/lib/serialization.js | 30 +++++++++++++++++-- .../NodeJS/ms-rest/test/serializationTests.js | 6 ++++ 13 files changed, 141 insertions(+), 62 deletions(-) diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/AcceptanceTests/acceptanceTests.ts b/AutoRest/Generators/NodeJS/NodeJS.Tests/AcceptanceTests/acceptanceTests.ts index 0a81b3420068b..db5042f716ed3 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/AcceptanceTests/acceptanceTests.ts +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/AcceptanceTests/acceptanceTests.ts @@ -199,6 +199,29 @@ describe('nodejs', function () { }); }); }); + + it('should put and get UnixTime date correctly', function (done) { + var d = new Date('2016-04-13T00:00:00.000Z'); + testClient.intModel.putUnixTimeDate(d, function (error, result) { + should.not.exist(error); + testClient.intModel.getUnixTime(function (error, result) { + should.not.exist(error); + assert.deepEqual(result, d); + done(); + }); + }); + }); + + it('should throw an error for invalid UnixTime date anf get null value for UnixTime', function (done) { + testClient.intModel.getInvalidUnixTime(function (error, result) { + should.exist(error); + testClient.intModel.getNullUnixTime(function (error, result) { + should.not.exist(error); + should.not.exist(result); + done(); + }); + }); + }); }); describe('CompositeBoolInt Client', function () { @@ -1891,6 +1914,13 @@ describe('nodejs', function () { }); }); + it('should work when path has a paramaeter in UnixTime format', function (done) { + testClient.paths.unixTimeUrl(new Date('2016-04-13T00:00:00.000Z'), function (error, result) { + should.not.exist(error); + done(); + }); + }); + it('should work when path has datetime', function (done) { testClient.paths.dateTimeValid(new Date('2012-01-01T01:01:01Z'), function (error, result) { should.not.exist(error); diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/index.d.ts b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/index.d.ts index 1b00b43d81429..6fddcb9d06757 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/index.d.ts +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/index.d.ts @@ -179,13 +179,13 @@ export interface IntModel { * @param {ServiceCallback} [callback] callback function; see ServiceCallback * doc in ms-rest index.d.ts for details */ - getUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; - getUnixTime(callback: ServiceCallback): void; + getUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + getUnixTime(callback: ServiceCallback): void; /** * Put datetime encoded as Unix time * - * @param {number} intBody + * @param {date} intBody * * @param {object} [options] Optional Parameters. * @@ -195,8 +195,8 @@ export interface IntModel { * @param {ServiceCallback} [callback] callback function; see ServiceCallback * doc in ms-rest index.d.ts for details */ - putUnixTimeDate(intBody: number, options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; - putUnixTimeDate(intBody: number, callback: ServiceCallback): void; + putUnixTimeDate(intBody: Date, options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + putUnixTimeDate(intBody: Date, callback: ServiceCallback): void; /** * Get invalid Unix time value @@ -209,8 +209,8 @@ export interface IntModel { * @param {ServiceCallback} [callback] callback function; see ServiceCallback * doc in ms-rest index.d.ts for details */ - getInvalidUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; - getInvalidUnixTime(callback: ServiceCallback): void; + getInvalidUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + getInvalidUnixTime(callback: ServiceCallback): void; /** * Get null Unix time value @@ -223,6 +223,6 @@ export interface IntModel { * @param {ServiceCallback} [callback] callback function; see ServiceCallback * doc in ms-rest index.d.ts for details */ - getNullUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; - getNullUnixTime(callback: ServiceCallback): void; + getNullUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + getNullUnixTime(callback: ServiceCallback): void; } diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/intModel.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/intModel.js index b1ed3fbf470cf..290a93e9b35ef 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/intModel.js +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/BodyInteger/operations/intModel.js @@ -1210,7 +1210,7 @@ IntModel.prototype.putMin64 = function (intBody, options, callback) { * * {Error} err - The Error object if an error occurred, null otherwise. * - * {number} [result] - The deserialized result object. + * {date} [result] - The deserialized result object. * * {object} [request] - The HTTP Request object if an error did not occur. * @@ -1293,7 +1293,7 @@ IntModel.prototype.getUnixTime = function (options, callback) { required: false, serializedName: 'parsedResponse', type: { - name: 'Number' + name: 'UnixTime' } }; result = client.deserialize(resultMapper, parsedResponse, 'result'); @@ -1313,7 +1313,7 @@ IntModel.prototype.getUnixTime = function (options, callback) { /** * Put datetime encoded as Unix time * - * @param {number} intBody + * @param {date} intBody * * @param {object} [options] Optional Parameters. * @@ -1343,9 +1343,10 @@ IntModel.prototype.putUnixTimeDate = function (intBody, options, callback) { } // Validate try { - if (intBody === null || intBody === undefined || typeof intBody !== 'number') { - throw new Error('intBody cannot be null or undefined and it must be of type number.'); - } + if(!intBody || !(intBody instanceof Date || + (typeof intBody.valueOf() === 'string' && !isNaN(Date.parse(intBody))))) { + throw new Error('intBody cannot be null or undefined and it must be of type date.'); + } } catch (error) { return callback(error); } @@ -1380,7 +1381,7 @@ IntModel.prototype.putUnixTimeDate = function (intBody, options, callback) { required: true, serializedName: 'intBody', type: { - name: 'Number' + name: 'UnixTime' } }; requestModel = client.serialize(requestModelMapper, intBody, 'intBody'); @@ -1445,7 +1446,7 @@ IntModel.prototype.putUnixTimeDate = function (intBody, options, callback) { * * {Error} err - The Error object if an error occurred, null otherwise. * - * {number} [result] - The deserialized result object. + * {date} [result] - The deserialized result object. * * {object} [request] - The HTTP Request object if an error did not occur. * @@ -1528,7 +1529,7 @@ IntModel.prototype.getInvalidUnixTime = function (options, callback) { required: false, serializedName: 'parsedResponse', type: { - name: 'Number' + name: 'UnixTime' } }; result = client.deserialize(resultMapper, parsedResponse, 'result'); @@ -1559,7 +1560,7 @@ IntModel.prototype.getInvalidUnixTime = function (options, callback) { * * {Error} err - The Error object if an error occurred, null otherwise. * - * {number} [result] - The deserialized result object. + * {date} [result] - The deserialized result object. * * {object} [request] - The HTTP Request object if an error did not occur. * @@ -1642,7 +1643,7 @@ IntModel.prototype.getNullUnixTime = function (options, callback) { required: false, serializedName: 'parsedResponse', type: { - name: 'Number' + name: 'UnixTime' } }; result = client.deserialize(resultMapper, parsedResponse, 'result'); diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/index.d.ts b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/index.d.ts index ac60442293ccf..507488a58f3f6 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/index.d.ts +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/index.d.ts @@ -276,13 +276,13 @@ export interface IntModel { * @param {ServiceCallback} [callback] callback function; see ServiceCallback * doc in ms-rest index.d.ts for details */ - getUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; - getUnixTime(callback: ServiceCallback): void; + getUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + getUnixTime(callback: ServiceCallback): void; /** * Put datetime encoded as Unix time * - * @param {number} intBody + * @param {date} intBody * * @param {object} [options] Optional Parameters. * @@ -292,8 +292,8 @@ export interface IntModel { * @param {ServiceCallback} [callback] callback function; see ServiceCallback * doc in ms-rest index.d.ts for details */ - putUnixTimeDate(intBody: number, options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; - putUnixTimeDate(intBody: number, callback: ServiceCallback): void; + putUnixTimeDate(intBody: Date, options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + putUnixTimeDate(intBody: Date, callback: ServiceCallback): void; /** * Get invalid Unix time value @@ -306,8 +306,8 @@ export interface IntModel { * @param {ServiceCallback} [callback] callback function; see ServiceCallback * doc in ms-rest index.d.ts for details */ - getInvalidUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; - getInvalidUnixTime(callback: ServiceCallback): void; + getInvalidUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + getInvalidUnixTime(callback: ServiceCallback): void; /** * Get null Unix time value @@ -320,6 +320,6 @@ export interface IntModel { * @param {ServiceCallback} [callback] callback function; see ServiceCallback * doc in ms-rest index.d.ts for details */ - getNullUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; - getNullUnixTime(callback: ServiceCallback): void; + getNullUnixTime(options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + getNullUnixTime(callback: ServiceCallback): void; } diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/intModel.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/intModel.js index 42f1d72ab3f7f..d00f8cb625a0c 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/intModel.js +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/operations/intModel.js @@ -1210,7 +1210,7 @@ IntModel.prototype.putMin64 = function (intBody, options, callback) { * * {Error} err - The Error object if an error occurred, null otherwise. * - * {number} [result] - The deserialized result object. + * {date} [result] - The deserialized result object. * * {object} [request] - The HTTP Request object if an error did not occur. * @@ -1293,7 +1293,7 @@ IntModel.prototype.getUnixTime = function (options, callback) { required: false, serializedName: 'parsedResponse', type: { - name: 'Number' + name: 'UnixTime' } }; result = client.deserialize(resultMapper, parsedResponse, 'result'); @@ -1313,7 +1313,7 @@ IntModel.prototype.getUnixTime = function (options, callback) { /** * Put datetime encoded as Unix time * - * @param {number} intBody + * @param {date} intBody * * @param {object} [options] Optional Parameters. * @@ -1343,9 +1343,10 @@ IntModel.prototype.putUnixTimeDate = function (intBody, options, callback) { } // Validate try { - if (intBody === null || intBody === undefined || typeof intBody !== 'number') { - throw new Error('intBody cannot be null or undefined and it must be of type number.'); - } + if(!intBody || !(intBody instanceof Date || + (typeof intBody.valueOf() === 'string' && !isNaN(Date.parse(intBody))))) { + throw new Error('intBody cannot be null or undefined and it must be of type date.'); + } } catch (error) { return callback(error); } @@ -1380,7 +1381,7 @@ IntModel.prototype.putUnixTimeDate = function (intBody, options, callback) { required: true, serializedName: 'intBody', type: { - name: 'Number' + name: 'UnixTime' } }; requestModel = client.serialize(requestModelMapper, intBody, 'intBody'); @@ -1445,7 +1446,7 @@ IntModel.prototype.putUnixTimeDate = function (intBody, options, callback) { * * {Error} err - The Error object if an error occurred, null otherwise. * - * {number} [result] - The deserialized result object. + * {date} [result] - The deserialized result object. * * {object} [request] - The HTTP Request object if an error did not occur. * @@ -1528,7 +1529,7 @@ IntModel.prototype.getInvalidUnixTime = function (options, callback) { required: false, serializedName: 'parsedResponse', type: { - name: 'Number' + name: 'UnixTime' } }; result = client.deserialize(resultMapper, parsedResponse, 'result'); @@ -1559,7 +1560,7 @@ IntModel.prototype.getInvalidUnixTime = function (options, callback) { * * {Error} err - The Error object if an error occurred, null otherwise. * - * {number} [result] - The deserialized result object. + * {date} [result] - The deserialized result object. * * {object} [request] - The HTTP Request object if an error did not occur. * @@ -1642,7 +1643,7 @@ IntModel.prototype.getNullUnixTime = function (options, callback) { required: false, serializedName: 'parsedResponse', type: { - name: 'Number' + name: 'UnixTime' } }; result = client.deserialize(resultMapper, parsedResponse, 'result'); diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/index.d.ts b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/index.d.ts index 3f5e24643883c..36fd5ba34f312 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/index.d.ts +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/index.d.ts @@ -398,7 +398,7 @@ export interface Paths { /** * Get the date 2016-04-13 encoded value as '1460505600' (Unix time) * - * @param {number} unixTimeUrlPath Unix time encoded value + * @param {date} unixTimeUrlPath Unix time encoded value * * @param {object} [options] Optional Parameters. * @@ -408,8 +408,8 @@ export interface Paths { * @param {ServiceCallback} [callback] callback function; see ServiceCallback * doc in ms-rest index.d.ts for details */ - unixTimeUrl(unixTimeUrlPath: number, options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; - unixTimeUrl(unixTimeUrlPath: number, callback: ServiceCallback): void; + unixTimeUrl(unixTimeUrlPath: Date, options: { customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + unixTimeUrl(unixTimeUrlPath: Date, callback: ServiceCallback): void; } /** diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/paths.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/paths.js index 4039b0ce9664a..2b5ff16d6bf66 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/paths.js +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/Url/operations/paths.js @@ -2461,7 +2461,7 @@ Paths.prototype.arrayCsvInPath = function (arrayPath, options, callback) { /** * Get the date 2016-04-13 encoded value as '1460505600' (Unix time) * - * @param {number} unixTimeUrlPath Unix time encoded value + * @param {date} unixTimeUrlPath Unix time encoded value * * @param {object} [options] Optional Parameters. * @@ -2491,9 +2491,10 @@ Paths.prototype.unixTimeUrl = function (unixTimeUrlPath, options, callback) { } // Validate try { - if (unixTimeUrlPath === null || unixTimeUrlPath === undefined || typeof unixTimeUrlPath !== 'number') { - throw new Error('unixTimeUrlPath cannot be null or undefined and it must be of type number.'); - } + if(!unixTimeUrlPath || !(unixTimeUrlPath instanceof Date || + (typeof unixTimeUrlPath.valueOf() === 'string' && !isNaN(Date.parse(unixTimeUrlPath))))) { + throw new Error('unixTimeUrlPath cannot be null or undefined and it must be of type date.'); + } } catch (error) { return callback(error); } @@ -2501,7 +2502,7 @@ Paths.prototype.unixTimeUrl = function (unixTimeUrlPath, options, callback) { // Construct URL var requestUrl = this.client.baseUri + '//paths/int/1460505600/{unixTimeUrlPath}'; - requestUrl = requestUrl.replace('{unixTimeUrlPath}', encodeURIComponent(unixTimeUrlPath.toString())); + requestUrl = requestUrl.replace('{unixTimeUrlPath}', encodeURIComponent(client.serialize({required: true, serializedName: 'unixTimeUrlPath', type: {name: 'UnixTime'}}, unixTimeUrlPath, 'unixTimeUrlPath'))); // trim all duplicate forward slashes in the url var regex = /([^:]\/)\/+/gi; requestUrl = requestUrl.replace(regex, '$1'); diff --git a/AutoRest/Generators/NodeJS/NodeJS/ClientModelExtensions.cs b/AutoRest/Generators/NodeJS/NodeJS/ClientModelExtensions.cs index 8f36adeec8742..ba3a24c17bf8f 100644 --- a/AutoRest/Generators/NodeJS/NodeJS/ClientModelExtensions.cs +++ b/AutoRest/Generators/NodeJS/NodeJS/ClientModelExtensions.cs @@ -131,6 +131,12 @@ public static string ToString(this IType type, string reference) return string.Format(CultureInfo.InvariantCulture, "client.serialize({{required: true, serializedName: '{0}', type: {{name: 'Base64Url'}}}}, {0}, '{0}')", reference); } + + if (known.Type == KnownPrimaryType.UnixTime) + { + return string.Format(CultureInfo.InvariantCulture, + "client.serialize({{required: true, serializedName: '{0}', type: {{name: 'UnixTime'}}}}, {0}, '{0}')", reference); + } } return string.Format(CultureInfo.InvariantCulture, "{0}.toString()", reference); @@ -195,8 +201,7 @@ private static string ValidatePrimaryType(this PrimaryType primary, IScopeProvid primary.Type == KnownPrimaryType.Decimal || primary.Type == KnownPrimaryType.Int || primary.Type == KnownPrimaryType.Long || - primary.Type == KnownPrimaryType.Object || - primary.Type == KnownPrimaryType.UnixTime) + primary.Type == KnownPrimaryType.Object) { if (isRequired) { @@ -254,7 +259,8 @@ private static string ValidatePrimaryType(this PrimaryType primary, IScopeProvid builder.AppendLine("if ({0} && !Buffer.isBuffer({0})) {{", valueReference, lowercaseTypeName); return ConstructValidationCheck(builder, typeErrorMessage, valueReference, primary.Name).ToString(); } - else if (primary.Type == KnownPrimaryType.DateTime || primary.Type == KnownPrimaryType.Date || primary.Type == KnownPrimaryType.DateTimeRfc1123) + else if (primary.Type == KnownPrimaryType.DateTime || primary.Type == KnownPrimaryType.Date || + primary.Type == KnownPrimaryType.DateTimeRfc1123 || primary.Type == KnownPrimaryType.UnixTime) { if (isRequired) { @@ -303,11 +309,13 @@ private static string PrimaryTSType(this PrimaryType primary) if (primary.Type == KnownPrimaryType.Boolean) return "boolean"; - else if (primary.Type == KnownPrimaryType.Double || primary.Type == KnownPrimaryType.Decimal || primary.Type == KnownPrimaryType.Int || primary.Type == KnownPrimaryType.Long || primary.Type == KnownPrimaryType.UnixTime) + else if (primary.Type == KnownPrimaryType.Double || primary.Type == KnownPrimaryType.Decimal || + primary.Type == KnownPrimaryType.Int || primary.Type == KnownPrimaryType.Long) return "number"; else if (primary.Type == KnownPrimaryType.String || primary.Type == KnownPrimaryType.Uuid) return "string"; - else if (primary.Type == KnownPrimaryType.Date || primary.Type == KnownPrimaryType.DateTime || primary.Type == KnownPrimaryType.DateTimeRfc1123) + else if (primary.Type == KnownPrimaryType.Date || primary.Type == KnownPrimaryType.DateTime || + primary.Type == KnownPrimaryType.DateTimeRfc1123 || primary.Type == KnownPrimaryType.UnixTime) return "Date"; else if (primary.Type == KnownPrimaryType.Object) return "any"; // TODO: test this @@ -747,8 +755,8 @@ public static string ConstructMapper(this IType type, string serializedName, IPa { builder.AppendLine("type: {").Indent().AppendLine("name: 'Boolean'").Outdent().AppendLine("}"); } - else if(primary.Type == KnownPrimaryType.Int || primary.Type == KnownPrimaryType.Long || primary.Type == KnownPrimaryType.Decimal || - primary.Type == KnownPrimaryType.Double || primary.Type == KnownPrimaryType.UnixTime) + else if (primary.Type == KnownPrimaryType.Int || primary.Type == KnownPrimaryType.Long || + primary.Type == KnownPrimaryType.Decimal || primary.Type == KnownPrimaryType.Double) { builder.AppendLine("type: {").Indent().AppendLine("name: 'Number'").Outdent().AppendLine("}"); } @@ -784,6 +792,10 @@ public static string ConstructMapper(this IType type, string serializedName, IPa { builder.AppendLine("type: {").Indent().AppendLine("name: 'TimeSpan'").Outdent().AppendLine("}"); } + else if (primary.Type == KnownPrimaryType.UnixTime) + { + builder.AppendLine("type: {").Indent().AppendLine("name: 'UnixTime'").Outdent().AppendLine("}"); + } else if (primary.Type == KnownPrimaryType.Object) { builder.AppendLine("type: {").Indent().AppendLine("name: 'Object'").Outdent().AppendLine("}"); diff --git a/AutoRest/Generators/NodeJS/NodeJS/GlobalSuppressions.cs b/AutoRest/Generators/NodeJS/NodeJS/GlobalSuppressions.cs index a0c9b570f4d8c..9fecaab118c8e 100644 --- a/AutoRest/Generators/NodeJS/NodeJS/GlobalSuppressions.cs +++ b/AutoRest/Generators/NodeJS/NodeJS/GlobalSuppressions.cs @@ -193,4 +193,5 @@ [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "readOnly", Scope = "member", Target = "Microsoft.Rest.Generator.NodeJS.TemplateModels.ClientModelExtensions.#ConstructMapper(Microsoft.Rest.Generator.ClientModel.IType,System.String,Microsoft.Rest.Generator.ClientModel.IParameter,System.Boolean,System.Boolean)")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Rest.Generator.NodeJS.TemplateModels.ClientModelExtensions.#ValidatePrimaryType(Microsoft.Rest.Generator.ClientModel.PrimaryType,Microsoft.Rest.Generator.Utilities.IScopeProvider,System.String,System.Boolean)")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Scope = "member", Target = "Microsoft.Rest.Generator.NodeJS.TemplateModels.ClientModelExtensions.#ConstructMapper(Microsoft.Rest.Generator.ClientModel.IType,System.String,Microsoft.Rest.Generator.ClientModel.IParameter,System.Boolean,System.Boolean)")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "UnixTime", Scope = "member", Target = "Microsoft.Rest.Generator.NodeJS.TemplateModels.ClientModelExtensions.#ConstructMapper(Microsoft.Rest.Generator.ClientModel.IType,System.String,Microsoft.Rest.Generator.ClientModel.IParameter,System.Boolean,System.Boolean)")] diff --git a/AutoRest/Generators/NodeJS/NodeJS/NodeJsCodeNamer.cs b/AutoRest/Generators/NodeJS/NodeJS/NodeJsCodeNamer.cs index d2f43a402f589..2dc7c2f0edd6a 100644 --- a/AutoRest/Generators/NodeJS/NodeJS/NodeJsCodeNamer.cs +++ b/AutoRest/Generators/NodeJS/NodeJS/NodeJsCodeNamer.cs @@ -365,6 +365,10 @@ private static IType NormalizePrimaryType(PrimaryType primaryType) { primaryType.Name = "Date"; } + else if (primaryType.Type == KnownPrimaryType.UnixTime) + { + primaryType.Name = "Date"; + } else if (primaryType.Type == KnownPrimaryType.Double) { primaryType.Name = "Number"; @@ -393,10 +397,6 @@ private static IType NormalizePrimaryType(PrimaryType primaryType) { primaryType.Name = "moment.duration"; } - else if (primaryType.Type == KnownPrimaryType.UnixTime) - { - primaryType.Name = "Number"; - } else if (primaryType.Type == KnownPrimaryType.Uuid) { primaryType.Name = "Uuid"; diff --git a/ClientRuntimes/NodeJS/ms-rest/README.md b/ClientRuntimes/NodeJS/ms-rest/README.md index cb4aca73ab405..1da52bff1ac92 100644 --- a/ClientRuntimes/NodeJS/ms-rest/README.md +++ b/ClientRuntimes/NodeJS/ms-rest/README.md @@ -18,7 +18,7 @@ var msrest = require('ms-rest'); ## Serialization/Deserialization Features - Type checking - - (String, Number, Boolean, ByteArray, Date, DateTime, Enum, TimeSpan, DateTimeRfc1123, Object, Stream, Sequence, Dictionary, Composite, Uuid(as a string)) + - (String, Number, Boolean, ByteArray, Base64Url, Date, DateTime, Enum, TimeSpan, DateTimeRfc1123, UnixTime, Object, Stream, Sequence, Dictionary, Composite, Uuid(as a string)) - Validation of specified constraints - ExclusiveMaximum, ExclusiveMinimum, InclusiveMaximum, InclusiveMinimum, MaxItems, MaxLength, MinItems, MinLength, MultipleOf, Pattern, UniqueItems - Flattening/Unflattening properties @@ -26,6 +26,7 @@ Features - Model Properties marked as constant are set during serialization, irrespective of they being provided or not - Required check (If a model or property is marked required and is not provided in the object then an error is thrown) - Readonly check (If a model or property is marked readonly then it is not sent on the wire during, serialization) +- Serializing Constant values - serialize an array of dictionary of primitive values ```javascript diff --git a/ClientRuntimes/NodeJS/ms-rest/lib/serialization.js b/ClientRuntimes/NodeJS/ms-rest/lib/serialization.js index de8d0778efd92..671292b9f43ba 100644 --- a/ClientRuntimes/NodeJS/ms-rest/lib/serialization.js +++ b/ClientRuntimes/NodeJS/ms-rest/lib/serialization.js @@ -74,7 +74,7 @@ exports.serialize = function (mapper, object, objectName) { payload = serializeBasicTypes.call(this, mapperType, objectName, object); } else if (mapperType.match(/^Enum$/ig) !== null) { payload = serializeEnumType.call(this, objectName, mapper.type.allowedValues, object); - } else if (mapperType.match(/^(Date|DateTime|TimeSpan|DateTimeRfc1123)$/ig) !== null) { + } else if (mapperType.match(/^(Date|DateTime|TimeSpan|DateTimeRfc1123|UnixTime)$/ig) !== null) { payload = serializeDateTypes.call(this, mapperType, object, objectName); } else if (mapperType.match(/^ByteArray$/ig) !== null) { payload = serializeBufferType.call(this, objectName, object); @@ -370,6 +370,13 @@ function serializeDateTypes(typeName, value, objectName) { throw new Error(util.format('%s must be an instanceof Date or a string in RFC-1123 format.', objectName)); } value = (value instanceof Date) ? value.toUTCString() : new Date(value).toUTCString(); + } else if (typeName.match(/^UnixTime$/ig) !== null) { + if (!(value instanceof Date || + (typeof value.valueOf() === 'string' && !isNaN(Date.parse(value))))) { + throw new Error(util.format('%s must be an instanceof Date or a string in RFC-1123/ISO8601 format ' + + 'for it to be serialized in UnixTime/Epoch format.', objectName)); + } + value = dateToUnixTime(value); } else if (typeName.match(/^TimeSpan$/ig) !== null) { if (!moment.isDuration(value)) { throw new Error(util.format('%s must be a TimeSpan/Duration.', objectName)); @@ -402,8 +409,10 @@ exports.deserialize = function (mapper, responseBody, objectName) { payload = responseBody; } else if (mapperType.match(/^(Date|DateTime|DateTimeRfc1123)$/ig) !== null) { payload = new Date(responseBody); - } else if (mapperType.match(/^(TimeSpan)$/ig) !== null) { + } else if (mapperType.match(/^TimeSpan$/ig) !== null) { payload = moment.duration(responseBody); + } else if (mapperType.match(/^UnixTime$/ig) !== null) { + payload = unixTimeToDate(responseBody); } else if (mapperType.match(/^ByteArray$/ig) !== null) { payload = new Buffer(responseBody, 'base64'); } else if (mapperType.match(/^Base64Url$/ig) !== null) { @@ -595,4 +604,21 @@ function base64UrlToBuffer(str) { return new Buffer(str, 'base64'); } +function dateToUnixTime(d) { + if (!d) { + return null; + } + if (typeof d.valueOf() === 'string') { + d = new Date(d); + } + return parseInt(d.getTime() / 1000); +} + +function unixTimeToDate(n) { + if (!n) { + return null; + } + return new Date(n*1000); +} + exports = module.exports; \ No newline at end of file diff --git a/ClientRuntimes/NodeJS/ms-rest/test/serializationTests.js b/ClientRuntimes/NodeJS/ms-rest/test/serializationTests.js index d9be4bd39fba9..32c89671d37cf 100644 --- a/ClientRuntimes/NodeJS/ms-rest/test/serializationTests.js +++ b/ClientRuntimes/NodeJS/ms-rest/test/serializationTests.js @@ -195,6 +195,12 @@ describe('msrest', function () { serializedDateString.should.equal('+010000-01-01T11:59:59.000Z'); done(); }); + it('should correctly serialize a Date object with max value and format UnixTime', function (done) { + mapper = { type : { name: 'UnixTime' } }; + var serializedDate = msRest.serialize(mapper, new Date('9999-12-31T23:59:59-12:00'), 'dateTimeObj'); + serializedDate.should.equal(253402343999); + done(); + }); it('should correctly serialize a string in DateTimeRfc1123', function (done) { mapper = { type : { name: 'DateTimeRfc1123' } }; var rfc = new Date('Mon, 01 Jan 0001 00:00:00 GMT'); From 78ce979446012ac718636397282e573baeb9e5eb Mon Sep 17 00:00:00 2001 From: John Hart Date: Fri, 29 Apr 2016 18:54:15 -0700 Subject: [PATCH 24/29] Updated the UserAgent ProductInfoHeaderValue to use the AssemblyInformationalVersion or the AssemblyFileVersion, if neither attribute is available it will default to the Assembly Version. (#979) --- .../CSharp/CSharp.Tests/AcceptanceTests.cs | 3 ++ .../CSharp.Tests/Properties/AssemblyInfo.cs | 1 + .../ServiceClient.cs | 54 ++++++++++++++----- 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs b/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs index 804db915e6111..bdd10a6f30136 100644 --- a/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs +++ b/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs @@ -1366,6 +1366,9 @@ public void HeaderTests() SwaggerPath("header.json"), ExpectedPath("Header")); using (var client = new AutoRestSwaggerBATHeaderService(Fixture.Uri)) { + // Check the UserAgent ProductInfoHeaderValue + Assert.Equal("1.5.0.1", client.UserAgent.Select(c => c.Product.Version.ToString()).FirstOrDefault()); + // POST param/prim/integer client.Header.ParamInteger("positive", 1); client.Header.ParamInteger("negative", -2); diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Properties/AssemblyInfo.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Properties/AssemblyInfo.cs index 68d34505c6d76..61dbf33914dc9 100644 --- a/AutoRest/Generators/CSharp/CSharp.Tests/Properties/AssemblyInfo.cs +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Properties/AssemblyInfo.cs @@ -17,3 +17,4 @@ [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.5.0.0")] +[assembly: AssemblyInformationalVersion("1.5.0.1")] diff --git a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime/ServiceClient.cs b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime/ServiceClient.cs index e80afc887e0f8..6763f4e6641fa 100644 --- a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime/ServiceClient.cs +++ b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime/ServiceClient.cs @@ -208,25 +208,53 @@ protected void InitializeHttpClient(HttpClientHandler httpClientHandler, params HttpClient = newClient; Type type = this.GetType(); HttpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(type.FullName, - GetAssemblyVersion())); + GetClientVersion())); } /// - /// Get the assembly version of a service client. + /// Gets the AssemblyInformationalVersion if available + /// if not it gets the AssemblyFileVerion + /// if neither are available it will default to the Assembly Version of a service client. /// - /// The assembly version of the client. - private string GetAssemblyVersion() + /// The version of the client. + private string GetClientVersion() { + + string version = String.Empty; Type type = this.GetType(); - string version = - type - .GetTypeInfo() - .Assembly - .FullName - .Split(',') - .Select(c => c.Trim()) - .First(c => c.StartsWith("Version=", StringComparison.OrdinalIgnoreCase)) - .Substring("Version=".Length); + Assembly assembly = type.GetTypeInfo().Assembly; + + try + { + // try to get AssemblyInformationalVersion first + AssemblyInformationalVersionAttribute aivAttribute = + assembly.GetCustomAttribute(typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute; + version = aivAttribute?.InformationalVersion; + + // if not available try to get AssemblyFileVersion + if (String.IsNullOrEmpty(version)) + { + AssemblyFileVersionAttribute fvAttribute = + assembly.GetCustomAttribute(typeof(AssemblyFileVersionAttribute)) as AssemblyFileVersionAttribute; + version = fvAttribute?.Version; + } + } + catch (AmbiguousMatchException) + { + // in case there are more then one attribute of the type + } + + // no usable version attribute found so default to Assembly Version + if (String.IsNullOrEmpty(version)) + { + version = + assembly + .FullName + .Split(',') + .Select(c => c.Trim()) + .First(c => c.StartsWith("Version=", StringComparison.OrdinalIgnoreCase)) + .Substring("Version=".Length); + } return version; } } From 1f4cc357f631f24ba0e837c236cd0e75d23946d9 Mon Sep 17 00:00:00 2001 From: Laurent Mazuel Date: Fri, 29 Apr 2016 18:54:24 -0700 Subject: [PATCH 25/29] msrest/msrestazure 0.3.0 (#982) --- .../Azure.Python/AzurePythonCodeGenerator.cs | 2 +- .../AzureServiceClientTemplateModel.cs | 2 +- .../Python/Python/PythonCodeGenerator.cs | 2 +- ClientRuntimes/Python/msrest/doc/conf.py | 4 ++-- ClientRuntimes/Python/msrest/msrest/version.py | 2 +- ClientRuntimes/Python/msrest/readme.rst | 15 ++++++++++++++- ClientRuntimes/Python/msrest/setup.py | 2 +- ClientRuntimes/Python/msrestazure/doc/conf.py | 4 ++-- .../Python/msrestazure/msrestazure/version.py | 2 +- ClientRuntimes/Python/msrestazure/readme.rst | 15 +++++++++++++++ ClientRuntimes/Python/msrestazure/setup.py | 4 ++-- 11 files changed, 41 insertions(+), 13 deletions(-) diff --git a/AutoRest/Generators/Python/Azure.Python/AzurePythonCodeGenerator.cs b/AutoRest/Generators/Python/Azure.Python/AzurePythonCodeGenerator.cs index 0ad15558928b5..eeb311593bb52 100644 --- a/AutoRest/Generators/Python/Azure.Python/AzurePythonCodeGenerator.cs +++ b/AutoRest/Generators/Python/Azure.Python/AzurePythonCodeGenerator.cs @@ -19,7 +19,7 @@ namespace Microsoft.Rest.Generator.Azure.Python { public class AzurePythonCodeGenerator : PythonCodeGenerator { - private const string ClientRuntimePackage = "msrestazure version 0.2.1"; + private const string ClientRuntimePackage = "msrestazure version 0.3.0"; // page extensions class dictionary. private IList pageModels; diff --git a/AutoRest/Generators/Python/Azure.Python/TemplateModels/AzureServiceClientTemplateModel.cs b/AutoRest/Generators/Python/Azure.Python/TemplateModels/AzureServiceClientTemplateModel.cs index f56bc3935547a..0a3b44b0e6446 100644 --- a/AutoRest/Generators/Python/Azure.Python/TemplateModels/AzureServiceClientTemplateModel.cs +++ b/AutoRest/Generators/Python/Azure.Python/TemplateModels/AzureServiceClientTemplateModel.cs @@ -97,7 +97,7 @@ public override string SetupRequires { get { - return "\"msrest>=0.2.0\", \"msrestazure>=0.2.1\""; + return "\"msrest>=0.3.0\", \"msrestazure>=0.3.0\""; } } diff --git a/AutoRest/Generators/Python/Python/PythonCodeGenerator.cs b/AutoRest/Generators/Python/Python/PythonCodeGenerator.cs index d987055d49f6f..8131b8cba6d34 100644 --- a/AutoRest/Generators/Python/Python/PythonCodeGenerator.cs +++ b/AutoRest/Generators/Python/Python/PythonCodeGenerator.cs @@ -16,7 +16,7 @@ namespace Microsoft.Rest.Generator.Python { public class PythonCodeGenerator : CodeGenerator { - private const string ClientRuntimePackage = "msrest version 0.2.0"; + private const string ClientRuntimePackage = "msrest version 0.3.0"; public PythonCodeGenerator(Settings settings) : base(settings) { diff --git a/ClientRuntimes/Python/msrest/doc/conf.py b/ClientRuntimes/Python/msrest/doc/conf.py index 1dfe56981ffc9..169d6053b55f8 100644 --- a/ClientRuntimes/Python/msrest/doc/conf.py +++ b/ClientRuntimes/Python/msrest/doc/conf.py @@ -57,9 +57,9 @@ # built documents. # # The short X.Y version. -version = '0.2.0' +version = '0.3.0' # The full version, including alpha/beta/rc tags. -release = '0.2.0' +release = '0.3.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/ClientRuntimes/Python/msrest/msrest/version.py b/ClientRuntimes/Python/msrest/msrest/version.py index 11739ebc3606c..527b2a717c20b 100644 --- a/ClientRuntimes/Python/msrest/msrest/version.py +++ b/ClientRuntimes/Python/msrest/msrest/version.py @@ -25,4 +25,4 @@ # -------------------------------------------------------------------------- -msrest_version = "0.2.0" +msrest_version = "0.3.0" diff --git a/ClientRuntimes/Python/msrest/readme.rst b/ClientRuntimes/Python/msrest/readme.rst index 77e50e0da4bb2..b65e1bf5b13a5 100644 --- a/ClientRuntimes/Python/msrest/readme.rst +++ b/ClientRuntimes/Python/msrest/readme.rst @@ -15,6 +15,19 @@ To install: Release History --------------- +2016-04-26 Version 0.3.0 +++++++++++++++++++++++++ + +**Bugfixes** + +- Read only values are no longer in __init__ or sent to the server (https://github.com/Azure/autorest/pull/959) +- Useless kwarg removed + +**Behaviour changes** + +- Needs Autorest > 0.16.0 Nightly 20160426 + + 2016-03-25 Version 0.2.0 ++++++++++++++++++++++++ @@ -23,7 +36,7 @@ Release History - Manage integer enum values (https://github.com/Azure/autorest/pull/879) - Add missing application/json Accept HTTP header (https://github.com/Azure/azure-sdk-for-python/issues/553) -**Beheviour changes** +**Behaviour changes** - Needs Autorest > 0.16.0 Nightly 20160324 diff --git a/ClientRuntimes/Python/msrest/setup.py b/ClientRuntimes/Python/msrest/setup.py index b3dca9089b534..02bdd49b71aab 100644 --- a/ClientRuntimes/Python/msrest/setup.py +++ b/ClientRuntimes/Python/msrest/setup.py @@ -28,7 +28,7 @@ setup( name='msrest', - version='0.2.0', + version='0.3.0', author='Microsoft Corporation', packages=['msrest'], url=("https://github.com/xingwu1/autorest/tree/python/" diff --git a/ClientRuntimes/Python/msrestazure/doc/conf.py b/ClientRuntimes/Python/msrestazure/doc/conf.py index 9a76b3204d5c2..1225f72e6ec9d 100644 --- a/ClientRuntimes/Python/msrestazure/doc/conf.py +++ b/ClientRuntimes/Python/msrestazure/doc/conf.py @@ -58,9 +58,9 @@ # built documents. # # The short X.Y version. -version = '0.2.1' +version = '0.3.0' # The full version, including alpha/beta/rc tags. -release = '0.2.1' +release = '0.3.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/ClientRuntimes/Python/msrestazure/msrestazure/version.py b/ClientRuntimes/Python/msrestazure/msrestazure/version.py index 23c80b2514da3..edb859f0a87d2 100644 --- a/ClientRuntimes/Python/msrestazure/msrestazure/version.py +++ b/ClientRuntimes/Python/msrestazure/msrestazure/version.py @@ -24,4 +24,4 @@ # # -------------------------------------------------------------------------- -msrestazure_version = "0.2.1" +msrestazure_version = "0.3.0" diff --git a/ClientRuntimes/Python/msrestazure/readme.rst b/ClientRuntimes/Python/msrestazure/readme.rst index 18a49a8035f2b..7ba256b12c10a 100644 --- a/ClientRuntimes/Python/msrestazure/readme.rst +++ b/ClientRuntimes/Python/msrestazure/readme.rst @@ -15,6 +15,21 @@ To install: Release History --------------- +2016-04-26 Version 0.3.0 +++++++++++++++++++++++++ + +Update msrest dependency to 0.3.0 + +**Bugfixes** + +- Read only values are no longer in __init__ or sent to the server (https://github.com/Azure/autorest/pull/959) +- Useless kwarg removed + +**Behaviour changes** + +- Needs Autorest > 0.16.0 Nightly 20160426 + + 2016-03-31 Version 0.2.1 ++++++++++++++++++++++++ diff --git a/ClientRuntimes/Python/msrestazure/setup.py b/ClientRuntimes/Python/msrestazure/setup.py index d25ce47f33493..7778b0185d42b 100644 --- a/ClientRuntimes/Python/msrestazure/setup.py +++ b/ClientRuntimes/Python/msrestazure/setup.py @@ -28,7 +28,7 @@ setup( name='msrestazure', - version='0.2.1', + version='0.3.0', author='Microsoft Corporation', packages=['msrestazure'], url=('https://github.com/xingwu1/autorest/tree/python/' @@ -49,5 +49,5 @@ 'License :: OSI Approved :: MIT License', 'Topic :: Software Development'], install_requires=[ - "msrest>=0.2.0"], + "msrest>=0.3.0"], ) From 47753e5c3b665d2a8033bf0d82cb6bad65b39ceb Mon Sep 17 00:00:00 2001 From: Dan Schulte Date: Fri, 29 Apr 2016 18:54:41 -0700 Subject: [PATCH 26/29] Fix AzureResourceSchema projects (#956) * Automatically detect MSBuild tools version in Windows platform * Add initial AzureResourceSchema project and test project * Update AzureResourceSchema projects and add initial c# files * Add AzureResourceSchema to configuration file * AzureResourceSchemaCodeGenerator shows up in AutoRest help and tests pass * Almost have Storage schema generating from swagger spec * Fix AzureResourceSchema project * Can generate storage schema from swagger * Fix FXCopy issues --- AutoRest.sln | 10 +- AutoRest/AutoRest.Core/AutoRest.nuspec | 1 + AutoRest/AutoRest/AutoRest.Release.json | 3 + AutoRest/AutoRest/AutoRest.json | 3 + ...Generator.AzureResourceSchema.Tests.csproj | 31 ++- .../AzureResourceSchemaCodeGeneratorTests.cs | 155 +++++++++++++ .../AzureResourceSchema.Tests/packages.config | 1 + ...oRest.Generator.AzureResourceSchema.csproj | 50 +++- .../AzureResourceSchemaCodeGenerator.cs | 218 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 6 +- .../AzureResourceSchema/Resource.cs | 56 +++++ .../AzureResourceSchema/ResourceProperty.cs | 50 ++++ .../AzureResourceSchema/ResourceSchema.cs | 171 ++++++++++++++ .../AzureResourceSchema/packages.config | 4 + CodeGenerator.sln | 27 ++- 15 files changed, 771 insertions(+), 15 deletions(-) create mode 100644 AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AzureResourceSchemaCodeGeneratorTests.cs create mode 100644 AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AzureResourceSchemaCodeGenerator.cs create mode 100644 AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/Resource.cs create mode 100644 AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/ResourceProperty.cs create mode 100644 AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/ResourceSchema.cs create mode 100644 AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/packages.config diff --git a/AutoRest.sln b/AutoRest.sln index b11b89d798ca5..e9e2ddf312323 100644 --- a/AutoRest.sln +++ b/AutoRest.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 +VisualStudioVersion = 14.0.25123.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoRest.Core", "AutoRest\AutoRest.Core\AutoRest.Core.csproj", "{C876085F-9DC3-41F0-B7B4-17022CD84684}" EndProject @@ -372,6 +372,14 @@ Global {DA37E6A9-5D59-45A3-A809-ABA85031C369}.Portable-Debug|Any CPU.Build.0 = Portable-Debug|Any CPU {DA37E6A9-5D59-45A3-A809-ABA85031C369}.Portable-Release|Any CPU.ActiveCfg = Portable-Release|Any CPU {DA37E6A9-5D59-45A3-A809-ABA85031C369}.Portable-Release|Any CPU.Build.0 = Portable-Release|Any CPU + {654344A5-0556-49C7-BFB3-59676D7440D3}.Net45-Debug|Any CPU.ActiveCfg = Net45-Debug|Any CPU + {654344A5-0556-49C7-BFB3-59676D7440D3}.Net45-Debug|Any CPU.Build.0 = Net45-Debug|Any CPU + {654344A5-0556-49C7-BFB3-59676D7440D3}.Net45-Release|Any CPU.ActiveCfg = Net45-Release|Any CPU + {654344A5-0556-49C7-BFB3-59676D7440D3}.Net45-Release|Any CPU.Build.0 = Net45-Release|Any CPU + {654344A5-0556-49C7-BFB3-59676D7440D3}.Portable-Debug|Any CPU.ActiveCfg = Portable-Debug|Any CPU + {654344A5-0556-49C7-BFB3-59676D7440D3}.Portable-Debug|Any CPU.Build.0 = Portable-Debug|Any CPU + {654344A5-0556-49C7-BFB3-59676D7440D3}.Portable-Release|Any CPU.ActiveCfg = Portable-Release|Any CPU + {654344A5-0556-49C7-BFB3-59676D7440D3}.Portable-Release|Any CPU.Build.0 = Portable-Release|Any CPU {654344A5-0556-49C7-BFB3-59676D7440D3}.Net45-Debug|Any CPU.ActiveCfg = Debug|Any CPU {654344A5-0556-49C7-BFB3-59676D7440D3}.Net45-Debug|Any CPU.Build.0 = Debug|Any CPU {654344A5-0556-49C7-BFB3-59676D7440D3}.Net45-Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/AutoRest/AutoRest.Core/AutoRest.nuspec b/AutoRest/AutoRest.Core/AutoRest.nuspec index 0451285cb520a..2af544a885822 100644 --- a/AutoRest/AutoRest.Core/AutoRest.nuspec +++ b/AutoRest/AutoRest.Core/AutoRest.nuspec @@ -31,6 +31,7 @@ + diff --git a/AutoRest/AutoRest/AutoRest.Release.json b/AutoRest/AutoRest/AutoRest.Release.json index b488b12ca1fc8..f368702db7a63 100644 --- a/AutoRest/AutoRest/AutoRest.Release.json +++ b/AutoRest/AutoRest/AutoRest.Release.json @@ -29,6 +29,9 @@ }, "Azure.Python": { "type": "AzurePythonCodeGenerator, AutoRest.Generator.Azure.Python" + }, + "AzureResourceSchema": { + "type": "AzureResourceSchemaCodeGenerator, AutoRest.Generator.AzureResourceSchema" } }, "modelers": { diff --git a/AutoRest/AutoRest/AutoRest.json b/AutoRest/AutoRest/AutoRest.json index b488b12ca1fc8..f368702db7a63 100644 --- a/AutoRest/AutoRest/AutoRest.json +++ b/AutoRest/AutoRest/AutoRest.json @@ -29,6 +29,9 @@ }, "Azure.Python": { "type": "AzurePythonCodeGenerator, AutoRest.Generator.Azure.Python" + }, + "AzureResourceSchema": { + "type": "AzureResourceSchemaCodeGenerator, AutoRest.Generator.AzureResourceSchema" } }, "modelers": { diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj index 01522ea89f2b4..be1ade26d44d8 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj @@ -1,6 +1,7 @@  - - + + + Debug @@ -8,6 +9,7 @@ {1C3B4A33-E045-4C8F-9202-1B651A686567} Library Properties + Microsoft.Rest.Generator.AzureResourceSchema.Tests AutoRest.Generator.AzureResourceSchema.Tests AutoRest.Generator.AzureResourceSchema.Tests v4.5.2 @@ -33,6 +35,10 @@ 4 + + ..\..\..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + True + @@ -42,25 +48,32 @@ - ..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll + ..\..\..\..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll True - ..\packages\xunit.assert.2.1.0\lib\dotnet\xunit.assert.dll + ..\..\..\..\packages\xunit.assert.2.1.0\lib\dotnet\xunit.assert.dll True - ..\packages\xunit.extensibility.core.2.1.0\lib\dotnet\xunit.core.dll + ..\..\..\..\packages\xunit.extensibility.core.2.1.0\lib\dotnet\xunit.core.dll True - ..\packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll + ..\..\..\..\packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll True + + + + {c876085f-9dc3-41f0-b7b4-17022cd84684} + AutoRest.Core + + PreserveNewest @@ -72,12 +85,16 @@ AutoRest.Generator.AzureResourceSchema + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + +