UNPKG

6.27 kBPlain TextView Raw
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT License. See License.txt in the project root for license information.
3
4import { HttpOperationResponse, RequestOptionsBase, RestResponse, flattenResponse } from "@azure/ms-rest-js";
5import { AzureServiceClient } from "./azureServiceClient";
6import { createLROPollStrategyFromInitialResponse, createLROPollStrategyFromPollState, LROPollState, LROPollStrategy } from "./lroPollStrategy";
7import { LongRunningOperationStates } from "./util/constants";
8
9/**
10 * An HTTP operation response that provides special methods for interacting with LROs (long running
11 * operations).
12 */
13export class LROPoller {
14 /**
15 * Create a new HttpLongRunningOperationResponse.
16 * @param _lroPollStrategy The LROPollStrategy that this HttpLongRunningOperationResponse will
17 * use to interact with the LRO.
18 */
19 constructor(private readonly _lroPollStrategy: LROPollStrategy | undefined, private readonly _initialResponse: HttpOperationResponse) {
20 }
21
22 /**
23 * Get the first response that the service sent back when the LRO was initiated.
24 */
25 public getInitialResponse(): HttpOperationResponse {
26 return this._initialResponse;
27 }
28
29 /**
30 * Get the most recent response that the service sent back during this LRO.
31 */
32 public getMostRecentResponse(): HttpOperationResponse {
33 const lroPollStrategy: LROPollStrategy | undefined = this._lroPollStrategy;
34 return !lroPollStrategy ? this._initialResponse : lroPollStrategy.getMostRecentResponse();
35 }
36
37 /**
38 * Get whether or not the LRO is finished.
39 */
40 public isFinished(): boolean {
41 const lroPollStrategy: LROPollStrategy | undefined = this._lroPollStrategy;
42 return !lroPollStrategy ? true : lroPollStrategy.isFinished();
43 }
44
45 /**
46 * Get whether or not the LRO is finished and its final state is acceptable. If the LRO has not
47 * finished yet, then undefined will be returned. An "acceptable" final state is determined by the
48 * LRO strategy that the Azure service uses to perform long running operations.
49 */
50 public isFinalStatusAcceptable(): boolean | undefined {
51 let result: boolean | undefined;
52 const lroPollStrategy: LROPollStrategy | undefined = this._lroPollStrategy;
53 if (!lroPollStrategy) {
54 result = true;
55 } else if (lroPollStrategy.isFinished()) {
56 result = lroPollStrategy.isFinalStatusAcceptable();
57 }
58 return result;
59 }
60
61 /**
62 * Get the current status of the LRO.
63 */
64 public getOperationStatus(): LongRunningOperationStates {
65 const lroPollStrategy: LROPollStrategy | undefined = this._lroPollStrategy;
66 return !lroPollStrategy ? "Succeeded" : lroPollStrategy.getOperationStatus();
67 }
68
69 /**
70 * If the LRO is finished and in an acceptable state, then return the HttpOperationResponse. If
71 * the LRO is finished and not in an acceptable state, then throw the error that the LRO produced.
72 * If the LRO is not finished, then return undefined.
73 */
74 public getOperationResponse(): Promise<HttpOperationResponse | undefined> {
75 let result: Promise<HttpOperationResponse | undefined>;
76 const lroPollStrategy: LROPollStrategy | undefined = this._lroPollStrategy;
77 if (!lroPollStrategy) {
78 result = Promise.resolve(this._initialResponse);
79 } else if (!lroPollStrategy.isFinished()) {
80 result = Promise.resolve(undefined);
81 } else if (lroPollStrategy.isFinalStatusAcceptable()) {
82 result = lroPollStrategy.getOperationResponse();
83 } else {
84 throw lroPollStrategy.getRestError();
85 }
86 return result;
87 }
88
89 /**
90 * Send a single poll request and return the LRO's state.
91 */
92 public poll(): Promise<LongRunningOperationStates> {
93 let result: Promise<LongRunningOperationStates>;
94 const lroPollStrategy: LROPollStrategy | undefined = this._lroPollStrategy;
95 if (!lroPollStrategy) {
96 result = Promise.resolve<LongRunningOperationStates>("Succeeded");
97 } else {
98 result = lroPollStrategy.sendPollRequest().then(() => {
99 return lroPollStrategy.getOperationStatus();
100 });
101 }
102 return result;
103 }
104
105 /**
106 * Send poll requests that check the LRO's status until it is determined that the LRO is finished.
107 */
108 public async pollUntilFinished(): Promise<RestResponse> {
109 let result: Promise<RestResponse>;
110 const lroPollStrategy: LROPollStrategy | undefined = this._lroPollStrategy;
111
112 if (!lroPollStrategy) {
113 result = Promise.resolve(flattenAzureResponse(this._initialResponse));
114 } else {
115 result = lroPollStrategy.pollUntilFinished().then((succeeded: boolean) => {
116 if (succeeded) {
117 return lroPollStrategy.getOperationResponse().then(flattenAzureResponse);
118 } else {
119 throw lroPollStrategy.getRestError();
120 }
121 });
122 }
123 return result;
124 }
125
126 /**
127 * Get an LROPollState object that can be used to poll this LRO in a different context (such as on
128 * a different process or a different machine). If the LRO couldn't produce an LRO polling
129 * strategy, then this will return undefined.
130 */
131 public getPollState(): LROPollState | undefined {
132 const lroPollStrategy: LROPollStrategy | undefined = this._lroPollStrategy;
133 return !lroPollStrategy ? undefined : lroPollStrategy.getPollState();
134 }
135}
136
137export function createLROPollerFromInitialResponse(azureServiceClient: AzureServiceClient, initialResponse: HttpOperationResponse, options?: RequestOptionsBase): LROPoller {
138 const lroPollStrategy: LROPollStrategy | undefined = createLROPollStrategyFromInitialResponse(initialResponse, azureServiceClient, options);
139 return new LROPoller(lroPollStrategy, initialResponse);
140}
141
142export function createLROPollerFromPollState(azureServiceClient: AzureServiceClient, lroMemento: LROPollState): LROPoller {
143 const lroPollStrategy: LROPollStrategy | undefined = createLROPollStrategyFromPollState(azureServiceClient, lroMemento);
144 return new LROPoller(lroPollStrategy, lroMemento.initialResponse);
145}
146
147function flattenAzureResponse(response: HttpOperationResponse): RestResponse {
148 const { operationResponseGetter, operationSpec } = response.request;
149 return flattenResponse(response, operationResponseGetter && operationSpec && operationResponseGetter(operationSpec, response));
150}