Skip to content

Commit

Permalink
[#152269178] Migrate ComputeVisibleServices to runtime v2 (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
francescopersico authored and cloudify committed Sep 20, 2019
1 parent 843f63b commit 1f4f117
Show file tree
Hide file tree
Showing 19 changed files with 789 additions and 96 deletions.
51 changes: 51 additions & 0 deletions CreateService/__tests__/handler.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* tslint:disable: no-any */
/* tslint:disable: no-big-function */

import * as df from "durable-functions";

import { left, right } from "fp-ts/lib/Either";
import { none } from "fp-ts/lib/Option";

Expand All @@ -10,8 +12,14 @@ import {
aService,
aServicePayload
} from "../../__mocks__/mocks";
import { UpsertServiceEvent } from "../../utils/UpsertServiceEvent";
import { CreateServiceHandler } from "../handler";

beforeEach(() => {
(df.getClient as any).mockClear();
(df as any).mockStartNew.mockClear();
});

describe("CreateServiceHandler", () => {
it("should return a query error if the service fails to be created", async () => {
const mockServiceModel = {
Expand Down Expand Up @@ -72,4 +80,47 @@ describe("CreateServiceHandler", () => {
expect(response.value).toEqual(aSeralizedService);
}
});

it("should start the orchestrator with an appropriate event after the service is created", async () => {
const mockServiceModel = {
create: jest.fn(() => {
return Promise.resolve(right(aRetrievedService));
}),
findOneByServiceId: jest.fn(() => {
return Promise.resolve(right(none));
})
};

const contextMock = {
log: jest.fn()
};

const createServiceHandler = CreateServiceHandler(
undefined as any,
mockServiceModel as any
);

await createServiceHandler(
contextMock as any, // Not used
undefined as any, // Not used
undefined as any, // Not used
undefined as any, // Not used
aServicePayload
);

const upsertServiceEvent = UpsertServiceEvent.encode({
newService: aRetrievedService,
updatedAt: new Date()
});

expect(df.getClient).toHaveBeenCalledTimes(1);

const dfClient = df.getClient(contextMock);
expect(dfClient.startNew).toHaveBeenCalledTimes(1);
expect(dfClient.startNew).toHaveBeenCalledWith(
"UpsertServiceOrchestrator",
undefined,
upsertServiceEvent
);
});
});
5 changes: 5 additions & 0 deletions CreateService/function.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "orchestrationClient",
"direction": "in",
"name": "starter"
}
],
"scriptFile": "../dist/CreateService/index.js"
Expand Down
43 changes: 35 additions & 8 deletions CreateService/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import { Context } from "@azure/functions";

import * as express from "express";

import * as df from "durable-functions";

import { isLeft } from "fp-ts/lib/Either";

import {
IResponseErrorValidation,
IResponseSuccessJson,
ResponseSuccessJson
} from "italia-ts-commons/lib/responses";
Expand Down Expand Up @@ -42,32 +47,54 @@ import {
retrievedServiceToApiService
} from "../utils/conversions";
import { ServicePayloadMiddleware } from "../utils/middlewares/service";
import { UpsertServiceEvent } from "../utils/UpsertServiceEvent";

type ICreateServiceHandler = (
context: Context,
auth: IAzureApiAuthorization,
clientIp: ClientIp,
userAttributes: IAzureUserAttributes,
servicePayload: ApiService
) => Promise<IResponseSuccessJson<ApiService> | IResponseErrorQuery>;
) => Promise<
| IResponseSuccessJson<ApiService>
| IResponseErrorQuery
| IResponseErrorValidation
>;

