From f6a581b484aa5ae7e0610c74b62ddf915922f6d1 Mon Sep 17 00:00:00 2001 From: hossam-nasr Date: Wed, 1 Feb 2023 12:06:17 -0800 Subject: [PATCH 1/6] add DurableClient interface --- src/durableorchestrationclient.ts | 146 +------------------- src/types/durableClientTypes.ts | 219 +++++++++++++++++++++++++++++- 2 files changed, 225 insertions(+), 140 deletions(-) diff --git a/src/durableorchestrationclient.ts b/src/durableorchestrationclient.ts index 0eb88d0..c969397 100644 --- a/src/durableorchestrationclient.ts +++ b/src/durableorchestrationclient.ts @@ -21,7 +21,7 @@ import { PurgeHistoryResult, Utils, } from "./classes"; -import { StartNewOptions, DurableClientInput } from "./types"; +import { StartNewOptions, DurableClientInput, DurableClient } from "./types"; import { WebhookUtils } from "./webhookutils"; /** @hidden */ @@ -33,7 +33,7 @@ const URL = url.URL; * calls this method. * */ -export function getClient(context: InvocationContext): DurableOrchestrationClient { +export function getClient(context: InvocationContext): DurableClient { const foundInput: FunctionInput | undefined = context.options.extraInputs.find( isDurableClientInput ); @@ -109,11 +109,7 @@ function correctUrls(obj: { [key: string]: string }): { [key: string]: string } * Client for starting, querying, terminating and raising events to * orchestration instances. */ -export class DurableOrchestrationClient { - /** - * The name of the task hub configured on this orchestration client - * instance. - */ +export class DurableOrchestrationClient implements DurableClient { public readonly taskHubName: string; /** @hidden */ public readonly uniqueWebhookOrigins: string[]; @@ -163,20 +159,14 @@ export class DurableOrchestrationClient { this.uniqueWebhookOrigins = this.extractUniqueWebhookOrigins(this.clientData); } - /** - * Creates an HTTP response that is useful for checking the status of the - * specified instance. - * @param request The HTTP request that triggered the current orchestration - * instance. - * @param instanceId The ID of the orchestration instance to check. - * @returns An HTTP 202 response with a Location header and a payload - * containing instance management URLs. - */ public createCheckStatusResponse( request: HttpRequest | undefined, instanceId: string ): HttpResponse { - const httpManagementPayload = this.getClientResponseLinks(request, instanceId); + const httpManagementPayload: HttpManagementPayload = this.getClientResponseLinks( + request, + instanceId + ); return new HttpResponse({ status: 202, @@ -189,23 +179,10 @@ export class DurableOrchestrationClient { }); } - /** - * Creates an [[HttpManagementPayload]] object that contains instance - * management HTTP endpoints. - * @param instanceId The ID of the orchestration instance to check. - */ public createHttpManagementPayload(instanceId: string): HttpManagementPayload { return this.getClientResponseLinks(undefined, instanceId); } - /** - * Gets the status of the specified orchestration instance. - * @param instanceId The ID of the orchestration instance to query. - * @param showHistory Boolean marker for including execution history in the - * response. - * @param showHistoryOutput Boolean marker for including input and output - * in the execution history response. - */ public async getStatus( instanceId: string, showHistory?: boolean, @@ -232,9 +209,6 @@ export class DurableOrchestrationClient { } } - /** - * Gets the status of all orchestration instances. - */ public async getStatusAll(): Promise { const response = await this.getStatusInternal({}); switch (response.status) { @@ -245,16 +219,6 @@ export class DurableOrchestrationClient { } } - /** - * Gets the status of all orchestration instances that match the specified - * conditions. - * @param createdTimeFrom Return orchestration instances which were created - * after this Date. - * @param createdTimeTo Return orchestration instances which were created - * before this DateTime. - * @param runtimeStatus Return orchestration instances which match any of - * the runtimeStatus values in this array. - */ public async getStatusBy( createdTimeFrom: Date | undefined, createdTimeTo: Date | undefined, @@ -275,10 +239,6 @@ export class DurableOrchestrationClient { } } - /** - * Purge the history for a specific orchestration instance. - * @param instanceId The ID of the orchestration instance to purge. - */ public async purgeInstanceHistory(instanceId: string): Promise { let requestUrl: string; if (this.clientData.rpcBaseUrl) { @@ -302,15 +262,6 @@ export class DurableOrchestrationClient { } } - /** - * Purge the orchestration history for instances that match the conditions. - * @param createdTimeFrom Start creation time for querying instances for - * purging. - * @param createdTimeTo End creation time for querying instances for - * purging. - * @param runtimeStatus List of runtime statuses for querying instances for - * purging. Only Completed, Terminated or Failed will be processed. - */ public async purgeInstanceHistoryBy( createdTimeFrom: Date, createdTimeTo?: Date, @@ -379,26 +330,6 @@ export class DurableOrchestrationClient { } } - /** - * Sends an event notification message to a waiting orchestration instance. - * @param instanceId The ID of the orchestration instance that will handle - * the event. - * @param eventName The name of the event. - * @param eventData The JSON-serializable data associated with the event. - * @param taskHubName The TaskHubName of the orchestration that will handle - * the event. - * @param connectionName The name of the connection string associated with - * `taskHubName.` - * @returns A promise that resolves when the event notification message has - * been enqueued. - * - * In order to handle the event, the target orchestration instance must be - * waiting for an event named `eventName` using - * [[waitForExternalEvent]]. - * - * If the specified instance is not found or not running, this operation - * will have no effect. - */ public async raiseEvent( instanceId: string, eventName: string, @@ -455,17 +386,6 @@ export class DurableOrchestrationClient { } } - /** - * Tries to read the current state of an entity. Returnes undefined if the - * entity does not exist, or if the JSON-serialized state of the entity is - * larger than 16KB. - * @param T The JSON-serializable type of the entity. - * @param entityId The target entity. - * @param taskHubName The TaskHubName of the target entity. - * @param connectionName The name of the connection string associated with - * [taskHubName]. - * @returns A response containing the current state of the entity. - */ public async readEntityState( entityId: EntityId, taskHubName?: string, @@ -517,14 +437,6 @@ export class DurableOrchestrationClient { } } - /** - * Rewinds the specified failed orchestration instance with a reason. - * @param instanceId The ID of the orchestration instance to rewind. - * @param reason The reason for rewinding the orchestration instance. - * @returns A promise that resolves when the rewind message is enqueued. - * - * This feature is currently in preview. - */ public async rewind( instanceId: string, reason: string, @@ -574,14 +486,6 @@ export class DurableOrchestrationClient { } } - /** - * Signals an entity to perform an operation. - * @param entityId The target entity. - * @param operationName The name of the operation. - * @param operationContent The content for the operation. - * @param taskHubName The TaskHubName of the target entity. - * @param connectionName The name of the connection string associated with [taskHubName]. - */ public async signalEntity( entityId: EntityId, operationName?: string, @@ -640,16 +544,6 @@ export class DurableOrchestrationClient { } } - /** - * Starts a new instance of the specified orchestrator function. - * - * If an orchestration instance with the specified ID already exists, the - * existing instance will be silently replaced by this new instance. - * @param orchestratorFunctionName The name of the orchestrator function to - * start. - * @param options optional object to control the scheduled orchestrator (e.g provide input, instanceID) - * @returns The ID of the new orchestration instance. - */ public async startNew( orchestratorFunctionName: string, options?: StartNewOptions @@ -684,16 +578,6 @@ export class DurableOrchestrationClient { } } - /** - * Terminates a running orchestration instance. - * @param instanceId The ID of the orchestration instance to terminate. - * @param reason The reason for terminating the orchestration instance. - * @returns A promise that resolves when the terminate message is enqueued. - * - * Terminating an orchestration instance has no effect on any in-flight - * activity function executions or sub-orchestrations that were started - * by the current orchestration instance. - */ public async terminate(instanceId: string, reason: string): Promise { const idPlaceholder = this.clientData.managementUrls.id; let requestUrl: string; @@ -722,22 +606,6 @@ export class DurableOrchestrationClient { } } - /** - * Creates an HTTP response which either contains a payload of management - * URLs for a non-completed instance or contains the payload containing - * the output of the completed orchestration. - * - * If the orchestration does not complete within the specified timeout, - * then the HTTP response will be identical to that of - * [[createCheckStatusResponse]]. - * - * @param request The HTTP request that triggered the current function. - * @param instanceId The unique ID of the instance to check. - * @param timeoutInMilliseconds Total allowed timeout for output from the - * durable function. The default value is 10 seconds. - * @param retryIntervalInMilliseconds The timeout between checks for output - * from the durable function. The default value is 1 second. - */ public async waitForCompletionOrCreateCheckStatusResponse( request: HttpRequest, instanceId: string, diff --git a/src/types/durableClientTypes.ts b/src/types/durableClientTypes.ts index ef38b6d..dcd31ac 100644 --- a/src/types/durableClientTypes.ts +++ b/src/types/durableClientTypes.ts @@ -1,9 +1,226 @@ -import { FunctionInput } from "@azure/functions"; +import { FunctionInput, HttpRequest, HttpResponse } from "@azure/functions"; +import { EntityId, EntityStateResponse, HttpManagementPayload, IHttpResponse } from "../classes"; +import { DurableOrchestrationStatus } from "../durableorchestrationstatus"; +import { IHttpRequest } from "../ihttprequest"; +import { OrchestrationRuntimeStatus } from "../orchestrationruntimestatus"; +import { PurgeHistoryResult } from "../purgehistoryresult"; export interface DurableClientInput extends FunctionInput { type: "durableClient"; } +/** + * Client for starting, querying, terminating and raising events to + * orchestration instances. + */ +export interface DurableClient { + /** + * The name of the task hub configured on this orchestration client + * instance. + */ + readonly taskHubName: string; + + /** + * Creates an HTTP response that is useful for checking the status of the + * specified instance. + * @param request The HTTP request that triggered the current orchestration + * instance. + * @param instanceId The ID of the orchestration instance to check. + * @returns An HTTP 202 response with a Location header and a payload + * containing instance management URLs. + */ + createCheckStatusResponse( + request: IHttpRequest | HttpRequest | undefined, + instanceId: string + ): HttpResponse; + + /** + * Creates an [[HttpManagementPayload]] object that contains instance + * management HTTP endpoints. + * @param instanceId The ID of the orchestration instance to check. + */ + createHttpManagementPayload(instanceId: string): HttpManagementPayload; + + /** + * Gets the status of the specified orchestration instance. + * @param instanceId The ID of the orchestration instance to query. + * @param showHistory Boolean marker for including execution history in the + * response. + * @param showHistoryOutput Boolean marker for including input and output + * in the execution history response. + */ + getStatus( + instanceId: string, + showHistory?: boolean, + showHistoryOutput?: boolean, + showInput?: boolean + ): Promise; + + /** + * Gets the status of all orchestration instances. + */ + getStatusAll(): Promise; + + /** + * Gets the status of all orchestration instances that match the specified + * conditions. + * @param createdTimeFrom Return orchestration instances which were created + * after this Date. + * @param createdTimeTo Return orchestration instances which were created + * before this DateTime. + * @param runtimeStatus Return orchestration instances which match any of + * the runtimeStatus values in this array. + */ + getStatusBy( + createdTimeFrom: Date | undefined, + createdTimeTo: Date | undefined, + runtimeStatus: OrchestrationRuntimeStatus[] + ): Promise; + + /** + * Purge the history for a specific orchestration instance. + * @param instanceId The ID of the orchestration instance to purge. + */ + purgeInstanceHistory(instanceId: string): Promise; + + /** + * Purge the orchestration history for instances that match the conditions. + * @param createdTimeFrom Start creation time for querying instances for + * purging. + * @param createdTimeTo End creation time for querying instances for + * purging. + * @param runtimeStatus List of runtime statuses for querying instances for + * purging. Only Completed, Terminated or Failed will be processed. + */ + purgeInstanceHistoryBy( + createdTimeFrom: Date, + createdTimeTo?: Date, + runtimeStatus?: OrchestrationRuntimeStatus[] + ): Promise; + + /** + * Sends an event notification message to a waiting orchestration instance. + * @param instanceId The ID of the orchestration instance that will handle + * the event. + * @param eventName The name of the event. + * @param eventData The JSON-serializable data associated with the event. + * @param taskHubName The TaskHubName of the orchestration that will handle + * the event. + * @param connectionName The name of the connection string associated with + * `taskHubName.` + * @returns A promise that resolves when the event notification message has + * been enqueued. + * + * In order to handle the event, the target orchestration instance must be + * waiting for an event named `eventName` using + * [[waitForExternalEvent]]. + * + * If the specified instance is not found or not running, this operation + * will have no effect. + */ + raiseEvent( + instanceId: string, + eventName: string, + eventData: unknown, + taskHubName?: string, + connectionName?: string + ): Promise; + + /** + * Tries to read the current state of an entity. Returnes undefined if the + * entity does not exist, or if the JSON-serialized state of the entity is + * larger than 16KB. + * @param T The JSON-serializable type of the entity. + * @param entityId The target entity. + * @param taskHubName The TaskHubName of the target entity. + * @param connectionName The name of the connection string associated with + * [taskHubName]. + * @returns A response containing the current state of the entity. + */ + readEntityState( + entityId: EntityId, + taskHubName?: string, + connectionName?: string + ): Promise>; + + /** + * Rewinds the specified failed orchestration instance with a reason. + * @param instanceId The ID of the orchestration instance to rewind. + * @param reason The reason for rewinding the orchestration instance. + * @returns A promise that resolves when the rewind message is enqueued. + * + * This feature is currently in preview. + */ + rewind( + instanceId: string, + reason: string, + taskHubName?: string, + connectionName?: string + ): Promise; + + /** + * Signals an entity to perform an operation. + * @param entityId The target entity. + * @param operationName The name of the operation. + * @param operationContent The content for the operation. + * @param taskHubName The TaskHubName of the target entity. + * @param connectionName The name of the connection string associated with [taskHubName]. + */ + signalEntity( + entityId: EntityId, + operationName?: string, + operationContent?: unknown, + taskHubName?: string, + connectionName?: string + ): Promise; + + /** + * Starts a new instance of the specified orchestrator function. + * + * If an orchestration instance with the specified ID already exists, the + * existing instance will be silently replaced by this new instance. + * @param orchestratorFunctionName The name of the orchestrator function to + * start. + * @param options optional object to control the scheduled orchestrator (e.g provide input, instanceID) + * @returns The ID of the new orchestration instance. + */ + startNew(orchestratorFunctionName: string, options?: StartNewOptions): Promise; + + /** + * Terminates a running orchestration instance. + * @param instanceId The ID of the orchestration instance to terminate. + * @param reason The reason for terminating the orchestration instance. + * @returns A promise that resolves when the terminate message is enqueued. + * + * Terminating an orchestration instance has no effect on any in-flight + * activity function executions or sub-orchestrations that were started + * by the current orchestration instance. + */ + terminate(instanceId: string, reason: string): Promise; + + /** + * Creates an HTTP response which either contains a payload of management + * URLs for a non-completed instance or contains the payload containing + * the output of the completed orchestration. + * + * If the orchestration does not complete within the specified timeout, + * then the HTTP response will be identical to that of createCheckStatusResponse(). + * + * @param request The HTTP request that triggered the current function. + * @param instanceId The unique ID of the instance to check. + * @param timeoutInMilliseconds Total allowed timeout for output from the + * durable function. The default value is 10 seconds. + * @param retryIntervalInMilliseconds The timeout between checks for output + * from the durable function. The default value is 1 second. + */ + waitForCompletionOrCreateCheckStatusResponse( + request: HttpRequest, + instanceId: string, + timeoutInMilliseconds: number, + retryIntervalInMilliseconds: number + ): Promise; +} + /** * Options object provided as an optional second argument to the `client.startNew()` method */ From a1e2cdd0c30a9dac13d4ae3fa4bdbff37dfac0ff Mon Sep 17 00:00:00 2001 From: hossam-nasr Date: Tue, 7 Feb 2023 18:32:35 -0800 Subject: [PATCH 2/6] convert to class declaration --- src/types/durableClientTypes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/durableClientTypes.ts b/src/types/durableClientTypes.ts index dcd31ac..2f4f001 100644 --- a/src/types/durableClientTypes.ts +++ b/src/types/durableClientTypes.ts @@ -13,7 +13,7 @@ export interface DurableClientInput extends FunctionInput { * Client for starting, querying, terminating and raising events to * orchestration instances. */ -export interface DurableClient { +export declare class DurableClient { /** * The name of the task hub configured on this orchestration client * instance. From fc063349baa6531899e9befc8b0ff876f426267e Mon Sep 17 00:00:00 2001 From: hossam-nasr Date: Tue, 7 Feb 2023 18:40:32 -0800 Subject: [PATCH 3/6] add uniqueWebHookOrigins --- src/types/durableClientTypes.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/types/durableClientTypes.ts b/src/types/durableClientTypes.ts index 2f4f001..a910848 100644 --- a/src/types/durableClientTypes.ts +++ b/src/types/durableClientTypes.ts @@ -20,6 +20,9 @@ export declare class DurableClient { */ readonly taskHubName: string; + /** @hidden */ + public readonly uniqueWebhookOrigins: string[]; + /** * Creates an HTTP response that is useful for checking the status of the * specified instance. From 1f9bafcbd6333182ed66d471a748d33470b2ff38 Mon Sep 17 00:00:00 2001 From: hossam-nasr Date: Wed, 8 Feb 2023 14:57:32 -0800 Subject: [PATCH 4/6] update comment --- src/types/durableClientTypes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/durableClientTypes.ts b/src/types/durableClientTypes.ts index a910848..55ccf08 100644 --- a/src/types/durableClientTypes.ts +++ b/src/types/durableClientTypes.ts @@ -11,7 +11,7 @@ export interface DurableClientInput extends FunctionInput { /** * Client for starting, querying, terminating and raising events to - * orchestration instances. + * orchestration and entity instances. */ export declare class DurableClient { /** From 44814ac222d3c792c9213e5a3799d1e5151f8577 Mon Sep 17 00:00:00 2001 From: hossam-nasr Date: Wed, 8 Feb 2023 15:15:51 -0800 Subject: [PATCH 5/6] add constructor --- src/types/durableClientTypes.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/types/durableClientTypes.ts b/src/types/durableClientTypes.ts index 55ccf08..bf9beb3 100644 --- a/src/types/durableClientTypes.ts +++ b/src/types/durableClientTypes.ts @@ -1,5 +1,11 @@ import { FunctionInput, HttpRequest, HttpResponse } from "@azure/functions"; -import { EntityId, EntityStateResponse, HttpManagementPayload, IHttpResponse } from "../classes"; +import { + EntityId, + EntityStateResponse, + HttpManagementPayload, + IHttpResponse, + OrchestrationClientInputData, +} from "../classes"; import { DurableOrchestrationStatus } from "../durableorchestrationstatus"; import { IHttpRequest } from "../ihttprequest"; import { OrchestrationRuntimeStatus } from "../orchestrationruntimestatus"; @@ -14,6 +20,8 @@ export interface DurableClientInput extends FunctionInput { * orchestration and entity instances. */ export declare class DurableClient { + constructor(clientData: OrchestrationClientInputData); + /** * The name of the task hub configured on this orchestration client * instance. From c028bcf828876fa74312e0f7182bf192c9ad9852 Mon Sep 17 00:00:00 2001 From: hossam-nasr Date: Wed, 8 Feb 2023 15:17:33 -0800 Subject: [PATCH 6/6] fix tests --- src/types/durableClientTypes.ts | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/types/durableClientTypes.ts b/src/types/durableClientTypes.ts index bf9beb3..a5674e7 100644 --- a/src/types/durableClientTypes.ts +++ b/src/types/durableClientTypes.ts @@ -1,15 +1,7 @@ import { FunctionInput, HttpRequest, HttpResponse } from "@azure/functions"; -import { - EntityId, - EntityStateResponse, - HttpManagementPayload, - IHttpResponse, - OrchestrationClientInputData, -} from "../classes"; +import { EntityId, EntityStateResponse, OrchestrationClientInputData } from "../classes"; import { DurableOrchestrationStatus } from "../durableorchestrationstatus"; -import { IHttpRequest } from "../ihttprequest"; import { OrchestrationRuntimeStatus } from "../orchestrationruntimestatus"; -import { PurgeHistoryResult } from "../purgehistoryresult"; export interface DurableClientInput extends FunctionInput { type: "durableClient"; @@ -40,10 +32,7 @@ export declare class DurableClient { * @returns An HTTP 202 response with a Location header and a payload * containing instance management URLs. */ - createCheckStatusResponse( - request: IHttpRequest | HttpRequest | undefined, - instanceId: string - ): HttpResponse; + createCheckStatusResponse(request: HttpRequest | undefined, instanceId: string): HttpResponse; /** * Creates an [[HttpManagementPayload]] object that contains instance @@ -229,7 +218,7 @@ export declare class DurableClient { instanceId: string, timeoutInMilliseconds: number, retryIntervalInMilliseconds: number - ): Promise; + ): Promise; } /**