From f05854345598a2be3978557d41c39e34c3f61b65 Mon Sep 17 00:00:00 2001 From: Qinyuan Wan Date: Tue, 22 Mar 2016 16:47:05 -0700 Subject: [PATCH 01/96] 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 ae1798dc5e56..4b967ca5cd37 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 87a68bf6dfc2..0d7c48fd1df0 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/96] 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 4b967ca5cd37..4a7ce94cf713 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 e28f44bf5ad6..bab92dc1e627 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/96] 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 4a7ce94cf713..dabedd8d3217 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 0d7c48fd1df0..114eedf25c57 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 bab92dc1e627..f358540bb6aa 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/96] 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 ae1798dc5e56..dabedd8d3217 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 87a68bf6dfc2..114eedf25c57 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 e28f44bf5ad6..f358540bb6aa 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/96] 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 dabedd8d3217..fa2e530176f8 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 965e722ab492d19524c2a0db0da77b30879bbb77 Mon Sep 17 00:00:00 2001 From: Parvez Ahmed Date: Tue, 5 Apr 2016 19:03:26 +0530 Subject: [PATCH 06/96] Adding a method in the AzureClientExtensions to handle the PutOrPatch async calls with 202 responses which have no body and no specific headers --- .../AzureClientExtensions.cs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure/AzureClientExtensions.cs b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure/AzureClientExtensions.cs index 57bbd064b95c..9a38463a88e0 100644 --- a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure/AzureClientExtensions.cs +++ b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure/AzureClientExtensions.cs @@ -122,6 +122,38 @@ public static class AzureClientExtensions return pollingState.AzureOperationResponse; } + /// + /// Gets operation result for PUT and PATCH operations. + /// + /// IAzureClient + /// Response from the begin operation + /// Headers that will be added to request + /// Cancellation token + /// Operation response + public static async Task GetPutOrPatchOperationResultAsync( + this IAzureClient client, + AzureOperationResponse response, + Dictionary> customHeaders, + CancellationToken cancellationToken) + { + var newResponse = new AzureOperationResponse + { + Request = response.Request, + Response = response.Response, + RequestId = response.RequestId + }; + + var azureOperationResponse = await client.GetPutOrPatchOperationResultAsync( + newResponse, customHeaders, cancellationToken); + + return new AzureOperationResponse + { + Request = azureOperationResponse.Request, + Response = azureOperationResponse.Response, + RequestId = azureOperationResponse.RequestId + }; + } + /// /// Gets operation result for DELETE and POST operations. /// From 94b15ef88f84bff1782d83cd0dffea0d47131e30 Mon Sep 17 00:00:00 2001 From: Dan Schulte Date: Wed, 6 Apr 2016 09:27:31 -0700 Subject: [PATCH 07/96] Automatically detect MSBuild tools version in Windows platform --- gulpfile.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index 46785dfa2104..942ac3a898b8 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -411,13 +411,23 @@ gulp.task('regenerate:expected:samples:azure', function(){ } }); +var msBuildToolsVersion = 12.0; +if (isWindows) { + fs.readdirSync('C:/Program Files (x86)/MSBuild/').forEach(function (item) { + var itemAsFloat = parseFloat(item); + if (itemAsFloat > msBuildToolsVersion) { + msBuildToolsVersion = itemAsFloat; + } + }); +} + var msbuildDefaults = { stdout: process.stdout, stderr: process.stderr, maxBuffer: MAX_BUFFER, verbosity: 'minimal', errorOnFail: true, - toolsVersion: 12.0 + toolsVersion: msBuildToolsVersion }; gulp.task('clean:node_modules', function(cb) { From 0522974532d5b99417f3bf615d4c63d8c06e9b9d Mon Sep 17 00:00:00 2001 From: Dan Schulte Date: Wed, 6 Apr 2016 10:44:40 -0700 Subject: [PATCH 08/96] Add initial AzureResourceSchema project and test project --- AutoRest.sln | 25 ++++++ ...Generator.AzureResourceSchema.Tests.csproj | 87 +++++++++++++++++++ .../Properties/AssemblyInfo.cs | 36 ++++++++ .../AzureResourceSchema.Tests/packages.config | 10 +++ ...oRest.Generator.AzureResourceSchema.csproj | 53 +++++++++++ .../Properties/AssemblyInfo.cs | 36 ++++++++ 6 files changed, 247 insertions(+) create mode 100644 AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj create mode 100644 AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Properties/AssemblyInfo.cs create mode 100644 AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config create mode 100644 AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AutoRest.Generator.AzureResourceSchema.csproj create mode 100644 AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/Properties/AssemblyInfo.cs diff --git a/AutoRest.sln b/AutoRest.sln index f616c9ac420d..b11b89d798ca 100644 --- a/AutoRest.sln +++ b/AutoRest.sln @@ -118,6 +118,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoRest.Modeler.CompositeS EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoRest.Modeler.CompositeSwagger.Tests", "AutoRest\Modelers\CompositeSwagger.Tests\AutoRest.Modeler.CompositeSwagger.Tests.csproj", "{DA37E6A9-5D59-45A3-A809-ABA85031C369}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AzureResourceSchema", "AzureResourceSchema", "{B6A1FC1E-0779-4900-84EE-262DD0E53FF4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoRest.Generator.AzureResourceSchema", "AutoRest\Generators\AzureResourceSchema\AzureResourceSchema\AutoRest.Generator.AzureResourceSchema.csproj", "{654344A5-0556-49C7-BFB3-59676D7440D3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoRest.Generator.AzureResourceSchema.Tests", "AutoRest\Generators\AzureResourceSchema\AzureResourceSchema.Tests\AutoRest.Generator.AzureResourceSchema.Tests.csproj", "{1C3B4A33-E045-4C8F-9202-1B651A686567}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Net45-Debug|Any CPU = Net45-Debug|Any CPU @@ -366,6 +372,22 @@ 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 = 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 + {654344A5-0556-49C7-BFB3-59676D7440D3}.Net45-Release|Any CPU.Build.0 = Release|Any CPU + {654344A5-0556-49C7-BFB3-59676D7440D3}.Portable-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {654344A5-0556-49C7-BFB3-59676D7440D3}.Portable-Debug|Any CPU.Build.0 = Debug|Any CPU + {654344A5-0556-49C7-BFB3-59676D7440D3}.Portable-Release|Any CPU.ActiveCfg = Release|Any CPU + {654344A5-0556-49C7-BFB3-59676D7440D3}.Portable-Release|Any CPU.Build.0 = Release|Any CPU + {1C3B4A33-E045-4C8F-9202-1B651A686567}.Net45-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1C3B4A33-E045-4C8F-9202-1B651A686567}.Net45-Debug|Any CPU.Build.0 = Debug|Any CPU + {1C3B4A33-E045-4C8F-9202-1B651A686567}.Net45-Release|Any CPU.ActiveCfg = Release|Any CPU + {1C3B4A33-E045-4C8F-9202-1B651A686567}.Net45-Release|Any CPU.Build.0 = Release|Any CPU + {1C3B4A33-E045-4C8F-9202-1B651A686567}.Portable-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1C3B4A33-E045-4C8F-9202-1B651A686567}.Portable-Debug|Any CPU.Build.0 = Debug|Any CPU + {1C3B4A33-E045-4C8F-9202-1B651A686567}.Portable-Release|Any CPU.ActiveCfg = Release|Any CPU + {1C3B4A33-E045-4C8F-9202-1B651A686567}.Portable-Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -407,5 +429,8 @@ Global {74BE0601-FF65-4B46-8A8B-E670056061C4} = {74F7C659-952F-400C-839F-90BED9BB66C3} {31AEC9B5-35C9-4FEA-8420-4C34D3FEAAC8} = {02144BF6-4489-4AFC-9B2D-0306C3DD3C19} {DA37E6A9-5D59-45A3-A809-ABA85031C369} = {02144BF6-4489-4AFC-9B2D-0306C3DD3C19} + {B6A1FC1E-0779-4900-84EE-262DD0E53FF4} = {EF9E346D-70C6-45F5-8FF9-9B734F4A1298} + {654344A5-0556-49C7-BFB3-59676D7440D3} = {B6A1FC1E-0779-4900-84EE-262DD0E53FF4} + {1C3B4A33-E045-4C8F-9202-1B651A686567} = {B6A1FC1E-0779-4900-84EE-262DD0E53FF4} EndGlobalSection EndGlobal diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj new file mode 100644 index 000000000000..079278b9d781 --- /dev/null +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj @@ -0,0 +1,87 @@ + + + + + + Debug + AnyCPU + {1C3B4A33-E045-4C8F-9202-1B651A686567} + Library + Properties + AutoRest.Generator.AzureResourceSchema.Tests + AutoRest.Generator.AzureResourceSchema.Tests + v4.5.2 + 512 + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + ..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll + True + + + ..\packages\xunit.assert.2.1.0\lib\dotnet\xunit.assert.dll + True + + + ..\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 + True + + + + + + + + + + + {654344a5-0556-49c7-bfb3-59676d7440d3} + 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}. + + + + + \ No newline at end of file diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Properties/AssemblyInfo.cs b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 000000000000..d8be4efbcaee --- /dev/null +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AutoRest.Generator.AzureResourceSchema.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AutoRest.Generator.AzureResourceSchema.Tests")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("1c3b4a33-e045-4c8f-9202-1b651a686567")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config new file mode 100644 index 000000000000..64fb5d7b3b79 --- /dev/null +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AutoRest.Generator.AzureResourceSchema.csproj b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AutoRest.Generator.AzureResourceSchema.csproj new file mode 100644 index 000000000000..9afbe46b7ef4 --- /dev/null +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AutoRest.Generator.AzureResourceSchema.csproj @@ -0,0 +1,53 @@ + + + + + Debug + AnyCPU + {654344A5-0556-49C7-BFB3-59676D7440D3} + Library + Properties + Microsoft.Rest.Generator.AzureResourceSchema + AutoRest.Generator.AzureResourceSchema + v4.5.2 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/Properties/AssemblyInfo.cs b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/Properties/AssemblyInfo.cs new file mode 100644 index 000000000000..34f7036d5899 --- /dev/null +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AutoRest.Generator.AzureResourceSchema")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AutoRest.Generator.AzureResourceSchema")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("654344a5-0556-49c7-bfb3-59676d7440d3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] From f7840bfd355ac8ec5c4b4b9bb4062bb561213959 Mon Sep 17 00:00:00 2001 From: Dan Schulte Date: Wed, 6 Apr 2016 13:08:41 -0700 Subject: [PATCH 09/96] Update AzureResourceSchema projects and add initial c# files --- AutoRest.sln | 18 ++--- ...Generator.AzureResourceSchema.Tests.csproj | 37 +++++++---- .../AzureResourceSchemaCodeGeneratorTests.cs | 65 +++++++++++++++++++ ...oRest.Generator.AzureResourceSchema.csproj | 57 ++++++++-------- .../AzureResourceSchemaCodeGenerator.cs | 59 +++++++++++++++++ 5 files changed, 182 insertions(+), 54 deletions(-) create mode 100644 AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AzureResourceSchemaCodeGeneratorTests.cs create mode 100644 AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AzureResourceSchemaCodeGenerator.cs diff --git a/AutoRest.sln b/AutoRest.sln index b11b89d798ca..46bf92830fd3 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,14 +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 = 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 - {654344A5-0556-49C7-BFB3-59676D7440D3}.Net45-Release|Any CPU.Build.0 = Release|Any CPU - {654344A5-0556-49C7-BFB3-59676D7440D3}.Portable-Debug|Any CPU.ActiveCfg = Debug|Any CPU - {654344A5-0556-49C7-BFB3-59676D7440D3}.Portable-Debug|Any CPU.Build.0 = Debug|Any CPU - {654344A5-0556-49C7-BFB3-59676D7440D3}.Portable-Release|Any CPU.ActiveCfg = Release|Any CPU - {654344A5-0556-49C7-BFB3-59676D7440D3}.Portable-Release|Any CPU.Build.0 = 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 {1C3B4A33-E045-4C8F-9202-1B651A686567}.Net45-Debug|Any CPU.ActiveCfg = Debug|Any CPU {1C3B4A33-E045-4C8F-9202-1B651A686567}.Net45-Debug|Any CPU.Build.0 = Debug|Any CPU {1C3B4A33-E045-4C8F-9202-1B651A686567}.Net45-Release|Any CPU.ActiveCfg = Release|Any CPU 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 079278b9d781..242444dbc8c0 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj @@ -1,5 +1,6 @@  - + + @@ -8,7 +9,7 @@ {1C3B4A33-E045-4C8F-9202-1B651A686567} Library Properties - AutoRest.Generator.AzureResourceSchema.Tests + Microsoft.Rest.Generator.AzureResourceSchema.Tests AutoRest.Generator.AzureResourceSchema.Tests v4.5.2 512 @@ -41,41 +42,49 @@ - - ..\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 + {654344a5-0556-49c7-bfb3-59676d7440d3} 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}. - + \ No newline at end of file diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AzureResourceSchemaCodeGenerator.cs b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AzureResourceSchemaCodeGenerator.cs new file mode 100644 index 000000000000..9a461a2fbc1d --- /dev/null +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AzureResourceSchemaCodeGenerator.cs @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; +using Microsoft.Rest.Generator.ClientModel; + +namespace Microsoft.Rest.Generator.AzureResourceSchema +{ + public class AzureResourceSchemaCodeGenerator : CodeGenerator + { + public AzureResourceSchemaCodeGenerator(Settings settings) + : base(settings) + { + } + + public override string Description + { + get + { + throw new NotImplementedException(); + } + } + + public override string ImplementationFileExtension + { + get + { + throw new NotImplementedException(); + } + } + + public override string Name + { + get + { + throw new NotImplementedException(); + } + } + + public override string UsageInstructions + { + get + { + return "MOCK USAGE INSTRUCTIONS"; + } + } + + public override Task Generate(ServiceClient serviceClient) + { + throw new NotImplementedException(); + } + + public override void NormalizeClientModel(ServiceClient serviceClient) + { + throw new NotImplementedException(); + } + } +} From 7bfc5c27b3406d02fded1323b5545ee11e61c107 Mon Sep 17 00:00:00 2001 From: Dan Schulte Date: Wed, 6 Apr 2016 13:13:34 -0700 Subject: [PATCH 10/96] Add AzureResourceSchema to configuration file --- AutoRest/AutoRest/AutoRest.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AutoRest/AutoRest/AutoRest.json b/AutoRest/AutoRest/AutoRest.json index b488b12ca1fc..c4674f06132c 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": "AzureResourceSchema, AutoRest.Generator.AzureResourceSchema" } }, "modelers": { From a8c03288fff267b363399e9c955ccdfc73d7a34e Mon Sep 17 00:00:00 2001 From: Dan Schulte Date: Wed, 6 Apr 2016 13:50:51 -0700 Subject: [PATCH 11/96] AzureResourceSchemaCodeGenerator shows up in AutoRest help and tests pass --- AutoRest/AutoRest/AutoRest.json | 2 +- .../AzureResourceSchemaCodeGeneratorTests.cs | 31 +++++++------------ .../AzureResourceSchemaCodeGenerator.cs | 22 +++---------- 3 files changed, 17 insertions(+), 38 deletions(-) diff --git a/AutoRest/AutoRest/AutoRest.json b/AutoRest/AutoRest/AutoRest.json index c4674f06132c..f368702db7a6 100644 --- a/AutoRest/AutoRest/AutoRest.json +++ b/AutoRest/AutoRest/AutoRest.json @@ -31,7 +31,7 @@ "type": "AzurePythonCodeGenerator, AutoRest.Generator.Azure.Python" }, "AzureResourceSchema": { - "type": "AzureResourceSchema, AutoRest.Generator.AzureResourceSchema" + "type": "AzureResourceSchemaCodeGenerator, AutoRest.Generator.AzureResourceSchema" } }, "modelers": { diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AzureResourceSchemaCodeGeneratorTests.cs b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AzureResourceSchemaCodeGeneratorTests.cs index 2791f0ca370b..4591537496b3 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AzureResourceSchemaCodeGeneratorTests.cs +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AzureResourceSchemaCodeGeneratorTests.cs @@ -13,53 +13,44 @@ public class AzureResourceSchemaCodeGeneratorTests [Fact] public void DescriptionThrowsException() { - Settings settings = new Settings(); - AzureResourceSchemaCodeGenerator codeGen = new AzureResourceSchemaCodeGenerator(settings); - Assert.Throws(() => { string value = codeGen.Description; }); + Assert.Equal("Azure Resource Schema generator", CreateGenerator().Description); } [Fact] public void ImplementationFileExtensionThrowsException() { - Settings settings = new Settings(); - AzureResourceSchemaCodeGenerator codeGen = new AzureResourceSchemaCodeGenerator(settings); - Assert.Throws(() => { string value = codeGen.ImplementationFileExtension; }); + Assert.Equal(".json", CreateGenerator().ImplementationFileExtension); } [Fact] public void NameThrowsException() { - Settings settings = new Settings(); - AzureResourceSchemaCodeGenerator codeGen = new AzureResourceSchemaCodeGenerator(settings); - Assert.Throws(() => { string value = codeGen.Name; }); + Assert.Equal("AzureResourceSchema", CreateGenerator().Name); } [Fact] public void UsageInstructionsThrowsException() { - Settings settings = new Settings(); - AzureResourceSchemaCodeGenerator codeGen = new AzureResourceSchemaCodeGenerator(settings); - Assert.Throws(() => { string value = codeGen.UsageInstructions; }); + Assert.Equal("MOCK USAGE INSTRUCTIONS", CreateGenerator().UsageInstructions); } [Fact] public void GenerateThrowsException() { - Settings settings = new Settings(); - AzureResourceSchemaCodeGenerator codeGen = new AzureResourceSchemaCodeGenerator(settings); - ServiceClient serviceClient = new ServiceClient(); - Assert.Throws(() => { codeGen.Generate(serviceClient); }); + Assert.Throws(() => { CreateGenerator().Generate(serviceClient); }); } [Fact] public void NormalizeClientModelThrowsException() { - Settings settings = new Settings(); - AzureResourceSchemaCodeGenerator codeGen = new AzureResourceSchemaCodeGenerator(settings); - ServiceClient serviceClient = new ServiceClient(); - Assert.Throws(() => { codeGen.NormalizeClientModel(serviceClient); }); + Assert.Throws(() => { CreateGenerator().NormalizeClientModel(serviceClient); }); + } + + private static AzureResourceSchemaCodeGenerator CreateGenerator() + { + return new AzureResourceSchemaCodeGenerator(new Settings()); } } } diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AzureResourceSchemaCodeGenerator.cs b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AzureResourceSchemaCodeGenerator.cs index 9a461a2fbc1d..e879d0b9bd2f 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AzureResourceSchemaCodeGenerator.cs +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AzureResourceSchemaCodeGenerator.cs @@ -1,9 +1,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. +using Microsoft.Rest.Generator.ClientModel; using System; using System.Threading.Tasks; -using Microsoft.Rest.Generator.ClientModel; namespace Microsoft.Rest.Generator.AzureResourceSchema { @@ -16,34 +16,22 @@ public AzureResourceSchemaCodeGenerator(Settings settings) public override string Description { - get - { - throw new NotImplementedException(); - } + get { return "Azure Resource Schema generator"; } } public override string ImplementationFileExtension { - get - { - throw new NotImplementedException(); - } + get { return ".json"; } } public override string Name { - get - { - throw new NotImplementedException(); - } + get { return "AzureResourceSchema"; } } public override string UsageInstructions { - get - { - return "MOCK USAGE INSTRUCTIONS"; - } + get { return "MOCK USAGE INSTRUCTIONS"; } } public override Task Generate(ServiceClient serviceClient) From 39b4b190dfe0098bdb93c3075b93b651ba554d7d Mon Sep 17 00:00:00 2001 From: Qinyuan Wan Date: Wed, 6 Apr 2016 15:54:30 -0700 Subject: [PATCH 12/96] 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 fa2e530176f8..5d462e43b35c 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 13/96] 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 f358540bb6aa..98c1e78c2d47 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 14/96] 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 5d462e43b35c..c81827aa1906 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 15/96] 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 c81827aa1906..7e07c3aea86a 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 ffb8fa38eb401baf3da49776985a63c9d4e9c61c Mon Sep 17 00:00:00 2001 From: Dan Schulte Date: Thu, 7 Apr 2016 13:58:34 -0700 Subject: [PATCH 16/96] Almost have Storage schema generating from swagger spec --- ...Generator.AzureResourceSchema.Tests.csproj | 4 + .../AzureResourceSchemaCodeGeneratorTests.cs | 123 ++++++++++++-- .../AzureResourceSchema.Tests/packages.config | 1 + ...oRest.Generator.AzureResourceSchema.csproj | 7 + .../AzureResourceSchemaCodeGenerator.cs | 153 +++++++++++++++++- .../AzureResourceSchema/packages.config | 4 + 6 files changed, 275 insertions(+), 17 deletions(-) create mode 100644 AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/packages.config 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 242444dbc8c0..dda8fa1fd640 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj @@ -34,6 +34,10 @@ 4 + + ..\..\..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + True + diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AzureResourceSchemaCodeGeneratorTests.cs b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AzureResourceSchemaCodeGeneratorTests.cs index 4591537496b3..c5c37c0a235f 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AzureResourceSchemaCodeGeneratorTests.cs +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AzureResourceSchemaCodeGeneratorTests.cs @@ -2,7 +2,10 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using Microsoft.Rest.Generator.ClientModel; -using System; +using Microsoft.Rest.Generator.Utilities; +using Newtonsoft.Json.Linq; +using System.Linq; +using System.Threading.Tasks; using Xunit; namespace Microsoft.Rest.Generator.AzureResourceSchema.Tests @@ -11,46 +14,142 @@ namespace Microsoft.Rest.Generator.AzureResourceSchema.Tests public class AzureResourceSchemaCodeGeneratorTests { [Fact] - public void DescriptionThrowsException() + public void Description() { Assert.Equal("Azure Resource Schema generator", CreateGenerator().Description); } [Fact] - public void ImplementationFileExtensionThrowsException() + public void ImplementationFileExtension() { Assert.Equal(".json", CreateGenerator().ImplementationFileExtension); } [Fact] - public void NameThrowsException() + public void Name() { Assert.Equal("AzureResourceSchema", CreateGenerator().Name); } [Fact] - public void UsageInstructionsThrowsException() + public void UsageInstructionsWithNoOutputFileSetting() { - Assert.Equal("MOCK USAGE INSTRUCTIONS", CreateGenerator().UsageInstructions); + AzureResourceSchemaCodeGenerator codeGen = CreateGenerator(); + Assert.Equal("Your Azure Resource Schema can be found at " + codeGen.SchemaPath, codeGen.UsageInstructions); } [Fact] - public void GenerateThrowsException() + public void UsageInstructionsWithOutputFileSetting() { - ServiceClient serviceClient = new ServiceClient(); - Assert.Throws(() => { CreateGenerator().Generate(serviceClient); }); + Settings settings = new Settings() + { + OutputFileName = "spam.json" + }; + AzureResourceSchemaCodeGenerator codeGen = CreateGenerator(settings); + + Assert.Equal("Your Azure Resource Schema can be found at " + codeGen.SchemaPath, codeGen.UsageInstructions); + } + + [Fact] + public async void GenerateWithEmptyServiceClient() + { + await TestGenerate(new string[0], + @"{ + 'id': 'http://schema.management.azure.com/schemas//Microsoft.Storage.json#', + '$schema': 'http://json-schema.org/draft-04/schema#', + 'title': 'Microsoft.Storage', + 'description': 'Microsoft Storage Resource Types', + 'resourceDefinitions': { } + }"); + } + + [Fact] + public async void GenerateWithServiceClientWithOneType() + { + await TestGenerate(new string[] + { + "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Mock.Provider/mockType" + }, + @"{ + 'id': 'http://schema.management.azure.com/schemas//Microsoft.Storage.json#', + '$schema': 'http://json-schema.org/draft-04/schema#', + 'title': 'Microsoft.Storage', + 'description': 'Microsoft Storage Resource Types', + 'resourceDefinitions': { + 'mockType': { + } + } + }"); + } + + [Fact] + public async void GenerateWithServiceClientWithTwoTypes() + { + await TestGenerate(new string[] + { + "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Mock.Provider/mockType1", + "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Mock.Provider/mockType2" + }, + @"{ + 'id': 'http://schema.management.azure.com/schemas//Microsoft.Storage.json#', + '$schema': 'http://json-schema.org/draft-04/schema#', + 'title': 'Microsoft.Storage', + 'description': 'Microsoft Storage Resource Types', + 'resourceDefinitions': { + 'mockType1': { + }, + 'mockType2': { + } + } + }"); } [Fact] - public void NormalizeClientModelThrowsException() + public void NormalizeClientModelDoesNothing() { ServiceClient serviceClient = new ServiceClient(); - Assert.Throws(() => { CreateGenerator().NormalizeClientModel(serviceClient); }); + CreateGenerator().NormalizeClientModel(serviceClient); + + // Nothing happens } private static AzureResourceSchemaCodeGenerator CreateGenerator() { - return new AzureResourceSchemaCodeGenerator(new Settings()); + return CreateGenerator(new Settings()); + } + private static AzureResourceSchemaCodeGenerator CreateGenerator(Settings settings) + { + return new AzureResourceSchemaCodeGenerator(settings); + } + + private static async Task TestGenerate(string[] methodUrls, string expectedJsonString) + { + MemoryFileSystem fileSystem = new MemoryFileSystem(); + + Settings settings = new Settings(); + settings.FileSystem = fileSystem; + + ServiceClient serviceClient = new ServiceClient(); + foreach(string methodUrl in methodUrls) + { + serviceClient.Methods.Add(new Method() + { + Url = methodUrl + }); + } + await CreateGenerator(settings).Generate(serviceClient); + + Assert.Equal(2, fileSystem.VirtualStore.Count); + + string folderPath = fileSystem.VirtualStore.Keys.First(); + Assert.Equal("Folder", fileSystem.VirtualStore[folderPath].ToString()); + + JObject expectedJSON = JObject.Parse(expectedJsonString); + + string fileContents = fileSystem.VirtualStore[fileSystem.VirtualStore.Keys.Skip(1).First()].ToString(); + JObject actualJson = JObject.Parse(fileContents); + + Assert.Equal(expectedJSON, actualJson); } } } diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config index 64fb5d7b3b79..c2c499b747eb 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config @@ -1,5 +1,6 @@  + diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AutoRest.Generator.AzureResourceSchema.csproj b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AutoRest.Generator.AzureResourceSchema.csproj index f934e945c6e9..5b00abb1fff4 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AutoRest.Generator.AzureResourceSchema.csproj +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AutoRest.Generator.AzureResourceSchema.csproj @@ -20,6 +20,10 @@ 4 + + ..\..\..\..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + True + @@ -44,5 +48,8 @@ CustomDictionary.xml + + + \ No newline at end of file diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AzureResourceSchemaCodeGenerator.cs b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AzureResourceSchemaCodeGenerator.cs index e879d0b9bd2f..5d5df37291ca 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AzureResourceSchemaCodeGenerator.cs +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/AzureResourceSchemaCodeGenerator.cs @@ -2,18 +2,33 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using Microsoft.Rest.Generator.ClientModel; +using Newtonsoft.Json; using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; using System.Threading.Tasks; namespace Microsoft.Rest.Generator.AzureResourceSchema { public class AzureResourceSchemaCodeGenerator : CodeGenerator { + private const string resourceMethodPrefix = "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/"; + public AzureResourceSchemaCodeGenerator(Settings settings) : base(settings) { } + public string SchemaPath + { + get + { + string defaultSchemaFileName = Path.GetFileNameWithoutExtension(Settings.Input) + ".schema.json"; + return Path.Combine(Settings.OutputDirectory, Settings.OutputFileName ?? defaultSchemaFileName); + } + } + public override string Description { get { return "Azure Resource Schema generator"; } @@ -31,17 +46,145 @@ public override string Name public override string UsageInstructions { - get { return "MOCK USAGE INSTRUCTIONS"; } + get { return "Your Azure Resource Schema can be found at " + SchemaPath; } } - public override Task Generate(ServiceClient serviceClient) + public override void NormalizeClientModel(ServiceClient serviceClient) { - throw new NotImplementedException(); } - public override void NormalizeClientModel(ServiceClient serviceClient) + public override async Task Generate(ServiceClient serviceClient) { - throw new NotImplementedException(); + StringWriter stringWriter = new StringWriter(); + using (JsonTextWriter writer = new JsonTextWriter(stringWriter)) + { + writer.Formatting = Formatting.Indented; + writer.Indentation = 2; + writer.IndentChar = ' '; + + string resourceProvider = GetResourceProvider(serviceClient); + IEnumerable resourceFullTypes = GetResourceFullTypes(serviceClient); + + WriteObject(writer, () => { + WriteProperty(writer, "id", string.Format("http://schema.management.azure.com/schemas/{0}/Microsoft.Storage.json#", serviceClient.ApiVersion)); + WriteProperty(writer, "$schema", "http://json-schema.org/draft-04/schema#"); + WriteProperty(writer, "title", resourceProvider); + WriteProperty(writer, "description", resourceProvider.Replace('.', ' ') + " Resource Types"); + WriteProperty(writer, "resourceDefinitions", () => { + foreach (string resourceFullType in resourceFullTypes) + { + string resourceShortType = resourceFullType.Substring(resourceFullType.IndexOf('/') + 1); + + WriteProperty(writer, resourceShortType, () => { + WriteProperty(writer, "type", "object"); + WriteProperty(writer, "properties", () => { + WriteProperty(writer, "type", () => { + WriteProperty(writer, "enum", new string[] { + resourceFullType + }); + }); + WriteProperty(writer, "apiVersion", () => { + WriteProperty(writer, "enum", new string[] { + serviceClient.ApiVersion + }); + }); + WriteProperty(writer, "properties", () => { + WriteProperty(writer, "type", "object"); + WriteProperty(writer, "properties", () => { + }); + WriteProperty(writer, "required", new string[0]); + }); + }); + WriteProperty(writer, "required", new string[] { + "type", + "apiVersion", + "properties", + "location" + }); + WriteProperty(writer, "description", resourceFullType); + }); + } + }); + }); + } + + await Write(stringWriter.ToString(), SchemaPath); + } + + private static IEnumerable GetResourceMethods(ServiceClient serviceClient) + { + return GetResourceMethods(serviceClient.Methods); + } + + private static IEnumerable GetResourceMethods(IEnumerable methods) + { + return methods.Where(m => m.Url.StartsWith(resourceMethodPrefix)); + } + + private static IEnumerable GetResourceMethodUrisAfterPrefix(ServiceClient serviceClient) + { + IEnumerable resourceMethods = GetResourceMethods(serviceClient); + IEnumerable resourceMethodUris = resourceMethods.Select(rm => rm.Url); + return resourceMethodUris.Select(rmu => rmu.Substring(resourceMethodPrefix.Length)); + } + + private static string GetResourceProvider(ServiceClient serviceClient) + { + IEnumerable resourceMethodUrisAfterPrefix = GetResourceMethodUrisAfterPrefix(serviceClient); + return resourceMethodUrisAfterPrefix.Select(rmuap => rmuap.Substring(0, rmuap.IndexOf('/'))).Distinct().Single(); + } + + private static IEnumerable GetResourceFullTypes(ServiceClient serviceClient) + { + IEnumerable resourceMethodUrisAfterPrefix = GetResourceMethodUrisAfterPrefix(serviceClient); + return resourceMethodUrisAfterPrefix.Select(rmuap => + { + int forwardSlashAfterProvider = rmuap.IndexOf('/'); + int forwardSlashAfterType = rmuap.IndexOf('/', forwardSlashAfterProvider + 1); + int startIndex = forwardSlashAfterProvider + 1; + if (forwardSlashAfterType == -1) + { + return rmuap; + } + else + { + return rmuap.Substring(0, forwardSlashAfterType); + } + }).Distinct(); + } + + private static void WriteObject(JsonTextWriter writer, Action writeObjectContents) + { + writer.WriteStartObject(); + + writeObjectContents.Invoke(); + + writer.WriteEndObject(); + } + + private static void WriteProperty(JsonTextWriter writer, string propertyName, string propertyValue) + { + writer.WritePropertyName(propertyName); + writer.WriteValue(propertyValue); + } + + private static void WriteProperty(JsonTextWriter writer, string propertyName, Action writeObjectContents) + { + writer.WritePropertyName(propertyName); + WriteObject(writer, writeObjectContents); + } + + private static void WriteProperty(JsonTextWriter writer, string propertyName, string[] writeArrayContents) + { + writer.WritePropertyName(propertyName); + writer.WriteStartArray(); + + foreach (string value in writeArrayContents) + { + writer.WriteValue(value); + } + + writer.WriteEndArray(); } } } diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/packages.config b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/packages.config new file mode 100644 index 000000000000..505e58836bae --- /dev/null +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From 5b4ca29a393a30f1f452436996d952e0aa868c3a Mon Sep 17 00:00:00 2001 From: Qinyuan Wan Date: Thu, 7 Apr 2016 14:13:09 -0700 Subject: [PATCH 17/96] 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 f3cb1fecfb34..bacca9fd614a 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 33fff6078369..850509ad638e 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 b0cc6a272fd5..f403121e6dfe 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 9dc6656111ba..3d4d296e68aa 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 95a519d366c9..a6fbcc9e356e 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 7e07c3aea86a..e0207511c4c3 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 98c1e78c2d47..3a56e378e4d9 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 63b9fd6403b55679f7a35931b880812f51456f1b Mon Sep 17 00:00:00 2001 From: Amar Zavery Date: Thu, 7 Apr 2016 21:17:27 -0700 Subject: [PATCH 18/96] Enhancement to x-ms-parameterized-host extension --- ...Generator.AzureResourceSchema.Tests.csproj | 4 +- .../AzureResourceSchema.Tests/packages.config | 14 +- .../CSharp/CSharp.Tests/AcceptanceTests.cs | 16 ++ ...toRestParameterizedCustomHostTestClient.cs | 128 +++++++++ ...toRestParameterizedCustomHostTestClient.cs | 57 ++++ .../CustomBaseUriMoreOptions/IPaths.cs | 47 ++++ .../CustomBaseUriMoreOptions/Models/Error.cs | 45 ++++ .../Models/ErrorException.cs | 99 +++++++ .../CustomBaseUriMoreOptions/Paths.cs | 203 +++++++++++++++ .../PathsExtensions.cs | 74 ++++++ .../Extensions/Extensions/Extensions.cs | 57 +++- .../Properties/Resources.Designer.cs | 9 + .../Extensions/Properties/Resources.resx | 3 + ...RestParameterizedCustomHostTestClient.java | 86 ++++++ ...ParameterizedCustomHostTestClientImpl.java | 121 +++++++++ .../PathsOperations.java | 75 ++++++ .../PathsOperationsImpl.java | 245 ++++++++++++++++++ .../models/Error.java | 64 +++++ .../models/ErrorException.java | 89 +++++++ .../models/package-info.java | 13 + .../package-info.java | 13 + .../AcceptanceTests/acceptanceTests.ts | 15 +- ...RestParameterizedCustomHostTestClient.d.ts | 44 ++++ ...toRestParameterizedCustomHostTestClient.js | 65 +++++ .../models/errorModel.js | 58 +++++ .../models/index.d.ts | 24 ++ .../CustomBaseUriMoreOptions/models/index.js | 17 ++ .../operations/index.d.ts | 44 ++++ .../operations/index.js | 17 ++ .../operations/paths.js | 167 ++++++++++++ .../__init__.py | 21 ++ ...t_parameterized_custom_host_test_client.py | 69 +++++ .../credentials.py | 15 ++ .../exceptions.py | 21 ++ .../models/__init__.py | 16 ++ .../models/error.py | 44 ++++ .../operations/__init__.py | 16 ++ .../operations/paths.py | 87 +++++++ .../version.py | 13 + .../CustomBaseUriMoreOptions/setup.py | 40 +++ .../Python/Python.Tests/Python.Tests.pyproj | 4 + AutoRest/TestServer/server/app.js | 2 + .../TestServer/server/routes/customUri.js | 11 + .../swagger/custom-baseUrl-more-options.json | 109 ++++++++ Documentation/swagger-extensions.md | 2 + gulpfile.js | 3 +- schema/swagger-extensions.json | 9 + 47 files changed, 2378 insertions(+), 17 deletions(-) create mode 100644 AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/AutoRestParameterizedCustomHostTestClient.cs create mode 100644 AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IAutoRestParameterizedCustomHostTestClient.cs create mode 100644 AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IPaths.cs create mode 100644 AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/Error.cs create mode 100644 AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/ErrorException.cs create mode 100644 AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Paths.cs create mode 100644 AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/PathsExtensions.cs create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClient.java create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClientImpl.java create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperations.java create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperationsImpl.java create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/Error.java create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/ErrorException.java create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/package-info.java create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/package-info.java create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.d.ts create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.js create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/errorModel.js create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.d.ts create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.js create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.d.ts create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.js create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/paths.js create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/__init__.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/auto_rest_parameterized_custom_host_test_client.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/credentials.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/exceptions.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/__init__.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/error.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/__init__.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/paths.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/version.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/setup.py create mode 100644 AutoRest/TestServer/swagger/custom-baseUrl-more-options.json 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 079278b9d781..01522ea89f2b 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj @@ -62,7 +62,9 @@ - + + PreserveNewest + diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config index 64fb5d7b3b79..4e690e09d9de 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config @@ -1,10 +1,10 @@  - - - - - - - + + + + + + + \ No newline at end of file diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs b/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs index 0c6e31b1c146..0d5c31f0e518 100644 --- a/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs +++ b/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs @@ -50,6 +50,7 @@ using Fixtures.PetstoreV2; using Fixtures.AcceptanceTestsCompositeBoolIntClient; using Fixtures.AcceptanceTestsCustomBaseUri; +using Fixtures.AcceptanceTestsCustomBaseUriMoreOptions; using System.Net.Http; using Fixtures.AcceptanceTestsModelFlattening; using Fixtures.AcceptanceTestsModelFlattening.Models; @@ -1951,6 +1952,21 @@ public void CustomBaseUriTests() } } + [Fact] + public void CustomBaseUriMoreOptionsTests() + { + SwaggerSpecRunner.RunTests( + SwaggerPath("custom-baseUrl-more-options.json"), ExpectedPath("CustomBaseUriMoreOptions")); + using (var client = new AutoRestParameterizedCustomHostTestClient()) + { + client.SubscriptionId = "test12"; + // small modification to the "host" portion to include the port and the '.' + client.DnsSuffix = string.Format(CultureInfo.InvariantCulture, "{0}.:{1}", "host", Fixture.Port); + Assert.Equal(HttpStatusCode.OK, + client.Paths.GetEmptyWithHttpMessagesAsync("http://lo", "cal", "key1").Result.Response.StatusCode); + } + } + [Fact] public void CustomBaseUriNegativeTests() { diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/AutoRestParameterizedCustomHostTestClient.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/AutoRestParameterizedCustomHostTestClient.cs new file mode 100644 index 000000000000..e680cbe6a873 --- /dev/null +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/AutoRestParameterizedCustomHostTestClient.cs @@ -0,0 +1,128 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +namespace Fixtures.AcceptanceTestsCustomBaseUriMoreOptions +{ + using System; + using System.Linq; + using System.Collections.Generic; + using System.Diagnostics; + using System.Net; + using System.Net.Http; + using System.Net.Http.Headers; + using System.Text; + using System.Text.RegularExpressions; + using System.Threading; + using System.Threading.Tasks; + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Newtonsoft.Json; + using Models; + + /// + /// Test Infrastructure for AutoRest + /// + public partial class AutoRestParameterizedCustomHostTestClient : ServiceClient, IAutoRestParameterizedCustomHostTestClient + { + /// + /// The base URI of the service. + /// + internal string BaseUri {get; set;} + + /// + /// Gets or sets json serialization settings. + /// + public JsonSerializerSettings SerializationSettings { get; private set; } + + /// + /// Gets or sets json deserialization settings. + /// + public JsonSerializerSettings DeserializationSettings { get; private set; } + + /// + /// The subscription id with value 'test12'. + /// + public string SubscriptionId { get; set; } + + /// + /// A string value that is used as a global part of the parameterized host. + /// Default value 'host'. + /// + public string DnsSuffix { get; set; } + + /// + /// Gets the IPaths. + /// + public virtual IPaths Paths { get; private set; } + + /// + /// Initializes a new instance of the AutoRestParameterizedCustomHostTestClient class. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + public AutoRestParameterizedCustomHostTestClient(params DelegatingHandler[] handlers) : base(handlers) + { + this.Initialize(); + } + + /// + /// Initializes a new instance of the AutoRestParameterizedCustomHostTestClient class. + /// + /// + /// Optional. The http client handler used to handle http transport. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + public AutoRestParameterizedCustomHostTestClient(HttpClientHandler rootHandler, params DelegatingHandler[] handlers) : base(rootHandler, handlers) + { + this.Initialize(); + } + + /// + /// An optional partial-method to perform custom initialization. + /// + partial void CustomInitialize(); + /// + /// Initializes client properties. + /// + private void Initialize() + { + this.Paths = new Paths(this); + this.BaseUri = "{vault}{secret}{dnsSuffix}"; + this.DnsSuffix = "host"; + SerializationSettings = new JsonSerializerSettings + { + Formatting = Formatting.Indented, + DateFormatHandling = DateFormatHandling.IsoDateFormat, + DateTimeZoneHandling = DateTimeZoneHandling.Utc, + NullValueHandling = NullValueHandling.Ignore, + ReferenceLoopHandling = ReferenceLoopHandling.Serialize, + ContractResolver = new ReadOnlyJsonContractResolver(), + Converters = new List + { + new Iso8601TimeSpanConverter() + } + }; + DeserializationSettings = new JsonSerializerSettings + { + DateFormatHandling = DateFormatHandling.IsoDateFormat, + DateTimeZoneHandling = DateTimeZoneHandling.Utc, + NullValueHandling = NullValueHandling.Ignore, + ReferenceLoopHandling = ReferenceLoopHandling.Serialize, + ContractResolver = new ReadOnlyJsonContractResolver(), + Converters = new List + { + new Iso8601TimeSpanConverter() + } + }; + CustomInitialize(); + } + } +} diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IAutoRestParameterizedCustomHostTestClient.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IAutoRestParameterizedCustomHostTestClient.cs new file mode 100644 index 000000000000..87db999d81c4 --- /dev/null +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IAutoRestParameterizedCustomHostTestClient.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +namespace Fixtures.AcceptanceTestsCustomBaseUriMoreOptions +{ + using System; + using System.Collections.Generic; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + using Newtonsoft.Json; + using Microsoft.Rest; + using Models; + + /// + /// Test Infrastructure for AutoRest + /// + public partial interface IAutoRestParameterizedCustomHostTestClient : IDisposable + { + /// + /// The base URI of the service. + /// + + /// + /// Gets or sets json serialization settings. + /// + JsonSerializerSettings SerializationSettings { get; } + + /// + /// Gets or sets json deserialization settings. + /// + JsonSerializerSettings DeserializationSettings { get; } + + /// + /// The subscription id with value 'test12'. + /// + string SubscriptionId { get; set; } + + /// + /// A string value that is used as a global part of the parameterized + /// host. Default value 'host'. + /// + string DnsSuffix { get; set; } + + + /// + /// Gets the IPaths. + /// + IPaths Paths { get; } + + } +} diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IPaths.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IPaths.cs new file mode 100644 index 000000000000..a117b914e752 --- /dev/null +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IPaths.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +namespace Fixtures.AcceptanceTestsCustomBaseUriMoreOptions +{ + using System; + using System.Collections.Generic; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + using Microsoft.Rest; + using Models; + + /// + /// Paths operations. + /// + public partial interface IPaths + { + /// + /// Get a 200 to test a valid base uri + /// + /// + /// The vault name, e.g. https://myvault + /// + /// + /// Secret value. + /// + /// + /// The key name with value 'key1'. + /// + /// + /// The key version. Default value 'v1'. + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + Task GetEmptyWithHttpMessagesAsync(string vault, string secret, string keyName, string keyVersion = "v1", Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + } +} diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/Error.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/Error.cs new file mode 100644 index 000000000000..82a4873e6138 --- /dev/null +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/Error.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +namespace Fixtures.AcceptanceTestsCustomBaseUriMoreOptions.Models +{ + using System; + using System.Linq; + using System.Collections.Generic; + using Newtonsoft.Json; + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + + public partial class Error + { + /// + /// Initializes a new instance of the Error class. + /// + public Error() { } + + /// + /// Initializes a new instance of the Error class. + /// + public Error(int? status = default(int?), string message = default(string)) + { + Status = status; + Message = message; + } + + /// + /// + [JsonProperty(PropertyName = "status")] + public int? Status { get; set; } + + /// + /// + [JsonProperty(PropertyName = "message")] + public string Message { get; set; } + + } +} diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/ErrorException.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/ErrorException.cs new file mode 100644 index 000000000000..e3ab1c0a08ab --- /dev/null +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/ErrorException.cs @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +namespace Fixtures.AcceptanceTestsCustomBaseUriMoreOptions.Models +{ + using Microsoft.Rest; + using System; + using System.Net.Http; + using System.Runtime.Serialization; +#if !PORTABLE && !DNXCORE50 + using System.Security.Permissions; +#endif + + /// + /// Exception thrown for an invalid response with Error information. + /// +#if !PORTABLE && !DNXCORE50 + [Serializable] +#endif + public class ErrorException : RestException + { + /// + /// Gets information about the associated HTTP request. + /// + public HttpRequestMessageWrapper Request { get; set; } + + /// + /// Gets information about the associated HTTP response. + /// + public HttpResponseMessageWrapper Response { get; set; } + + /// + /// Gets or sets the body object. + /// + public Error Body { get; set; } + + /// + /// Initializes a new instance of the ErrorException class. + /// + public ErrorException() + { + } + + /// + /// Initializes a new instance of the ErrorException class. + /// + /// The exception message. + public ErrorException(string message) + : this(message, null) + { + } + + /// + /// Initializes a new instance of the ErrorException class. + /// + /// The exception message. + /// Inner exception. + public ErrorException(string message, Exception innerException) + : base(message, innerException) + { + } + +#if !PORTABLE && !DNXCORE50 + /// + /// Initializes a new instance of the ErrorException class. + /// + /// Serialization info. + /// Streaming context. + protected ErrorException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Serializes content of the exception. + /// + /// Serialization info. + /// Streaming context. + [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + if (info == null) + { + throw new ArgumentNullException("info"); + } + + info.AddValue("Request", Request); + info.AddValue("Response", Response); + info.AddValue("Body", Body); + } +#endif + } +} diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Paths.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Paths.cs new file mode 100644 index 000000000000..a8599cf08338 --- /dev/null +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Paths.cs @@ -0,0 +1,203 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +namespace Fixtures.AcceptanceTestsCustomBaseUriMoreOptions +{ + using System; + using System.Linq; + using System.Collections.Generic; + using System.Net; + using System.Net.Http; + using System.Net.Http.Headers; + using System.Text; + using System.Text.RegularExpressions; + using System.Threading; + using System.Threading.Tasks; + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Newtonsoft.Json; + using Models; + + /// + /// Paths operations. + /// + public partial class Paths : IServiceOperations, IPaths + { + /// + /// Initializes a new instance of the Paths class. + /// + /// + /// Reference to the service client. + /// + public Paths(AutoRestParameterizedCustomHostTestClient client) + { + if (client == null) + { + throw new ArgumentNullException("client"); + } + this.Client = client; + } + + /// + /// Gets a reference to the AutoRestParameterizedCustomHostTestClient + /// + public AutoRestParameterizedCustomHostTestClient Client { get; private set; } + + /// + /// Get a 200 to test a valid base uri + /// + /// + /// The vault name, e.g. https://myvault + /// + /// + /// Secret value. + /// + /// + /// The key name with value 'key1'. + /// + /// + /// The key version. Default value 'v1'. + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task GetEmptyWithHttpMessagesAsync(string vault, string secret, string keyName, string keyVersion = "v1", Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + if (vault == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "vault"); + } + if (secret == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "secret"); + } + if (this.Client.DnsSuffix == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "this.Client.DnsSuffix"); + } + if (keyName == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "keyName"); + } + if (this.Client.SubscriptionId == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "this.Client.SubscriptionId"); + } + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("vault", vault); + tracingParameters.Add("secret", secret); + tracingParameters.Add("keyName", keyName); + tracingParameters.Add("keyVersion", keyVersion); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "GetEmpty", tracingParameters); + } + // Construct URL + var _baseUrl = this.Client.BaseUri; + var _url = _baseUrl + (_baseUrl.EndsWith("/") ? "" : "/") + "customuri/{subscriptionId}/{keyName}"; + _url = _url.Replace("{vault}", vault); + _url = _url.Replace("{secret}", secret); + _url = _url.Replace("{dnsSuffix}", this.Client.DnsSuffix); + _url = _url.Replace("{keyName}", Uri.EscapeDataString(keyName)); + _url = _url.Replace("{subscriptionId}", Uri.EscapeDataString(this.Client.SubscriptionId)); + List _queryParameters = new List(); + if (keyVersion != null) + { + _queryParameters.Add(string.Format("keyVersion={0}", Uri.EscapeDataString(keyVersion))); + } + if (_queryParameters.Count > 0) + { + _url += "?" + string.Join("&", _queryParameters); + } + // Create HTTP transport objects + HttpRequestMessage _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new Uri(_url); + // Set Headers + 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; + // 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) + { + var ex = new ErrorException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + try + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + Error _errorBody = SafeJsonConvert.DeserializeObject(_responseContent, this.Client.DeserializationSettings); + if (_errorBody != null) + { + ex.Body = _errorBody; + } + } + catch (JsonException) + { + // Ignore the exception + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + } +} diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/PathsExtensions.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/PathsExtensions.cs new file mode 100644 index 000000000000..c553414304ed --- /dev/null +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/PathsExtensions.cs @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +namespace Fixtures.AcceptanceTestsCustomBaseUriMoreOptions +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Threading; + using System.Threading.Tasks; + using Microsoft.Rest; + using Models; + + /// + /// Extension methods for Paths. + /// + public static partial class PathsExtensions + { + /// + /// Get a 200 to test a valid base uri + /// + /// + /// The operations group for this extension method. + /// + /// + /// The vault name, e.g. https://myvault + /// + /// + /// Secret value. + /// + /// + /// The key name with value 'key1'. + /// + /// + /// The key version. Default value 'v1'. + /// + public static void GetEmpty(this IPaths operations, string vault, string secret, string keyName, string keyVersion = "v1") + { + Task.Factory.StartNew(s => ((IPaths)s).GetEmptyAsync(vault, secret, keyName, keyVersion), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult(); + } + + /// + /// Get a 200 to test a valid base uri + /// + /// + /// The operations group for this extension method. + /// + /// + /// The vault name, e.g. https://myvault + /// + /// + /// Secret value. + /// + /// + /// The key name with value 'key1'. + /// + /// + /// The key version. Default value 'v1'. + /// + /// + /// The cancellation token. + /// + public static async Task GetEmptyAsync(this IPaths operations, string vault, string secret, string keyName, string keyVersion = "v1", CancellationToken cancellationToken = default(CancellationToken)) + { + await operations.GetEmptyWithHttpMessagesAsync(vault, secret, keyName, keyVersion, null, cancellationToken).ConfigureAwait(false); + } + + } +} diff --git a/AutoRest/Generators/Extensions/Extensions/Extensions.cs b/AutoRest/Generators/Extensions/Extensions/Extensions.cs index e974d9563af2..b80820b8c0c5 100644 --- a/AutoRest/Generators/Extensions/Extensions/Extensions.cs +++ b/AutoRest/Generators/Extensions/Extensions/Extensions.cs @@ -12,6 +12,8 @@ using Microsoft.Rest.Modeler.Swagger.Model; using Newtonsoft.Json.Linq; using Newtonsoft.Json; +using System.Text.RegularExpressions; +using Microsoft.Rest.Generator.Properties; namespace Microsoft.Rest.Generator { @@ -27,6 +29,8 @@ public abstract class Extensions public const string FlattenOriginalTypeName = "x-ms-client-flatten-original-type-name"; public const string ParameterGroupExtension = "x-ms-parameter-grouping"; public const string ParameterizedHostExtension = "x-ms-parameterized-host"; + public const string UseSchemePrefix = "useSchemePrefix"; + public const string PositionInOperation = "positionInOperation"; private static bool hostChecked = false; @@ -67,6 +71,28 @@ public static void ProcessParameterizedHost(ServiceClient serviceClient, Setting { var hostTemplate = (string)hostExtension["hostTemplate"]; var parametersJson = hostExtension["parameters"].ToString(); + var useSchemePrefix = true; + if (hostExtension[UseSchemePrefix] != null) + { + useSchemePrefix = bool.Parse(hostExtension[UseSchemePrefix].ToString()); + } + + var position = "last"; + + if (hostExtension[PositionInOperation] != null) + { + var pat = "^(fir|la)st$"; + Regex r = new Regex(pat, RegexOptions.IgnoreCase); + var text = hostExtension[PositionInOperation].ToString(); + Match m = r.Match(text); + if (!m.Success) + { + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, + Resources.InvalidExtensionProperty, text, PositionInOperation, ParameterizedHostExtension, "first, last")); + } + position = text; + } + if (!string.IsNullOrEmpty(parametersJson)) { var jsonSettings = new JsonSerializerSettings @@ -76,7 +102,7 @@ public static void ProcessParameterizedHost(ServiceClient serviceClient, Setting }; var swaggerParams = JsonConvert.DeserializeObject>(parametersJson, jsonSettings); - + List hostParamList = new List(); foreach (var swaggerParameter in swaggerParams) { // Build parameter @@ -89,16 +115,33 @@ public static void ProcessParameterizedHost(ServiceClient serviceClient, Setting parameter.ClientProperty = serviceClient.Properties.Single(p => p.SerializedName.Equals(parameter.SerializedName)); } parameter.Extensions["hostParameter"] = true; + hostParamList.Add(parameter); + } - foreach (var method in serviceClient.Methods) + foreach (var method in serviceClient.Methods) + { + if (position.Equals("first", StringComparison.OrdinalIgnoreCase)) { - method.Parameters.Add(parameter); + method.Parameters.InsertRange(0, hostParamList); } + else + { + method.Parameters.AddRange(hostParamList); + } + } - - serviceClient.BaseUrl = string.Format(CultureInfo.InvariantCulture, "{0}://{1}{2}", - modeler.ServiceDefinition.Schemes[0].ToString().ToLowerInvariant(), - hostTemplate, modeler.ServiceDefinition.BasePath); + if (useSchemePrefix) + { + serviceClient.BaseUrl = string.Format(CultureInfo.InvariantCulture, "{0}://{1}{2}", + modeler.ServiceDefinition.Schemes[0].ToString().ToLowerInvariant(), + hostTemplate, modeler.ServiceDefinition.BasePath); + } + else + { + serviceClient.BaseUrl = string.Format(CultureInfo.InvariantCulture, "{0}{1}", + hostTemplate, modeler.ServiceDefinition.BasePath); + } + } } } diff --git a/AutoRest/Generators/Extensions/Extensions/Properties/Resources.Designer.cs b/AutoRest/Generators/Extensions/Extensions/Properties/Resources.Designer.cs index 689a601b826f..f98e2ea0b022 100644 --- a/AutoRest/Generators/Extensions/Extensions/Properties/Resources.Designer.cs +++ b/AutoRest/Generators/Extensions/Extensions/Properties/Resources.Designer.cs @@ -69,6 +69,15 @@ internal class Resources { } } + /// + /// Looks up a localized string similar to The value '{0}' provided for property '{1}' of extension '{2} is invalid. Valid values are: '{3}'.. + /// + internal static string InvalidExtensionProperty { + get { + return ResourceManager.GetString("InvalidExtensionProperty", resourceCulture); + } + } + /// /// Looks up a localized string similar to Azure resource {0} is missing required 'properties' property.. /// diff --git a/AutoRest/Generators/Extensions/Extensions/Properties/Resources.resx b/AutoRest/Generators/Extensions/Extensions/Properties/Resources.resx index d06a580a716f..7df584f0a47a 100644 --- a/AutoRest/Generators/Extensions/Extensions/Properties/Resources.resx +++ b/AutoRest/Generators/Extensions/Extensions/Properties/Resources.resx @@ -120,6 +120,9 @@ Head method '{0}' should contain only 200 level responses, or 404. + + The value '{0}' provided for property '{1}' of extension '{2} is invalid. Valid values are: '{3}'. + Azure resource {0} is missing required 'properties' property. diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClient.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClient.java new file mode 100644 index 000000000000..7c5bb29be05d --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClient.java @@ -0,0 +1,86 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +package fixtures.custombaseurimoreoptions; + +import java.util.List; +import okhttp3.Interceptor; +import okhttp3.logging.HttpLoggingInterceptor.Level; +import com.microsoft.rest.AutoRestBaseUrl; +import com.microsoft.rest.serializer.JacksonMapperAdapter; + +/** + * The interface for AutoRestParameterizedCustomHostTestClient class. + */ +public interface AutoRestParameterizedCustomHostTestClient { + /** + * Gets the URL used as the base for all cloud service requests. + * + * @return the BaseUrl object. + */ + AutoRestBaseUrl getBaseUrl(); + + /** + * Gets the list of interceptors the OkHttp client will execute. + * + * @return the list of interceptors. + */ + List getClientInterceptors(); + + /** + * Sets the logging level for OkHttp client. + * + * @param logLevel the logging level enum. + */ + void setLogLevel(Level logLevel); + + /** + * Gets the adapter for {@link com.fasterxml.jackson.databind.ObjectMapper} for serialization + * and deserialization operations.. + * + * @return the adapter. + */ + JacksonMapperAdapter getMapperAdapter(); + + /** + * Gets The subscription id with value 'test12'.. + * + * @return the subscriptionId value. + */ + String getSubscriptionId(); + + /** + * Sets The subscription id with value 'test12'.. + * + * @param subscriptionId the subscriptionId value. + */ + void setSubscriptionId(String subscriptionId); + + /** + * Gets A string value that is used as a global part of the parameterized host. Default value 'host'.. + * + * @return the dnsSuffix value. + */ + String getDnsSuffix(); + + /** + * Sets A string value that is used as a global part of the parameterized host. Default value 'host'.. + * + * @param dnsSuffix the dnsSuffix value. + */ + void setDnsSuffix(String dnsSuffix); + + /** + * Gets the PathsOperations object to access its operations. + * @return the PathsOperations object. + */ + PathsOperations getPathsOperations(); + +} diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClientImpl.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClientImpl.java new file mode 100644 index 000000000000..ad9fe946dc42 --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClientImpl.java @@ -0,0 +1,121 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +package fixtures.custombaseurimoreoptions; + +import com.microsoft.rest.ServiceClient; +import com.microsoft.rest.AutoRestBaseUrl; +import okhttp3.OkHttpClient; +import retrofit2.Retrofit; + +/** + * Initializes a new instance of the AutoRestParameterizedCustomHostTestClient class. + */ +public final class AutoRestParameterizedCustomHostTestClientImpl extends ServiceClient implements AutoRestParameterizedCustomHostTestClient { + /** + * The URL used as the base for all cloud service requests. + */ + private final AutoRestBaseUrl baseUrl; + + /** + * Gets the URL used as the base for all cloud service requests. + * + * @return The BaseUrl value. + */ + public AutoRestBaseUrl getBaseUrl() { + return this.baseUrl; + } + + /** The subscription id with value 'test12'. */ + private String subscriptionId; + + /** + * Gets The subscription id with value 'test12'. + * + * @return the subscriptionId value. + */ + public String getSubscriptionId() { + return this.subscriptionId; + } + + /** + * Sets The subscription id with value 'test12'. + * + * @param subscriptionId the subscriptionId value. + */ + public void setSubscriptionId(String subscriptionId) { + this.subscriptionId = subscriptionId; + } + + /** A string value that is used as a global part of the parameterized host. Default value 'host'. */ + private String dnsSuffix; + + /** + * Gets A string value that is used as a global part of the parameterized host. Default value 'host'. + * + * @return the dnsSuffix value. + */ + public String getDnsSuffix() { + return this.dnsSuffix; + } + + /** + * Sets A string value that is used as a global part of the parameterized host. Default value 'host'. + * + * @param dnsSuffix the dnsSuffix value. + */ + public void setDnsSuffix(String dnsSuffix) { + this.dnsSuffix = dnsSuffix; + } + + /** + * Gets the PathsOperations object to access its operations. + * @return the PathsOperations object. + */ + public PathsOperations getPathsOperations() { + return new PathsOperationsImpl(this.retrofitBuilder.client(clientBuilder.build()).build(), this); + } + + /** + * Initializes an instance of AutoRestParameterizedCustomHostTestClient client. + */ + public AutoRestParameterizedCustomHostTestClientImpl() { + this("{vault}{secret}{dnsSuffix}"); + } + + /** + * Initializes an instance of AutoRestParameterizedCustomHostTestClient client. + * + * @param baseUrl the base URL of the host + */ + private AutoRestParameterizedCustomHostTestClientImpl(String baseUrl) { + super(); + this.baseUrl = new AutoRestBaseUrl(baseUrl); + initialize(); + } + + /** + * Initializes an instance of AutoRestParameterizedCustomHostTestClient client. + * + * @param clientBuilder the builder for building up an {@link OkHttpClient} + * @param retrofitBuilder the builder for building up a {@link Retrofit} + */ + public AutoRestParameterizedCustomHostTestClientImpl(OkHttpClient.Builder clientBuilder, Retrofit.Builder retrofitBuilder) { + super(clientBuilder, retrofitBuilder); + this.baseUrl = new AutoRestBaseUrl("{vault}{secret}{dnsSuffix}"); + initialize(); + } + + @Override + protected void initialize() { + super.initialize(); + this.retrofitBuilder.baseUrl(baseUrl); + } +} diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperations.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperations.java new file mode 100644 index 000000000000..6273f3426d73 --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperations.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +package fixtures.custombaseurimoreoptions; + +import com.microsoft.rest.ServiceCall; +import com.microsoft.rest.ServiceCallback; +import com.microsoft.rest.ServiceResponse; +import fixtures.custombaseurimoreoptions.models.ErrorException; +import java.io.IOException; + +/** + * An instance of this class provides access to all the operations defined + * in PathsOperations. + */ +public interface PathsOperations { + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @throws IllegalArgumentException exception thrown from invalid parameters + * @return the {@link ServiceResponse} object if successful. + */ + ServiceResponse getEmpty(String vault, String secret, String keyName) throws ErrorException, IOException, IllegalArgumentException; + + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link ServiceCall} object + */ + ServiceCall getEmptyAsync(String vault, String secret, String keyName, final ServiceCallback serviceCallback) throws IllegalArgumentException; + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @param keyVersion The key version. Default value 'v1'. + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @throws IllegalArgumentException exception thrown from invalid parameters + * @return the {@link ServiceResponse} object if successful. + */ + ServiceResponse getEmpty(String vault, String secret, String keyName, String keyVersion) throws ErrorException, IOException, IllegalArgumentException; + + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @param keyVersion The key version. Default value 'v1'. + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link ServiceCall} object + */ + ServiceCall getEmptyAsync(String vault, String secret, String keyName, String keyVersion, final ServiceCallback serviceCallback) throws IllegalArgumentException; + +} diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperationsImpl.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperationsImpl.java new file mode 100644 index 000000000000..13994720257b --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperationsImpl.java @@ -0,0 +1,245 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +package fixtures.custombaseurimoreoptions; + +import com.google.common.reflect.TypeToken; +import com.microsoft.rest.ServiceCall; +import com.microsoft.rest.ServiceCallback; +import com.microsoft.rest.ServiceResponse; +import com.microsoft.rest.ServiceResponseBuilder; +import com.microsoft.rest.ServiceResponseCallback; +import fixtures.custombaseurimoreoptions.models.ErrorException; +import java.io.IOException; +import okhttp3.ResponseBody; +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Headers; +import retrofit2.http.Path; +import retrofit2.http.Query; +import retrofit2.Response; +import retrofit2.Retrofit; + +/** + * An instance of this class provides access to all the operations defined + * in PathsOperations. + */ +public final class PathsOperationsImpl implements PathsOperations { + /** The Retrofit service to perform REST calls. */ + private PathsService service; + /** The service client containing this operation class. */ + private AutoRestParameterizedCustomHostTestClient client; + + /** + * Initializes an instance of PathsOperations. + * + * @param retrofit the Retrofit instance built from a Retrofit Builder. + * @param client the instance of the service client containing this operation class. + */ + public PathsOperationsImpl(Retrofit retrofit, AutoRestParameterizedCustomHostTestClient client) { + this.service = retrofit.create(PathsService.class); + this.client = client; + } + + /** + * The interface defining all the services for PathsOperations to be + * used by Retrofit to perform actually REST calls. + */ + interface PathsService { + @Headers("Content-Type: application/json; charset=utf-8") + @GET("customuri/{subscriptionId}/{keyName}") + Call getEmpty(@Path("keyName") String keyName, @Path("subscriptionId") String subscriptionId, @Query("keyVersion") String keyVersion); + + } + + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @throws IllegalArgumentException exception thrown from invalid parameters + * @return the {@link ServiceResponse} object if successful. + */ + public ServiceResponse getEmpty(String vault, String secret, String keyName) throws ErrorException, IOException, IllegalArgumentException { + if (vault == null) { + throw new IllegalArgumentException("Parameter vault is required and cannot be null."); + } + if (secret == null) { + throw new IllegalArgumentException("Parameter secret is required and cannot be null."); + } + if (this.client.getDnsSuffix() == null) { + throw new IllegalArgumentException("Parameter this.client.getDnsSuffix() is required and cannot be null."); + } + if (keyName == null) { + throw new IllegalArgumentException("Parameter keyName is required and cannot be null."); + } + if (this.client.getSubscriptionId() == null) { + throw new IllegalArgumentException("Parameter this.client.getSubscriptionId() is required and cannot be null."); + } + final String keyVersion = null; + this.client.getBaseUrl().set("{vault}", vault); + this.client.getBaseUrl().set("{secret}", secret); + this.client.getBaseUrl().set("{dnsSuffix}", this.client.getDnsSuffix()); + Call call = service.getEmpty(keyName, this.client.getSubscriptionId(), keyVersion); + return getEmptyDelegate(call.execute()); + } + + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @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 getEmptyAsync(String vault, String secret, String keyName, final ServiceCallback serviceCallback) throws IllegalArgumentException { + if (serviceCallback == null) { + throw new IllegalArgumentException("ServiceCallback is required for async calls."); + } + if (vault == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter vault is required and cannot be null.")); + return null; + } + if (secret == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter secret is required and cannot be null.")); + return null; + } + if (this.client.getDnsSuffix() == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter this.client.getDnsSuffix() is required and cannot be null.")); + return null; + } + if (keyName == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter keyName is required and cannot be null.")); + return null; + } + if (this.client.getSubscriptionId() == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter this.client.getSubscriptionId() is required and cannot be null.")); + return null; + } + final String keyVersion = null; + this.client.getBaseUrl().set("{vault}", vault); + this.client.getBaseUrl().set("{secret}", secret); + this.client.getBaseUrl().set("{dnsSuffix}", this.client.getDnsSuffix()); + Call call = service.getEmpty(keyName, this.client.getSubscriptionId(), keyVersion); + final ServiceCall serviceCall = new ServiceCall(call); + call.enqueue(new ServiceResponseCallback(serviceCallback) { + @Override + public void onResponse(Call call, Response response) { + try { + serviceCallback.success(getEmptyDelegate(response)); + } catch (ErrorException | IOException exception) { + serviceCallback.failure(exception); + } + } + }); + return serviceCall; + } + + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @param keyVersion The key version. Default value 'v1'. + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @throws IllegalArgumentException exception thrown from invalid parameters + * @return the {@link ServiceResponse} object if successful. + */ + public ServiceResponse getEmpty(String vault, String secret, String keyName, String keyVersion) throws ErrorException, IOException, IllegalArgumentException { + if (vault == null) { + throw new IllegalArgumentException("Parameter vault is required and cannot be null."); + } + if (secret == null) { + throw new IllegalArgumentException("Parameter secret is required and cannot be null."); + } + if (this.client.getDnsSuffix() == null) { + throw new IllegalArgumentException("Parameter this.client.getDnsSuffix() is required and cannot be null."); + } + if (keyName == null) { + throw new IllegalArgumentException("Parameter keyName is required and cannot be null."); + } + if (this.client.getSubscriptionId() == null) { + throw new IllegalArgumentException("Parameter this.client.getSubscriptionId() is required and cannot be null."); + } + this.client.getBaseUrl().set("{vault}", vault); + this.client.getBaseUrl().set("{secret}", secret); + this.client.getBaseUrl().set("{dnsSuffix}", this.client.getDnsSuffix()); + Call call = service.getEmpty(keyName, this.client.getSubscriptionId(), keyVersion); + return getEmptyDelegate(call.execute()); + } + + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @param keyVersion The key version. Default value 'v1'. + * @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 getEmptyAsync(String vault, String secret, String keyName, String keyVersion, final ServiceCallback serviceCallback) throws IllegalArgumentException { + if (serviceCallback == null) { + throw new IllegalArgumentException("ServiceCallback is required for async calls."); + } + if (vault == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter vault is required and cannot be null.")); + return null; + } + if (secret == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter secret is required and cannot be null.")); + return null; + } + if (this.client.getDnsSuffix() == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter this.client.getDnsSuffix() is required and cannot be null.")); + return null; + } + if (keyName == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter keyName is required and cannot be null.")); + return null; + } + if (this.client.getSubscriptionId() == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter this.client.getSubscriptionId() is required and cannot be null.")); + return null; + } + this.client.getBaseUrl().set("{vault}", vault); + this.client.getBaseUrl().set("{secret}", secret); + this.client.getBaseUrl().set("{dnsSuffix}", this.client.getDnsSuffix()); + Call call = service.getEmpty(keyName, this.client.getSubscriptionId(), keyVersion); + final ServiceCall serviceCall = new ServiceCall(call); + call.enqueue(new ServiceResponseCallback(serviceCallback) { + @Override + public void onResponse(Call call, Response response) { + try { + serviceCallback.success(getEmptyDelegate(response)); + } catch (ErrorException | IOException exception) { + serviceCallback.failure(exception); + } + } + }); + return serviceCall; + } + + private ServiceResponse getEmptyDelegate(Response response) throws ErrorException, IOException, IllegalArgumentException { + 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/custombaseurimoreoptions/models/Error.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/Error.java new file mode 100644 index 000000000000..73232cf4ed43 --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/Error.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +package fixtures.custombaseurimoreoptions.models; + + +/** + * The Error model. + */ +public class Error { + /** + * The status property. + */ + private Integer status; + + /** + * The message property. + */ + private String message; + + /** + * Get the status value. + * + * @return the status value + */ + public Integer getStatus() { + return this.status; + } + + /** + * Set the status value. + * + * @param status the status value to set + */ + public void setStatus(Integer status) { + this.status = status; + } + + /** + * Get the message value. + * + * @return the message value + */ + public String getMessage() { + return this.message; + } + + /** + * Set the message value. + * + * @param message the message value to set + */ + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/ErrorException.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/ErrorException.java new file mode 100644 index 000000000000..0c4458e200da --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/ErrorException.java @@ -0,0 +1,89 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +package fixtures.custombaseurimoreoptions.models; + +import com.microsoft.rest.AutoRestException; +import retrofit2.Response; + +/** + * Exception thrown for an invalid response with Error information. + */ +public class ErrorException extends AutoRestException { + /** + * Information about the associated HTTP response. + */ + private Response response; + /** + * The actual response body. + */ + private Error body; + /** + * Initializes a new instance of the ErrorException class. + */ + public ErrorException() { } + /** + * Initializes a new instance of the ErrorException class. + * + * @param message The exception message. + */ + public ErrorException(final String message) { + super(message); + } + /** + * Initializes a new instance of the ErrorException class. + * + * @param message the exception message + * @param cause exception that caused this exception to occur + */ + public ErrorException(final String message, final Throwable cause) { + super(message, cause); + } + /** + * Initializes a new instance of the ErrorException class. + * + * @param cause exception that caused this exception to occur + */ + public ErrorException(final Throwable cause) { + super(cause); + } + /** + * Gets information about the associated HTTP response. + * + * @return the HTTP response + */ + public Response getResponse() { + return response; + } + /** + * Gets the HTTP response body. + * + * @return the response body + */ + public Error getBody() { + return body; + } + /** + * Sets the HTTP response. + * + * @param response the HTTP response + */ + public void setResponse(Response response) { + this.response = response; + } + /** + * Sets the HTTP response body. + * + * @param body the response body + */ + public void setBody(Error body) { + this.body = body; + } +} diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/package-info.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/package-info.java new file mode 100644 index 000000000000..b5c9a91ec97d --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/package-info.java @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +/** + * This package contains the model classes for AutoRestParameterizedCustomHostTestClient. + * Test Infrastructure for AutoRest. + */ +package fixtures.custombaseurimoreoptions.models; diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/package-info.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/package-info.java new file mode 100644 index 000000000000..a6434083eb1c --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/package-info.java @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +/** + * This package contains the classes for AutoRestParameterizedCustomHostTestClient. + * Test Infrastructure for AutoRest. + */ +package fixtures.custombaseurimoreoptions; diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/AcceptanceTests/acceptanceTests.ts b/AutoRest/Generators/NodeJS/NodeJS.Tests/AcceptanceTests/acceptanceTests.ts index c7404da84e36..0a81b3420068 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/AcceptanceTests/acceptanceTests.ts +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/AcceptanceTests/acceptanceTests.ts @@ -32,7 +32,7 @@ import dictionaryModels = require('../Expected/AcceptanceTests/BodyDictionary/mo import httpClient = require('../Expected/AcceptanceTests/Http/autoRestHttpInfrastructureTestService'); import formDataClient = require('../Expected/AcceptanceTests/BodyFormData/autoRestSwaggerBATFormDataService'); import customBaseUriClient = require('../Expected/AcceptanceTests/CustomBaseUri/autoRestParameterizedHostTestClient'); - +import customBaseUriClientMoreOptions = require('../Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient'); var dummyToken = 'dummy12321343423'; var credentials = new msRest.TokenCredentials(dummyToken); @@ -94,6 +94,19 @@ describe('nodejs', function () { }); }); }); + describe('Custom BaseUri Client with more options', function () { + var customOptions = { + dnsSuffix: 'host:3000' + }; + var testClient = new customBaseUriClientMoreOptions('test12', customOptions); + it('should return 200', function (done) { + testClient.paths.getEmpty('http://lo','cal', 'key1', function (error, result, request, response) { + should.not.exist(error); + response.statusCode.should.equal(200); + done(); + }); + }); + }); describe('Bool Client', function () { var testClient = new boolClient(baseUri, clientOptions); it('should get valid boolean values', function (done) { diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.d.ts b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.d.ts new file mode 100644 index 000000000000..98c22ab85f4d --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.d.ts @@ -0,0 +1,44 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +import { ServiceClientOptions, RequestOptions, ServiceCallback } from 'ms-rest'; +import * as operations from "./operations"; + +declare class AutoRestParameterizedCustomHostTestClient { + /** + * @class + * Initializes a new instance of the AutoRestParameterizedCustomHostTestClient class. + * @constructor + * + * @param {string} subscriptionId - The subscription id with value 'test12'. + * + * @param {object} [options] - The parameter options + * + * @param {Array} [options.filters] - Filters to be added to the request pipeline + * + * @param {object} [options.requestOptions] - Options for the underlying request object + * {@link https://github.com/request/request#requestoptions-callback Options doc} + * + * @param {boolean} [options.noRetryPolicy] - If set to true, turn off default retry policy + * + * @param {string} [options.dnsSuffix] - A string value that is used as a global part of the parameterized host. Default value 'host'. + * + */ + constructor(subscriptionId: string, options: ServiceClientOptions); + + subscriptionId: string; + + dnsSuffix: string; + + // Operation groups + paths: operations.Paths; + } + +export = AutoRestParameterizedCustomHostTestClient; diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.js new file mode 100644 index 000000000000..391f7b50deb3 --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.js @@ -0,0 +1,65 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +/* jshint latedef:false */ +/* jshint forin:false */ +/* jshint noempty:false */ + +'use strict'; + +var util = require('util'); +var msRest = require('ms-rest'); +var ServiceClient = msRest.ServiceClient; + +var models = require('./models'); +var operations = require('./operations'); + +/** + * @class + * Initializes a new instance of the AutoRestParameterizedCustomHostTestClient class. + * @constructor + * + * @param {string} subscriptionId - The subscription id with value 'test12'. + * + * @param {object} [options] - The parameter options + * + * @param {Array} [options.filters] - Filters to be added to the request pipeline + * + * @param {object} [options.requestOptions] - Options for the underlying request object + * {@link https://github.com/request/request#requestoptions-callback Options doc} + * + * @param {boolean} [options.noRetryPolicy] - If set to true, turn off default retry policy + * + * @param {string} [options.dnsSuffix] - A string value that is used as a global part of the parameterized host. Default value 'host'. + * + */ +function AutoRestParameterizedCustomHostTestClient(subscriptionId, options) { + this.dnsSuffix = 'host'; + if (subscriptionId === null || subscriptionId === undefined) { + throw new Error('\'subscriptionId\' cannot be null.'); + } + + if (!options) options = {}; + + AutoRestParameterizedCustomHostTestClient['super_'].call(this, null, options); + this.baseUri = '{vault}{secret}{dnsSuffix}'; + this.subscriptionId = subscriptionId; + + if(options.dnsSuffix !== null && options.dnsSuffix !== undefined) { + this.dnsSuffix = options.dnsSuffix; + } + this.paths = new operations.Paths(this); + this.models = models; + msRest.addSerializationMixin(this); +} + +util.inherits(AutoRestParameterizedCustomHostTestClient, ServiceClient); + +module.exports = AutoRestParameterizedCustomHostTestClient; diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/errorModel.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/errorModel.js new file mode 100644 index 000000000000..663be0f4aaa8 --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/errorModel.js @@ -0,0 +1,58 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +'use strict'; + +/** + * @class + * Initializes a new instance of the ErrorModel class. + * @constructor + * @member {number} [status] + * + * @member {string} [message] + * + */ +function ErrorModel() { +} + +/** + * Defines the metadata of ErrorModel + * + * @returns {object} metadata of ErrorModel + * + */ +ErrorModel.prototype.mapper = function () { + return { + required: false, + serializedName: 'Error', + type: { + name: 'Composite', + className: 'ErrorModel', + modelProperties: { + status: { + required: false, + serializedName: 'status', + type: { + name: 'Number' + } + }, + message: { + required: false, + serializedName: 'message', + type: { + name: 'String' + } + } + } + } + }; +}; + +module.exports = ErrorModel; diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.d.ts b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.d.ts new file mode 100644 index 000000000000..5405a199a075 --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.d.ts @@ -0,0 +1,24 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + + +/** + * @class + * Initializes a new instance of the ErrorModel class. + * @constructor + * @member {number} [status] + * + * @member {string} [message] + * + */ +export interface ErrorModel { + status?: number; + message?: string; +} diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.js new file mode 100644 index 000000000000..3430295d8bd8 --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.js @@ -0,0 +1,17 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +/* jshint latedef:false */ +/* jshint forin:false */ +/* jshint noempty:false */ + +'use strict'; + +exports.ErrorModel = require('./errorModel'); diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.d.ts b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.d.ts new file mode 100644 index 000000000000..3fa4ea5d9bf1 --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.d.ts @@ -0,0 +1,44 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. +*/ + +import { ServiceClientOptions, RequestOptions, ServiceCallback } from 'ms-rest'; +import * as models from '../models'; + + +/** + * @class + * Paths + * __NOTE__: An instance of this class is automatically created for an + * instance of the AutoRestParameterizedCustomHostTestClient. + */ +export interface Paths { + + /** + * Get a 200 to test a valid base uri + * + * @param {string} vault The vault name, e.g. https://myvault + * + * @param {string} secret Secret value. + * + * @param {string} keyName The key name with value 'key1'. + * + * @param {object} [options] Optional Parameters. + * + * @param {string} [options.keyVersion] The key version. Default value 'v1'. + * + * @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 + */ + getEmpty(vault: string, secret: string, keyName: string, options: { keyVersion? : string, customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + getEmpty(vault: string, secret: string, keyName: string, callback: ServiceCallback): void; +} diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.js new file mode 100644 index 000000000000..412d88e67668 --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.js @@ -0,0 +1,17 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +/* jshint latedef:false */ +/* jshint forin:false */ +/* jshint noempty:false */ + +'use strict'; + +exports.Paths = require('./paths'); diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/paths.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/paths.js new file mode 100644 index 000000000000..dc2c66f05c60 --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/paths.js @@ -0,0 +1,167 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +'use strict'; + +var util = require('util'); +var msRest = require('ms-rest'); +var WebResource = msRest.WebResource; + +/** + * @class + * Paths + * __NOTE__: An instance of this class is automatically created for an + * instance of the AutoRestParameterizedCustomHostTestClient. + * Initializes a new instance of the Paths class. + * @constructor + * + * @param {AutoRestParameterizedCustomHostTestClient} client Reference to the service client. + */ +function Paths(client) { + this.client = client; +} + +/** + * Get a 200 to test a valid base uri + * + * @param {string} vault The vault name, e.g. https://myvault + * + * @param {string} secret Secret value. + * + * @param {string} keyName The key name with value 'key1'. + * + * @param {object} [options] Optional Parameters. + * + * @param {string} [options.keyVersion] The key version. Default value 'v1'. + * + * @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.getEmpty = function (vault, secret, keyName, 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 keyVersion = (options && options.keyVersion !== undefined) ? options.keyVersion : 'v1'; + // Validate + try { + if (vault === null || vault === undefined || typeof vault.valueOf() !== 'string') { + throw new Error('vault cannot be null or undefined and it must be of type string.'); + } + if (secret === null || secret === undefined || typeof secret.valueOf() !== 'string') { + throw new Error('secret cannot be null or undefined and it must be of type string.'); + } + if (this.client.dnsSuffix === null || this.client.dnsSuffix === undefined || typeof this.client.dnsSuffix.valueOf() !== 'string') { + throw new Error('this.client.dnsSuffix cannot be null or undefined and it must be of type string.'); + } + if (keyName === null || keyName === undefined || typeof keyName.valueOf() !== 'string') { + throw new Error('keyName cannot be null or undefined and it must be of type string.'); + } + if (this.client.subscriptionId === null || this.client.subscriptionId === undefined || typeof this.client.subscriptionId.valueOf() !== 'string') { + throw new Error('this.client.subscriptionId cannot be null or undefined and it must be of type string.'); + } + if (keyVersion !== null && keyVersion !== undefined && typeof keyVersion.valueOf() !== 'string') { + throw new Error('keyVersion must be of type string.'); + } + } catch (error) { + return callback(error); + } + + // Construct URL + var requestUrl = this.client.baseUri + + '//customuri/{subscriptionId}/{keyName}'; + requestUrl = requestUrl.replace('{vault}', vault); + requestUrl = requestUrl.replace('{secret}', secret); + requestUrl = requestUrl.replace('{dnsSuffix}', this.client.dnsSuffix); + requestUrl = requestUrl.replace('{keyName}', encodeURIComponent(keyName)); + requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId)); + var queryParameters = []; + if (keyVersion !== null && keyVersion !== undefined) { + queryParameters.push('keyVersion=' + encodeURIComponent(keyVersion)); + } + 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 = '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/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/__init__.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/__init__.py new file mode 100644 index 000000000000..6711cf5b14df --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/__init__.py @@ -0,0 +1,21 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from .auto_rest_parameterized_custom_host_test_client import AutoRestParameterizedCustomHostTestClient, AutoRestParameterizedCustomHostTestClientConfiguration +from .version import VERSION + +__all__ = [ + 'AutoRestParameterizedCustomHostTestClient', + 'AutoRestParameterizedCustomHostTestClientConfiguration' +] + +__version__ = VERSION + diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/auto_rest_parameterized_custom_host_test_client.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/auto_rest_parameterized_custom_host_test_client.py new file mode 100644 index 000000000000..1e9140c3e5f7 --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/auto_rest_parameterized_custom_host_test_client.py @@ -0,0 +1,69 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.service_client import ServiceClient +from msrest import Configuration, Serializer, Deserializer +from .version import VERSION +from .operations.paths import Paths +from . import models + + +class AutoRestParameterizedCustomHostTestClientConfiguration(Configuration): + """Configuration for AutoRestParameterizedCustomHostTestClient + Note that all parameters used to create this instance are saved as instance + attributes. + + :param subscription_id: The subscription id with value 'test12'. + :type subscription_id: str + :param dns_suffix: A string value that is used as a global part of the + parameterized host. Default value 'host'. + :type dns_suffix: str + :param str filepath: Existing config + """ + + def __init__( + self, subscription_id, dns_suffix, filepath=None): + + if subscription_id is None: + raise ValueError('subscription_id must not be None.') + if dns_suffix is None: + raise ValueError('dns_suffix must not be None.') + base_url = '{vault}{secret}{dnsSuffix}' + + super(AutoRestParameterizedCustomHostTestClientConfiguration, self).__init__(base_url, filepath) + + self.add_user_agent('autorestparameterizedcustomhosttestclient/{}'.format(VERSION)) + + self.subscription_id = subscription_id + self.dns_suffix = dns_suffix + + +class AutoRestParameterizedCustomHostTestClient(object): + """Test Infrastructure for AutoRest + + :param config: Configuration for client. + :type config: AutoRestParameterizedCustomHostTestClientConfiguration + + :ivar paths: Paths operations + :vartype paths: .operations.Paths + """ + + def __init__(self, config): + + self._client = ServiceClient(None, config) + + client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)} + self._serialize = Serializer() + self._deserialize = Deserializer(client_models) + + self.config = config + self.paths = Paths( + self._client, self.config, self._serialize, self._deserialize) diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/credentials.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/credentials.py new file mode 100644 index 000000000000..0d097b4f2a6c --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/credentials.py @@ -0,0 +1,15 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.authentication import ( + BasicAuthentication, + BasicTokenAuthentication, + OAuthTokenAuthentication) diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/exceptions.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/exceptions.py new file mode 100644 index 000000000000..c3cc00226060 --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/exceptions.py @@ -0,0 +1,21 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.exceptions import ( + ClientException, + SerializationError, + DeserializationError, + TokenExpiredError, + ClientRequestError, + AuthenticationError, + HttpOperationError, + ValidationError, +) diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/__init__.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/__init__.py new file mode 100644 index 000000000000..fd6d517a4711 --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/__init__.py @@ -0,0 +1,16 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from .error import Error, ErrorException + +__all__ = [ + 'Error', 'ErrorException', +] diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/error.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/error.py new file mode 100644 index 000000000000..c2d19e377e00 --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/error.py @@ -0,0 +1,44 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model +from msrest.exceptions import HttpOperationError + + +class Error(Model): + """Error + + :param status: + :type status: int + :param message: + :type message: str + """ + + _attribute_map = { + 'status': {'key': 'status', 'type': 'int'}, + 'message': {'key': 'message', 'type': 'str'}, + } + + def __init__(self, status=None, message=None): + self.status = status + self.message = message + + +class ErrorException(HttpOperationError): + """Server responsed with exception of type: 'Error'. + + :param deserialize: A deserializer + :param response: Server response to be deserialized. + """ + + def __init__(self, deserialize, response, *args): + + super(ErrorException, self).__init__(deserialize, response, 'Error', *args) diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/__init__.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/__init__.py new file mode 100644 index 000000000000..fa4a82a28df5 --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/__init__.py @@ -0,0 +1,16 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from .paths import Paths + +__all__ = [ + 'Paths', +] diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/paths.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/paths.py new file mode 100644 index 000000000000..2c43f455f742 --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/paths.py @@ -0,0 +1,87 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.pipeline import ClientRawResponse + +from .. import models + + +class Paths(object): + """Paths operations. + + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An objec model deserializer. + """ + + def __init__(self, client, config, serializer, deserializer): + + self._client = client + self._serialize = serializer + self._deserialize = deserializer + + self.config = config + + def get_empty( + self, vault, secret, key_name, key_version="v1", custom_headers={}, raw=False, **operation_config): + """ + Get a 200 to test a valid base uri + + :param vault: The vault name, e.g. https://myvault + :type vault: str + :param secret: Secret value. + :type secret: str + :param key_name: The key name with value 'key1'. + :type key_name: str + :param key_version: The key version. Default value 'v1'. + :type key_version: str + :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 = '/customuri/{subscriptionId}/{keyName}' + path_format_arguments = { + 'vault': self._serialize.url("vault", vault, 'str', skip_quote=True), + 'secret': self._serialize.url("secret", secret, 'str', skip_quote=True), + 'dnsSuffix': self._serialize.url("self.config.dns_suffix", self.config.dns_suffix, 'str', skip_quote=True), + 'keyName': self._serialize.url("key_name", key_name, 'str'), + 'subscriptionId': self._serialize.url("self.config.subscription_id", self.config.subscription_id, 'str') + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} + if key_version is not None: + query_parameters['keyVersion'] = self._serialize.query("key_version", key_version, 'str') + + # 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 diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/version.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/version.py new file mode 100644 index 000000000000..a39916c162ce --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/version.py @@ -0,0 +1,13 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +VERSION = "1.0.0" + diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/setup.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/setup.py new file mode 100644 index 000000000000..3521fb6abef9 --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/setup.py @@ -0,0 +1,40 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- +# coding: utf-8 + +from setuptools import setup, find_packages + +NAME = "autorestparameterizedcustomhosttestclient" +VERSION = "1.0.0" + +# To install the library, run the following +# +# python setup.py install +# +# prerequisite: setuptools +# http://pypi.python.org/pypi/setuptools + +REQUIRES = ["msrest>=0.2.0"] + +setup( + name=NAME, + version=VERSION, + description="AutoRestParameterizedCustomHostTestClient", + author_email="", + url="", + keywords=["Swagger", "AutoRestParameterizedCustomHostTestClient"], + install_requires=REQUIRES, + packages=find_packages(), + include_package_data=True, + long_description="""\ + Test Infrastructure for AutoRest + """ +) diff --git a/AutoRest/Generators/Python/Python.Tests/Python.Tests.pyproj b/AutoRest/Generators/Python/Python.Tests/Python.Tests.pyproj index 551692fe3e19..b6cfb6ea96c3 100644 --- a/AutoRest/Generators/Python/Python.Tests/Python.Tests.pyproj +++ b/AutoRest/Generators/Python/Python.Tests/Python.Tests.pyproj @@ -125,6 +125,10 @@ + + + + diff --git a/AutoRest/TestServer/server/app.js b/AutoRest/TestServer/server/app.js index f0da0d60682c..8bb3b105ba76 100644 --- a/AutoRest/TestServer/server/app.js +++ b/AutoRest/TestServer/server/app.js @@ -428,6 +428,8 @@ var coverage = { "ConstantsInPath": 0, "ConstantsInBody": 0, "CustomBaseUri": 0, + //Once all the languages implement this test, the scenario counter should be reset to zero. It is currently implemented in C# and node.js + "CustomBaseUriMoreOptions": 1, 'getModelFlattenArray': 0, 'putModelFlattenArray': 0, 'getModelFlattenDictionary': 0, diff --git a/AutoRest/TestServer/server/routes/customUri.js b/AutoRest/TestServer/server/routes/customUri.js index 2eee79cadfc3..85d074cdeceb 100644 --- a/AutoRest/TestServer/server/routes/customUri.js +++ b/AutoRest/TestServer/server/routes/customUri.js @@ -9,6 +9,17 @@ var specials = function (coverage) { coverage['CustomBaseUri']++; res.status(200).end(); }); + + router.get('/:subscriptionId/:keyName', function (req, res, next) { + if (req.params.subscriptionId === 'test12' && req.params.keyName === 'key1' + && Object.keys(req.query).length == 1 && req.query.keyVersion === 'v1') { + coverage['CustomBaseUriMoreOptions']++; + res.status(200).end(); + } else { + utils.send400(res, next, 'Either one of the path parameters (subscriptionId=test12, keyName=key1) or query parameter (keyVersion=v1) did not match. ' + + 'Received parameters are: subscriptionId ' + subscriptionId + ', keyName ' + keyName + ', keyVersion ' + keyVersion); + } + }); } specials.prototype.router = router; diff --git a/AutoRest/TestServer/swagger/custom-baseUrl-more-options.json b/AutoRest/TestServer/swagger/custom-baseUrl-more-options.json new file mode 100644 index 000000000000..875759e680fd --- /dev/null +++ b/AutoRest/TestServer/swagger/custom-baseUrl-more-options.json @@ -0,0 +1,109 @@ +{ + "swagger": "2.0", + "info": { + "title": "AutoRest Parameterized Custom Host Test Client", + "description": "Test Infrastructure for AutoRest", + "version": "1.0.0" + }, + "x-ms-parameterized-host": { + "hostTemplate": "{vault}{secret}{dnsSuffix}", + "useSchemePrefix": false, + "positionInOperation": "first", + "parameters": [ + { + "name": "vault", + "description": "The vault name, e.g. https://myvault", + "required": true, + "type": "string", + "in": "path", + "x-ms-skip-url-encoding": true + }, + { + "name": "secret", + "description": "Secret value.", + "required": true, + "type": "string", + "in": "path", + "x-ms-skip-url-encoding": true + }, + { + "$ref": "#/parameters/dnsSuffix" + } + ] + }, + "produces": [ "application/json" ], + "consumes": [ "application/json" ], + "paths": { + "/customuri/{subscriptionId}/{keyName}": { + "get": { + "operationId": "paths_getEmpty", + "description": "Get a 200 to test a valid base uri", + "tags": [ + "Path Operations" + ], + "parameters": [ + { + "name": "keyName", + "in": "path", + "required": true, + "type": "string", + "description": "The key name with value 'key1'." + }, + { + "$ref": "#/parameters/SubscriptionIdParameter" + }, + { + "name": "keyVersion", + "in": "query", + "required": false, + "type": "string", + "default": "v1", + "description": "The key version. Default value 'v1'." + } + ], + "responses": { + "200": { + "description": "Successfully received a 200 response" + }, + "default": { + "description": "Unexpected error", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + } + }, + "parameters": { + "SubscriptionIdParameter": { + "name": "subscriptionId", + "in": "path", + "required": true, + "type": "string", + "description": "The subscription id with value 'test12'." + }, + "dnsSuffix": { + "name": "dnsSuffix", + "description": "A string value that is used as a global part of the parameterized host. Default value 'host'.", + "type": "string", + "required": false, + "default": "host", + "in": "path", + "x-ms-skip-url-encoding": true + } + }, + "definitions": { + "Error": { + "properties": { + "status": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } +} diff --git a/Documentation/swagger-extensions.md b/Documentation/swagger-extensions.md index cb3bed17ab58..dba70ead920b 100644 --- a/Documentation/swagger-extensions.md +++ b/Documentation/swagger-extensions.md @@ -389,6 +389,8 @@ When used, replaces the standard Swagger "host" attribute with a host that conta Field Name | Type | Description ---|:---:|--- hostTemplate | `string` | **Required**. Specifies the parameterized template for the host. +useSchemePrefix | `boolean` | **Optional, Default: true**. Specifes whether to prepend the default scheme a.k.a protocol to the base uri of client. +positionInOperation | `string` | **Optional, Default: last**. Specifies whether the list of parameters will appear in the beginning or in the end, in the method signature for every operation. The order within the parameters provided in the below mentioned array will be preserved. Either the array of parameters will be prepended or appended, based on the value provided over here. Valid values are **"first", "last"**. parameters | [Array of Parameter Objects](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameterObject) | The list of parameters that are used within the hostTemplate. This can include both reference parameters as well as explicit parameters. Note that "in" is **required** and **must be** set to "path" **Example**: diff --git a/gulpfile.js b/gulpfile.js index 942ac3a898b8..e7bc6be0adf4 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -63,7 +63,8 @@ var defaultMappings = { 'AcceptanceTests/Url': '../../../TestServer/swagger/url.json', 'AcceptanceTests/Validation': '../../../TestServer/swagger/validation.json', 'AcceptanceTests/CustomBaseUri': '../../../TestServer/swagger/custom-baseUrl.json', - 'AcceptanceTests/ModelFlattening': '../../../TestServer/swagger/model-flattening.json', + 'AcceptanceTests/CustomBaseUriMoreOptions': '../../../TestServer/swagger/custom-baseUrl-more-options.json', + 'AcceptanceTests/ModelFlattening': '../../../TestServer/swagger/model-flattening.json' }; var rubyMappings = { diff --git a/schema/swagger-extensions.json b/schema/swagger-extensions.json index 199078f32eee..8b93156a8363 100644 --- a/schema/swagger-extensions.json +++ b/schema/swagger-extensions.json @@ -1540,6 +1540,15 @@ "hostTemplate": { "type": "string" }, + "useSchemePrefix": { + "type": "boolean", + "default": true + }, + "positionInOperation": { + "type": "string", + "default": "end", + "pattern": "^(fir|la)st$" + }, "parameters": { "$ref": "#/definitions/xmsHostParametersList" } From d8110cffea020031b48f5c85c2e61493144c5328 Mon Sep 17 00:00:00 2001 From: Amar Zavery Date: Sat, 9 Apr 2016 12:14:03 -0700 Subject: [PATCH 19/96] positionInOperation defaults to first --- AutoRest/Generators/Extensions/Extensions/Extensions.cs | 2 +- AutoRest/TestServer/swagger/custom-baseUrl-more-options.json | 1 - AutoRest/TestServer/swagger/custom-baseUrl.json | 1 + Documentation/swagger-extensions.md | 4 ++-- schema/swagger-extensions.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/AutoRest/Generators/Extensions/Extensions/Extensions.cs b/AutoRest/Generators/Extensions/Extensions/Extensions.cs index b80820b8c0c5..620a2d594c83 100644 --- a/AutoRest/Generators/Extensions/Extensions/Extensions.cs +++ b/AutoRest/Generators/Extensions/Extensions/Extensions.cs @@ -77,7 +77,7 @@ public static void ProcessParameterizedHost(ServiceClient serviceClient, Setting useSchemePrefix = bool.Parse(hostExtension[UseSchemePrefix].ToString()); } - var position = "last"; + var position = "first"; if (hostExtension[PositionInOperation] != null) { diff --git a/AutoRest/TestServer/swagger/custom-baseUrl-more-options.json b/AutoRest/TestServer/swagger/custom-baseUrl-more-options.json index 875759e680fd..75ef7453976e 100644 --- a/AutoRest/TestServer/swagger/custom-baseUrl-more-options.json +++ b/AutoRest/TestServer/swagger/custom-baseUrl-more-options.json @@ -8,7 +8,6 @@ "x-ms-parameterized-host": { "hostTemplate": "{vault}{secret}{dnsSuffix}", "useSchemePrefix": false, - "positionInOperation": "first", "parameters": [ { "name": "vault", diff --git a/AutoRest/TestServer/swagger/custom-baseUrl.json b/AutoRest/TestServer/swagger/custom-baseUrl.json index 5ca07d1627a0..aaa0309f4b94 100644 --- a/AutoRest/TestServer/swagger/custom-baseUrl.json +++ b/AutoRest/TestServer/swagger/custom-baseUrl.json @@ -8,6 +8,7 @@ "host": "badhost", "x-ms-parameterized-host": { "hostTemplate": "{accountName}{host}", + "positionInOperation": "last", "parameters": [ { "name": "accountName", diff --git a/Documentation/swagger-extensions.md b/Documentation/swagger-extensions.md index dba70ead920b..f606ac335567 100644 --- a/Documentation/swagger-extensions.md +++ b/Documentation/swagger-extensions.md @@ -390,8 +390,8 @@ Field Name | Type | Description ---|:---:|--- hostTemplate | `string` | **Required**. Specifies the parameterized template for the host. useSchemePrefix | `boolean` | **Optional, Default: true**. Specifes whether to prepend the default scheme a.k.a protocol to the base uri of client. -positionInOperation | `string` | **Optional, Default: last**. Specifies whether the list of parameters will appear in the beginning or in the end, in the method signature for every operation. The order within the parameters provided in the below mentioned array will be preserved. Either the array of parameters will be prepended or appended, based on the value provided over here. Valid values are **"first", "last"**. -parameters | [Array of Parameter Objects](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameterObject) | The list of parameters that are used within the hostTemplate. This can include both reference parameters as well as explicit parameters. Note that "in" is **required** and **must be** set to "path" +positionInOperation | `string` | **Optional, Default: first**. Specifies whether the list of parameters will appear in the beginning or in the end, in the method signature for every operation. The order within the parameters provided in the below mentioned array will be preserved. Either the array of parameters will be prepended or appended, based on the value provided over here. Valid values are **"first", "last"**. Every method/operation in any programming language has parameters categorized into two buckets **"required"** and **"optional"**. It is natural for optional paramaters to appear in the end in a method signature. **This aspect will be preserved, while prepending(first) or appending(last) hostTemplate parameters .** +parameters | [Array of Parameter Objects](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameterObject) | The list of parameters that are used within the hostTemplate. This can include both reference parameters as well as explicit parameters. Note that "in" is **required** and **must be** set to **"path"**. The reference parameters will be treated as **global parameters** and will end up as property of the client. **Example**: Using both explicit and reference parameters diff --git a/schema/swagger-extensions.json b/schema/swagger-extensions.json index 8b93156a8363..6e6476c56dbf 100644 --- a/schema/swagger-extensions.json +++ b/schema/swagger-extensions.json @@ -1546,7 +1546,7 @@ }, "positionInOperation": { "type": "string", - "default": "end", + "default": "first", "pattern": "^(fir|la)st$" }, "parameters": { From 016cef65f6cc532f4c80c53ff73be5368dcd9860 Mon Sep 17 00:00:00 2001 From: Amar Zavery Date: Sat, 9 Apr 2016 12:28:10 -0700 Subject: [PATCH 20/96] Enhancement to "x-ms-parameterized-host" extension (#929) * Enhancement to x-ms-parameterized-host extension * positionInOperation defaults to first --- ...Generator.AzureResourceSchema.Tests.csproj | 4 +- .../AzureResourceSchema.Tests/packages.config | 14 +- .../CSharp/CSharp.Tests/AcceptanceTests.cs | 16 ++ ...toRestParameterizedCustomHostTestClient.cs | 128 +++++++++ ...toRestParameterizedCustomHostTestClient.cs | 57 ++++ .../CustomBaseUriMoreOptions/IPaths.cs | 47 ++++ .../CustomBaseUriMoreOptions/Models/Error.cs | 45 ++++ .../Models/ErrorException.cs | 99 +++++++ .../CustomBaseUriMoreOptions/Paths.cs | 203 +++++++++++++++ .../PathsExtensions.cs | 74 ++++++ .../Extensions/Extensions/Extensions.cs | 57 +++- .../Properties/Resources.Designer.cs | 9 + .../Extensions/Properties/Resources.resx | 3 + ...RestParameterizedCustomHostTestClient.java | 86 ++++++ ...ParameterizedCustomHostTestClientImpl.java | 121 +++++++++ .../PathsOperations.java | 75 ++++++ .../PathsOperationsImpl.java | 245 ++++++++++++++++++ .../models/Error.java | 64 +++++ .../models/ErrorException.java | 89 +++++++ .../models/package-info.java | 13 + .../package-info.java | 13 + .../AcceptanceTests/acceptanceTests.ts | 15 +- ...RestParameterizedCustomHostTestClient.d.ts | 44 ++++ ...toRestParameterizedCustomHostTestClient.js | 65 +++++ .../models/errorModel.js | 58 +++++ .../models/index.d.ts | 24 ++ .../CustomBaseUriMoreOptions/models/index.js | 17 ++ .../operations/index.d.ts | 44 ++++ .../operations/index.js | 17 ++ .../operations/paths.js | 167 ++++++++++++ .../__init__.py | 21 ++ ...t_parameterized_custom_host_test_client.py | 69 +++++ .../credentials.py | 15 ++ .../exceptions.py | 21 ++ .../models/__init__.py | 16 ++ .../models/error.py | 44 ++++ .../operations/__init__.py | 16 ++ .../operations/paths.py | 87 +++++++ .../version.py | 13 + .../CustomBaseUriMoreOptions/setup.py | 40 +++ .../Python/Python.Tests/Python.Tests.pyproj | 4 + AutoRest/TestServer/server/app.js | 2 + .../TestServer/server/routes/customUri.js | 11 + .../swagger/custom-baseUrl-more-options.json | 108 ++++++++ .../TestServer/swagger/custom-baseUrl.json | 1 + Documentation/swagger-extensions.md | 4 +- gulpfile.js | 3 +- schema/swagger-extensions.json | 9 + 48 files changed, 2379 insertions(+), 18 deletions(-) create mode 100644 AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/AutoRestParameterizedCustomHostTestClient.cs create mode 100644 AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IAutoRestParameterizedCustomHostTestClient.cs create mode 100644 AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IPaths.cs create mode 100644 AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/Error.cs create mode 100644 AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/ErrorException.cs create mode 100644 AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Paths.cs create mode 100644 AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/PathsExtensions.cs create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClient.java create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClientImpl.java create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperations.java create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperationsImpl.java create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/Error.java create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/ErrorException.java create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/package-info.java create mode 100644 AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/package-info.java create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.d.ts create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.js create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/errorModel.js create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.d.ts create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.js create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.d.ts create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.js create mode 100644 AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/paths.js create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/__init__.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/auto_rest_parameterized_custom_host_test_client.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/credentials.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/exceptions.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/__init__.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/error.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/__init__.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/paths.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/version.py create mode 100644 AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/setup.py create mode 100644 AutoRest/TestServer/swagger/custom-baseUrl-more-options.json 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 079278b9d781..01522ea89f2b 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj @@ -62,7 +62,9 @@ - + + PreserveNewest + diff --git a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config index 64fb5d7b3b79..4e690e09d9de 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/packages.config @@ -1,10 +1,10 @@  - - - - - - - + + + + + + + \ No newline at end of file diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs b/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs index 0c6e31b1c146..0d5c31f0e518 100644 --- a/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs +++ b/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs @@ -50,6 +50,7 @@ using Fixtures.PetstoreV2; using Fixtures.AcceptanceTestsCompositeBoolIntClient; using Fixtures.AcceptanceTestsCustomBaseUri; +using Fixtures.AcceptanceTestsCustomBaseUriMoreOptions; using System.Net.Http; using Fixtures.AcceptanceTestsModelFlattening; using Fixtures.AcceptanceTestsModelFlattening.Models; @@ -1951,6 +1952,21 @@ public void CustomBaseUriTests() } } + [Fact] + public void CustomBaseUriMoreOptionsTests() + { + SwaggerSpecRunner.RunTests( + SwaggerPath("custom-baseUrl-more-options.json"), ExpectedPath("CustomBaseUriMoreOptions")); + using (var client = new AutoRestParameterizedCustomHostTestClient()) + { + client.SubscriptionId = "test12"; + // small modification to the "host" portion to include the port and the '.' + client.DnsSuffix = string.Format(CultureInfo.InvariantCulture, "{0}.:{1}", "host", Fixture.Port); + Assert.Equal(HttpStatusCode.OK, + client.Paths.GetEmptyWithHttpMessagesAsync("http://lo", "cal", "key1").Result.Response.StatusCode); + } + } + [Fact] public void CustomBaseUriNegativeTests() { diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/AutoRestParameterizedCustomHostTestClient.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/AutoRestParameterizedCustomHostTestClient.cs new file mode 100644 index 000000000000..e680cbe6a873 --- /dev/null +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/AutoRestParameterizedCustomHostTestClient.cs @@ -0,0 +1,128 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +namespace Fixtures.AcceptanceTestsCustomBaseUriMoreOptions +{ + using System; + using System.Linq; + using System.Collections.Generic; + using System.Diagnostics; + using System.Net; + using System.Net.Http; + using System.Net.Http.Headers; + using System.Text; + using System.Text.RegularExpressions; + using System.Threading; + using System.Threading.Tasks; + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Newtonsoft.Json; + using Models; + + /// + /// Test Infrastructure for AutoRest + /// + public partial class AutoRestParameterizedCustomHostTestClient : ServiceClient, IAutoRestParameterizedCustomHostTestClient + { + /// + /// The base URI of the service. + /// + internal string BaseUri {get; set;} + + /// + /// Gets or sets json serialization settings. + /// + public JsonSerializerSettings SerializationSettings { get; private set; } + + /// + /// Gets or sets json deserialization settings. + /// + public JsonSerializerSettings DeserializationSettings { get; private set; } + + /// + /// The subscription id with value 'test12'. + /// + public string SubscriptionId { get; set; } + + /// + /// A string value that is used as a global part of the parameterized host. + /// Default value 'host'. + /// + public string DnsSuffix { get; set; } + + /// + /// Gets the IPaths. + /// + public virtual IPaths Paths { get; private set; } + + /// + /// Initializes a new instance of the AutoRestParameterizedCustomHostTestClient class. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + public AutoRestParameterizedCustomHostTestClient(params DelegatingHandler[] handlers) : base(handlers) + { + this.Initialize(); + } + + /// + /// Initializes a new instance of the AutoRestParameterizedCustomHostTestClient class. + /// + /// + /// Optional. The http client handler used to handle http transport. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + public AutoRestParameterizedCustomHostTestClient(HttpClientHandler rootHandler, params DelegatingHandler[] handlers) : base(rootHandler, handlers) + { + this.Initialize(); + } + + /// + /// An optional partial-method to perform custom initialization. + /// + partial void CustomInitialize(); + /// + /// Initializes client properties. + /// + private void Initialize() + { + this.Paths = new Paths(this); + this.BaseUri = "{vault}{secret}{dnsSuffix}"; + this.DnsSuffix = "host"; + SerializationSettings = new JsonSerializerSettings + { + Formatting = Formatting.Indented, + DateFormatHandling = DateFormatHandling.IsoDateFormat, + DateTimeZoneHandling = DateTimeZoneHandling.Utc, + NullValueHandling = NullValueHandling.Ignore, + ReferenceLoopHandling = ReferenceLoopHandling.Serialize, + ContractResolver = new ReadOnlyJsonContractResolver(), + Converters = new List + { + new Iso8601TimeSpanConverter() + } + }; + DeserializationSettings = new JsonSerializerSettings + { + DateFormatHandling = DateFormatHandling.IsoDateFormat, + DateTimeZoneHandling = DateTimeZoneHandling.Utc, + NullValueHandling = NullValueHandling.Ignore, + ReferenceLoopHandling = ReferenceLoopHandling.Serialize, + ContractResolver = new ReadOnlyJsonContractResolver(), + Converters = new List + { + new Iso8601TimeSpanConverter() + } + }; + CustomInitialize(); + } + } +} diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IAutoRestParameterizedCustomHostTestClient.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IAutoRestParameterizedCustomHostTestClient.cs new file mode 100644 index 000000000000..87db999d81c4 --- /dev/null +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IAutoRestParameterizedCustomHostTestClient.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +namespace Fixtures.AcceptanceTestsCustomBaseUriMoreOptions +{ + using System; + using System.Collections.Generic; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + using Newtonsoft.Json; + using Microsoft.Rest; + using Models; + + /// + /// Test Infrastructure for AutoRest + /// + public partial interface IAutoRestParameterizedCustomHostTestClient : IDisposable + { + /// + /// The base URI of the service. + /// + + /// + /// Gets or sets json serialization settings. + /// + JsonSerializerSettings SerializationSettings { get; } + + /// + /// Gets or sets json deserialization settings. + /// + JsonSerializerSettings DeserializationSettings { get; } + + /// + /// The subscription id with value 'test12'. + /// + string SubscriptionId { get; set; } + + /// + /// A string value that is used as a global part of the parameterized + /// host. Default value 'host'. + /// + string DnsSuffix { get; set; } + + + /// + /// Gets the IPaths. + /// + IPaths Paths { get; } + + } +} diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IPaths.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IPaths.cs new file mode 100644 index 000000000000..a117b914e752 --- /dev/null +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/IPaths.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +namespace Fixtures.AcceptanceTestsCustomBaseUriMoreOptions +{ + using System; + using System.Collections.Generic; + using System.Net.Http; + using System.Threading; + using System.Threading.Tasks; + using Microsoft.Rest; + using Models; + + /// + /// Paths operations. + /// + public partial interface IPaths + { + /// + /// Get a 200 to test a valid base uri + /// + /// + /// The vault name, e.g. https://myvault + /// + /// + /// Secret value. + /// + /// + /// The key name with value 'key1'. + /// + /// + /// The key version. Default value 'v1'. + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + Task GetEmptyWithHttpMessagesAsync(string vault, string secret, string keyName, string keyVersion = "v1", Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + } +} diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/Error.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/Error.cs new file mode 100644 index 000000000000..82a4873e6138 --- /dev/null +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/Error.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +namespace Fixtures.AcceptanceTestsCustomBaseUriMoreOptions.Models +{ + using System; + using System.Linq; + using System.Collections.Generic; + using Newtonsoft.Json; + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + + public partial class Error + { + /// + /// Initializes a new instance of the Error class. + /// + public Error() { } + + /// + /// Initializes a new instance of the Error class. + /// + public Error(int? status = default(int?), string message = default(string)) + { + Status = status; + Message = message; + } + + /// + /// + [JsonProperty(PropertyName = "status")] + public int? Status { get; set; } + + /// + /// + [JsonProperty(PropertyName = "message")] + public string Message { get; set; } + + } +} diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/ErrorException.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/ErrorException.cs new file mode 100644 index 000000000000..e3ab1c0a08ab --- /dev/null +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Models/ErrorException.cs @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +namespace Fixtures.AcceptanceTestsCustomBaseUriMoreOptions.Models +{ + using Microsoft.Rest; + using System; + using System.Net.Http; + using System.Runtime.Serialization; +#if !PORTABLE && !DNXCORE50 + using System.Security.Permissions; +#endif + + /// + /// Exception thrown for an invalid response with Error information. + /// +#if !PORTABLE && !DNXCORE50 + [Serializable] +#endif + public class ErrorException : RestException + { + /// + /// Gets information about the associated HTTP request. + /// + public HttpRequestMessageWrapper Request { get; set; } + + /// + /// Gets information about the associated HTTP response. + /// + public HttpResponseMessageWrapper Response { get; set; } + + /// + /// Gets or sets the body object. + /// + public Error Body { get; set; } + + /// + /// Initializes a new instance of the ErrorException class. + /// + public ErrorException() + { + } + + /// + /// Initializes a new instance of the ErrorException class. + /// + /// The exception message. + public ErrorException(string message) + : this(message, null) + { + } + + /// + /// Initializes a new instance of the ErrorException class. + /// + /// The exception message. + /// Inner exception. + public ErrorException(string message, Exception innerException) + : base(message, innerException) + { + } + +#if !PORTABLE && !DNXCORE50 + /// + /// Initializes a new instance of the ErrorException class. + /// + /// Serialization info. + /// Streaming context. + protected ErrorException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + /// + /// Serializes content of the exception. + /// + /// Serialization info. + /// Streaming context. + [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + if (info == null) + { + throw new ArgumentNullException("info"); + } + + info.AddValue("Request", Request); + info.AddValue("Response", Response); + info.AddValue("Body", Body); + } +#endif + } +} diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Paths.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Paths.cs new file mode 100644 index 000000000000..a8599cf08338 --- /dev/null +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/Paths.cs @@ -0,0 +1,203 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +namespace Fixtures.AcceptanceTestsCustomBaseUriMoreOptions +{ + using System; + using System.Linq; + using System.Collections.Generic; + using System.Net; + using System.Net.Http; + using System.Net.Http.Headers; + using System.Text; + using System.Text.RegularExpressions; + using System.Threading; + using System.Threading.Tasks; + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Newtonsoft.Json; + using Models; + + /// + /// Paths operations. + /// + public partial class Paths : IServiceOperations, IPaths + { + /// + /// Initializes a new instance of the Paths class. + /// + /// + /// Reference to the service client. + /// + public Paths(AutoRestParameterizedCustomHostTestClient client) + { + if (client == null) + { + throw new ArgumentNullException("client"); + } + this.Client = client; + } + + /// + /// Gets a reference to the AutoRestParameterizedCustomHostTestClient + /// + public AutoRestParameterizedCustomHostTestClient Client { get; private set; } + + /// + /// Get a 200 to test a valid base uri + /// + /// + /// The vault name, e.g. https://myvault + /// + /// + /// Secret value. + /// + /// + /// The key name with value 'key1'. + /// + /// + /// The key version. Default value 'v1'. + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task GetEmptyWithHttpMessagesAsync(string vault, string secret, string keyName, string keyVersion = "v1", Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + if (vault == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "vault"); + } + if (secret == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "secret"); + } + if (this.Client.DnsSuffix == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "this.Client.DnsSuffix"); + } + if (keyName == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "keyName"); + } + if (this.Client.SubscriptionId == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "this.Client.SubscriptionId"); + } + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("vault", vault); + tracingParameters.Add("secret", secret); + tracingParameters.Add("keyName", keyName); + tracingParameters.Add("keyVersion", keyVersion); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "GetEmpty", tracingParameters); + } + // Construct URL + var _baseUrl = this.Client.BaseUri; + var _url = _baseUrl + (_baseUrl.EndsWith("/") ? "" : "/") + "customuri/{subscriptionId}/{keyName}"; + _url = _url.Replace("{vault}", vault); + _url = _url.Replace("{secret}", secret); + _url = _url.Replace("{dnsSuffix}", this.Client.DnsSuffix); + _url = _url.Replace("{keyName}", Uri.EscapeDataString(keyName)); + _url = _url.Replace("{subscriptionId}", Uri.EscapeDataString(this.Client.SubscriptionId)); + List _queryParameters = new List(); + if (keyVersion != null) + { + _queryParameters.Add(string.Format("keyVersion={0}", Uri.EscapeDataString(keyVersion))); + } + if (_queryParameters.Count > 0) + { + _url += "?" + string.Join("&", _queryParameters); + } + // Create HTTP transport objects + HttpRequestMessage _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new Uri(_url); + // Set Headers + 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; + // 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) + { + var ex = new ErrorException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + try + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + Error _errorBody = SafeJsonConvert.DeserializeObject(_responseContent, this.Client.DeserializationSettings); + if (_errorBody != null) + { + ex.Body = _errorBody; + } + } + catch (JsonException) + { + // Ignore the exception + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + } +} diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/PathsExtensions.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/PathsExtensions.cs new file mode 100644 index 000000000000..c553414304ed --- /dev/null +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/PathsExtensions.cs @@ -0,0 +1,74 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +namespace Fixtures.AcceptanceTestsCustomBaseUriMoreOptions +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Threading; + using System.Threading.Tasks; + using Microsoft.Rest; + using Models; + + /// + /// Extension methods for Paths. + /// + public static partial class PathsExtensions + { + /// + /// Get a 200 to test a valid base uri + /// + /// + /// The operations group for this extension method. + /// + /// + /// The vault name, e.g. https://myvault + /// + /// + /// Secret value. + /// + /// + /// The key name with value 'key1'. + /// + /// + /// The key version. Default value 'v1'. + /// + public static void GetEmpty(this IPaths operations, string vault, string secret, string keyName, string keyVersion = "v1") + { + Task.Factory.StartNew(s => ((IPaths)s).GetEmptyAsync(vault, secret, keyName, keyVersion), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult(); + } + + /// + /// Get a 200 to test a valid base uri + /// + /// + /// The operations group for this extension method. + /// + /// + /// The vault name, e.g. https://myvault + /// + /// + /// Secret value. + /// + /// + /// The key name with value 'key1'. + /// + /// + /// The key version. Default value 'v1'. + /// + /// + /// The cancellation token. + /// + public static async Task GetEmptyAsync(this IPaths operations, string vault, string secret, string keyName, string keyVersion = "v1", CancellationToken cancellationToken = default(CancellationToken)) + { + await operations.GetEmptyWithHttpMessagesAsync(vault, secret, keyName, keyVersion, null, cancellationToken).ConfigureAwait(false); + } + + } +} diff --git a/AutoRest/Generators/Extensions/Extensions/Extensions.cs b/AutoRest/Generators/Extensions/Extensions/Extensions.cs index e974d9563af2..620a2d594c83 100644 --- a/AutoRest/Generators/Extensions/Extensions/Extensions.cs +++ b/AutoRest/Generators/Extensions/Extensions/Extensions.cs @@ -12,6 +12,8 @@ using Microsoft.Rest.Modeler.Swagger.Model; using Newtonsoft.Json.Linq; using Newtonsoft.Json; +using System.Text.RegularExpressions; +using Microsoft.Rest.Generator.Properties; namespace Microsoft.Rest.Generator { @@ -27,6 +29,8 @@ public abstract class Extensions public const string FlattenOriginalTypeName = "x-ms-client-flatten-original-type-name"; public const string ParameterGroupExtension = "x-ms-parameter-grouping"; public const string ParameterizedHostExtension = "x-ms-parameterized-host"; + public const string UseSchemePrefix = "useSchemePrefix"; + public const string PositionInOperation = "positionInOperation"; private static bool hostChecked = false; @@ -67,6 +71,28 @@ public static void ProcessParameterizedHost(ServiceClient serviceClient, Setting { var hostTemplate = (string)hostExtension["hostTemplate"]; var parametersJson = hostExtension["parameters"].ToString(); + var useSchemePrefix = true; + if (hostExtension[UseSchemePrefix] != null) + { + useSchemePrefix = bool.Parse(hostExtension[UseSchemePrefix].ToString()); + } + + var position = "first"; + + if (hostExtension[PositionInOperation] != null) + { + var pat = "^(fir|la)st$"; + Regex r = new Regex(pat, RegexOptions.IgnoreCase); + var text = hostExtension[PositionInOperation].ToString(); + Match m = r.Match(text); + if (!m.Success) + { + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, + Resources.InvalidExtensionProperty, text, PositionInOperation, ParameterizedHostExtension, "first, last")); + } + position = text; + } + if (!string.IsNullOrEmpty(parametersJson)) { var jsonSettings = new JsonSerializerSettings @@ -76,7 +102,7 @@ public static void ProcessParameterizedHost(ServiceClient serviceClient, Setting }; var swaggerParams = JsonConvert.DeserializeObject>(parametersJson, jsonSettings); - + List hostParamList = new List(); foreach (var swaggerParameter in swaggerParams) { // Build parameter @@ -89,16 +115,33 @@ public static void ProcessParameterizedHost(ServiceClient serviceClient, Setting parameter.ClientProperty = serviceClient.Properties.Single(p => p.SerializedName.Equals(parameter.SerializedName)); } parameter.Extensions["hostParameter"] = true; + hostParamList.Add(parameter); + } - foreach (var method in serviceClient.Methods) + foreach (var method in serviceClient.Methods) + { + if (position.Equals("first", StringComparison.OrdinalIgnoreCase)) { - method.Parameters.Add(parameter); + method.Parameters.InsertRange(0, hostParamList); } + else + { + method.Parameters.AddRange(hostParamList); + } + } - - serviceClient.BaseUrl = string.Format(CultureInfo.InvariantCulture, "{0}://{1}{2}", - modeler.ServiceDefinition.Schemes[0].ToString().ToLowerInvariant(), - hostTemplate, modeler.ServiceDefinition.BasePath); + if (useSchemePrefix) + { + serviceClient.BaseUrl = string.Format(CultureInfo.InvariantCulture, "{0}://{1}{2}", + modeler.ServiceDefinition.Schemes[0].ToString().ToLowerInvariant(), + hostTemplate, modeler.ServiceDefinition.BasePath); + } + else + { + serviceClient.BaseUrl = string.Format(CultureInfo.InvariantCulture, "{0}{1}", + hostTemplate, modeler.ServiceDefinition.BasePath); + } + } } } diff --git a/AutoRest/Generators/Extensions/Extensions/Properties/Resources.Designer.cs b/AutoRest/Generators/Extensions/Extensions/Properties/Resources.Designer.cs index 689a601b826f..f98e2ea0b022 100644 --- a/AutoRest/Generators/Extensions/Extensions/Properties/Resources.Designer.cs +++ b/AutoRest/Generators/Extensions/Extensions/Properties/Resources.Designer.cs @@ -69,6 +69,15 @@ internal class Resources { } } + /// + /// Looks up a localized string similar to The value '{0}' provided for property '{1}' of extension '{2} is invalid. Valid values are: '{3}'.. + /// + internal static string InvalidExtensionProperty { + get { + return ResourceManager.GetString("InvalidExtensionProperty", resourceCulture); + } + } + /// /// Looks up a localized string similar to Azure resource {0} is missing required 'properties' property.. /// diff --git a/AutoRest/Generators/Extensions/Extensions/Properties/Resources.resx b/AutoRest/Generators/Extensions/Extensions/Properties/Resources.resx index d06a580a716f..7df584f0a47a 100644 --- a/AutoRest/Generators/Extensions/Extensions/Properties/Resources.resx +++ b/AutoRest/Generators/Extensions/Extensions/Properties/Resources.resx @@ -120,6 +120,9 @@ Head method '{0}' should contain only 200 level responses, or 404. + + The value '{0}' provided for property '{1}' of extension '{2} is invalid. Valid values are: '{3}'. + Azure resource {0} is missing required 'properties' property. diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClient.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClient.java new file mode 100644 index 000000000000..7c5bb29be05d --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClient.java @@ -0,0 +1,86 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +package fixtures.custombaseurimoreoptions; + +import java.util.List; +import okhttp3.Interceptor; +import okhttp3.logging.HttpLoggingInterceptor.Level; +import com.microsoft.rest.AutoRestBaseUrl; +import com.microsoft.rest.serializer.JacksonMapperAdapter; + +/** + * The interface for AutoRestParameterizedCustomHostTestClient class. + */ +public interface AutoRestParameterizedCustomHostTestClient { + /** + * Gets the URL used as the base for all cloud service requests. + * + * @return the BaseUrl object. + */ + AutoRestBaseUrl getBaseUrl(); + + /** + * Gets the list of interceptors the OkHttp client will execute. + * + * @return the list of interceptors. + */ + List getClientInterceptors(); + + /** + * Sets the logging level for OkHttp client. + * + * @param logLevel the logging level enum. + */ + void setLogLevel(Level logLevel); + + /** + * Gets the adapter for {@link com.fasterxml.jackson.databind.ObjectMapper} for serialization + * and deserialization operations.. + * + * @return the adapter. + */ + JacksonMapperAdapter getMapperAdapter(); + + /** + * Gets The subscription id with value 'test12'.. + * + * @return the subscriptionId value. + */ + String getSubscriptionId(); + + /** + * Sets The subscription id with value 'test12'.. + * + * @param subscriptionId the subscriptionId value. + */ + void setSubscriptionId(String subscriptionId); + + /** + * Gets A string value that is used as a global part of the parameterized host. Default value 'host'.. + * + * @return the dnsSuffix value. + */ + String getDnsSuffix(); + + /** + * Sets A string value that is used as a global part of the parameterized host. Default value 'host'.. + * + * @param dnsSuffix the dnsSuffix value. + */ + void setDnsSuffix(String dnsSuffix); + + /** + * Gets the PathsOperations object to access its operations. + * @return the PathsOperations object. + */ + PathsOperations getPathsOperations(); + +} diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClientImpl.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClientImpl.java new file mode 100644 index 000000000000..ad9fe946dc42 --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/AutoRestParameterizedCustomHostTestClientImpl.java @@ -0,0 +1,121 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +package fixtures.custombaseurimoreoptions; + +import com.microsoft.rest.ServiceClient; +import com.microsoft.rest.AutoRestBaseUrl; +import okhttp3.OkHttpClient; +import retrofit2.Retrofit; + +/** + * Initializes a new instance of the AutoRestParameterizedCustomHostTestClient class. + */ +public final class AutoRestParameterizedCustomHostTestClientImpl extends ServiceClient implements AutoRestParameterizedCustomHostTestClient { + /** + * The URL used as the base for all cloud service requests. + */ + private final AutoRestBaseUrl baseUrl; + + /** + * Gets the URL used as the base for all cloud service requests. + * + * @return The BaseUrl value. + */ + public AutoRestBaseUrl getBaseUrl() { + return this.baseUrl; + } + + /** The subscription id with value 'test12'. */ + private String subscriptionId; + + /** + * Gets The subscription id with value 'test12'. + * + * @return the subscriptionId value. + */ + public String getSubscriptionId() { + return this.subscriptionId; + } + + /** + * Sets The subscription id with value 'test12'. + * + * @param subscriptionId the subscriptionId value. + */ + public void setSubscriptionId(String subscriptionId) { + this.subscriptionId = subscriptionId; + } + + /** A string value that is used as a global part of the parameterized host. Default value 'host'. */ + private String dnsSuffix; + + /** + * Gets A string value that is used as a global part of the parameterized host. Default value 'host'. + * + * @return the dnsSuffix value. + */ + public String getDnsSuffix() { + return this.dnsSuffix; + } + + /** + * Sets A string value that is used as a global part of the parameterized host. Default value 'host'. + * + * @param dnsSuffix the dnsSuffix value. + */ + public void setDnsSuffix(String dnsSuffix) { + this.dnsSuffix = dnsSuffix; + } + + /** + * Gets the PathsOperations object to access its operations. + * @return the PathsOperations object. + */ + public PathsOperations getPathsOperations() { + return new PathsOperationsImpl(this.retrofitBuilder.client(clientBuilder.build()).build(), this); + } + + /** + * Initializes an instance of AutoRestParameterizedCustomHostTestClient client. + */ + public AutoRestParameterizedCustomHostTestClientImpl() { + this("{vault}{secret}{dnsSuffix}"); + } + + /** + * Initializes an instance of AutoRestParameterizedCustomHostTestClient client. + * + * @param baseUrl the base URL of the host + */ + private AutoRestParameterizedCustomHostTestClientImpl(String baseUrl) { + super(); + this.baseUrl = new AutoRestBaseUrl(baseUrl); + initialize(); + } + + /** + * Initializes an instance of AutoRestParameterizedCustomHostTestClient client. + * + * @param clientBuilder the builder for building up an {@link OkHttpClient} + * @param retrofitBuilder the builder for building up a {@link Retrofit} + */ + public AutoRestParameterizedCustomHostTestClientImpl(OkHttpClient.Builder clientBuilder, Retrofit.Builder retrofitBuilder) { + super(clientBuilder, retrofitBuilder); + this.baseUrl = new AutoRestBaseUrl("{vault}{secret}{dnsSuffix}"); + initialize(); + } + + @Override + protected void initialize() { + super.initialize(); + this.retrofitBuilder.baseUrl(baseUrl); + } +} diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperations.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperations.java new file mode 100644 index 000000000000..6273f3426d73 --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperations.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +package fixtures.custombaseurimoreoptions; + +import com.microsoft.rest.ServiceCall; +import com.microsoft.rest.ServiceCallback; +import com.microsoft.rest.ServiceResponse; +import fixtures.custombaseurimoreoptions.models.ErrorException; +import java.io.IOException; + +/** + * An instance of this class provides access to all the operations defined + * in PathsOperations. + */ +public interface PathsOperations { + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @throws IllegalArgumentException exception thrown from invalid parameters + * @return the {@link ServiceResponse} object if successful. + */ + ServiceResponse getEmpty(String vault, String secret, String keyName) throws ErrorException, IOException, IllegalArgumentException; + + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link ServiceCall} object + */ + ServiceCall getEmptyAsync(String vault, String secret, String keyName, final ServiceCallback serviceCallback) throws IllegalArgumentException; + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @param keyVersion The key version. Default value 'v1'. + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @throws IllegalArgumentException exception thrown from invalid parameters + * @return the {@link ServiceResponse} object if successful. + */ + ServiceResponse getEmpty(String vault, String secret, String keyName, String keyVersion) throws ErrorException, IOException, IllegalArgumentException; + + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @param keyVersion The key version. Default value 'v1'. + * @param serviceCallback the async ServiceCallback to handle successful and failed responses. + * @throws IllegalArgumentException thrown if callback is null + * @return the {@link ServiceCall} object + */ + ServiceCall getEmptyAsync(String vault, String secret, String keyName, String keyVersion, final ServiceCallback serviceCallback) throws IllegalArgumentException; + +} diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperationsImpl.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperationsImpl.java new file mode 100644 index 000000000000..13994720257b --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/PathsOperationsImpl.java @@ -0,0 +1,245 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +package fixtures.custombaseurimoreoptions; + +import com.google.common.reflect.TypeToken; +import com.microsoft.rest.ServiceCall; +import com.microsoft.rest.ServiceCallback; +import com.microsoft.rest.ServiceResponse; +import com.microsoft.rest.ServiceResponseBuilder; +import com.microsoft.rest.ServiceResponseCallback; +import fixtures.custombaseurimoreoptions.models.ErrorException; +import java.io.IOException; +import okhttp3.ResponseBody; +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Headers; +import retrofit2.http.Path; +import retrofit2.http.Query; +import retrofit2.Response; +import retrofit2.Retrofit; + +/** + * An instance of this class provides access to all the operations defined + * in PathsOperations. + */ +public final class PathsOperationsImpl implements PathsOperations { + /** The Retrofit service to perform REST calls. */ + private PathsService service; + /** The service client containing this operation class. */ + private AutoRestParameterizedCustomHostTestClient client; + + /** + * Initializes an instance of PathsOperations. + * + * @param retrofit the Retrofit instance built from a Retrofit Builder. + * @param client the instance of the service client containing this operation class. + */ + public PathsOperationsImpl(Retrofit retrofit, AutoRestParameterizedCustomHostTestClient client) { + this.service = retrofit.create(PathsService.class); + this.client = client; + } + + /** + * The interface defining all the services for PathsOperations to be + * used by Retrofit to perform actually REST calls. + */ + interface PathsService { + @Headers("Content-Type: application/json; charset=utf-8") + @GET("customuri/{subscriptionId}/{keyName}") + Call getEmpty(@Path("keyName") String keyName, @Path("subscriptionId") String subscriptionId, @Query("keyVersion") String keyVersion); + + } + + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @throws IllegalArgumentException exception thrown from invalid parameters + * @return the {@link ServiceResponse} object if successful. + */ + public ServiceResponse getEmpty(String vault, String secret, String keyName) throws ErrorException, IOException, IllegalArgumentException { + if (vault == null) { + throw new IllegalArgumentException("Parameter vault is required and cannot be null."); + } + if (secret == null) { + throw new IllegalArgumentException("Parameter secret is required and cannot be null."); + } + if (this.client.getDnsSuffix() == null) { + throw new IllegalArgumentException("Parameter this.client.getDnsSuffix() is required and cannot be null."); + } + if (keyName == null) { + throw new IllegalArgumentException("Parameter keyName is required and cannot be null."); + } + if (this.client.getSubscriptionId() == null) { + throw new IllegalArgumentException("Parameter this.client.getSubscriptionId() is required and cannot be null."); + } + final String keyVersion = null; + this.client.getBaseUrl().set("{vault}", vault); + this.client.getBaseUrl().set("{secret}", secret); + this.client.getBaseUrl().set("{dnsSuffix}", this.client.getDnsSuffix()); + Call call = service.getEmpty(keyName, this.client.getSubscriptionId(), keyVersion); + return getEmptyDelegate(call.execute()); + } + + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @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 getEmptyAsync(String vault, String secret, String keyName, final ServiceCallback serviceCallback) throws IllegalArgumentException { + if (serviceCallback == null) { + throw new IllegalArgumentException("ServiceCallback is required for async calls."); + } + if (vault == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter vault is required and cannot be null.")); + return null; + } + if (secret == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter secret is required and cannot be null.")); + return null; + } + if (this.client.getDnsSuffix() == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter this.client.getDnsSuffix() is required and cannot be null.")); + return null; + } + if (keyName == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter keyName is required and cannot be null.")); + return null; + } + if (this.client.getSubscriptionId() == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter this.client.getSubscriptionId() is required and cannot be null.")); + return null; + } + final String keyVersion = null; + this.client.getBaseUrl().set("{vault}", vault); + this.client.getBaseUrl().set("{secret}", secret); + this.client.getBaseUrl().set("{dnsSuffix}", this.client.getDnsSuffix()); + Call call = service.getEmpty(keyName, this.client.getSubscriptionId(), keyVersion); + final ServiceCall serviceCall = new ServiceCall(call); + call.enqueue(new ServiceResponseCallback(serviceCallback) { + @Override + public void onResponse(Call call, Response response) { + try { + serviceCallback.success(getEmptyDelegate(response)); + } catch (ErrorException | IOException exception) { + serviceCallback.failure(exception); + } + } + }); + return serviceCall; + } + + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @param keyVersion The key version. Default value 'v1'. + * @throws ErrorException exception thrown from REST call + * @throws IOException exception thrown from serialization/deserialization + * @throws IllegalArgumentException exception thrown from invalid parameters + * @return the {@link ServiceResponse} object if successful. + */ + public ServiceResponse getEmpty(String vault, String secret, String keyName, String keyVersion) throws ErrorException, IOException, IllegalArgumentException { + if (vault == null) { + throw new IllegalArgumentException("Parameter vault is required and cannot be null."); + } + if (secret == null) { + throw new IllegalArgumentException("Parameter secret is required and cannot be null."); + } + if (this.client.getDnsSuffix() == null) { + throw new IllegalArgumentException("Parameter this.client.getDnsSuffix() is required and cannot be null."); + } + if (keyName == null) { + throw new IllegalArgumentException("Parameter keyName is required and cannot be null."); + } + if (this.client.getSubscriptionId() == null) { + throw new IllegalArgumentException("Parameter this.client.getSubscriptionId() is required and cannot be null."); + } + this.client.getBaseUrl().set("{vault}", vault); + this.client.getBaseUrl().set("{secret}", secret); + this.client.getBaseUrl().set("{dnsSuffix}", this.client.getDnsSuffix()); + Call call = service.getEmpty(keyName, this.client.getSubscriptionId(), keyVersion); + return getEmptyDelegate(call.execute()); + } + + /** + * Get a 200 to test a valid base uri. + * + * @param vault The vault name, e.g. https://myvault + * @param secret Secret value. + * @param keyName The key name with value 'key1'. + * @param keyVersion The key version. Default value 'v1'. + * @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 getEmptyAsync(String vault, String secret, String keyName, String keyVersion, final ServiceCallback serviceCallback) throws IllegalArgumentException { + if (serviceCallback == null) { + throw new IllegalArgumentException("ServiceCallback is required for async calls."); + } + if (vault == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter vault is required and cannot be null.")); + return null; + } + if (secret == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter secret is required and cannot be null.")); + return null; + } + if (this.client.getDnsSuffix() == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter this.client.getDnsSuffix() is required and cannot be null.")); + return null; + } + if (keyName == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter keyName is required and cannot be null.")); + return null; + } + if (this.client.getSubscriptionId() == null) { + serviceCallback.failure(new IllegalArgumentException("Parameter this.client.getSubscriptionId() is required and cannot be null.")); + return null; + } + this.client.getBaseUrl().set("{vault}", vault); + this.client.getBaseUrl().set("{secret}", secret); + this.client.getBaseUrl().set("{dnsSuffix}", this.client.getDnsSuffix()); + Call call = service.getEmpty(keyName, this.client.getSubscriptionId(), keyVersion); + final ServiceCall serviceCall = new ServiceCall(call); + call.enqueue(new ServiceResponseCallback(serviceCallback) { + @Override + public void onResponse(Call call, Response response) { + try { + serviceCallback.success(getEmptyDelegate(response)); + } catch (ErrorException | IOException exception) { + serviceCallback.failure(exception); + } + } + }); + return serviceCall; + } + + private ServiceResponse getEmptyDelegate(Response response) throws ErrorException, IOException, IllegalArgumentException { + 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/custombaseurimoreoptions/models/Error.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/Error.java new file mode 100644 index 000000000000..73232cf4ed43 --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/Error.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +package fixtures.custombaseurimoreoptions.models; + + +/** + * The Error model. + */ +public class Error { + /** + * The status property. + */ + private Integer status; + + /** + * The message property. + */ + private String message; + + /** + * Get the status value. + * + * @return the status value + */ + public Integer getStatus() { + return this.status; + } + + /** + * Set the status value. + * + * @param status the status value to set + */ + public void setStatus(Integer status) { + this.status = status; + } + + /** + * Get the message value. + * + * @return the message value + */ + public String getMessage() { + return this.message; + } + + /** + * Set the message value. + * + * @param message the message value to set + */ + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/ErrorException.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/ErrorException.java new file mode 100644 index 000000000000..0c4458e200da --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/ErrorException.java @@ -0,0 +1,89 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +package fixtures.custombaseurimoreoptions.models; + +import com.microsoft.rest.AutoRestException; +import retrofit2.Response; + +/** + * Exception thrown for an invalid response with Error information. + */ +public class ErrorException extends AutoRestException { + /** + * Information about the associated HTTP response. + */ + private Response response; + /** + * The actual response body. + */ + private Error body; + /** + * Initializes a new instance of the ErrorException class. + */ + public ErrorException() { } + /** + * Initializes a new instance of the ErrorException class. + * + * @param message The exception message. + */ + public ErrorException(final String message) { + super(message); + } + /** + * Initializes a new instance of the ErrorException class. + * + * @param message the exception message + * @param cause exception that caused this exception to occur + */ + public ErrorException(final String message, final Throwable cause) { + super(message, cause); + } + /** + * Initializes a new instance of the ErrorException class. + * + * @param cause exception that caused this exception to occur + */ + public ErrorException(final Throwable cause) { + super(cause); + } + /** + * Gets information about the associated HTTP response. + * + * @return the HTTP response + */ + public Response getResponse() { + return response; + } + /** + * Gets the HTTP response body. + * + * @return the response body + */ + public Error getBody() { + return body; + } + /** + * Sets the HTTP response. + * + * @param response the HTTP response + */ + public void setResponse(Response response) { + this.response = response; + } + /** + * Sets the HTTP response body. + * + * @param body the response body + */ + public void setBody(Error body) { + this.body = body; + } +} diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/package-info.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/package-info.java new file mode 100644 index 000000000000..b5c9a91ec97d --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/models/package-info.java @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +/** + * This package contains the model classes for AutoRestParameterizedCustomHostTestClient. + * Test Infrastructure for AutoRest. + */ +package fixtures.custombaseurimoreoptions.models; diff --git a/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/package-info.java b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/package-info.java new file mode 100644 index 000000000000..a6434083eb1c --- /dev/null +++ b/AutoRest/Generators/Java/Java.Tests/src/main/java/fixtures/custombaseurimoreoptions/package-info.java @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +/** + * This package contains the classes for AutoRestParameterizedCustomHostTestClient. + * Test Infrastructure for AutoRest. + */ +package fixtures.custombaseurimoreoptions; diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/AcceptanceTests/acceptanceTests.ts b/AutoRest/Generators/NodeJS/NodeJS.Tests/AcceptanceTests/acceptanceTests.ts index c7404da84e36..0a81b3420068 100644 --- a/AutoRest/Generators/NodeJS/NodeJS.Tests/AcceptanceTests/acceptanceTests.ts +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/AcceptanceTests/acceptanceTests.ts @@ -32,7 +32,7 @@ import dictionaryModels = require('../Expected/AcceptanceTests/BodyDictionary/mo import httpClient = require('../Expected/AcceptanceTests/Http/autoRestHttpInfrastructureTestService'); import formDataClient = require('../Expected/AcceptanceTests/BodyFormData/autoRestSwaggerBATFormDataService'); import customBaseUriClient = require('../Expected/AcceptanceTests/CustomBaseUri/autoRestParameterizedHostTestClient'); - +import customBaseUriClientMoreOptions = require('../Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient'); var dummyToken = 'dummy12321343423'; var credentials = new msRest.TokenCredentials(dummyToken); @@ -94,6 +94,19 @@ describe('nodejs', function () { }); }); }); + describe('Custom BaseUri Client with more options', function () { + var customOptions = { + dnsSuffix: 'host:3000' + }; + var testClient = new customBaseUriClientMoreOptions('test12', customOptions); + it('should return 200', function (done) { + testClient.paths.getEmpty('http://lo','cal', 'key1', function (error, result, request, response) { + should.not.exist(error); + response.statusCode.should.equal(200); + done(); + }); + }); + }); describe('Bool Client', function () { var testClient = new boolClient(baseUri, clientOptions); it('should get valid boolean values', function (done) { diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.d.ts b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.d.ts new file mode 100644 index 000000000000..98c22ab85f4d --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.d.ts @@ -0,0 +1,44 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +import { ServiceClientOptions, RequestOptions, ServiceCallback } from 'ms-rest'; +import * as operations from "./operations"; + +declare class AutoRestParameterizedCustomHostTestClient { + /** + * @class + * Initializes a new instance of the AutoRestParameterizedCustomHostTestClient class. + * @constructor + * + * @param {string} subscriptionId - The subscription id with value 'test12'. + * + * @param {object} [options] - The parameter options + * + * @param {Array} [options.filters] - Filters to be added to the request pipeline + * + * @param {object} [options.requestOptions] - Options for the underlying request object + * {@link https://github.com/request/request#requestoptions-callback Options doc} + * + * @param {boolean} [options.noRetryPolicy] - If set to true, turn off default retry policy + * + * @param {string} [options.dnsSuffix] - A string value that is used as a global part of the parameterized host. Default value 'host'. + * + */ + constructor(subscriptionId: string, options: ServiceClientOptions); + + subscriptionId: string; + + dnsSuffix: string; + + // Operation groups + paths: operations.Paths; + } + +export = AutoRestParameterizedCustomHostTestClient; diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.js new file mode 100644 index 000000000000..391f7b50deb3 --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autoRestParameterizedCustomHostTestClient.js @@ -0,0 +1,65 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +/* jshint latedef:false */ +/* jshint forin:false */ +/* jshint noempty:false */ + +'use strict'; + +var util = require('util'); +var msRest = require('ms-rest'); +var ServiceClient = msRest.ServiceClient; + +var models = require('./models'); +var operations = require('./operations'); + +/** + * @class + * Initializes a new instance of the AutoRestParameterizedCustomHostTestClient class. + * @constructor + * + * @param {string} subscriptionId - The subscription id with value 'test12'. + * + * @param {object} [options] - The parameter options + * + * @param {Array} [options.filters] - Filters to be added to the request pipeline + * + * @param {object} [options.requestOptions] - Options for the underlying request object + * {@link https://github.com/request/request#requestoptions-callback Options doc} + * + * @param {boolean} [options.noRetryPolicy] - If set to true, turn off default retry policy + * + * @param {string} [options.dnsSuffix] - A string value that is used as a global part of the parameterized host. Default value 'host'. + * + */ +function AutoRestParameterizedCustomHostTestClient(subscriptionId, options) { + this.dnsSuffix = 'host'; + if (subscriptionId === null || subscriptionId === undefined) { + throw new Error('\'subscriptionId\' cannot be null.'); + } + + if (!options) options = {}; + + AutoRestParameterizedCustomHostTestClient['super_'].call(this, null, options); + this.baseUri = '{vault}{secret}{dnsSuffix}'; + this.subscriptionId = subscriptionId; + + if(options.dnsSuffix !== null && options.dnsSuffix !== undefined) { + this.dnsSuffix = options.dnsSuffix; + } + this.paths = new operations.Paths(this); + this.models = models; + msRest.addSerializationMixin(this); +} + +util.inherits(AutoRestParameterizedCustomHostTestClient, ServiceClient); + +module.exports = AutoRestParameterizedCustomHostTestClient; diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/errorModel.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/errorModel.js new file mode 100644 index 000000000000..663be0f4aaa8 --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/errorModel.js @@ -0,0 +1,58 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +'use strict'; + +/** + * @class + * Initializes a new instance of the ErrorModel class. + * @constructor + * @member {number} [status] + * + * @member {string} [message] + * + */ +function ErrorModel() { +} + +/** + * Defines the metadata of ErrorModel + * + * @returns {object} metadata of ErrorModel + * + */ +ErrorModel.prototype.mapper = function () { + return { + required: false, + serializedName: 'Error', + type: { + name: 'Composite', + className: 'ErrorModel', + modelProperties: { + status: { + required: false, + serializedName: 'status', + type: { + name: 'Number' + } + }, + message: { + required: false, + serializedName: 'message', + type: { + name: 'String' + } + } + } + } + }; +}; + +module.exports = ErrorModel; diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.d.ts b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.d.ts new file mode 100644 index 000000000000..5405a199a075 --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.d.ts @@ -0,0 +1,24 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + + +/** + * @class + * Initializes a new instance of the ErrorModel class. + * @constructor + * @member {number} [status] + * + * @member {string} [message] + * + */ +export interface ErrorModel { + status?: number; + message?: string; +} diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.js new file mode 100644 index 000000000000..3430295d8bd8 --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/models/index.js @@ -0,0 +1,17 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +/* jshint latedef:false */ +/* jshint forin:false */ +/* jshint noempty:false */ + +'use strict'; + +exports.ErrorModel = require('./errorModel'); diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.d.ts b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.d.ts new file mode 100644 index 000000000000..3fa4ea5d9bf1 --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.d.ts @@ -0,0 +1,44 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. +*/ + +import { ServiceClientOptions, RequestOptions, ServiceCallback } from 'ms-rest'; +import * as models from '../models'; + + +/** + * @class + * Paths + * __NOTE__: An instance of this class is automatically created for an + * instance of the AutoRestParameterizedCustomHostTestClient. + */ +export interface Paths { + + /** + * Get a 200 to test a valid base uri + * + * @param {string} vault The vault name, e.g. https://myvault + * + * @param {string} secret Secret value. + * + * @param {string} keyName The key name with value 'key1'. + * + * @param {object} [options] Optional Parameters. + * + * @param {string} [options.keyVersion] The key version. Default value 'v1'. + * + * @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 + */ + getEmpty(vault: string, secret: string, keyName: string, options: { keyVersion? : string, customHeaders? : { [headerName: string]: string; } }, callback: ServiceCallback): void; + getEmpty(vault: string, secret: string, keyName: string, callback: ServiceCallback): void; +} diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.js new file mode 100644 index 000000000000..412d88e67668 --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/index.js @@ -0,0 +1,17 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +/* jshint latedef:false */ +/* jshint forin:false */ +/* jshint noempty:false */ + +'use strict'; + +exports.Paths = require('./paths'); diff --git a/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/paths.js b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/paths.js new file mode 100644 index 000000000000..dc2c66f05c60 --- /dev/null +++ b/AutoRest/Generators/NodeJS/NodeJS.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/operations/paths.js @@ -0,0 +1,167 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + * + * Code generated by Microsoft (R) AutoRest Code Generator. + * Changes may cause incorrect behavior and will be lost if the code is + * regenerated. + */ + +'use strict'; + +var util = require('util'); +var msRest = require('ms-rest'); +var WebResource = msRest.WebResource; + +/** + * @class + * Paths + * __NOTE__: An instance of this class is automatically created for an + * instance of the AutoRestParameterizedCustomHostTestClient. + * Initializes a new instance of the Paths class. + * @constructor + * + * @param {AutoRestParameterizedCustomHostTestClient} client Reference to the service client. + */ +function Paths(client) { + this.client = client; +} + +/** + * Get a 200 to test a valid base uri + * + * @param {string} vault The vault name, e.g. https://myvault + * + * @param {string} secret Secret value. + * + * @param {string} keyName The key name with value 'key1'. + * + * @param {object} [options] Optional Parameters. + * + * @param {string} [options.keyVersion] The key version. Default value 'v1'. + * + * @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.getEmpty = function (vault, secret, keyName, 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 keyVersion = (options && options.keyVersion !== undefined) ? options.keyVersion : 'v1'; + // Validate + try { + if (vault === null || vault === undefined || typeof vault.valueOf() !== 'string') { + throw new Error('vault cannot be null or undefined and it must be of type string.'); + } + if (secret === null || secret === undefined || typeof secret.valueOf() !== 'string') { + throw new Error('secret cannot be null or undefined and it must be of type string.'); + } + if (this.client.dnsSuffix === null || this.client.dnsSuffix === undefined || typeof this.client.dnsSuffix.valueOf() !== 'string') { + throw new Error('this.client.dnsSuffix cannot be null or undefined and it must be of type string.'); + } + if (keyName === null || keyName === undefined || typeof keyName.valueOf() !== 'string') { + throw new Error('keyName cannot be null or undefined and it must be of type string.'); + } + if (this.client.subscriptionId === null || this.client.subscriptionId === undefined || typeof this.client.subscriptionId.valueOf() !== 'string') { + throw new Error('this.client.subscriptionId cannot be null or undefined and it must be of type string.'); + } + if (keyVersion !== null && keyVersion !== undefined && typeof keyVersion.valueOf() !== 'string') { + throw new Error('keyVersion must be of type string.'); + } + } catch (error) { + return callback(error); + } + + // Construct URL + var requestUrl = this.client.baseUri + + '//customuri/{subscriptionId}/{keyName}'; + requestUrl = requestUrl.replace('{vault}', vault); + requestUrl = requestUrl.replace('{secret}', secret); + requestUrl = requestUrl.replace('{dnsSuffix}', this.client.dnsSuffix); + requestUrl = requestUrl.replace('{keyName}', encodeURIComponent(keyName)); + requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId)); + var queryParameters = []; + if (keyVersion !== null && keyVersion !== undefined) { + queryParameters.push('keyVersion=' + encodeURIComponent(keyVersion)); + } + 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 = '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/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/__init__.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/__init__.py new file mode 100644 index 000000000000..6711cf5b14df --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/__init__.py @@ -0,0 +1,21 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from .auto_rest_parameterized_custom_host_test_client import AutoRestParameterizedCustomHostTestClient, AutoRestParameterizedCustomHostTestClientConfiguration +from .version import VERSION + +__all__ = [ + 'AutoRestParameterizedCustomHostTestClient', + 'AutoRestParameterizedCustomHostTestClientConfiguration' +] + +__version__ = VERSION + diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/auto_rest_parameterized_custom_host_test_client.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/auto_rest_parameterized_custom_host_test_client.py new file mode 100644 index 000000000000..1e9140c3e5f7 --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/auto_rest_parameterized_custom_host_test_client.py @@ -0,0 +1,69 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.service_client import ServiceClient +from msrest import Configuration, Serializer, Deserializer +from .version import VERSION +from .operations.paths import Paths +from . import models + + +class AutoRestParameterizedCustomHostTestClientConfiguration(Configuration): + """Configuration for AutoRestParameterizedCustomHostTestClient + Note that all parameters used to create this instance are saved as instance + attributes. + + :param subscription_id: The subscription id with value 'test12'. + :type subscription_id: str + :param dns_suffix: A string value that is used as a global part of the + parameterized host. Default value 'host'. + :type dns_suffix: str + :param str filepath: Existing config + """ + + def __init__( + self, subscription_id, dns_suffix, filepath=None): + + if subscription_id is None: + raise ValueError('subscription_id must not be None.') + if dns_suffix is None: + raise ValueError('dns_suffix must not be None.') + base_url = '{vault}{secret}{dnsSuffix}' + + super(AutoRestParameterizedCustomHostTestClientConfiguration, self).__init__(base_url, filepath) + + self.add_user_agent('autorestparameterizedcustomhosttestclient/{}'.format(VERSION)) + + self.subscription_id = subscription_id + self.dns_suffix = dns_suffix + + +class AutoRestParameterizedCustomHostTestClient(object): + """Test Infrastructure for AutoRest + + :param config: Configuration for client. + :type config: AutoRestParameterizedCustomHostTestClientConfiguration + + :ivar paths: Paths operations + :vartype paths: .operations.Paths + """ + + def __init__(self, config): + + self._client = ServiceClient(None, config) + + client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)} + self._serialize = Serializer() + self._deserialize = Deserializer(client_models) + + self.config = config + self.paths = Paths( + self._client, self.config, self._serialize, self._deserialize) diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/credentials.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/credentials.py new file mode 100644 index 000000000000..0d097b4f2a6c --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/credentials.py @@ -0,0 +1,15 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.authentication import ( + BasicAuthentication, + BasicTokenAuthentication, + OAuthTokenAuthentication) diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/exceptions.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/exceptions.py new file mode 100644 index 000000000000..c3cc00226060 --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/exceptions.py @@ -0,0 +1,21 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.exceptions import ( + ClientException, + SerializationError, + DeserializationError, + TokenExpiredError, + ClientRequestError, + AuthenticationError, + HttpOperationError, + ValidationError, +) diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/__init__.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/__init__.py new file mode 100644 index 000000000000..fd6d517a4711 --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/__init__.py @@ -0,0 +1,16 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from .error import Error, ErrorException + +__all__ = [ + 'Error', 'ErrorException', +] diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/error.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/error.py new file mode 100644 index 000000000000..c2d19e377e00 --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/models/error.py @@ -0,0 +1,44 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.serialization import Model +from msrest.exceptions import HttpOperationError + + +class Error(Model): + """Error + + :param status: + :type status: int + :param message: + :type message: str + """ + + _attribute_map = { + 'status': {'key': 'status', 'type': 'int'}, + 'message': {'key': 'message', 'type': 'str'}, + } + + def __init__(self, status=None, message=None): + self.status = status + self.message = message + + +class ErrorException(HttpOperationError): + """Server responsed with exception of type: 'Error'. + + :param deserialize: A deserializer + :param response: Server response to be deserialized. + """ + + def __init__(self, deserialize, response, *args): + + super(ErrorException, self).__init__(deserialize, response, 'Error', *args) diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/__init__.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/__init__.py new file mode 100644 index 000000000000..fa4a82a28df5 --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/__init__.py @@ -0,0 +1,16 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from .paths import Paths + +__all__ = [ + 'Paths', +] diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/paths.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/paths.py new file mode 100644 index 000000000000..2c43f455f742 --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/operations/paths.py @@ -0,0 +1,87 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +from msrest.pipeline import ClientRawResponse + +from .. import models + + +class Paths(object): + """Paths operations. + + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An objec model deserializer. + """ + + def __init__(self, client, config, serializer, deserializer): + + self._client = client + self._serialize = serializer + self._deserialize = deserializer + + self.config = config + + def get_empty( + self, vault, secret, key_name, key_version="v1", custom_headers={}, raw=False, **operation_config): + """ + Get a 200 to test a valid base uri + + :param vault: The vault name, e.g. https://myvault + :type vault: str + :param secret: Secret value. + :type secret: str + :param key_name: The key name with value 'key1'. + :type key_name: str + :param key_version: The key version. Default value 'v1'. + :type key_version: str + :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 = '/customuri/{subscriptionId}/{keyName}' + path_format_arguments = { + 'vault': self._serialize.url("vault", vault, 'str', skip_quote=True), + 'secret': self._serialize.url("secret", secret, 'str', skip_quote=True), + 'dnsSuffix': self._serialize.url("self.config.dns_suffix", self.config.dns_suffix, 'str', skip_quote=True), + 'keyName': self._serialize.url("key_name", key_name, 'str'), + 'subscriptionId': self._serialize.url("self.config.subscription_id", self.config.subscription_id, 'str') + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} + if key_version is not None: + query_parameters['keyVersion'] = self._serialize.query("key_version", key_version, 'str') + + # 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 diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/version.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/version.py new file mode 100644 index 000000000000..a39916c162ce --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/autorestparameterizedcustomhosttestclient/version.py @@ -0,0 +1,13 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- + +VERSION = "1.0.0" + diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/setup.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/setup.py new file mode 100644 index 000000000000..3521fb6abef9 --- /dev/null +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUriMoreOptions/setup.py @@ -0,0 +1,40 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is +# regenerated. +# -------------------------------------------------------------------------- +# coding: utf-8 + +from setuptools import setup, find_packages + +NAME = "autorestparameterizedcustomhosttestclient" +VERSION = "1.0.0" + +# To install the library, run the following +# +# python setup.py install +# +# prerequisite: setuptools +# http://pypi.python.org/pypi/setuptools + +REQUIRES = ["msrest>=0.2.0"] + +setup( + name=NAME, + version=VERSION, + description="AutoRestParameterizedCustomHostTestClient", + author_email="", + url="", + keywords=["Swagger", "AutoRestParameterizedCustomHostTestClient"], + install_requires=REQUIRES, + packages=find_packages(), + include_package_data=True, + long_description="""\ + Test Infrastructure for AutoRest + """ +) diff --git a/AutoRest/Generators/Python/Python.Tests/Python.Tests.pyproj b/AutoRest/Generators/Python/Python.Tests/Python.Tests.pyproj index 551692fe3e19..b6cfb6ea96c3 100644 --- a/AutoRest/Generators/Python/Python.Tests/Python.Tests.pyproj +++ b/AutoRest/Generators/Python/Python.Tests/Python.Tests.pyproj @@ -125,6 +125,10 @@ + + + + diff --git a/AutoRest/TestServer/server/app.js b/AutoRest/TestServer/server/app.js index f0da0d60682c..8bb3b105ba76 100644 --- a/AutoRest/TestServer/server/app.js +++ b/AutoRest/TestServer/server/app.js @@ -428,6 +428,8 @@ var coverage = { "ConstantsInPath": 0, "ConstantsInBody": 0, "CustomBaseUri": 0, + //Once all the languages implement this test, the scenario counter should be reset to zero. It is currently implemented in C# and node.js + "CustomBaseUriMoreOptions": 1, 'getModelFlattenArray': 0, 'putModelFlattenArray': 0, 'getModelFlattenDictionary': 0, diff --git a/AutoRest/TestServer/server/routes/customUri.js b/AutoRest/TestServer/server/routes/customUri.js index 2eee79cadfc3..85d074cdeceb 100644 --- a/AutoRest/TestServer/server/routes/customUri.js +++ b/AutoRest/TestServer/server/routes/customUri.js @@ -9,6 +9,17 @@ var specials = function (coverage) { coverage['CustomBaseUri']++; res.status(200).end(); }); + + router.get('/:subscriptionId/:keyName', function (req, res, next) { + if (req.params.subscriptionId === 'test12' && req.params.keyName === 'key1' + && Object.keys(req.query).length == 1 && req.query.keyVersion === 'v1') { + coverage['CustomBaseUriMoreOptions']++; + res.status(200).end(); + } else { + utils.send400(res, next, 'Either one of the path parameters (subscriptionId=test12, keyName=key1) or query parameter (keyVersion=v1) did not match. ' + + 'Received parameters are: subscriptionId ' + subscriptionId + ', keyName ' + keyName + ', keyVersion ' + keyVersion); + } + }); } specials.prototype.router = router; diff --git a/AutoRest/TestServer/swagger/custom-baseUrl-more-options.json b/AutoRest/TestServer/swagger/custom-baseUrl-more-options.json new file mode 100644 index 000000000000..75ef7453976e --- /dev/null +++ b/AutoRest/TestServer/swagger/custom-baseUrl-more-options.json @@ -0,0 +1,108 @@ +{ + "swagger": "2.0", + "info": { + "title": "AutoRest Parameterized Custom Host Test Client", + "description": "Test Infrastructure for AutoRest", + "version": "1.0.0" + }, + "x-ms-parameterized-host": { + "hostTemplate": "{vault}{secret}{dnsSuffix}", + "useSchemePrefix": false, + "parameters": [ + { + "name": "vault", + "description": "The vault name, e.g. https://myvault", + "required": true, + "type": "string", + "in": "path", + "x-ms-skip-url-encoding": true + }, + { + "name": "secret", + "description": "Secret value.", + "required": true, + "type": "string", + "in": "path", + "x-ms-skip-url-encoding": true + }, + { + "$ref": "#/parameters/dnsSuffix" + } + ] + }, + "produces": [ "application/json" ], + "consumes": [ "application/json" ], + "paths": { + "/customuri/{subscriptionId}/{keyName}": { + "get": { + "operationId": "paths_getEmpty", + "description": "Get a 200 to test a valid base uri", + "tags": [ + "Path Operations" + ], + "parameters": [ + { + "name": "keyName", + "in": "path", + "required": true, + "type": "string", + "description": "The key name with value 'key1'." + }, + { + "$ref": "#/parameters/SubscriptionIdParameter" + }, + { + "name": "keyVersion", + "in": "query", + "required": false, + "type": "string", + "default": "v1", + "description": "The key version. Default value 'v1'." + } + ], + "responses": { + "200": { + "description": "Successfully received a 200 response" + }, + "default": { + "description": "Unexpected error", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + } + }, + "parameters": { + "SubscriptionIdParameter": { + "name": "subscriptionId", + "in": "path", + "required": true, + "type": "string", + "description": "The subscription id with value 'test12'." + }, + "dnsSuffix": { + "name": "dnsSuffix", + "description": "A string value that is used as a global part of the parameterized host. Default value 'host'.", + "type": "string", + "required": false, + "default": "host", + "in": "path", + "x-ms-skip-url-encoding": true + } + }, + "definitions": { + "Error": { + "properties": { + "status": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } +} diff --git a/AutoRest/TestServer/swagger/custom-baseUrl.json b/AutoRest/TestServer/swagger/custom-baseUrl.json index 5ca07d1627a0..aaa0309f4b94 100644 --- a/AutoRest/TestServer/swagger/custom-baseUrl.json +++ b/AutoRest/TestServer/swagger/custom-baseUrl.json @@ -8,6 +8,7 @@ "host": "badhost", "x-ms-parameterized-host": { "hostTemplate": "{accountName}{host}", + "positionInOperation": "last", "parameters": [ { "name": "accountName", diff --git a/Documentation/swagger-extensions.md b/Documentation/swagger-extensions.md index cb3bed17ab58..f606ac335567 100644 --- a/Documentation/swagger-extensions.md +++ b/Documentation/swagger-extensions.md @@ -389,7 +389,9 @@ When used, replaces the standard Swagger "host" attribute with a host that conta Field Name | Type | Description ---|:---:|--- hostTemplate | `string` | **Required**. Specifies the parameterized template for the host. -parameters | [Array of Parameter Objects](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameterObject) | The list of parameters that are used within the hostTemplate. This can include both reference parameters as well as explicit parameters. Note that "in" is **required** and **must be** set to "path" +useSchemePrefix | `boolean` | **Optional, Default: true**. Specifes whether to prepend the default scheme a.k.a protocol to the base uri of client. +positionInOperation | `string` | **Optional, Default: first**. Specifies whether the list of parameters will appear in the beginning or in the end, in the method signature for every operation. The order within the parameters provided in the below mentioned array will be preserved. Either the array of parameters will be prepended or appended, based on the value provided over here. Valid values are **"first", "last"**. Every method/operation in any programming language has parameters categorized into two buckets **"required"** and **"optional"**. It is natural for optional paramaters to appear in the end in a method signature. **This aspect will be preserved, while prepending(first) or appending(last) hostTemplate parameters .** +parameters | [Array of Parameter Objects](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameterObject) | The list of parameters that are used within the hostTemplate. This can include both reference parameters as well as explicit parameters. Note that "in" is **required** and **must be** set to **"path"**. The reference parameters will be treated as **global parameters** and will end up as property of the client. **Example**: Using both explicit and reference parameters diff --git a/gulpfile.js b/gulpfile.js index 942ac3a898b8..e7bc6be0adf4 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -63,7 +63,8 @@ var defaultMappings = { 'AcceptanceTests/Url': '../../../TestServer/swagger/url.json', 'AcceptanceTests/Validation': '../../../TestServer/swagger/validation.json', 'AcceptanceTests/CustomBaseUri': '../../../TestServer/swagger/custom-baseUrl.json', - 'AcceptanceTests/ModelFlattening': '../../../TestServer/swagger/model-flattening.json', + 'AcceptanceTests/CustomBaseUriMoreOptions': '../../../TestServer/swagger/custom-baseUrl-more-options.json', + 'AcceptanceTests/ModelFlattening': '../../../TestServer/swagger/model-flattening.json' }; var rubyMappings = { diff --git a/schema/swagger-extensions.json b/schema/swagger-extensions.json index 199078f32eee..6e6476c56dbf 100644 --- a/schema/swagger-extensions.json +++ b/schema/swagger-extensions.json @@ -1540,6 +1540,15 @@ "hostTemplate": { "type": "string" }, + "useSchemePrefix": { + "type": "boolean", + "default": true + }, + "positionInOperation": { + "type": "string", + "default": "first", + "pattern": "^(fir|la)st$" + }, "parameters": { "$ref": "#/definitions/xmsHostParametersList" } From 0e2d13a68cc00dca17c4f548298bbbebd24259b2 Mon Sep 17 00:00:00 2001 From: Amar Zavery Date: Sun, 10 Apr 2016 20:15:51 -0700 Subject: [PATCH 21/96] Update swagger-extensions.md --- Documentation/swagger-extensions.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Documentation/swagger-extensions.md b/Documentation/swagger-extensions.md index f606ac335567..1fbf0efe46d7 100644 --- a/Documentation/swagger-extensions.md +++ b/Documentation/swagger-extensions.md @@ -394,10 +394,14 @@ positionInOperation | `string` | **Optional, Default: first**. Specifies whether parameters | [Array of Parameter Objects](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameterObject) | The list of parameters that are used within the hostTemplate. This can include both reference parameters as well as explicit parameters. Note that "in" is **required** and **must be** set to **"path"**. The reference parameters will be treated as **global parameters** and will end up as property of the client. **Example**: -Using both explicit and reference parameters +- Using both explicit and reference parameters. + - Since "useSchemePrefix" is not specified, it's default value true will be applied. The user is expected to provide only the value of accountName. The generated code will fit it as a part of the url. + - Since "positionInOperation" with value "last" is specified, "accountName" will be the last required parameter in every method. "adlaJobDnsSuffixInPath" will be a property on the client as it is defined in the global parameters section and is referenced here. + ```js "x-ms-parameterized-host": { "hostTemplate": "{accountName}.{adlaJobDnsSuffix}", + "positionInOperation": "last", "parameters": [ { "name": "accountName", @@ -423,10 +427,13 @@ Using both explicit and reference parameters "description": "Gets the DNS suffix used as the base for all Azure Data Lake Analytics Job service requests." } ``` -Using only explicit parameters +- Using explicit parameters and specifying the positionInOperation and schemePrefix. + - This means that accountName will be the first required parameter in all the methods and the user is expected to provide a url (protocol + accountName), since "useSchemePrfix" is set to false. ```js "x-ms-parameterized-host": { "hostTemplate": "{accountName}.mystaticsuffix.com", + "useSchemePrefix": false, + "positionInOperation": "first", "parameters": [ { "name": "accountName", From 296bb25496b473dceb167a807ffb4ff5a7704d79 Mon Sep 17 00:00:00 2001 From: Brody Berg Date: Wed, 13 Apr 2016 09:46:39 -0700 Subject: [PATCH 22/96] Correct bug link re: multi (#939) --- AutoRest/Modelers/Swagger/CollectionFormatBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutoRest/Modelers/Swagger/CollectionFormatBuilder.cs b/AutoRest/Modelers/Swagger/CollectionFormatBuilder.cs index edfba8a2c134..f9ee08f3c57f 100644 --- a/AutoRest/Modelers/Swagger/CollectionFormatBuilder.cs +++ b/AutoRest/Modelers/Swagger/CollectionFormatBuilder.cs @@ -80,7 +80,7 @@ private static void AddCollectionFormat(SwaggerParameter swaggerParameter, Strin break; case CollectionFormat.Multi: - // TODO multi is not supported yet: http://vstfrd:8080/Azure/RD/_workitems/edit/3172867 + // TODO multi is not supported yet: https://github.com/Azure/autorest/issues/717 throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, Resources.MultiCollectionFormatNotSupported, swaggerParameter.Name)); From 1833d260869ba361676fa0b99bfd1928d5a37dbd Mon Sep 17 00:00:00 2001 From: tbombach Date: Wed, 13 Apr 2016 15:39:59 -0700 Subject: [PATCH 23/96] Adding a new primary type for unix time and updating namers to handle this type --- .../ClientModel/KnownPrimaryType.cs | 3 +- .../CSharp/CSharp/CSharpCodeNamer.cs | 7 +- .../CSharp/CSharp/ClientModelExtensions.cs | 5 ++ .../TemplateModels/MethodTemplateModel.cs | 18 ++++- .../CSharp/Templates/ModelTemplate.cshtml | 8 ++ .../Java/Java/TypeModels/PrimaryTypeModel.cs | 4 + .../NodeJS/NodeJS/NodeJsCodeNamer.cs | 4 + .../Python/Python/PythonCodeNamer.cs | 4 + .../Generators/Ruby/Ruby/RubyCodeNamer.cs | 4 + .../Modelers/Swagger/Model/SwaggerObject.cs | 4 + .../Serialization/UnixTimeJsonConverter.cs | 76 +++++++++++++++++++ 11 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime/Serialization/UnixTimeJsonConverter.cs diff --git a/AutoRest/AutoRest.Core/ClientModel/KnownPrimaryType.cs b/AutoRest/AutoRest.Core/ClientModel/KnownPrimaryType.cs index 200dcfe018df..94dd5ffd7b72 100644 --- a/AutoRest/AutoRest.Core/ClientModel/KnownPrimaryType.cs +++ b/AutoRest/AutoRest.Core/ClientModel/KnownPrimaryType.cs @@ -25,6 +25,7 @@ public enum KnownPrimaryType Boolean, Credentials, Uuid, - Base64Url + Base64Url, + UnixTime } } diff --git a/AutoRest/Generators/CSharp/CSharp/CSharpCodeNamer.cs b/AutoRest/Generators/CSharp/CSharp/CSharpCodeNamer.cs index d9562cf4ca63..3504b01cb57d 100644 --- a/AutoRest/Generators/CSharp/CSharp/CSharpCodeNamer.cs +++ b/AutoRest/Generators/CSharp/CSharp/CSharpCodeNamer.cs @@ -297,6 +297,10 @@ protected virtual IType NormalizePrimaryType(PrimaryType primaryType) { primaryType.Name = "ServiceClientCredentials"; } + else if (primaryType.Type == KnownPrimaryType.UnixTime) + { + primaryType.Name = "DateTime"; + } else if (primaryType.Type == KnownPrimaryType.Uuid) { primaryType.Name = "Guid"; @@ -401,7 +405,8 @@ public override string EscapeDefaultValue(string defaultValue, IType type) primaryType.Type == KnownPrimaryType.DateTimeRfc1123 || primaryType.Type == KnownPrimaryType.TimeSpan || primaryType.Type == KnownPrimaryType.ByteArray || - primaryType.Type == KnownPrimaryType.Base64Url) + primaryType.Type == KnownPrimaryType.Base64Url || + primaryType.Type == KnownPrimaryType.UnixTime) { return "SafeJsonConvert.DeserializeObject<" + primaryType.Name.TrimEnd('?') + diff --git a/AutoRest/Generators/CSharp/CSharp/ClientModelExtensions.cs b/AutoRest/Generators/CSharp/CSharp/ClientModelExtensions.cs index ded2055e683b..ae4d9f11159d 100644 --- a/AutoRest/Generators/CSharp/CSharp/ClientModelExtensions.cs +++ b/AutoRest/Generators/CSharp/CSharp/ClientModelExtensions.cs @@ -225,6 +225,10 @@ public static string ToString(this IType type, string clientReference, string re { serializationSettings = "new Base64UrlJsonConverter()"; } + else if (primaryType.Type == KnownPrimaryType.UnixTime) + { + serializationSettings = "new UnixTimeJsonConverter()"; + } } return string.Format(CultureInfo.InvariantCulture, @@ -268,6 +272,7 @@ public static bool IsValueType(this IType type) || primaryType.Type == KnownPrimaryType.Long || primaryType.Type == KnownPrimaryType.TimeSpan || primaryType.Type == KnownPrimaryType.DateTimeRfc1123 + || primaryType.Type == KnownPrimaryType.UnixTime || primaryType.Type == KnownPrimaryType.Uuid)); } diff --git a/AutoRest/Generators/CSharp/CSharp/TemplateModels/MethodTemplateModel.cs b/AutoRest/Generators/CSharp/CSharp/TemplateModels/MethodTemplateModel.cs index cc44708181ec..d4a380df2765 100644 --- a/AutoRest/Generators/CSharp/CSharp/TemplateModels/MethodTemplateModel.cs +++ b/AutoRest/Generators/CSharp/CSharp/TemplateModels/MethodTemplateModel.cs @@ -351,6 +351,14 @@ public string GetSerializationSettingsReference(IType serializationType) { return "new Base64UrlJsonConverter()"; } + else if (serializationType.IsPrimaryType(KnownPrimaryType.UnixTime) || + (sequenceType != null && sequenceType.ElementType is PrimaryType + && ((PrimaryType)sequenceType.ElementType).Type == KnownPrimaryType.UnixTime) || + (dictionaryType != null && dictionaryType.ValueType is PrimaryType + && ((PrimaryType)dictionaryType.ValueType).Type == KnownPrimaryType.UnixTime)) + { + return "new UnixTimeJsonConverter()"; + } return ClientReference + ".SerializationSettings"; } @@ -371,7 +379,7 @@ public string GetDeserializationSettingsReference(IType deserializationType) { return "new DateJsonConverter()"; } - if (deserializationType.IsPrimaryType(KnownPrimaryType.Base64Url) || + else if (deserializationType.IsPrimaryType(KnownPrimaryType.Base64Url) || (sequenceType != null && sequenceType.ElementType is PrimaryType && ((PrimaryType)sequenceType.ElementType).Type == KnownPrimaryType.Base64Url) || (dictionaryType != null && dictionaryType.ValueType is PrimaryType @@ -379,6 +387,14 @@ public string GetDeserializationSettingsReference(IType deserializationType) { return "new Base64UrlJsonConverter()"; } + else if (deserializationType.IsPrimaryType(KnownPrimaryType.UnixTime) || + (sequenceType != null && sequenceType.ElementType is PrimaryType + && ((PrimaryType)sequenceType.ElementType).Type == KnownPrimaryType.UnixTime) || + (dictionaryType != null && dictionaryType.ValueType is PrimaryType + && ((PrimaryType)dictionaryType.ValueType).Type == KnownPrimaryType.UnixTime)) + { + return "new UnixTimeJsonConverter()"; + } return ClientReference + ".DeserializationSettings"; } diff --git a/AutoRest/Generators/CSharp/CSharp/Templates/ModelTemplate.cshtml b/AutoRest/Generators/CSharp/CSharp/Templates/ModelTemplate.cshtml index 2bcf9676f095..942e67ef809e 100644 --- a/AutoRest/Generators/CSharp/CSharp/Templates/ModelTemplate.cshtml +++ b/AutoRest/Generators/CSharp/CSharp/Templates/ModelTemplate.cshtml @@ -123,6 +123,10 @@ namespace @(Settings.Namespace).Models { @:[JsonConverter(typeof(Base64UrlJsonConverter))] } + if (property.Type.IsPrimaryType(KnownPrimaryType.UnixTime)) + { + @:[JsonConverter(typeof(UnixTimeJsonConverter))] + } @:[JsonProperty(PropertyName = "@property.SerializedName")] @:public @property.Type.Name @property.Name { get; @(property.IsReadOnly ? "private " : "")set; } @EmptyLine @@ -145,6 +149,10 @@ namespace @(Settings.Namespace).Models { @:[JsonConverter(typeof(Base64UrlJsonConverter))] } + if (property.Type.IsPrimaryType(KnownPrimaryType.UnixTime)) + { + @:[JsonConverter(typeof(UnixTimeJsonConverter))] + } @:[JsonProperty(PropertyName = "@property.SerializedName")] @:public static @property.Type.Name @property.Name { get; private set; } @EmptyLine diff --git a/AutoRest/Generators/Java/Java/TypeModels/PrimaryTypeModel.cs b/AutoRest/Generators/Java/Java/TypeModels/PrimaryTypeModel.cs index 2d5a2fad7862..d6990c79ff68 100644 --- a/AutoRest/Generators/Java/Java/TypeModels/PrimaryTypeModel.cs +++ b/AutoRest/Generators/Java/Java/TypeModels/PrimaryTypeModel.cs @@ -202,6 +202,10 @@ private void Initialize(PrimaryType primaryType) Name = "Period"; _imports.Add("org.joda.time.Period"); } + else if (primaryType.Type == KnownPrimaryType.UnixTime) + { + Name = "long"; + } else if (primaryType.Type == KnownPrimaryType.Uuid) { Name = "UUID"; diff --git a/AutoRest/Generators/NodeJS/NodeJS/NodeJsCodeNamer.cs b/AutoRest/Generators/NodeJS/NodeJS/NodeJsCodeNamer.cs index 53ac858681ef..d2f43a402f58 100644 --- a/AutoRest/Generators/NodeJS/NodeJS/NodeJsCodeNamer.cs +++ b/AutoRest/Generators/NodeJS/NodeJS/NodeJsCodeNamer.cs @@ -393,6 +393,10 @@ 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/AutoRest/Generators/Python/Python/PythonCodeNamer.cs b/AutoRest/Generators/Python/Python/PythonCodeNamer.cs index 4aebfb6378a1..11ae0801acce 100644 --- a/AutoRest/Generators/Python/Python/PythonCodeNamer.cs +++ b/AutoRest/Generators/Python/Python/PythonCodeNamer.cs @@ -376,6 +376,10 @@ private static IType NormalizePrimaryType(PrimaryType primaryType) { primaryType.Name = "Decimal"; } + else if (primaryType.Type == KnownPrimaryType.UnixTime) + { + primaryType.Name = "long"; + } else if (primaryType.Type == KnownPrimaryType.Object) // Revisit here { primaryType.Name = "object"; diff --git a/AutoRest/Generators/Ruby/Ruby/RubyCodeNamer.cs b/AutoRest/Generators/Ruby/Ruby/RubyCodeNamer.cs index bcb90309c677..c40423ee1b4a 100644 --- a/AutoRest/Generators/Ruby/Ruby/RubyCodeNamer.cs +++ b/AutoRest/Generators/Ruby/Ruby/RubyCodeNamer.cs @@ -372,6 +372,10 @@ private IType NormalizePrimaryType(PrimaryType primaryType) { primaryType.Name = "Duration"; } + else if (primaryType.Type == KnownPrimaryType.UnixTime) + { + primaryType.Name = "Bignum"; + } else if (primaryType.Type == KnownPrimaryType.Object) { primaryType.Name = "Object"; diff --git a/AutoRest/Modelers/Swagger/Model/SwaggerObject.cs b/AutoRest/Modelers/Swagger/Model/SwaggerObject.cs index 2ca86ef10d3e..02bfb0d23b8b 100644 --- a/AutoRest/Modelers/Swagger/Model/SwaggerObject.cs +++ b/AutoRest/Modelers/Swagger/Model/SwaggerObject.cs @@ -132,6 +132,10 @@ public PrimaryType ToType() { return new PrimaryType(KnownPrimaryType.Long); } + if (string.Equals("unixtime", Format, StringComparison.OrdinalIgnoreCase)) + { + return new PrimaryType(KnownPrimaryType.UnixTime); + } return new PrimaryType(KnownPrimaryType.Int); case DataType.Boolean: return new PrimaryType(KnownPrimaryType.Boolean); diff --git a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime/Serialization/UnixTimeJsonConverter.cs b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime/Serialization/UnixTimeJsonConverter.cs new file mode 100644 index 000000000000..8f6283b6237c --- /dev/null +++ b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime/Serialization/UnixTimeJsonConverter.cs @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Rest.Serialization +{ + public class UnixTimeJsonConverter : JsonConverter + { + public static readonly DateTime EpochDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + /// + /// Converts a byte array to a Base64Url encoded string + /// + /// The byte array to convert + /// The Base64Url encoded form of the input + private static long? ToUnixTime(DateTime dateTime) + { + return (long?)dateTime.Subtract(EpochDate).TotalSeconds; + } + + /// + /// Converts a Base64Url encoded string to a byte array + /// + /// The Base64Url encoded string + /// The byte array represented by the enconded string + private static DateTime FromUnixTime(long? seconds) + { + if (seconds.HasValue) + { + return EpochDate.AddSeconds(seconds.Value); + } + return EpochDate; + } + + public override bool CanConvert(Type objectType) + { + if (objectType == typeof(DateTime)) + return true; + + return false; + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (objectType != typeof(DateTime)) + { + return serializer.Deserialize(reader, objectType); + } + else + { + var value = serializer.Deserialize(reader); + if (value.HasValue) + { + return FromUnixTime(value); + } + } + + return null; + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + if (value.GetType() != typeof(DateTime)) + { + JToken.FromObject(value).WriteTo(writer); + } + else + { + JToken.FromObject(ToUnixTime((DateTime)value)).WriteTo(writer); + } + } + } +} \ No newline at end of file From 166ff89b3daa50b4db041a182edec0595fd52b7b Mon Sep 17 00:00:00 2001 From: tbombach Date: Thu, 14 Apr 2016 00:03:36 -0700 Subject: [PATCH 24/96] Updating test server to add test scenarios for unix time --- .../CSharp/CSharp.Tests/AcceptanceTests.cs | 4 + .../AcceptanceTests/BodyInteger/IIntModel.cs | 42 ++ .../AcceptanceTests/BodyInteger/IntModel.cs | 467 ++++++++++++++++++ .../BodyInteger/IntModelExtensions.cs | 113 +++++ .../CompositeBoolIntClient/IIntModel.cs | 42 ++ .../CompositeBoolIntClient/IntModel.cs | 467 ++++++++++++++++++ .../IntModelExtensions.cs | 113 +++++ AutoRest/TestServer/server/routes/int.js | 19 +- AutoRest/TestServer/swagger/body-integer.json | 89 ++++ .../Serialization/UnixTimeJsonConverter.cs | 9 +- 10 files changed, 1360 insertions(+), 5 deletions(-) diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs b/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs index 0d5c31f0e518..9caea8d8df28 100644 --- a/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs +++ b/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs @@ -198,12 +198,16 @@ public void IntegerTests() client.IntModel.PutMin32(Int32.MinValue); client.IntModel.PutMax64(Int64.MaxValue); client.IntModel.PutMin64(Int64.MinValue); + client.IntModel.PutUnixTimeDate(new DateTime(2016, 4, 13, 0, 0, 0)); client.IntModel.GetNull(); Assert.Throws(() => client.IntModel.GetInvalid()); Assert.Throws(() => client.IntModel.GetOverflowInt32()); Assert.Throws(() => client.IntModel.GetOverflowInt64()); Assert.Throws(() => client.IntModel.GetUnderflowInt32()); Assert.Throws(() => client.IntModel.GetUnderflowInt64()); + Assert.Throws(() => client.IntModel.GetInvalidUnixTime()); + Assert.Null(client.IntModel.GetNullUnixTime()); + Assert.Equal(new DateTime(2016, 4, 13, 0, 0, 0), client.IntModel.GetUnixTime()); } [Fact] diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/BodyInteger/IIntModel.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/BodyInteger/IIntModel.cs index 4b90323fef26..7131504bb185 100644 --- a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/BodyInteger/IIntModel.cs +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/BodyInteger/IIntModel.cs @@ -129,5 +129,47 @@ public partial interface IIntModel /// The cancellation token. /// Task PutMin64WithHttpMessagesAsync(long intBody, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Get datetime encoded as Unix time value + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + Task> GetUnixTimeWithHttpMessagesAsync(Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Put datetime encoded as Unix time + /// + /// + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + Task PutUnixTimeDateWithHttpMessagesAsync(DateTime intBody, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Get invalid Unix time value + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + Task> GetInvalidUnixTimeWithHttpMessagesAsync(Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Get null Unix time value + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + Task> GetNullUnixTimeWithHttpMessagesAsync(Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); } } diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/BodyInteger/IntModel.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/BodyInteger/IntModel.cs index feb0d3013f37..9c9b57ebbb2a 100644 --- a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/BodyInteger/IntModel.cs +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/BodyInteger/IntModel.cs @@ -1202,5 +1202,472 @@ public async Task PutMin64WithHttpMessagesAsync(long intB return _result; } + /// + /// Get datetime encoded as Unix time value + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> GetUnixTimeWithHttpMessagesAsync(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("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "GetUnixTime", tracingParameters); + } + // Construct URL + var _baseUrl = this.Client.BaseUri.AbsoluteUri; + var _url = new Uri(new Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "int/unixtime").ToString(); + // Create HTTP transport objects + HttpRequestMessage _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new Uri(_url); + // Set Headers + 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; + // 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) + { + var ex = new ErrorException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + try + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + Error _errorBody = SafeJsonConvert.DeserializeObject(_responseContent, this.Client.DeserializationSettings); + if (_errorBody != null) + { + ex.Body = _errorBody; + } + } + catch (JsonException) + { + // Ignore the exception + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, new UnixTimeJsonConverter()); + } + 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; + } + + /// + /// Put datetime encoded as Unix time + /// + /// + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task PutUnixTimeDateWithHttpMessagesAsync(DateTime intBody, 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("intBody", intBody); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "PutUnixTimeDate", tracingParameters); + } + // Construct URL + var _baseUrl = this.Client.BaseUri.AbsoluteUri; + var _url = new Uri(new Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "int/unixtime").ToString(); + // Create HTTP transport objects + HttpRequestMessage _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("PUT"); + _httpRequest.RequestUri = new Uri(_url); + // Set Headers + 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(intBody != null) + { + _requestContent = SafeJsonConvert.SerializeObject(intBody, new UnixTimeJsonConverter()); + _httpRequest.Content = new StringContent(_requestContent, Encoding.UTF8); + _httpRequest.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); + } + // 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) + { + var ex = new ErrorException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + try + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + Error _errorBody = SafeJsonConvert.DeserializeObject(_responseContent, this.Client.DeserializationSettings); + if (_errorBody != null) + { + ex.Body = _errorBody; + } + } + catch (JsonException) + { + // Ignore the exception + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Get invalid Unix time value + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> GetInvalidUnixTimeWithHttpMessagesAsync(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("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "GetInvalidUnixTime", tracingParameters); + } + // Construct URL + var _baseUrl = this.Client.BaseUri.AbsoluteUri; + var _url = new Uri(new Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "int/invalidunixtime").ToString(); + // Create HTTP transport objects + HttpRequestMessage _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new Uri(_url); + // Set Headers + 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; + // 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) + { + var ex = new ErrorException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + try + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + Error _errorBody = SafeJsonConvert.DeserializeObject(_responseContent, this.Client.DeserializationSettings); + if (_errorBody != null) + { + ex.Body = _errorBody; + } + } + catch (JsonException) + { + // Ignore the exception + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, new UnixTimeJsonConverter()); + } + 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; + } + + /// + /// Get null Unix time value + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> GetNullUnixTimeWithHttpMessagesAsync(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("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "GetNullUnixTime", tracingParameters); + } + // Construct URL + var _baseUrl = this.Client.BaseUri.AbsoluteUri; + var _url = new Uri(new Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "int/nullunixtime").ToString(); + // Create HTTP transport objects + HttpRequestMessage _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new Uri(_url); + // Set Headers + 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; + // 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) + { + var ex = new ErrorException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + try + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + Error _errorBody = SafeJsonConvert.DeserializeObject(_responseContent, this.Client.DeserializationSettings); + if (_errorBody != null) + { + ex.Body = _errorBody; + } + } + catch (JsonException) + { + // Ignore the exception + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, new UnixTimeJsonConverter()); + } + 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; + } + } } diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/BodyInteger/IntModelExtensions.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/BodyInteger/IntModelExtensions.cs index 0c57e20b0aad..c0bc0812ebde 100644 --- a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/BodyInteger/IntModelExtensions.cs +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/BodyInteger/IntModelExtensions.cs @@ -305,5 +305,118 @@ public static async Task PutMin64Async(this IIntModel operations, long intBody, await operations.PutMin64WithHttpMessagesAsync(intBody, null, cancellationToken).ConfigureAwait(false); } + /// + /// Get datetime encoded as Unix time value + /// + /// + /// The operations group for this extension method. + /// + public static DateTime? GetUnixTime(this IIntModel operations) + { + return Task.Factory.StartNew(s => ((IIntModel)s).GetUnixTimeAsync(), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult(); + } + + /// + /// Get datetime encoded as Unix time value + /// + /// + /// The operations group for this extension method. + /// + /// + /// The cancellation token. + /// + public static async Task GetUnixTimeAsync(this IIntModel operations, CancellationToken cancellationToken = default(CancellationToken)) + { + using (var _result = await operations.GetUnixTimeWithHttpMessagesAsync(null, cancellationToken).ConfigureAwait(false)) + { + return _result.Body; + } + } + + /// + /// Put datetime encoded as Unix time + /// + /// + /// The operations group for this extension method. + /// + /// + /// + public static void PutUnixTimeDate(this IIntModel operations, DateTime intBody) + { + Task.Factory.StartNew(s => ((IIntModel)s).PutUnixTimeDateAsync(intBody), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult(); + } + + /// + /// Put datetime encoded as Unix time + /// + /// + /// The operations group for this extension method. + /// + /// + /// + /// + /// The cancellation token. + /// + public static async Task PutUnixTimeDateAsync(this IIntModel operations, DateTime intBody, CancellationToken cancellationToken = default(CancellationToken)) + { + await operations.PutUnixTimeDateWithHttpMessagesAsync(intBody, null, cancellationToken).ConfigureAwait(false); + } + + /// + /// Get invalid Unix time value + /// + /// + /// The operations group for this extension method. + /// + public static DateTime? GetInvalidUnixTime(this IIntModel operations) + { + return Task.Factory.StartNew(s => ((IIntModel)s).GetInvalidUnixTimeAsync(), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult(); + } + + /// + /// Get invalid Unix time value + /// + /// + /// The operations group for this extension method. + /// + /// + /// The cancellation token. + /// + public static async Task GetInvalidUnixTimeAsync(this IIntModel operations, CancellationToken cancellationToken = default(CancellationToken)) + { + using (var _result = await operations.GetInvalidUnixTimeWithHttpMessagesAsync(null, cancellationToken).ConfigureAwait(false)) + { + return _result.Body; + } + } + + /// + /// Get null Unix time value + /// + /// + /// The operations group for this extension method. + /// + public static DateTime? GetNullUnixTime(this IIntModel operations) + { + return Task.Factory.StartNew(s => ((IIntModel)s).GetNullUnixTimeAsync(), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult(); + } + + /// + /// Get null Unix time value + /// + /// + /// The operations group for this extension method. + /// + /// + /// The cancellation token. + /// + public static async Task GetNullUnixTimeAsync(this IIntModel operations, CancellationToken cancellationToken = default(CancellationToken)) + { + using (var _result = await operations.GetNullUnixTimeWithHttpMessagesAsync(null, cancellationToken).ConfigureAwait(false)) + { + return _result.Body; + } + } + } } diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/IIntModel.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/IIntModel.cs index 4917e355224d..d0b518478669 100644 --- a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/IIntModel.cs +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/IIntModel.cs @@ -129,5 +129,47 @@ public partial interface IIntModel /// The cancellation token. /// Task PutMin64WithHttpMessagesAsync(long intBody, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Get datetime encoded as Unix time value + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + Task> GetUnixTimeWithHttpMessagesAsync(Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Put datetime encoded as Unix time + /// + /// + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + Task PutUnixTimeDateWithHttpMessagesAsync(DateTime intBody, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Get invalid Unix time value + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + Task> GetInvalidUnixTimeWithHttpMessagesAsync(Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Get null Unix time value + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + Task> GetNullUnixTimeWithHttpMessagesAsync(Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); } } diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/IntModel.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/IntModel.cs index 1ed42f86ca54..2047fd860871 100644 --- a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/IntModel.cs +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/IntModel.cs @@ -1202,5 +1202,472 @@ public async Task PutMin64WithHttpMessagesAsync(long intB return _result; } + /// + /// Get datetime encoded as Unix time value + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> GetUnixTimeWithHttpMessagesAsync(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("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "GetUnixTime", tracingParameters); + } + // Construct URL + var _baseUrl = this.Client.BaseUri.AbsoluteUri; + var _url = new Uri(new Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "int/unixtime").ToString(); + // Create HTTP transport objects + HttpRequestMessage _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new Uri(_url); + // Set Headers + 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; + // 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) + { + var ex = new ErrorException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + try + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + Error _errorBody = SafeJsonConvert.DeserializeObject(_responseContent, this.Client.DeserializationSettings); + if (_errorBody != null) + { + ex.Body = _errorBody; + } + } + catch (JsonException) + { + // Ignore the exception + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, new UnixTimeJsonConverter()); + } + 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; + } + + /// + /// Put datetime encoded as Unix time + /// + /// + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task PutUnixTimeDateWithHttpMessagesAsync(DateTime intBody, 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("intBody", intBody); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "PutUnixTimeDate", tracingParameters); + } + // Construct URL + var _baseUrl = this.Client.BaseUri.AbsoluteUri; + var _url = new Uri(new Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "int/unixtime").ToString(); + // Create HTTP transport objects + HttpRequestMessage _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("PUT"); + _httpRequest.RequestUri = new Uri(_url); + // Set Headers + 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(intBody != null) + { + _requestContent = SafeJsonConvert.SerializeObject(intBody, new UnixTimeJsonConverter()); + _httpRequest.Content = new StringContent(_requestContent, Encoding.UTF8); + _httpRequest.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); + } + // 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) + { + var ex = new ErrorException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + try + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + Error _errorBody = SafeJsonConvert.DeserializeObject(_responseContent, this.Client.DeserializationSettings); + if (_errorBody != null) + { + ex.Body = _errorBody; + } + } + catch (JsonException) + { + // Ignore the exception + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Get invalid Unix time value + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> GetInvalidUnixTimeWithHttpMessagesAsync(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("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "GetInvalidUnixTime", tracingParameters); + } + // Construct URL + var _baseUrl = this.Client.BaseUri.AbsoluteUri; + var _url = new Uri(new Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "int/invalidunixtime").ToString(); + // Create HTTP transport objects + HttpRequestMessage _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new Uri(_url); + // Set Headers + 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; + // 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) + { + var ex = new ErrorException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + try + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + Error _errorBody = SafeJsonConvert.DeserializeObject(_responseContent, this.Client.DeserializationSettings); + if (_errorBody != null) + { + ex.Body = _errorBody; + } + } + catch (JsonException) + { + // Ignore the exception + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, new UnixTimeJsonConverter()); + } + 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; + } + + /// + /// Get null Unix time value + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> GetNullUnixTimeWithHttpMessagesAsync(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("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "GetNullUnixTime", tracingParameters); + } + // Construct URL + var _baseUrl = this.Client.BaseUri.AbsoluteUri; + var _url = new Uri(new Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "int/nullunixtime").ToString(); + // Create HTTP transport objects + HttpRequestMessage _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new Uri(_url); + // Set Headers + 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; + // 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) + { + var ex = new ErrorException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + try + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + Error _errorBody = SafeJsonConvert.DeserializeObject(_responseContent, this.Client.DeserializationSettings); + if (_errorBody != null) + { + ex.Body = _errorBody; + } + } + catch (JsonException) + { + // Ignore the exception + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, new UnixTimeJsonConverter()); + } + 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; + } + } } diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/IntModelExtensions.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/IntModelExtensions.cs index a203d3cee39e..009277ea5077 100644 --- a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/IntModelExtensions.cs +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/CompositeBoolIntClient/IntModelExtensions.cs @@ -305,5 +305,118 @@ public static async Task PutMin64Async(this IIntModel operations, long intBody, await operations.PutMin64WithHttpMessagesAsync(intBody, null, cancellationToken).ConfigureAwait(false); } + /// + /// Get datetime encoded as Unix time value + /// + /// + /// The operations group for this extension method. + /// + public static DateTime? GetUnixTime(this IIntModel operations) + { + return Task.Factory.StartNew(s => ((IIntModel)s).GetUnixTimeAsync(), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult(); + } + + /// + /// Get datetime encoded as Unix time value + /// + /// + /// The operations group for this extension method. + /// + /// + /// The cancellation token. + /// + public static async Task GetUnixTimeAsync(this IIntModel operations, CancellationToken cancellationToken = default(CancellationToken)) + { + using (var _result = await operations.GetUnixTimeWithHttpMessagesAsync(null, cancellationToken).ConfigureAwait(false)) + { + return _result.Body; + } + } + + /// + /// Put datetime encoded as Unix time + /// + /// + /// The operations group for this extension method. + /// + /// + /// + public static void PutUnixTimeDate(this IIntModel operations, DateTime intBody) + { + Task.Factory.StartNew(s => ((IIntModel)s).PutUnixTimeDateAsync(intBody), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult(); + } + + /// + /// Put datetime encoded as Unix time + /// + /// + /// The operations group for this extension method. + /// + /// + /// + /// + /// The cancellation token. + /// + public static async Task PutUnixTimeDateAsync(this IIntModel operations, DateTime intBody, CancellationToken cancellationToken = default(CancellationToken)) + { + await operations.PutUnixTimeDateWithHttpMessagesAsync(intBody, null, cancellationToken).ConfigureAwait(false); + } + + /// + /// Get invalid Unix time value + /// + /// + /// The operations group for this extension method. + /// + public static DateTime? GetInvalidUnixTime(this IIntModel operations) + { + return Task.Factory.StartNew(s => ((IIntModel)s).GetInvalidUnixTimeAsync(), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult(); + } + + /// + /// Get invalid Unix time value + /// + /// + /// The operations group for this extension method. + /// + /// + /// The cancellation token. + /// + public static async Task GetInvalidUnixTimeAsync(this IIntModel operations, CancellationToken cancellationToken = default(CancellationToken)) + { + using (var _result = await operations.GetInvalidUnixTimeWithHttpMessagesAsync(null, cancellationToken).ConfigureAwait(false)) + { + return _result.Body; + } + } + + /// + /// Get null Unix time value + /// + /// + /// The operations group for this extension method. + /// + public static DateTime? GetNullUnixTime(this IIntModel operations) + { + return Task.Factory.StartNew(s => ((IIntModel)s).GetNullUnixTimeAsync(), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult(); + } + + /// + /// Get null Unix time value + /// + /// + /// The operations group for this extension method. + /// + /// + /// The cancellation token. + /// + public static async Task GetNullUnixTimeAsync(this IIntModel operations, CancellationToken cancellationToken = default(CancellationToken)) + { + using (var _result = await operations.GetNullUnixTimeWithHttpMessagesAsync(null, cancellationToken).ConfigureAwait(false)) + { + return _result.Body; + } + } + } } diff --git a/AutoRest/TestServer/server/routes/int.js b/AutoRest/TestServer/server/routes/int.js index 2299732ca5ad..f4acbd7104cd 100644 --- a/AutoRest/TestServer/server/routes/int.js +++ b/AutoRest/TestServer/server/routes/int.js @@ -65,10 +65,27 @@ var integer = function(coverage) { } else if (req.params.scenario === 'underflowint64') { coverage['getLongUnderflow']++; res.status(200).end('-9223372036854775910'); + } else if (req.params.scenario === 'unixtime') { + coverage['getUnixTime']++; + res.status(200).end('1460505600'); + } else if (req.params.scenario === 'invalidunixtime') { + coverage['getInvalidUnixTime']++; + res.status(200).end('123jkl'); + } else if (req.params.scenario === 'nullunixtime') { + coverage['getNullUnixTime']++; + res.status(200).end(); } else { res.status(400).send('Request path must contain true or false'); } - + }); + + router.put('/unixtime', function(req, res, next) { + if (req.body != 1460505600) { + utils.send400(res, next, "Did not like the value provided for unixtime in the req " + util.inspect(req.body)); + } else { + coverage['putUnixTime']++; + res.status(200).end(); + } }); } diff --git a/AutoRest/TestServer/swagger/body-integer.json b/AutoRest/TestServer/swagger/body-integer.json index 00b73a2c2731..5f321e298169 100644 --- a/AutoRest/TestServer/swagger/body-integer.json +++ b/AutoRest/TestServer/swagger/body-integer.json @@ -251,6 +251,95 @@ } } } + }, + "/int/unixtime": { + "get": { + "operationId": "int_getUnixTime", + "description": "Get datetime encoded as Unix time value", + "responses": { + "200": { + "description": "The date value encoded as Unix time", + "schema": { + "type": "integer", + "format": "unixtime" + } + }, + "default": { + "description": "Unexpected error", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + }, + "put": { + "operationId": "int_putUnixTimeDate", + "description": "Put datetime encoded as Unix time", + "parameters": [ + { + "name": "intBody", + "in": "body", + "schema": { + "type": "integer", + "format": "unixtime" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "The datetime value encoded as Unix time" + }, + "default": { + "description": "Unexpected error", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/int/invalidunixtime": { + "get": { + "operationId": "int_getInvalidUnixTime", + "description": "Get invalid Unix time value", + "responses": { + "200": { + "description": "The invalid Unix time value", + "schema": { + "type": "integer", + "format": "unixtime" + } + }, + "default": { + "description": "Unexpected error", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, + "/int/nullunixtime": { + "get": { + "operationId": "int_getNullUnixTime", + "description": "Get null Unix time value", + "responses": { + "200": { + "description": "The null Unix time value", + "schema": { + "type": "integer", + "format": "unixtime" + } + }, + "default": { + "description": "Unexpected error", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } } }, "definitions": { diff --git a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime/Serialization/UnixTimeJsonConverter.cs b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime/Serialization/UnixTimeJsonConverter.cs index 8f6283b6237c..fd345541a6de 100644 --- a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime/Serialization/UnixTimeJsonConverter.cs +++ b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime/Serialization/UnixTimeJsonConverter.cs @@ -26,18 +26,18 @@ public class UnixTimeJsonConverter : JsonConverter /// /// The Base64Url encoded string /// The byte array represented by the enconded string - private static DateTime FromUnixTime(long? seconds) + private static DateTime? FromUnixTime(long? seconds) { if (seconds.HasValue) { return EpochDate.AddSeconds(seconds.Value); } - return EpochDate; + return null; } public override bool CanConvert(Type objectType) { - if (objectType == typeof(DateTime)) + if (objectType == typeof(DateTime?) || objectType == typeof(DateTime)) return true; return false; @@ -45,13 +45,14 @@ public override bool CanConvert(Type objectType) public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { - if (objectType != typeof(DateTime)) + if (objectType != typeof(DateTime?)) { return serializer.Deserialize(reader, objectType); } else { var value = serializer.Deserialize(reader); + if (value.HasValue) { return FromUnixTime(value); From 59d3fa94d2c1c186cf5a17d966376b61efec6bba Mon Sep 17 00:00:00 2001 From: tbombach Date: Thu, 14 Apr 2016 00:43:49 -0700 Subject: [PATCH 25/96] Adding test for Unix time encoded values in path --- .../CSharp/CSharp.Tests/AcceptanceTests.cs | 1 + .../Expected/AcceptanceTests/Url/IPaths.cs | 13 +++ .../Expected/AcceptanceTests/Url/Paths.cs | 106 ++++++++++++++++++ .../AcceptanceTests/Url/PathsExtensions.cs | 31 +++++ AutoRest/TestServer/server/routes/paths.js | 1 + AutoRest/TestServer/swagger/url.json | 30 +++++ 6 files changed, 182 insertions(+) diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs b/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs index 9caea8d8df28..804db915e611 100644 --- a/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs +++ b/AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs @@ -1355,6 +1355,7 @@ public void UrlPathTests() client.Paths.Base64Url(Encoding.UTF8.GetBytes("lorem")); var testArray = new List { "ArrayPath1", @"begin!*'();:@ &=+$,/?#[]end", null, "" }; client.Paths.ArrayCsvInPath(testArray); + client.Paths.UnixTimeUrl(new DateTime(2016, 4, 13, 0, 0, 0)); } } diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/Url/IPaths.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/Url/IPaths.cs index ce60b9a5c2f2..d8f9e2c76157 100644 --- a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/Url/IPaths.cs +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/Url/IPaths.cs @@ -305,5 +305,18 @@ public partial interface IPaths /// The cancellation token. /// Task ArrayCsvInPathWithHttpMessagesAsync(IList arrayPath, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Get the date 2016-04-13 encoded value as '1460505600' (Unix time) + /// + /// + /// Unix time encoded value + /// + /// + /// The headers that will be added to request. + /// + /// + /// The cancellation token. + /// + Task UnixTimeUrlWithHttpMessagesAsync(DateTime unixTimeUrlPath, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)); } } diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/Url/Paths.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/Url/Paths.cs index d880804521f0..3892f728ba11 100644 --- a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/Url/Paths.cs +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/Url/Paths.cs @@ -2692,5 +2692,111 @@ public async Task ArrayCsvInPathWithHttpMessagesAsync(ILi return _result; } + /// + /// Get the date 2016-04-13 encoded value as '1460505600' (Unix time) + /// + /// + /// Unix time encoded value + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task UnixTimeUrlWithHttpMessagesAsync(DateTime unixTimeUrlPath, 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("unixTimeUrlPath", unixTimeUrlPath); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "UnixTimeUrl", tracingParameters); + } + // Construct URL + var _baseUrl = this.Client.BaseUri.AbsoluteUri; + var _url = new Uri(new Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "paths/int/1460505600/{unixTimeUrlPath}").ToString(); + _url = _url.Replace("{unixTimeUrlPath}", Uri.EscapeDataString(SafeJsonConvert.SerializeObject(unixTimeUrlPath, new UnixTimeJsonConverter()).Trim('"'))); + // Create HTTP transport objects + HttpRequestMessage _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new Uri(_url); + // Set Headers + 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; + // 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) + { + var ex = new ErrorException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + try + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + Error _errorBody = SafeJsonConvert.DeserializeObject(_responseContent, this.Client.DeserializationSettings); + if (_errorBody != null) + { + ex.Body = _errorBody; + } + } + catch (JsonException) + { + // Ignore the exception + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + } } diff --git a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/Url/PathsExtensions.cs b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/Url/PathsExtensions.cs index 65ea07ea61b8..b4e8d2ce268e 100644 --- a/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/Url/PathsExtensions.cs +++ b/AutoRest/Generators/CSharp/CSharp.Tests/Expected/AcceptanceTests/Url/PathsExtensions.cs @@ -712,5 +712,36 @@ public static async Task ArrayCsvInPathAsync(this IPaths operations, IList + /// Get the date 2016-04-13 encoded value as '1460505600' (Unix time) + /// + /// + /// The operations group for this extension method. + /// + /// + /// Unix time encoded value + /// + public static void UnixTimeUrl(this IPaths operations, DateTime unixTimeUrlPath) + { + Task.Factory.StartNew(s => ((IPaths)s).UnixTimeUrlAsync(unixTimeUrlPath), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult(); + } + + /// + /// Get the date 2016-04-13 encoded value as '1460505600' (Unix time) + /// + /// + /// The operations group for this extension method. + /// + /// + /// Unix time encoded value + /// + /// + /// The cancellation token. + /// + public static async Task UnixTimeUrlAsync(this IPaths operations, DateTime unixTimeUrlPath, CancellationToken cancellationToken = default(CancellationToken)) + { + await operations.UnixTimeUrlWithHttpMessagesAsync(unixTimeUrlPath, null, cancellationToken).ConfigureAwait(false); + } + } } diff --git a/AutoRest/TestServer/server/routes/paths.js b/AutoRest/TestServer/server/routes/paths.js index ba1b8e99df9e..04b5002453c3 100644 --- a/AutoRest/TestServer/server/routes/paths.js +++ b/AutoRest/TestServer/server/routes/paths.js @@ -23,6 +23,7 @@ var scenarioMap = { "2012-01-01T01:01:01Z": "Valid", "green color" : "Valid", "bG9yZW0" : "Base64Url", + "1460505600": "UnixTime", "ArrayPath1,begin!*'();:@ &=+$,/?#[]end,,": "CSVInPath" }; diff --git a/AutoRest/TestServer/swagger/url.json b/AutoRest/TestServer/swagger/url.json index 4bf4530d177f..670ff00f9bd1 100644 --- a/AutoRest/TestServer/swagger/url.json +++ b/AutoRest/TestServer/swagger/url.json @@ -773,6 +773,36 @@ } } }, + "/paths/int/1460505600/{unixTimeUrlPath}": { + "get": { + "operationId": "paths_unixTimeUrl", + "description": "Get the date 2016-04-13 encoded value as '1460505600' (Unix time)", + "tags": [ + "Path Operations" + ], + "parameters": [ + { + "name": "unixTimeUrlPath", + "in": "path", + "description": "Unix time encoded value", + "type": "integer", + "format": "unixtime", + "required": true + } + ], + "responses": { + "200": { + "description": "Successfully Received date 2016-04-13 encoded value as '1460505600' (Unix time)" + }, + "default": { + "description": "Unexpected error", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, "/queries/bool/true": { "get": { "operationId": "queries_getBooleanTrue", From 557787508985b3e75e99defbfedf991989963ab1 Mon Sep 17 00:00:00 2001 From: tbombach Date: Thu, 14 Apr 2016 00:51:57 -0700 Subject: [PATCH 26/96] Updating test coverage list --- AutoRest/TestServer/server/app.js | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/AutoRest/TestServer/server/app.js b/AutoRest/TestServer/server/app.js index 8bb3b105ba76..9453e73965c2 100644 --- a/AutoRest/TestServer/server/app.js +++ b/AutoRest/TestServer/server/app.js @@ -195,15 +195,6 @@ var coverage = { "getStringWithLeadingAndTrailingWhitespace" : 0, "putStringWithLeadingAndTrailingWhitespace" : 0, "getStringNotProvided": 0, - /* TODO: only C# and node.js support the base64url format currently. Exclude these tests from code coverage until it is implemented in other languages */ - "getStringBase64Encoded": 1, - "getStringBase64UrlEncoded": 1, - "putStringBase64UrlEncoded": 1, - "getStringNullBase64UrlEncoding": 1, - "getArrayBase64Url": 1, - "getDictionaryBase64Url": 1, - "UrlPathsStringBase64Url": 1, - "UrlPathsArrayCSVInPath": 1, "getEnumNotExpandable": 0, "putEnumNotExpandable":0, "putComplexBasicValid": 0, @@ -438,7 +429,22 @@ var coverage = { 'putModelFlattenResourceCollection': 0, 'putModelFlattenCustomBase': 0, 'postModelFlattenCustomParameter': 0, - 'putModelFlattenCustomGroupedParameter': 0 + 'putModelFlattenCustomGroupedParameter': 0, + /* TODO: only C# and node.js support the base64url format currently. Exclude these tests from code coverage until it is implemented in other languages */ + "getStringBase64Encoded": 1, + "getStringBase64UrlEncoded": 1, + "putStringBase64UrlEncoded": 1, + "getStringNullBase64UrlEncoding": 1, + "getArrayBase64Url": 1, + "getDictionaryBase64Url": 1, + "UrlPathsStringBase64Url": 1, + "UrlPathsArrayCSVInPath": 1, + /* TODO: only C# supports the unixtime format currently. Exclude these tests from code coverage until it is implemented in other languages */ + "getUnixTime": 1, + "getInvalidUnixTime": 1, + "getNullUnixTime": 1, + "putUnixTime": 1, + "UrlPathsIntUnixTime": 1 }; // view engine setup From b6bf4ccfc3413a2ea50ad23c54b71e9c495e3b04 Mon Sep 17 00:00:00 2001 From: aescribano Date: Thu, 14 Apr 2016 11:57:30 +0100 Subject: [PATCH 27/96] Adding a User-Agent header to the request done in FileSystem.ReadFileAsText --- AutoRest/AutoRest.Core/Utilities/FileSystem.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/AutoRest/AutoRest.Core/Utilities/FileSystem.cs b/AutoRest/AutoRest.Core/Utilities/FileSystem.cs index 91b4f6c18bdd..231b6521090d 100644 --- a/AutoRest/AutoRest.Core/Utilities/FileSystem.cs +++ b/AutoRest/AutoRest.Core/Utilities/FileSystem.cs @@ -17,6 +17,7 @@ public string ReadFileAsText(string path) { using (var client = new WebClient()) { + client.Headers.Add("User-Agent: AutoRest"); return client.DownloadString(path); } } From 8b015ac266ddb655991927ac6a14c454d9e31b1d Mon Sep 17 00:00:00 2001 From: John-Hart Date: Thu, 14 Apr 2016 13:05:37 -0700 Subject: [PATCH 28/96] 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 57bbd064b95c..0d8505210fd5 100644 --- a/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure/AzureClientExtensions.cs +++ b/ClientRuntimes/CSharp/Microsoft.Rest.ClientRuntime.Azure/AzureClientExtensions.cs @@ -599,7 +599,16 @@ public static class AzureClientExtensions 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 29/96] 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 bf999fe9f7c1..1d0bb2069f1b 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 cd746ab36777f6b827d95517c43c01fb1620bbd7 Mon Sep 17 00:00:00 2001 From: Jianghao Lu Date: Fri, 15 Apr 2016 09:45:37 -0700 Subject: [PATCH 30/96] Okio 1.7.0 --- ClientRuntimes/Java/client-runtime/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ClientRuntimes/Java/client-runtime/build.gradle b/ClientRuntimes/Java/client-runtime/build.gradle index 47cbaf08c639..b734d33608ea 100644 --- a/ClientRuntimes/Java/client-runtime/build.gradle +++ b/ClientRuntimes/Java/client-runtime/build.gradle @@ -25,7 +25,7 @@ dependencies { compile 'com.google.guava:guava:18.0' compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4' compile 'com.squareup.okhttp3:okhttp:3.2.0' - compile ('com.squareup.okio:okio:1.7.0-SNAPSHOT') { changing = true } + compile 'com.squareup.okio:okio:1.7.0' compile 'com.squareup.okhttp3:logging-interceptor:3.1.1' compile 'com.squareup.okhttp3:okhttp-urlconnection:3.1.1' compile 'com.squareup.retrofit2:converter-jackson:2.0.0-beta4' From 29dc46d8d25b5509c5883688a5475cdb1da379e2 Mon Sep 17 00:00:00 2001 From: annatisch Date: Fri, 15 Apr 2016 13:22:00 -0700 Subject: [PATCH 31/96] Python Bug Fixes (#928) * Fix serializing lists into paths * Fix for streaming bug * Generated Python config type checking * Regenerated tests * fixed streaming bug * regenerated samples * Fixed runtime tests * Test server debuging * removed stream connection closing * ping build server --- .../auto_rest_duration_test_service.py | 4 +- ...to_rest_parameter_grouping_test_service.py | 4 +- .../auto_rest_report_service_for_azure.py | 4 +- ...o_rest_resource_flattening_test_service.py | 4 +- ...st_azure_special_parameters_test_client.py | 10 ++- ...uto_rest_parameterized_host_test_client.py | 8 ++- .../auto_rest_head_test_service.py | 4 +- .../auto_rest_head_exception_test_service.py | 4 +- ...est_long_running_operation_test_service.py | 4 +- .../auto_rest_paging_test_service.py | 4 +- .../storage_management_client.py | 10 ++- .../microsoft_azure_test_url.py | 10 ++- .../AcceptanceTests/file_tests.py | 61 ++++++------------- .../AcceptanceTests/form_data_tests.py | 1 - .../Python.Tests/AcceptanceTests/url_tests.py | 5 +- .../Python.Tests/AcceptanceTests/zzz_tests.py | 43 +++++++------ .../auto_rest_complex_test_service.py | 4 +- ...uto_rest_parameterized_host_test_client.py | 4 +- ...uto_rest_required_optional_test_service.py | 8 ++- .../auto_rest_url_test_service.py | 6 +- .../operations/paths.py | 2 +- .../auto_rest_validation_test.py | 8 ++- .../TemplateModels/MethodTemplateModel.cs | 7 +++ .../ServiceClientTemplateModel.cs | 29 ++++++++- .../Python/msrest/msrest/http_logger.py | 4 +- .../Python/msrest/msrest/serialization.py | 3 +- .../Python/msrest/msrest/service_client.py | 7 ++- .../Python/msrest/test/unittest_runtime.py | 8 ++- .../storage_management_client.py | 10 ++- 29 files changed, 181 insertions(+), 99 deletions(-) diff --git a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureBodyDuration/autorestdurationtestservice/auto_rest_duration_test_service.py b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureBodyDuration/autorestdurationtestservice/auto_rest_duration_test_service.py index bceee986fdda..668b135381e1 100644 --- a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureBodyDuration/autorestdurationtestservice/auto_rest_duration_test_service.py +++ b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureBodyDuration/autorestdurationtestservice/auto_rest_duration_test_service.py @@ -43,7 +43,9 @@ def __init__( self, credentials, accept_language='en-US', long_running_operation_retry_timeout=30, generate_client_request_id=True, base_url=None, filepath=None): if credentials is None: - raise ValueError('credentials must not be None.') + raise ValueError("Parameter 'credentials' must not be None.") + if accept_language is not None and not isinstance(accept_language, str): + raise TypeError("Optional parameter 'accept_language' must be str.") if not base_url: base_url = 'https://localhost' diff --git a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureParameterGrouping/autorestparametergroupingtestservice/auto_rest_parameter_grouping_test_service.py b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureParameterGrouping/autorestparametergroupingtestservice/auto_rest_parameter_grouping_test_service.py index b8bae0b1b522..13e63f9569c8 100644 --- a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureParameterGrouping/autorestparametergroupingtestservice/auto_rest_parameter_grouping_test_service.py +++ b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureParameterGrouping/autorestparametergroupingtestservice/auto_rest_parameter_grouping_test_service.py @@ -43,7 +43,9 @@ def __init__( self, credentials, accept_language='en-US', long_running_operation_retry_timeout=30, generate_client_request_id=True, base_url=None, filepath=None): if credentials is None: - raise ValueError('credentials must not be None.') + raise ValueError("Parameter 'credentials' must not be None.") + if accept_language is not None and not isinstance(accept_language, str): + raise TypeError("Optional parameter 'accept_language' must be str.") if not base_url: base_url = 'https://localhost' diff --git a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureReport/autorestreportserviceforazure/auto_rest_report_service_for_azure.py b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureReport/autorestreportserviceforazure/auto_rest_report_service_for_azure.py index b37530e7d798..c02088e43b1a 100644 --- a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureReport/autorestreportserviceforazure/auto_rest_report_service_for_azure.py +++ b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureReport/autorestreportserviceforazure/auto_rest_report_service_for_azure.py @@ -44,7 +44,9 @@ def __init__( self, credentials, accept_language='en-US', long_running_operation_retry_timeout=30, generate_client_request_id=True, base_url=None, filepath=None): if credentials is None: - raise ValueError('credentials must not be None.') + raise ValueError("Parameter 'credentials' must not be None.") + if accept_language is not None and not isinstance(accept_language, str): + raise TypeError("Optional parameter 'accept_language' must be str.") if not base_url: base_url = 'http://localhost' diff --git a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureResource/autorestresourceflatteningtestservice/auto_rest_resource_flattening_test_service.py b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureResource/autorestresourceflatteningtestservice/auto_rest_resource_flattening_test_service.py index 3a806d13f53f..74f09db9d340 100644 --- a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureResource/autorestresourceflatteningtestservice/auto_rest_resource_flattening_test_service.py +++ b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureResource/autorestresourceflatteningtestservice/auto_rest_resource_flattening_test_service.py @@ -44,7 +44,9 @@ def __init__( self, credentials, accept_language='en-US', long_running_operation_retry_timeout=30, generate_client_request_id=True, base_url=None, filepath=None): if credentials is None: - raise ValueError('credentials must not be None.') + raise ValueError("Parameter 'credentials' must not be None.") + if accept_language is not None and not isinstance(accept_language, str): + raise TypeError("Optional parameter 'accept_language' must be str.") if not base_url: base_url = 'http://localhost' diff --git a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureSpecials/autorestazurespecialparameterstestclient/auto_rest_azure_special_parameters_test_client.py b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureSpecials/autorestazurespecialparameterstestclient/auto_rest_azure_special_parameters_test_client.py index cc2d96c0ce71..95f2d47d0fb5 100644 --- a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureSpecials/autorestazurespecialparameterstestclient/auto_rest_azure_special_parameters_test_client.py +++ b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/AzureSpecials/autorestazurespecialparameterstestclient/auto_rest_azure_special_parameters_test_client.py @@ -56,9 +56,15 @@ def __init__( self, credentials, subscription_id, api_version='2015-07-01-preview', accept_language='en-US', long_running_operation_retry_timeout=30, generate_client_request_id=True, base_url=None, filepath=None): if credentials is None: - raise ValueError('credentials must not be None.') + raise ValueError("Parameter 'credentials' must not be None.") if subscription_id is None: - raise ValueError('subscription_id must not be None.') + raise ValueError("Parameter 'subscription_id' must not be None.") + if not isinstance(subscription_id, str): + raise TypeError("Parameter 'subscription_id' must be str.") + if api_version is not None and not isinstance(api_version, str): + raise TypeError("Optional parameter 'api_version' must be str.") + if accept_language is not None and not isinstance(accept_language, str): + raise TypeError("Optional parameter 'accept_language' must be str.") if not base_url: base_url = 'http://localhost' diff --git a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/CustomBaseUri/autorestparameterizedhosttestclient/auto_rest_parameterized_host_test_client.py b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/CustomBaseUri/autorestparameterizedhosttestclient/auto_rest_parameterized_host_test_client.py index ce9c7112afaf..79e862f82db7 100644 --- a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/CustomBaseUri/autorestparameterizedhosttestclient/auto_rest_parameterized_host_test_client.py +++ b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/CustomBaseUri/autorestparameterizedhosttestclient/auto_rest_parameterized_host_test_client.py @@ -45,9 +45,13 @@ def __init__( self, credentials, host, accept_language='en-US', long_running_operation_retry_timeout=30, generate_client_request_id=True, filepath=None): if credentials is None: - raise ValueError('credentials must not be None.') + raise ValueError("Parameter 'credentials' must not be None.") if host is None: - raise ValueError('host must not be None.') + raise ValueError("Parameter 'host' must not be None.") + if not isinstance(host, str): + raise TypeError("Parameter 'host' must be str.") + if accept_language is not None and not isinstance(accept_language, str): + raise TypeError("Optional parameter 'accept_language' must be str.") base_url = 'http://{accountName}{host}' super(AutoRestParameterizedHostTestClientConfiguration, self).__init__(base_url, filepath) diff --git a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Head/autorestheadtestservice/auto_rest_head_test_service.py b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Head/autorestheadtestservice/auto_rest_head_test_service.py index 85044ec1cbcc..fc86a3308cb2 100644 --- a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Head/autorestheadtestservice/auto_rest_head_test_service.py +++ b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Head/autorestheadtestservice/auto_rest_head_test_service.py @@ -42,7 +42,9 @@ def __init__( self, credentials, accept_language='en-US', long_running_operation_retry_timeout=30, generate_client_request_id=True, base_url=None, filepath=None): if credentials is None: - raise ValueError('credentials must not be None.') + raise ValueError("Parameter 'credentials' must not be None.") + if accept_language is not None and not isinstance(accept_language, str): + raise TypeError("Optional parameter 'accept_language' must be str.") if not base_url: base_url = 'http://localhost' diff --git a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/HeadExceptions/autorestheadexceptiontestservice/auto_rest_head_exception_test_service.py b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/HeadExceptions/autorestheadexceptiontestservice/auto_rest_head_exception_test_service.py index e7531777378d..d9745572729e 100644 --- a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/HeadExceptions/autorestheadexceptiontestservice/auto_rest_head_exception_test_service.py +++ b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/HeadExceptions/autorestheadexceptiontestservice/auto_rest_head_exception_test_service.py @@ -42,7 +42,9 @@ def __init__( self, credentials, accept_language='en-US', long_running_operation_retry_timeout=30, generate_client_request_id=True, base_url=None, filepath=None): if credentials is None: - raise ValueError('credentials must not be None.') + raise ValueError("Parameter 'credentials' must not be None.") + if accept_language is not None and not isinstance(accept_language, str): + raise TypeError("Optional parameter 'accept_language' must be str.") if not base_url: base_url = 'http://localhost' diff --git a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Lro/autorestlongrunningoperationtestservice/auto_rest_long_running_operation_test_service.py b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Lro/autorestlongrunningoperationtestservice/auto_rest_long_running_operation_test_service.py index 718b1114d10a..be1ddc0cc63c 100644 --- a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Lro/autorestlongrunningoperationtestservice/auto_rest_long_running_operation_test_service.py +++ b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Lro/autorestlongrunningoperationtestservice/auto_rest_long_running_operation_test_service.py @@ -46,7 +46,9 @@ def __init__( self, credentials, accept_language='en-US', long_running_operation_retry_timeout=30, generate_client_request_id=True, base_url=None, filepath=None): if credentials is None: - raise ValueError('credentials must not be None.') + raise ValueError("Parameter 'credentials' must not be None.") + if accept_language is not None and not isinstance(accept_language, str): + raise TypeError("Optional parameter 'accept_language' must be str.") if not base_url: base_url = 'http://localhost' diff --git a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Paging/autorestpagingtestservice/auto_rest_paging_test_service.py b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Paging/autorestpagingtestservice/auto_rest_paging_test_service.py index 532adc38d5ac..e3cf9310642e 100644 --- a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Paging/autorestpagingtestservice/auto_rest_paging_test_service.py +++ b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/Paging/autorestpagingtestservice/auto_rest_paging_test_service.py @@ -43,7 +43,9 @@ def __init__( self, credentials, accept_language='en-US', long_running_operation_retry_timeout=30, generate_client_request_id=True, base_url=None, filepath=None): if credentials is None: - raise ValueError('credentials must not be None.') + raise ValueError("Parameter 'credentials' must not be None.") + if accept_language is not None and not isinstance(accept_language, str): + raise TypeError("Optional parameter 'accept_language' must be str.") if not base_url: base_url = 'http://localhost' diff --git a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/StorageManagementClient/storagemanagementclient/storage_management_client.py b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/StorageManagementClient/storagemanagementclient/storage_management_client.py index cd2c45791519..1334ec94142e 100644 --- a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/StorageManagementClient/storagemanagementclient/storage_management_client.py +++ b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/StorageManagementClient/storagemanagementclient/storage_management_client.py @@ -50,9 +50,15 @@ def __init__( self, credentials, subscription_id, api_version='2015-05-01-preview', accept_language='en-US', long_running_operation_retry_timeout=30, generate_client_request_id=True, base_url=None, filepath=None): if credentials is None: - raise ValueError('credentials must not be None.') + raise ValueError("Parameter 'credentials' must not be None.") if subscription_id is None: - raise ValueError('subscription_id must not be None.') + raise ValueError("Parameter 'subscription_id' must not be None.") + if not isinstance(subscription_id, str): + raise TypeError("Parameter 'subscription_id' must be str.") + if api_version is not None and not isinstance(api_version, str): + raise TypeError("Optional parameter 'api_version' must be str.") + if accept_language is not None and not isinstance(accept_language, str): + raise TypeError("Optional parameter 'accept_language' must be str.") if not base_url: base_url = 'https://management.azure.com' diff --git a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/SubscriptionIdApiVersion/microsoftazuretesturl/microsoft_azure_test_url.py b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/SubscriptionIdApiVersion/microsoftazuretesturl/microsoft_azure_test_url.py index 99e3bc1f4ce9..d16f3f25706a 100644 --- a/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/SubscriptionIdApiVersion/microsoftazuretesturl/microsoft_azure_test_url.py +++ b/AutoRest/Generators/Python/Azure.Python.Tests/Expected/AcceptanceTests/SubscriptionIdApiVersion/microsoftazuretesturl/microsoft_azure_test_url.py @@ -47,9 +47,15 @@ def __init__( self, credentials, subscription_id, api_version='2014-04-01-preview', accept_language='en-US', long_running_operation_retry_timeout=30, generate_client_request_id=True, base_url=None, filepath=None): if credentials is None: - raise ValueError('credentials must not be None.') + raise ValueError("Parameter 'credentials' must not be None.") if subscription_id is None: - raise ValueError('subscription_id must not be None.') + raise ValueError("Parameter 'subscription_id' must not be None.") + if not isinstance(subscription_id, str): + raise TypeError("Parameter 'subscription_id' must be str.") + if api_version is not None and not isinstance(api_version, str): + raise TypeError("Optional parameter 'api_version' must be str.") + if accept_language is not None and not isinstance(accept_language, str): + raise TypeError("Optional parameter 'accept_language' must be str.") if not base_url: base_url = 'https://management.azure.com/' diff --git a/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/file_tests.py b/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/file_tests.py index cc7fb8d0f5eb..22511e8de15c 100644 --- a/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/file_tests.py +++ b/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/file_tests.py @@ -53,24 +53,21 @@ class FileTests(unittest.TestCase): def test_files(self): config = AutoRestSwaggerBATFileServiceConfiguration(base_url="http://localhost:3000") - config.log_level = log_level config.connection.data_block_size = 1000 client = AutoRestSwaggerBATFileService(config) - def test_callback(data, response, progress = [0], is_response_streamed=None): + def test_callback(data, response, progress=[0]): self.assertTrue(len(data) > 0) - if not is_response_streamed: - self.assertFalse(response._content_consumed) + self.assertIsNotNone(response) + self.assertFalse(response._content_consumed) + total = float(response.headers.get('Content-Length', 0)) + if total: progress[0] += len(data) - total = float(response.headers['Content-Length']) print("Downloading... {}%".format(int(progress[0]*100/total))) - self.assertIsNotNone(response) file_length = 0 with io.BytesIO() as file_handle: - - stream = client.files.get_file(callback=lambda x, response, progress=[0] : - test_callback(x, response, progress, False)) + stream = client.files.get_file(callback=test_callback) for data in stream: file_length += len(data) @@ -86,11 +83,10 @@ def test_callback(data, response, progress = [0], is_response_streamed=None): sample_data = hash(data.read()) self.assertEqual(sample_data, hash(file_handle.getvalue())) + config.connection.data_block_size = 4096 file_length = 0 with io.BytesIO() as file_handle: - - stream = client.files.get_empty_file(callback=lambda x, response, progress=[0] : - test_callback(x, response, progress, False)) + stream = client.files.get_empty_file(callback=test_callback) for data in stream: file_length += len(data) @@ -98,34 +94,30 @@ def test_callback(data, response, progress = [0], is_response_streamed=None): self.assertEqual(file_length, 0) - #file_length = 0 - #stream = client.files.get_file_large(callback=lambda x, response, progress=[0] : - # test_callback(x, response, progress, True)) - #for data in stream: - # file_length += len(data) + file_length = 0 + stream = client.files.get_file_large(callback=test_callback) + for data in stream: + file_length += len(data) - #self.assertEqual(file_length, 3000 * 1024 * 1024) + self.assertEqual(file_length, 3000 * 1024 * 1024) def test_files_raw(self): - def test_callback(data, response, progress = [0], is_response_streamed=None): + def test_callback(data, response, progress=[0]): self.assertTrue(len(data) > 0) - if not is_response_streamed: - self.assertFalse(response._content_consumed) + self.assertIsNotNone(response) + self.assertFalse(response._content_consumed) + total = float(response.headers.get('Content-Length', 0)) + if total: progress[0] += len(data) - total = float(response.headers['Content-Length']) print("Downloading... {}%".format(int(progress[0]*100/total))) - self.assertIsNotNone(response) config = AutoRestSwaggerBATFileServiceConfiguration(base_url="http://localhost:3000") - config.log_level = log_level client = AutoRestSwaggerBATFileService(config) file_length = 0 with io.BytesIO() as file_handle: - - response = client.files.get_file(raw=True, callback=lambda x, response, progress=[0] : - test_callback(x, response, progress, False)) + response = client.files.get_file(raw=True, callback=test_callback) stream = response.output for data in stream: @@ -144,9 +136,7 @@ def test_callback(data, response, progress = [0], is_response_streamed=None): file_length = 0 with io.BytesIO() as file_handle: - - response = client.files.get_empty_file(raw=True, callback=lambda x, response, progress=[0] : - test_callback(x, response, progress, False)) + response = client.files.get_empty_file(raw=True, callback=test_callback) stream = response.output for data in stream: @@ -155,16 +145,5 @@ def test_callback(data, response, progress = [0], is_response_streamed=None): self.assertEqual(file_length, 0) - #file_length = 0 - #response = client.files.get_file_large(raw=True, callback=lambda x, response, progress=[0] : - # test_callback(x, response, progress, True)) - - #stream = response.output - - #for data in stream: - # file_length += len(data) - - #self.assertEqual(file_length, 3000 * 1024 * 1024) - if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/form_data_tests.py b/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/form_data_tests.py index f18bfdb92aa0..ea1ed1a726f9 100644 --- a/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/form_data_tests.py +++ b/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/form_data_tests.py @@ -174,7 +174,6 @@ def test_callback(data, response, progress = [0]): with open(self.dummy_file, 'rb') as upload_data: resp = client.formdata.upload_file_via_body(upload_data, callback=test_callback) for r in resp: - print(r) result.write(r) self.assertEqual(result.getvalue().decode(), "Test file") diff --git a/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/url_tests.py b/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/url_tests.py index 05f7b4dcdba4..3204669e8568 100644 --- a/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/url_tests.py +++ b/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/url_tests.py @@ -90,8 +90,9 @@ def test_url_path(self): self.client.paths.get_negative_ten_billion(-10000000000) self.client.paths.get_ten_billion(10000000000) self.client.paths.string_empty("") - #test_array = ["ArrayPath1", r"begin!*'();:@ &=+$,/?#[]end", None, ""] - #self.client.paths.array_csv_in_path(test_array) + + test_array = ["ArrayPath1", r"begin!*'();:@ &=+$,/?#[]end", None, ""] + self.client.paths.array_csv_in_path(test_array) with self.assertRaises(ValidationError): self.client.paths.string_null(None) diff --git a/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/zzz_tests.py b/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/zzz_tests.py index b54157497620..ccafa013129b 100644 --- a/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/zzz_tests.py +++ b/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/zzz_tests.py @@ -54,33 +54,38 @@ def test_ensure_coverage(self): client = AutoRestReportService(config) report = client.get_report() - # These will not be supported in Python - report['getIntegerOverflow']=1 - report['getIntegerUnderflow']=1 - report['getLongOverflow']=1 - report['getLongUnderflow']=1 - report['getDateInvalid']=1 - report['getDictionaryNullkey']=1 - report['HttpRedirect300Get']=1 - - # TODO: Support large file streams - report['FileStreamVeryLarge']=1 + not_supported = { + 'getIntegerOverflow': 1, + 'getIntegerUnderflow': 1, + 'getLongOverflow': 1, + 'getLongUnderflow': 1, + 'getDateInvalid': 1, + 'getDictionaryNullkey': 1, + 'HttpRedirect300Get': 1, + } # TODO: Support ignore readonly property in http put - report['putComplexReadOnlyPropertyValid']=1 + missing_features_or_bugs = { + 'putComplexReadOnlyPropertyValid': 1, + } - skipped = [k for k, v in report.items() if v == 0] - manually_marked_successful = [k for k, v in report.items() if v == 2] - for s in manually_marked_successful: - print("SKIPPED {0}".format(s)) + report.update(not_supported) + report.update(missing_features_or_bugs) + failed = [k for k, v in report.items() if v == 0] - for s in skipped: + for s in not_supported.keys(): + print("IGNORING {0}".format(s)) + + for s in missing_features_or_bugs.keys(): + print("PENDING {0}".format(s)) + + for s in failed: print("FAILED TO EXECUTE {0}".format(s)) totalTests = len(report) - print ("The test coverage is {0}/{1}.".format(totalTests - len(skipped), totalTests)) + print ("The test coverage is {0}/{1}.".format(totalTests - len(failed), totalTests)) - self.assertEqual(0, len(skipped)) + self.assertEqual(0, len(failed)) if __name__ == '__main__': unittest.main() diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyComplex/autorestcomplextestservice/auto_rest_complex_test_service.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyComplex/autorestcomplextestservice/auto_rest_complex_test_service.py index 8ff86db017bb..3887687ac962 100644 --- a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyComplex/autorestcomplextestservice/auto_rest_complex_test_service.py +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyComplex/autorestcomplextestservice/auto_rest_complex_test_service.py @@ -38,7 +38,9 @@ def __init__( self, api_version, base_url=None, filepath=None): if api_version is None: - raise ValueError('api_version must not be None.') + raise ValueError("Parameter 'api_version' must not be None.") + if not isinstance(api_version, str): + raise TypeError("Parameter 'api_version' must be str.") if not base_url: base_url = 'http://localhost' diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUri/autorestparameterizedhosttestclient/auto_rest_parameterized_host_test_client.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUri/autorestparameterizedhosttestclient/auto_rest_parameterized_host_test_client.py index 570afdaa9512..5839338b5a2d 100644 --- a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUri/autorestparameterizedhosttestclient/auto_rest_parameterized_host_test_client.py +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/CustomBaseUri/autorestparameterizedhosttestclient/auto_rest_parameterized_host_test_client.py @@ -31,7 +31,9 @@ def __init__( self, host, filepath=None): if host is None: - raise ValueError('host must not be None.') + raise ValueError("Parameter 'host' must not be None.") + if not isinstance(host, str): + raise TypeError("Parameter 'host' must be str.") base_url = 'http://{accountName}{host}' super(AutoRestParameterizedHostTestClientConfiguration, self).__init__(base_url, filepath) diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/RequiredOptional/autorestrequiredoptionaltestservice/auto_rest_required_optional_test_service.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/RequiredOptional/autorestrequiredoptionaltestservice/auto_rest_required_optional_test_service.py index d9a36a8ffd5b..7dcce131d92a 100644 --- a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/RequiredOptional/autorestrequiredoptionaltestservice/auto_rest_required_optional_test_service.py +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/RequiredOptional/autorestrequiredoptionaltestservice/auto_rest_required_optional_test_service.py @@ -36,9 +36,13 @@ def __init__( self, required_global_path, required_global_query, optional_global_query=None, base_url=None, filepath=None): if required_global_path is None: - raise ValueError('required_global_path must not be None.') + raise ValueError("Parameter 'required_global_path' must not be None.") + if not isinstance(required_global_path, str): + raise TypeError("Parameter 'required_global_path' must be str.") if required_global_query is None: - raise ValueError('required_global_query must not be None.') + raise ValueError("Parameter 'required_global_query' must not be None.") + if not isinstance(required_global_query, str): + raise TypeError("Parameter 'required_global_query' must be str.") if not base_url: base_url = 'http://localhost' diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/auto_rest_url_test_service.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/auto_rest_url_test_service.py index 31c188092987..34efde192fd6 100644 --- a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/auto_rest_url_test_service.py +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/auto_rest_url_test_service.py @@ -36,7 +36,11 @@ def __init__( self, global_string_path, global_string_query=None, base_url=None, filepath=None): if global_string_path is None: - raise ValueError('global_string_path must not be None.') + raise ValueError("Parameter 'global_string_path' must not be None.") + if not isinstance(global_string_path, str): + raise TypeError("Parameter 'global_string_path' must be str.") + if global_string_query is not None and not isinstance(global_string_query, str): + raise TypeError("Optional parameter 'global_string_query' must be str.") if not base_url: base_url = 'http://localhost' 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 46bface0d937..97cd8878c0e6 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 @@ -1089,7 +1089,7 @@ def array_csv_in_path( if raw=true """ # Construct URL - url = '/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}' + url = '/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}' path_format_arguments = { 'arrayPath': self._serialize.url("array_path", array_path, '[str]', div=',') } diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Validation/autorestvalidationtest/auto_rest_validation_test.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Validation/autorestvalidationtest/auto_rest_validation_test.py index 7fd4093d00b6..f9a6b88ede46 100644 --- a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Validation/autorestvalidationtest/auto_rest_validation_test.py +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Validation/autorestvalidationtest/auto_rest_validation_test.py @@ -34,9 +34,13 @@ def __init__( self, subscription_id, api_version, base_url=None, filepath=None): if subscription_id is None: - raise ValueError('subscription_id must not be None.') + raise ValueError("Parameter 'subscription_id' must not be None.") + if not isinstance(subscription_id, str): + raise TypeError("Parameter 'subscription_id' must be str.") if api_version is None: - raise ValueError('api_version must not be None.') + raise ValueError("Parameter 'api_version' must not be None.") + if not isinstance(api_version, str): + raise TypeError("Parameter 'api_version' must be str.") if not base_url: base_url = 'http://localhost' diff --git a/AutoRest/Generators/Python/Python/TemplateModels/MethodTemplateModel.cs b/AutoRest/Generators/Python/Python/TemplateModels/MethodTemplateModel.cs index 5c47e7be1f83..0555d5cd4434 100644 --- a/AutoRest/Generators/Python/Python/TemplateModels/MethodTemplateModel.cs +++ b/AutoRest/Generators/Python/Python/TemplateModels/MethodTemplateModel.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.Linq; using System.Net; +using System.Text.RegularExpressions; using Microsoft.Rest.Generator.ClientModel; using Microsoft.Rest.Generator.Python.TemplateModels; using Microsoft.Rest.Generator.Utilities; @@ -31,6 +32,12 @@ public MethodTemplateModel(Method source, ServiceClient serviceClient) OperationName = serviceClient.Name; } AddCustomHeader = true; + string formatter; + foreach (Match m in Regex.Matches(Url, @"\{[\w]+:[\w]+\}")) + { + formatter = m.Value.Split(':').First() + '}'; + Url = Url.Replace(m.Value, formatter); + } } public bool AddCustomHeader { get; private set; } diff --git a/AutoRest/Generators/Python/Python/TemplateModels/ServiceClientTemplateModel.cs b/AutoRest/Generators/Python/Python/TemplateModels/ServiceClientTemplateModel.cs index 4eb487cdfdee..60629ea26ca2 100644 --- a/AutoRest/Generators/Python/Python/TemplateModels/ServiceClientTemplateModel.cs +++ b/AutoRest/Generators/Python/Python/TemplateModels/ServiceClientTemplateModel.cs @@ -105,7 +105,10 @@ public virtual string RequiredConstructorParameters } } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "ValueError"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Microsoft.Rest.Generator.Utilities.IndentedStringBuilder.AppendLine(System.String)")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "ValueError"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "TypeError"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "str"), + System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Microsoft.Rest.Generator.Utilities.IndentedStringBuilder.AppendLine(System.String)")] public virtual string ValidateRequiredParameters { get @@ -118,9 +121,31 @@ public virtual string ValidateRequiredParameters builder. AppendFormat("if {0} is None:", property.Name.ToPythonCase()).AppendLine(). Indent(). - AppendLine(string.Format(CultureInfo.InvariantCulture, "raise ValueError('{0} must not be None.')", property.Name.ToPythonCase())). + AppendLine(string.Format(CultureInfo.InvariantCulture, "raise ValueError(\"Parameter '{0}' must not be None.\")", property.Name.ToPythonCase())). Outdent(); + if (property.Type.IsPrimaryType(KnownPrimaryType.String)) + { + builder. + AppendFormat("if not isinstance({0}, str):", property.Name.ToPythonCase()).AppendLine(). + Indent(). + AppendLine(string.Format(CultureInfo.InvariantCulture, "raise TypeError(\"Parameter '{0}' must be str.\")", property.Name.ToPythonCase())). + Outdent(); + } } + else + { + if (property.Type.IsPrimaryType(KnownPrimaryType.String)) + { + builder. + AppendFormat("if {0} is not None and not isinstance({0}, str):", property.Name.ToPythonCase()).AppendLine(). + Indent(). + AppendLine(string.Format(CultureInfo.InvariantCulture, "raise TypeError(\"Optional parameter '{0}' must be str.\")", property.Name.ToPythonCase())). + Outdent(); + } + + } + + } return builder.ToString(); } diff --git a/ClientRuntimes/Python/msrest/msrest/http_logger.py b/ClientRuntimes/Python/msrest/msrest/http_logger.py index b19405528cf9..5159a996a6e8 100644 --- a/ClientRuntimes/Python/msrest/msrest/http_logger.py +++ b/ClientRuntimes/Python/msrest/msrest/http_logger.py @@ -81,8 +81,8 @@ def log_response(adapter, request, response, *args, **kwargs): _LOGGER.debug("Body contains binary data.") elif result.headers.get("content-type", "").startswith("image"): _LOGGER.debug("Body contains image data.") - # elif result.headers.get("transfer-encoding") == 'chunked': - # LOGGER.debug("Body contains chunked data.") + elif result.headers.get("transfer-encoding") == 'chunked': + _LOGGER.debug("Body contains chunked data.") else: _LOGGER.debug(str(result.content)) return result diff --git a/ClientRuntimes/Python/msrest/msrest/serialization.py b/ClientRuntimes/Python/msrest/msrest/serialization.py index 40f4c8857868..25aff136d153 100644 --- a/ClientRuntimes/Python/msrest/msrest/serialization.py +++ b/ClientRuntimes/Python/msrest/msrest/serialization.py @@ -406,7 +406,8 @@ def serialize_iter(self, data, iter_type, div=None, **kwargs): serialized.append(None) if div: - return div.join(serialized) + serialized = ['' if s is None else s for s in serialized] + serialized = div.join(serialized) return serialized def serialize_dict(self, attr, dict_type, **kwargs): diff --git a/ClientRuntimes/Python/msrest/msrest/service_client.py b/ClientRuntimes/Python/msrest/msrest/service_client.py index 523c6648582f..6c27b017e111 100644 --- a/ClientRuntimes/Python/msrest/msrest/service_client.py +++ b/ClientRuntimes/Python/msrest/msrest/service_client.py @@ -146,7 +146,7 @@ def send_formdata(self, request, headers={}, content={}, **config): :param ClientRequest request: The request object to be sent. :param dict headers: Any headers to add to the request. :param dict content: Dictionary of the fields of the formdata. - :param config: Any specific config overrides + :param config: Any specific config overrides. """ file_data = {f: self._format_data(d) for f, d in content.items()} try: @@ -163,6 +163,7 @@ def send(self, request, headers=None, content=None, **config): :param content: Any body data to add to the request. :param config: Any specific config overrides """ + response = None session = self.creds.signed_session() kwargs = self._configure_session(session, **config) @@ -204,7 +205,8 @@ def send(self, request, headers=None, content=None, **config): msg = "Error occurred in request." raise_with_traceback(ClientRequestError, msg, err) finally: - session.close() + if not response or response._content_consumed: + session.close() def stream_download(self, data, callback): """Generator for streaming request body data. @@ -228,7 +230,6 @@ def stream_download(self, data, callback): if callback and callable(callback): callback(chunk, response=data) yield chunk - data.close() def stream_upload(self, data, callback): """Generator for streaming request body data. diff --git a/ClientRuntimes/Python/msrest/test/unittest_runtime.py b/ClientRuntimes/Python/msrest/test/unittest_runtime.py index 7bb798d5af6d..fbdad6791f77 100644 --- a/ClientRuntimes/Python/msrest/test/unittest_runtime.py +++ b/ClientRuntimes/Python/msrest/test/unittest_runtime.py @@ -101,7 +101,7 @@ def hook(aptr, req, *args, **kwargs): @mock.patch.object(requests, 'Session') def test_request_fail(self, mock_requests): - mock_requests.return_value.request.return_value = "test" + mock_requests.return_value.request.return_value = mock.Mock(_content_consumed=True) cfg = Configuration("https://my_service.com") creds = Authentication() @@ -113,7 +113,7 @@ def test_request_fail(self, mock_requests): check = httpretty.last_request() - self.assertEqual(response, "test") + self.assertTrue(response._content_consumed) mock_requests.return_value.request.side_effect = requests.RequestException with self.assertRaises(ClientRequestError): @@ -127,6 +127,8 @@ def test_request_proxy(self): def hook(adptr, request, *args, **kwargs): self.assertEqual(kwargs.get('proxies'), {"http://my_service.com":'http://localhost:57979'}) + kwargs['result']._content_consumed = True + kwargs['result'].status_code = 200 return kwargs['result'] client = ServiceClient(creds, cfg) @@ -139,6 +141,8 @@ def hook(adptr, request, *args, **kwargs): def hook2(adptr, request, *args, **kwargs): self.assertEqual(kwargs.get('proxies')['https'], "http://localhost:1987") + kwargs['result']._content_consumed = True + kwargs['result'].status_code = 200 return kwargs['result'] cfg = Configuration("http://my_service.com") diff --git a/Samples/azure-storage/Azure.Python/storagemanagementclient/storage_management_client.py b/Samples/azure-storage/Azure.Python/storagemanagementclient/storage_management_client.py index 732eb30e70fb..00031c87fca7 100644 --- a/Samples/azure-storage/Azure.Python/storagemanagementclient/storage_management_client.py +++ b/Samples/azure-storage/Azure.Python/storagemanagementclient/storage_management_client.py @@ -43,9 +43,15 @@ def __init__( self, credentials, subscription_id, api_version='2015-06-15', accept_language='en-US', long_running_operation_retry_timeout=30, generate_client_request_id=True, base_url=None, filepath=None): if credentials is None: - raise ValueError('credentials must not be None.') + raise ValueError("Parameter 'credentials' must not be None.") if subscription_id is None: - raise ValueError('subscription_id must not be None.') + raise ValueError("Parameter 'subscription_id' must not be None.") + if not isinstance(subscription_id, str): + raise TypeError("Parameter 'subscription_id' must be str.") + if api_version is not None and not isinstance(api_version, str): + raise TypeError("Optional parameter 'api_version' must be str.") + if accept_language is not None and not isinstance(accept_language, str): + raise TypeError("Optional parameter 'accept_language' must be str.") if not base_url: base_url = 'https://management.azure.com' From 91d73c6bd81deebe2fd83090d60d63f38a08932a Mon Sep 17 00:00:00 2001 From: annatisch Date: Fri, 15 Apr 2016 16:19:30 -0700 Subject: [PATCH 32/96] Python Streaming Test Fix (#953) * Debugging test failure * testing without header * Adding header back again --- .../Python/Python.Tests/AcceptanceTests/file_tests.py | 8 ++++++-- ClientRuntimes/Python/msrest/msrest/service_client.py | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/file_tests.py b/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/file_tests.py index 22511e8de15c..c45c3e0db683 100644 --- a/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/file_tests.py +++ b/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/file_tests.py @@ -60,8 +60,8 @@ def test_callback(data, response, progress=[0]): self.assertTrue(len(data) > 0) self.assertIsNotNone(response) self.assertFalse(response._content_consumed) - total = float(response.headers.get('Content-Length', 0)) - if total: + total = float(response.headers['Content-Length']) + if total < 4096: progress[0] += len(data) print("Downloading... {}%".format(int(progress[0]*100/total))) @@ -94,7 +94,11 @@ def test_callback(data, response, progress=[0]): self.assertEqual(file_length, 0) + def add_headers(adapter, request, response, *args, **kwargs): + response.headers['Content-Length'] = str(3000 * 1024 * 1024) + file_length = 0 + client._client.add_hook('response', add_headers) stream = client.files.get_file_large(callback=test_callback) for data in stream: file_length += len(data) diff --git a/ClientRuntimes/Python/msrest/msrest/service_client.py b/ClientRuntimes/Python/msrest/msrest/service_client.py index 6c27b017e111..a204089838dd 100644 --- a/ClientRuntimes/Python/msrest/msrest/service_client.py +++ b/ClientRuntimes/Python/msrest/msrest/service_client.py @@ -230,6 +230,8 @@ def stream_download(self, data, callback): if callback and callable(callback): callback(chunk, response=data) yield chunk + data.close() + self._adapter.close() def stream_upload(self, data, callback): """Generator for streaming request body data. From ce5830645e9f447255a3f7c38f813f20ded5f6e3 Mon Sep 17 00:00:00 2001 From: Dan Schulte Date: Mon, 18 Apr 2016 12:11:33 -0700 Subject: [PATCH 33/96] Fix AzureResourceSchema project --- AutoRest/AutoRest.Core/AutoRest.nuspec | 1 + AutoRest/AutoRest/AutoRest.Release.json | 3 +++ ...Generator.AzureResourceSchema.Tests.csproj | 18 +++++-------- .../AzureResourceSchema.Tests/packages.config | 14 +++++----- ...oRest.Generator.AzureResourceSchema.csproj | 17 ++++-------- .../Properties/AssemblyInfo.cs | 2 -- CodeGenerator.sln | 27 ++++++++++++++++++- 7 files changed, 49 insertions(+), 33 deletions(-) diff --git a/AutoRest/AutoRest.Core/AutoRest.nuspec b/AutoRest/AutoRest.Core/AutoRest.nuspec index 0451285cb520..2af544a88582 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 b488b12ca1fc..f368702db7a6 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/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj index 4423130faf24..9be41978276c 100644 --- a/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj +++ b/AutoRest/Generators/AzureResourceSchema/AzureResourceSchema.Tests/AutoRest.Generator.AzureResourceSchema.Tests.csproj @@ -1,8 +1,7 @@  - - + Debug @@ -62,20 +61,21 @@ ..\..\..\..\packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll + - ..\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 @@ -88,7 +88,6 @@ {c876085f-9dc3-41f0-b7b4-17022cd84684} AutoRest.Core - @@ -101,9 +100,6 @@ AutoRest.Generator.AzureResourceSchema - - - @@ -113,7 +109,7 @@ 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}. - + true diff --git a/AutoRest/AutoRest.Core/Properties/AssemblyInfo.cs b/AutoRest/AutoRest.Core/Properties/AssemblyInfo.cs index aa48e093addc..f1686e243316 100644 --- a/AutoRest/AutoRest.Core/Properties/AssemblyInfo.cs +++ b/AutoRest/AutoRest.Core/Properties/AssemblyInfo.cs @@ -11,8 +11,8 @@ [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyProduct("Microsoft AutoRest")] [assembly: AssemblyCopyright("Copyright (c) Microsoft Corporation")] -[assembly: AssemblyVersion("0.16.0.0")] -[assembly: AssemblyFileVersion("0.16.0.0")] +[assembly: AssemblyVersion("0.17.0.0")] +[assembly: AssemblyFileVersion("0.17.0.0")] [assembly: NeutralResourcesLanguage("en")] [assembly: CLSCompliant(true)] diff --git a/AutoRest/NugetPackageTest/packages.config b/AutoRest/NugetPackageTest/packages.config index 356cf06d8836..6cc4944dba66 100644 --- a/AutoRest/NugetPackageTest/packages.config +++ b/AutoRest/NugetPackageTest/packages.config @@ -1,7 +1,7 @@ - +