Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HttpLongRunningOperationResponse #46

Merged
2 commits merged into from
Aug 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 26 additions & 13 deletions lib/azureServiceClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

import { HttpOperationResponse, RequestOptionsBase, RequestPrepareOptions, ServiceClient, ServiceClientCredentials, ServiceClientOptions, WebResource } from "ms-rest-js";
import { createLROPollStrategy, LROPollStrategy } from "./lroPollStrategy";
import { HttpLongRunningOperationResponse, createHttpLongRunningOperationResponseFromInitialResponse, createHttpLongRunningOperationResponseFromMemento } from "./httpLongRunningOperationResponse";
import * as Constants from "./util/constants";
import { LROMemento } from "./lroPollStrategy";

/**
* Options to be provided while creating the client.
Expand Down Expand Up @@ -58,7 +59,20 @@ export class AzureServiceClient extends ServiceClient {
* @returns {Promise<msRest.HttpOperationResponse>} The HttpOperationResponse containing the final polling request, response and the responseBody.
*/
async sendLongRunningRequest(request: RequestPrepareOptions | WebResource, options?: RequestOptionsBase): Promise<HttpOperationResponse> {
return this.sendRequest(request).then((response: HttpOperationResponse) => this.getLongRunningOperationResult(response, options));
return this.beginLongRunningRequest(request, options).then((lroResponse: HttpLongRunningOperationResponse) => lroResponse.pollUntilFinished());
}

/**
* Send the initial request of a LRO (long running operation) and get back an
* HttpLongRunningOperationResponse that provides methods for polling the LRO and checking if the
* LRO is finished.
* @param {msRest.RequestPrepareOptions|msRest.WebResource} request - The request object
* @param {AzureRequestOptionsBase} [options] Additional options to be sent while making the request
* @returns {Promise<HttpLongRunningOperationResponse>} The HttpLongRunningOperationResponse
* that provides methods for interacting with the LRO.
*/
async beginLongRunningRequest(request: RequestPrepareOptions | WebResource, options?: RequestOptionsBase): Promise<HttpLongRunningOperationResponse> {
return this.sendRequest(request).then((initialResponse: HttpOperationResponse) => createHttpLongRunningOperationResponseFromInitialResponse(this, initialResponse, options));
}

/**
Expand All @@ -68,17 +82,16 @@ export class AzureServiceClient extends ServiceClient {
* @returns {Promise<HttpOperationResponse>} The final response after polling is complete.
*/
async getLongRunningOperationResult(initialResponse: HttpOperationResponse, options?: RequestOptionsBase): Promise<HttpOperationResponse> {
const lroPollStrategy: LROPollStrategy | undefined = createLROPollStrategy(initialResponse, this, options);
if (!lroPollStrategy) {
return initialResponse;
} else {
const succeeded: boolean = await lroPollStrategy.pollUntilFinished();
if (succeeded) {
return lroPollStrategy.getOperationResponse();
} else {
throw lroPollStrategy.getRestError();
}
}
const lroResponse: HttpLongRunningOperationResponse = createHttpLongRunningOperationResponseFromInitialResponse(this, initialResponse, options);
return lroResponse.pollUntilFinished();
}

/**
* Restore an HttpLongRunningOperationResponse from the provided LROMemento. This method can be
* used to recreate an HttpLongRunningOperationResponse on a different process or machine.
*/
restoreHttpLongRunningOperationResponse(lroMemento: LROMemento): HttpLongRunningOperationResponse {
return createHttpLongRunningOperationResponseFromMemento(this, lroMemento);
}
}

Expand Down
88 changes: 88 additions & 0 deletions lib/httpLongRunningOperationResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

import { HttpOperationResponse, RequestOptionsBase } from "ms-rest-js";
import { AzureServiceClient } from "./azureServiceClient";
import { createLROPollStrategyFromInitialResponse, createLROPollStrategyFromMemento, LROMemento, LROPollStrategy } from "./lroPollStrategy";
import { LongRunningOperationStates } from "./util/constants";

/**
* An HTTP operation response that provides special methods for interacting with LROs (long running
* operations).
*/
export class HttpLongRunningOperationResponse {
/**
* Create a new HttpLongRunningOperationResponse.
* @param _lroPollStrategy The LROPollStrategy that this HttpLongRunningOperationResponse will
* use to interact with the LRO.
*/
constructor(private readonly _lroPollStrategy: LROPollStrategy | undefined, private readonly _initialResponse: HttpOperationResponse) {
}

/**
* Get the current status of the LRO.
* @returns The current status of the LRO.
*/
public getOperationStatus(): LongRunningOperationStates {
const lroPollStrategy: LROPollStrategy | undefined = this._lroPollStrategy;
return !lroPollStrategy ? "Succeeded" : lroPollStrategy.getOperationStatus();
}

/**
* Send a single poll request and return the LRO's state.
* @returns The LRO's state.
*/
public poll(): Promise<LongRunningOperationStates> {
let result: Promise<LongRunningOperationStates>;
const lroPollStrategy: LROPollStrategy | undefined = this._lroPollStrategy;
if (!lroPollStrategy) {
result = Promise.resolve<LongRunningOperationStates>("Succeeded");
} else {
result = lroPollStrategy.sendPollRequest().then(() => {
return lroPollStrategy.getOperationStatus();
});
}
return result;
}

/**
* Send poll requests that check the LRO's status until it is determined that the LRO is finished.
* @returns Whether or not the LRO succeeded.
*/
public async pollUntilFinished(): Promise<HttpOperationResponse> {
let result: Promise<HttpOperationResponse>;
const lroPollStrategy: LROPollStrategy | undefined = this._lroPollStrategy;
if (!lroPollStrategy) {
result = Promise.resolve(this._initialResponse);
} else {
result = lroPollStrategy.pollUntilFinished().then((succeeded: boolean) => {
if (succeeded) {
return lroPollStrategy.getOperationResponse();
} else {
throw lroPollStrategy.getRestError();
}
});
}
return result;
}

/**
* Get an LROMemento object that can be used to poll this LRO in a different context (such as on a
* different process or a different machine). If the LRO couldn't produce an LRO polling strategy,
* then this will return undefined.
*/
public getMemento(): LROMemento | undefined {
const lroPollStrategy: LROPollStrategy | undefined = this._lroPollStrategy;
return !lroPollStrategy ? undefined : lroPollStrategy.getMemento();
}
}

export function createHttpLongRunningOperationResponseFromInitialResponse(azureServiceClient: AzureServiceClient, initialResponse: HttpOperationResponse, options?: RequestOptionsBase): HttpLongRunningOperationResponse {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What makes export necessary for these 2 functions?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two functions serve as the constructor functions for HttpLongRunningOperationResponse objects. They're both used by the AzureServiceClient class.

const lroPollStrategy: LROPollStrategy | undefined = createLROPollStrategyFromInitialResponse(initialResponse, azureServiceClient, options);
return new HttpLongRunningOperationResponse(lroPollStrategy, initialResponse);
}

export function createHttpLongRunningOperationResponseFromMemento(azureServiceClient: AzureServiceClient, lroMemento: LROMemento): HttpLongRunningOperationResponse {
const lroPollStrategy: LROPollStrategy | undefined = createLROPollStrategyFromMemento(azureServiceClient, lroMemento);
return new HttpLongRunningOperationResponse(lroPollStrategy, lroMemento.initialResponse);
}
Loading