Skip to content

Commit

Permalink
adding src/generated/lro
Browse files Browse the repository at this point in the history
  • Loading branch information
deyaaeldeen committed Oct 7, 2020
1 parent 5f83af8 commit 01ba65c
Show file tree
Hide file tree
Showing 12 changed files with 852 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*
* Code generated by Microsoft (R) AutoRest Code Generator.
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
*/

import {
LROStrategy,
BaseResult,
LROOperationStep,
LROResponseInfo,
FinalStateVia
} from "./models";
import { OperationSpec, OperationArguments } from "@azure/core-http";
import { terminalStates } from "./constants";
import { SendOperationFn } from ".";

export function createAzureAsyncOperationStrategy<TResult extends BaseResult>(
initialOperation: LROOperationStep<TResult>,
sendOperationFn: SendOperationFn<TResult>,
finalStateVia?: FinalStateVia
): LROStrategy<TResult> {
const lroData = initialOperation.result._lroData;
if (!lroData) {
throw new Error(
"Expected lroData to be defined for Azure-AsyncOperation strategy"
);
}

let currentOperation = initialOperation;
let lastKnownPollingUrl =
lroData.azureAsyncOperation || lroData.operationLocation;

return {
isTerminal: () => {
const currentResult = currentOperation.result._lroData;

if (!currentResult) {
throw new Error("Expected lroData to determine terminal status");
}

if (currentOperation === initialOperation) {
// Azure-AsyncOperations don't need to check for terminal state
// on originalOperation result, always need to poll
return false;
}

const { status = "succeeded" } = currentResult;
return terminalStates.includes(status.toLowerCase());
},
sendFinalRequest: async () => {
if (!initialOperation.result._lroData) {
throw new Error("Expected lroData to determine terminal status");
}

if (!currentOperation.result._lroData) {
throw new Error("Expected lroData to determine terminal status");
}

const initialOperationResult = initialOperation.result._lroData;
const currentOperationResult = currentOperation.result._lroData;

if (
!shouldPerformFinalGet(initialOperationResult, currentOperationResult)
) {
return currentOperation;
}

if (initialOperationResult.requestMethod === "PUT") {
currentOperation = await sendFinalGet(
initialOperation,
sendOperationFn
);

return currentOperation;
}

if (initialOperationResult.location) {
switch (finalStateVia) {
case "original-uri":
currentOperation = await sendFinalGet(
initialOperation,
sendOperationFn
);
return currentOperation;

case "azure-async-operation":
return currentOperation;
case "location":
default:
const location =
initialOperationResult.location ||
currentOperationResult.location;

if (!location) {
throw new Error("Couldn't determine final GET URL from location");
}

return await sendFinalGet(
initialOperation,
sendOperationFn,
location
);
}
}

// All other cases return the last operation
return currentOperation;
},
poll: async () => {
if (!lastKnownPollingUrl) {
throw new Error("Unable to determine polling url");
}

const pollingArgs = currentOperation.args;
// Make sure we don't send any body to the get request
const { requestBody, ...restSpec } = currentOperation.spec;
const pollingSpec: OperationSpec = {
...restSpec,
httpMethod: "GET",
path: lastKnownPollingUrl
};

const result = await sendOperationFn(pollingArgs, pollingSpec);

// Update latest polling url
lastKnownPollingUrl =
result._lroData?.azureAsyncOperation ||
result._lroData?.operationLocation ||
lastKnownPollingUrl;

// Update lastOperation result
currentOperation = {
args: pollingArgs,
spec: pollingSpec,
result
};

return currentOperation;
}
};
}

function shouldPerformFinalGet(
initialResult: LROResponseInfo,
currentResult: LROResponseInfo
) {
const { status } = currentResult;
const { requestMethod: initialRequestMethod, location } = initialResult;
if (status && status.toLowerCase() !== "succeeded") {
return false;
}

if (initialRequestMethod === "DELETE") {
return false;
}

if (initialRequestMethod !== "PUT" && !location) {
return false;
}

return true;
}

