Skip to content

Commit 73fefce

Browse files
author
Gutierrez, Andres
committed
Add GRPC integration to simulation services
1 parent 6721a45 commit 73fefce

File tree

10 files changed

+6205
-5087
lines changed

10 files changed

+6205
-5087
lines changed

.env

+20-17
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
# GQL SETTINGS
2-
GQL_PORT=4000
3-
4-
# REST RESOURCES
5-
BASE_BACKEND_URL=http://localhost:5000/api/v1
6-
7-
# DATABASE
8-
MONGO_URL=mongodb://localhost:27017
9-
MONGO_DB=MOCK
10-
COLLECTION_RESPONSE=responses
11-
COLLECTION_API=apis
12-
COLLECTION_DEVICE=devices
13-
14-
# Docker
15-
IMAGE_NAME=mock-gql
16-
CONTAINER_NAME=mock-gql-container
17-
1+
# GQL SETTINGS
2+
GQL_PORT=4000
3+
4+
# REST RESOURCES
5+
BASE_BACKEND_URL=http://localhost:5000/api/v1
6+
7+
# DATABASE
8+
MONGO_URL=mongodb://localhost:27017
9+
MONGO_DB=MOCK
10+
COLLECTION_RESPONSE=responses
11+
COLLECTION_API=apis
12+
COLLECTION_DEVICE=devices
13+
14+
# Docker
15+
IMAGE_NAME=mock-gql
16+
CONTAINER_NAME=mock-gql-container
17+
18+
# Protocol Buffers
19+
PROTOCOL_BUFFER_SERVER=localhost:5001
20+

package-lock.json

+5,528-5,027
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
},
2020
"homepage": "https://github.com/andru1236/mock-gateway#readme",
2121
"dependencies": {
22+
"@grpc/proto-loader": "^0.6.1",
2223
"apollo-server": "^2.21.1",
2324
"apollo-server-express": "^2.21.1",
2425
"body-parser": "^1.19.0",
@@ -30,6 +31,7 @@
3031
"graphql-tag": "^2.11.0",
3132
"graphql-tools": "^7.0.4",
3233
"graphql-type-json": "^0.3.2",
34+
"grpc": "^1.24.3",
3335
"mongodb": "^3.6.5",
3436
"node-fetch": "^2.6.1",
3537
"winston": "^3.3.3",

src/infrastructure/errors/customErrors.js

+7
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,18 @@ class GatewayError extends ApolloError {
3636
}
3737
}
3838

39+
class SimulatorError extends Error {
40+
constructor(message) {
41+
super(message, "SIMULATOR_ERRORS")
42+
}
43+
}
44+
3945
export const errors = {
4046
DatabaseError,
4147
ResponseError,
4248
NoFoundError,
4349
LegacyErrorSystem,
4450
LegacyBadRequestError,
4551
GatewayError,
52+
SimulatorError
4653
};

src/infrastructure/errors/errorHandler.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import { ApolloError } from "apollo-server-errors";
12
import { errors } from "./customErrors";
23
import { logger } from "../logger";
34

