in src/WebJobs.Extensions.DurableTask/HttpApiHandler.cs [285:453]
public async Task<HttpResponseMessage> HandleRequestAsync(HttpRequestMessage request)
{
try
{
string basePath;
if (this.localHttpListener.IsListening
&& request.RequestUri.IsLoopback
&& request.RequestUri.Port == this.localHttpListener.InternalRpcUri.Port)
{
basePath = this.localHttpListener.InternalRpcUri.AbsolutePath;
}
else
{
basePath = this.GetWebhookUri().AbsolutePath;
}
string path = "/" + WebUtility.UrlDecode(request.RequestUri.AbsolutePath).Substring(basePath.Length).Trim('/');
var routeValues = new RouteValueDictionary();
if (StartOrchestrationRoute.TryMatch(path, routeValues))
{
string functionName = (string)routeValues[FunctionNameRouteParameter];
string instanceId = (string)routeValues[InstanceIdRouteParameter];
if (request.Method == HttpMethod.Post)
{
return await this.HandleStartOrchestratorRequestAsync(request, functionName, instanceId);
}
else
{
return request.CreateResponse(HttpStatusCode.NotFound);
}
}
if (EntityRoute.TryMatch(path, routeValues))
{
try
{
string entityName = (string)routeValues[EntityNameRouteParameter];
string entityKey = (string)routeValues[EntityKeyRouteParameter];
if (request.Method == HttpMethod.Get)
{
if (!string.IsNullOrEmpty(entityKey))
{
EntityId entityId = new EntityId(entityName, entityKey);
return await this.HandleGetEntityRequestAsync(request, entityId);
}
else
{
return await this.HandleListEntitiesRequestAsync(request, entityName);
}
}
else if (request.Method == HttpMethod.Post || request.Method == HttpMethod.Delete)
{
EntityId entityId = new EntityId(entityName, entityKey);
return await this.HandlePostEntityOperationRequestAsync(request, entityId);
}
else
{
return request.CreateResponse(HttpStatusCode.NotFound);
}
}
catch (ArgumentException e)
{
return request.CreateErrorResponse(HttpStatusCode.BadRequest, e.Message);
}
}
if (InstancesRoute.TryMatch(path, routeValues))
{
routeValues.TryGetValue(InstanceIdRouteParameter, out object instanceIdValue);
routeValues.TryGetValue(OperationRouteParameter, out object operationValue);
var instanceId = instanceIdValue as string;
var operation = operationValue as string;
if (instanceId == null)
{
// Retrieve All Status or conditional query in case of the request URL ends e.g. /instances/
if (request.Method == HttpMethod.Get)
{
return await this.HandleGetStatusRequestAsync(request);
}
else if (request.Method == HttpMethod.Delete)
{
return await this.HandleDeleteHistoryWithFiltersRequestAsync(request);
}
else
{
return request.CreateResponse(HttpStatusCode.NotFound);
}
}
else if (instanceId != null && operation == null)
{
if (request.Method == HttpMethod.Get)
{
return await this.HandleGetStatusRequestAsync(request, instanceId);
}
else if (request.Method == HttpMethod.Delete)
{
return await this.HandleDeleteHistoryByIdRequestAsync(request, instanceId);
}
else
{
return request.CreateResponse(HttpStatusCode.NotFound);
}
}
else if (request.Method == HttpMethod.Post)
{
if (string.Equals(operation, TerminateOperation, StringComparison.OrdinalIgnoreCase))
{
return await this.HandleTerminateInstanceRequestAsync(request, instanceId);
}
else if (string.Equals(operation, RewindOperation, StringComparison.OrdinalIgnoreCase))
{
return await this.HandleRewindInstanceRequestAsync(request, instanceId);
}
else if (string.Equals(operation, RestartOperation, StringComparison.OrdinalIgnoreCase))
{
return await this.HandleRestartInstanceRequestAsync(request, instanceId);
}
else if (string.Equals(operation, SuspendOperation, StringComparison.OrdinalIgnoreCase))
{
return await this.HandleSuspendInstanceRequestAsync(request, instanceId);
}
else if (string.Equals(operation, ResumeOperation, StringComparison.OrdinalIgnoreCase))
{
return await this.HandleResumeInstanceRequestAsync(request, instanceId);
}
}
else
{
return request.CreateResponse(HttpStatusCode.NotFound);
}
}
if (InstanceRaiseEventRoute.TryMatch(path, routeValues))
{
string instanceId = (string)routeValues[InstanceIdRouteParameter];
string eventName = (string)routeValues[EventNameRouteParameter];
if (request.Method == HttpMethod.Post)
{
return await this.HandleRaiseEventRequestAsync(request, instanceId, eventName);
}
else
{
return request.CreateResponse(HttpStatusCode.NotFound);
}
}
if (AppLeaseMakePrimaryRoute.TryMatch(path, routeValues))
{
return await this.HandleMakePrimaryRequestAsync(request);
}
return request.CreateResponse(HttpStatusCode.NotFound);
}
/* Some handler methods throw ArgumentExceptions in specialized cases which should be returned to the client, such as when:
* - the function name is not found (starting a new function)
* - the orchestration instance is not in a Failed state (rewinding an orchestration instance)
*/
catch (ArgumentException e)
{
return request.CreateErrorResponse(HttpStatusCode.BadRequest, "One or more of the arguments submitted is incorrect", e);
}
catch (Exception e)
{
return request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Something went wrong while processing your request", e);
}
}