async function sendFinalGet<TResult extends BaseResult>(
initialOperation: LROOperationStep<TResult>,
sendOperationFn: SendOperationFn<TResult>,
path?: string
): Promise<LROOperationStep<TResult>> {
// Make sure we don't send any body to the get request
const { requestBody, ...restSpec } = initialOperation.spec;
const finalGetSpec: OperationSpec = {
...restSpec,
httpMethod: "GET"
};

// Send final GET request to the Original URL
const spec = {
...finalGetSpec,
...(path && { path })
};

let operationArgs: OperationArguments = initialOperation.args;
if (operationArgs.options) {
operationArgs.options.shouldDeserialize = true;
}

const finalResult = await sendOperationFn(initialOperation.args, spec);

return {
args: initialOperation.args,
spec,
result: finalResult
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*
* Code generated by Microsoft (R) AutoRest Code Generator.
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
*/

import { LROStrategy, BaseResult, LROOperationStep } from "./models";
import { OperationSpec } from "@azure/core-http";
import { terminalStates } from "./constants";
import { SendOperationFn } from "./lroPoller";

/**
* Creates a polling strategy based on BodyPolling which uses the provisioning state
* from the result to determine the current operation state
*/
export function createBodyPollingStrategy<TResult extends BaseResult>(
initialOperation: LROOperationStep<TResult>,
sendOperation: SendOperationFn<TResult>
): LROStrategy<TResult> {
if (!initialOperation.result._lroData) {
throw new Error("Expected lroData to be defined for BodyPolling strategy");
}

let currentOperation = initialOperation;

return {
isTerminal: () => {
const currentResult = currentOperation.result._lroData;
if (!currentResult) {
throw new Error("Expected lroData to determine terminal status");
}

const { provisioningState = "succeeded" } = currentResult;
// If provisioning state is missing, default to Success

return terminalStates.includes(provisioningState.toLowerCase());
},
sendFinalRequest: () => {
// BodyPolling doesn't require a final get so return the lastOperation
return Promise.resolve(currentOperation);
},
poll: async () => {
// When doing BodyPolling, we need to poll to the original url with a
// GET http method
const { requestBody, ...restSpec } = initialOperation.spec;
const pollingSpec: OperationSpec = {
// Make sure we don't send any body to the get request
...restSpec,
httpMethod: "GET"
};

// Execute the polling operation
initialOperation.result = await sendOperation(
initialOperation.args,
pollingSpec
);
return initialOperation;
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*
* Code generated by Microsoft (R) AutoRest Code Generator.
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
*/

export const terminalStates = ["succeeded", "failed", "canceled", "cancelled"];
23 changes: 23 additions & 0 deletions sdk/textanalytics/ai-text-analytics/src/generated/lro/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*
* Code generated by Microsoft (R) AutoRest Code Generator.
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
*/

export { shouldDeserializeLRO } from "./requestUtils";
export { createBodyPollingStrategy } from "./bodyPollingStrategy";
export { terminalStates } from "./constants";
export { lroPolicy } from "./lroPolicy";
export { LROPoller, LROPollerOptions, SendOperationFn } from "./lroPoller";
export {
LROResponseInfo,
BaseResult,
LROOperationStep,
LROOperationState,
LROStrategy,
LROOperation
} from "./models";
export { makeOperation } from "./operation";
export * from "./locationStrategy";
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*
* Code generated by Microsoft (R) AutoRest Code Generator.
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
*/

import { BaseResult, LROOperationStep, LROStrategy } from "./models";
import { SendOperationFn } from "./lroPoller";
import { OperationSpec } from "@azure/core-http";

export function createLocationStrategy<TResult extends BaseResult>(
initialOperation: LROOperationStep<TResult>,
sendOperationFn: SendOperationFn<TResult>
): LROStrategy<TResult> {
const lroData = initialOperation.result._lroData;
if (!lroData) {
throw new Error(
"Expected lroData to be defined for Azure-AsyncOperation strategy"
);
}

let currentOperation = initialOperation;
let lastKnownPollingUrl = lroData.location;

return {
isTerminal: () => {
const currentResult = currentOperation.result._lroData;
if (!currentResult) {
throw new Error("Expected lroData to determine terminal status");
}

if (currentOperation === initialOperation) {
return false;
}

if (currentResult.statusCode === 202) {
return false;
}

return true;
},
sendFinalRequest: () => Promise.resolve(currentOperation),
poll: async () => {
if (!lastKnownPollingUrl) {
throw new Error("Unable to determine polling url");
}

const pollingArgs = currentOperation.args;
// Make sure we don't send any body to the get request
const { requestBody, ...restSpec } = currentOperation.spec;
const pollingSpec: OperationSpec = {
...restSpec,
httpMethod: "GET",
path: lastKnownPollingUrl
};

const result = await sendOperationFn(pollingArgs, pollingSpec);

// Update latest polling url
lastKnownPollingUrl = result._lroData?.location || lastKnownPollingUrl;

// Update lastOperation result
currentOperation = {
args: pollingArgs,
spec: pollingSpec,
result
};

return currentOperation;
}
};
}
Loading

0 comments on commit 01ba65c

Please sign in to comment.