5+
// TODO: Segregate the error handler based on the architecture layer
46
export const errorHandler = (error) => {
57
logger.error(error.message);
68
if (error instanceof errors.DatabaseError) {
@@ -21,9 +23,12 @@ export const errorHandler = (error) => {
2123
if (error instanceof errors.LegacyErrorSystem) {
2224
throw new error.GatewayError(error.message);
2325
}
26+
if (error instanceof errors.SimulatorError) {
27+
return false;
28+
}
2429
if (error instanceof Error) {
2530
logger.error(`Critical ${error.message}`);
26-
throw error;
31+
throw new ApolloError(error.message, "ERROR_APOLLO");
2732
}
2833
};
2934

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import grpc from "grpc";
2+
import protoLoader from "@grpc/proto-loader";
3+
import { logger } from "../logger";
4+
5+
// The file is generated for the backend, this client just should copy the proto and build it
6+
const PROTO_PATH = `${process.cwd()}/src/infrastructure/protocol_buffer/protos/simulator_services.proto`;
7+
logger.info(`loading file: ${PROTO_PATH}`);
8+
9+
const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
10+
keepCase: true,
11+
longs: String,
12+
enums: String,
13+
defaults: true,
14+
oneofs: true,
15+
});
16+
logger.info(`The gRPC client classes was created successfull`);
17+
18+
export const grpc_services = grpc.loadPackageDefinition(packageDefinition);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
syntax = "proto3";
2+
3+
4+
message EntityId {
5+
string id = 1;
6+
}
7+
8+
message DbAgent {
9+
string dbAgent=1;
10+
}
11+
12+
13+
message Response {
14+
bool sucessfull = 1;
15+
string message = 2;
16+
}
17+
18+
service Simulator {
19+
rpc startDeviceSimulation(EntityId) returns (Response);
20+
rpc stopDeviceSimulation(EntityId) returns (Response);
21+
rpc fixDbAgent(DbAgent) returns (DbAgent);
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import grpc from "grpc";
2+
import readEnv from "../readEnv";
3+
import { grpc_services } from "./client_grpc";
4+
import { logger } from "../logger";
5+
6+
readEnv();
7+
8+
const PROTOCOL_BUFFER_SERVER = process.env.PROTOCOL_BUFFER_SERVER;
9+
10+
export const client_for_simulator = new grpc_services.Simulator(
11+
PROTOCOL_BUFFER_SERVER,
12+
grpc.credentials.createInsecure()
13+
);
14+
15+
export const grpcStartSimulation = (id) => {
16+
return new Promise((resolve, reject) => {
17+
client_for_simulator.startDeviceSimulation({ id }, (err, grpcResponse) => {
18+
if (err) {
19+
logger.error("Problems to start simulation");
20+
resolve(false);
21+
}
22+
logger.debug(`Response: ${JSON.stringify(grpcResponse)}`);
23+
return grpcResponse?.sucessfull
24+
? resolve(grpcResponse.sucessfull)
25+
: resolve(false);
26+
});
27+
});
28+
};
29+
30+
export const grpcStopSimulation = async (id) => {
31+
return new Promise((resolve, reject) => {
32+
client_for_simulator.stopDeviceSimulation({ id }, (err, grpcResponse) => {
33+
if (err) {
34+
logger.error("Problems to stop simulation");
35+
resolve(false);
36+
}
37+
logger.debug(`Response: ${JSON.stringify(grpcResponse)}`);
38+
return grpcResponse?.sucessfull
39+
? resolve(grpcResponse.sucessfull)
40+
: resolve(false);
41+
});
42+
});
43+
};
44+
45+
export const grpcFixDbAgent = async (dbAgent) => {
46+
return new Promise((resolve, reject) => {
47+
client_for_simulator.fixDbAgent({ dbAgent }, (error, response) => {
48+
if (error) {
49+
logger.error("Problems to fix the db Agent simulation");
50+
reject(dbAgent);
51+
}
52+
logger.debug(`No errors`);
53+
response?.dbAgent ? resolve(response.dbAgent): reject(dbAgent);
54+
});
55+
});
56+
};

src/resolvers/device/mutations.js

+56-32
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,56 @@
1-
import { logger } from "../../infrastructure";
2-
import dal from "./dal";
3-
4-
const createDevice = async (_, args) => {
5-
logger.info("Executing MUTATION| createDevice");
6-
const { name, port, agentDb } = args;
7-
await dal.saveDevice(name, port, agentDb);
8-
return true;
9-
};
10-
11-
const updateDevice = async (_, args, { loaders }) => {
12-
logger.info("Executing MUTATION| UpdateDevice");
13-
const { deviceId, name, port, agentDb } = args;
14-
await dal.updateDevice(deviceId, name, port, agentDb);
15-
const deviceObj = await dal.searchOneDevice(deviceId);
16-
await loaders.devices.prime(deviceId, deviceObj[0]);
17-
return true;
18-
};
19-
20-
const removeDevice = async (_, args, { loaders }) => {
21-
logger.info("Executing MUTATION| removeDevice");
22-
const { deviceId } = args;
23-
await dal.removeDevice(deviceId);
24-
await loaders.devices.clear(deviceId);
25-
return true;
26-
};
27-
28-
export default {
29-
createDevice,
30-
updateDevice,
31-
removeDevice,
32-
};
1+
import {
2+
grpcStopSimulation,
3+
grpcStartSimulation,
4+
grpcFixDbAgent,
5+
} from "../../infrastructure/protocol_buffer/simulator_client";
6+
7+
import { logger } from "../../infrastructure";
8+
import dal from "./dal";
9+
10+
const createDevice = async (_, args) => {
11+
logger.info("Executing MUTATION| createDevice");
12+
const { name, port, agentDb } = args;
13+
await dal.saveDevice(name, port, agentDb);
14+
return true;
15+
};
16+
17+
const updateDevice = async (_, args, { loaders }) => {
18+
logger.info("Executing MUTATION| UpdateDevice");
19+
const { deviceId, name, port, agentDb } = args;
20+
await dal.updateDevice(deviceId, name, port, agentDb);
21+
const deviceObj = await dal.searchOneDevice(deviceId);
22+
await loaders.devices.prime(deviceId, deviceObj[0]);
23+
return true;
24+
};
25+
26+
const removeDevice = async (_, args, { loaders }) => {
27+
logger.info("Executing MUTATION| removeDevice");
28+
const { deviceId } = args;
29+
await dal.removeDevice(deviceId);
30+
await loaders.devices.clear(deviceId);
31+
return true;
32+
};
33+
34+
const startSimulation = async (_, { deviceId }) => {
35+
logger.info("Executing MUTATION| startSimulation");
36+
return await grpcStartSimulation(deviceId);
37+
};
38+
39+
const stopSimulation = async (_, { deviceId }) => {
40+
logger.info("Executing MUTATION| stopSimulation");
41+
return await grpcStopSimulation(deviceId);
42+
};
43+
44+
const fixAgentDb = async (_, { agentDb }) => {
45+
logger.info("Executing MUTATION| fixAgent");
46+
return await grpcFixDbAgent(agentDb);
47+
};
48+
49+
export default {
50+
createDevice,
51+
updateDevice,
52+
removeDevice,
53+
startSimulation,
54+
stopSimulation,
55+
fixAgentDb,
56+
};

0 commit comments

Comments
 (0)