export function CreateServiceHandler(
_GCTC: CustomTelemetryClientFactory,
serviceModel: ServiceModel
): ICreateServiceHandler {
return async (_, __, ___, ____, servicePayload) => {
return async (context, __, ___, ____, servicePayload) => {
const service = apiServiceToService(servicePayload);
const errorOrCreatedService = await serviceModel.create(
service,
service.serviceId
);
return errorOrCreatedService.fold<
IResponseErrorQuery | IResponseSuccessJson<ApiService>
>(
error => ResponseErrorQuery("CreateServiceHandler error", error),
createdService =>
ResponseSuccessJson(retrievedServiceToApiService(createdService))

if (isLeft(errorOrCreatedService)) {
return ResponseErrorQuery(
"CreateServiceHandler error",
errorOrCreatedService.value
);
}

const createdService = errorOrCreatedService.value;

const upsertServiceEvent = UpsertServiceEvent.encode({
newService: createdService,
updatedAt: new Date()
});

// Start orchestrator
const dfClient = df.getClient(context);
await dfClient.startNew(
"UpsertServiceOrchestrator",
undefined,
upsertServiceEvent
);

return ResponseSuccessJson(retrievedServiceToApiService(createdService));
};
}

Expand Down
58 changes: 58 additions & 0 deletions UpdateService/__tests__/handler.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* tslint:disable: no-any */
/* tslint:disable: no-big-function */

import * as df from "durable-functions";

import { left, right } from "fp-ts/lib/Either";
import { none, some } from "fp-ts/lib/Option";

Expand All @@ -12,8 +14,14 @@ import {
aSeralizedService,
aServicePayload
} from "../../__mocks__/mocks";
import { UpsertServiceEvent } from "../../utils/UpsertServiceEvent";
import { UpdateServiceHandler } from "../handler";

beforeEach(() => {
(df.getClient as any).mockClear();
(df as any).mockStartNew.mockClear();
});

describe("UpdateServiceHandler", () => {
it("should return a validation error and not update the service if the serviceid in the payload is not equal to the serviceid in the path", async () => {
const aServiceId = "DifferentSubscriptionId" as ServiceId;
Expand Down Expand Up @@ -223,4 +231,54 @@ describe("UpdateServiceHandler", () => {
});
}
});

it("should start the orchestrator with an appropriate event after the service is updated", async () => {
const aDepartmentName = "UpdateDept" as NonEmptyString;
const serviceModelMock = {
findOneByServiceId: jest.fn(() => {
return Promise.resolve(right(some(aRetrievedService)));
}),
update: jest.fn((_, __, f) => {
const updatedService = f(aRetrievedService);
return Promise.resolve(right(some(updatedService)));
})
};

const contextMock = {
log: jest.fn()
};

const updateServiceHandler = UpdateServiceHandler(
undefined as any,
serviceModelMock as any
);

await updateServiceHandler(
contextMock as any, // Not used
undefined as any, // Not used
undefined as any, // Not used
undefined as any, // Not used
aServicePayload.service_id,
{
...aServicePayload,
department_name: aDepartmentName
}
);

const upsertServiceEvent = UpsertServiceEvent.encode({
newService: { ...aRetrievedService, departmentName: aDepartmentName },
oldService: aRetrievedService,
updatedAt: new Date()
});

expect(df.getClient).toHaveBeenCalledTimes(1);

const dfClient = df.getClient(contextMock);
expect(dfClient.startNew).toHaveBeenCalledTimes(1);
expect(dfClient.startNew).toHaveBeenCalledWith(
"UpsertServiceOrchestrator",
undefined,
upsertServiceEvent
);
});
});
5 changes: 5 additions & 0 deletions UpdateService/function.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "orchestrationClient",
"direction": "in",
"name": "starter"
}
],
"scriptFile": "../dist/UpdateService/index.js"
Expand Down
23 changes: 20 additions & 3 deletions UpdateService/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Context } from "@azure/functions";

import * as express from "express";

import * as df from "durable-functions";

import { isLeft } from "fp-ts/lib/Either";
import { isNone } from "fp-ts/lib/Option";

Expand Down Expand Up @@ -53,6 +55,7 @@ import {
} from "../utils/conversions";
import { ServicePayloadMiddleware } from "../utils/middlewares/service";
import { ServiceIdMiddleware } from "../utils/middlewares/serviceid";
import { UpsertServiceEvent } from "../utils/UpsertServiceEvent";

type IUpdateServiceHandler = (
context: Context,
Expand All @@ -74,7 +77,7 @@ export function UpdateServiceHandler(
_GCTC: CustomTelemetryClientFactory,
serviceModel: ServiceModel
): IUpdateServiceHandler {
return async (_, __, ___, ____, serviceId, servicePayload) => {
return async (context, __, ___, ____, serviceId, servicePayload) => {
if (servicePayload.service_id !== serviceId) {
return ResponseErrorValidation(
"Error validating payload",
Expand Down Expand Up @@ -127,9 +130,23 @@ export function UpdateServiceHandler(
return ResponseErrorInternal("Error while updating the existing service");
}

return ResponseSuccessJson(
retrievedServiceToApiService(maybeUpdatedService.value)
const updatedService = maybeUpdatedService.value;

const upsertServiceEvent = UpsertServiceEvent.encode({
newService: updatedService,
oldService: existingService,
updatedAt: new Date()
});

// Start orchestrator
const dfClient = df.getClient(context);
await dfClient.startNew(
"UpsertServiceOrchestrator",
undefined,
upsertServiceEvent
);

return ResponseSuccessJson(retrievedServiceToApiService(updatedService));
};
}

Expand Down
10 changes: 10 additions & 0 deletions UpdateVisibleServicesActivity/function.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"bindings": [
{
"name": "name",
"type": "activityTrigger",
"direction": "in"
}
],
"scriptFile": "../dist/UpdateVisibleServicesActivity/index.js"
}
Loading

0 comments on commit 1f4f117

Please sign in to comment.