<|start_filename|>src/customers/customersController.js<|end_filename|>
const customersModel = require('./customersModel.js');

const customersController = {};
const path = require('path');

customersController.createCustomer = async (customer) => {
  return await customersModel.create(customer)
    .then((response) => response)
    .catch((error) => {
      console.log('ERROR from createCustomer controller : ', error);
      return 'error';
    })
};

customersController.deleteCustomer = async (custId) => {
  return await customersModel.findOneAndDelete(custId)
    .then((response) => response)
    .catch((error) => {
      console.log('ERROR from deleteCustomer controller : ', error);
      return 'error';
    })
};

customersController.getCustomer = async (custId) => {
  return await customersModel.findOne(custId)
    .catch((error) => {
      console.log('ERROR from getCustomer controller : ', error)
      return 'error';
    })
}

module.exports = customersController;


<|start_filename|>src/MockFrontEnd/server/routes/customersRouter.js<|end_filename|>
const express = require('express');
const customersClient = require('../../../customers/customersClient.js');

const customersRouter = express.Router();

customersRouter.post('/', customersClient.createCustomer, (req, res) => {
    return res.status(200).json(res.locals.customers)
});

customersRouter.get('/:custId', customersClient.getCustomer, (req, res) => {
    return res.status(200).json(res.locals.customers)
});

customersRouter.delete('/:custId', customersClient.deleteCustomer, (req, res) => {
    return res.status(200);
});

module.exports = customersRouter;


<|start_filename|>src/MockFrontEnd/server/routes/booksRouter.js<|end_filename|>
const express = require('express');
const booksClient = require('../../../books/booksClient.js');

const booksRouter = express.Router();

booksRouter.post('/', booksClient.createBook, (req, res) => {
    return res.status(200).json(res.locals.book)
});

booksRouter.get('/', booksClient.getBooks, (req, res) => {
    return res.status(200).json(res.locals.books)
});

booksRouter.delete('/:bookId', booksClient.deleteBook, (req, res) => {
    return res.status(200);
});

module.exports = booksRouter;


<|start_filename|>src/books/booksServer.js<|end_filename|>
const path = require('path');
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');
const HorusServerWrapper = require('@horustracer/serverwrapper');
const controller = require('./booksController.js');

const PROTO_PATH = path.join(__dirname, '../protos/books.proto');

const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
  keepCase: true,
  longs: String,
  enums: String,
  arrays: true,
});

const booksProto = grpc.loadPackageDefinition(packageDefinition);

const server = new grpc.Server();

// The Horus Server Wrapper "wraps" each server method passed in
// Replace server.addService({ .. methods}) with Const ServerWrapper = new HorusServerWrapper (serverObject, service, {..methods})
// Your preexisting methods can remain entirely the same
const ServerWrapper = new HorusServerWrapper(
  server,
  booksProto.BooksService.service,
  {
    CreateBook: async (call, callback) => {
      const result = await controller.createBook(call.request);

      if (result === 'error') {
        return callback({
          code: grpc.status.STATUS_UNKNOWN,
          message: 'There was an error writing to the database',
        });
      }

      callback(null, {
        title: result.title,
        author: result.author,
        numberOfPages: result.numberOfPages,
        publisher: result.publisher,
        bookId: result.bookId,
      });
    },
    DeleteBook: async (call, callback) => {
      const result = await controller.deleteBook(call.request);

      if (result === 'error') {
        return callback({
          code: grpc.status.STATUS_UNKNOWN,
          message: 'There was an error deleting from the database',
        });
      }

      callback(null, {});
    },
    GetBooks: async (call, callback) => {
      const result = await controller.getBooks();

      callback(null, { books: result });
    },
    GetBookByID: async (call, callback) => {
      const result = await controller.getBookByID(call.request, callback);
      if (result === 'error') {
        return callback({
          code: grpc.status.STATUS_UNKNOWN,
          message: 'There was an error reading from the database',
        });
      }
      callback(null, {
        title: result.title,
        author: result.author,
        numberOfPages: result.numberOfPages,
        publisher: result.publisher,
        bookId: result.bookId,
      });
    },
  },
);

server.bind('127.0.0.1:30043', grpc.ServerCredentials.createInsecure());
console.log('booksServer.js running at http://127.0.0.1:30043');

console.log('call from books server');

server.start();


<|start_filename|>src/stubs/customersStub.js<|end_filename|>
const path = require('path');
const grpc = require('grpc');
require('dotenv').config();
const protoLoader = require('@grpc/proto-loader');

const HorusClientWrapper = require('@horustracer/clientwrapper');

const PROTO_PATH = path.join(__dirname, '../protos/customers.proto');

const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
  keepCase: true,
  longs: String,
  enums: String,
  arrays: true,
});

const CustomersService = grpc.loadPackageDefinition(packageDefinition)
  .CustomersService;

const client = new CustomersService(
  'localhost:40043',
  grpc.credentials.createInsecure(),
);

// The Client Wrapper "wraps" all the methods within the client object
// The first parameter is the actual gRPC client object, the second is the service, and the third is the output file
// Your invocations of the client at whenever you export this module to can remain entirely the same
const ClientWrapper = new HorusClientWrapper(
  client,
  CustomersService,
  'customers.txt',
  'main',
  `${process.env.HORUS_DB}`,
  `${process.env.SLACK_URL}`,
);

// Export the Client Wrapper rather than the server object
module.exports = ClientWrapper;


<|start_filename|>src/customers/customersServer.js<|end_filename|>
const path = require('path');
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');
const HorusServerWrapper = require('@horustracer/serverwrapper');
const controller = require('./customersController.js');

const booksStub = require(path.join(__dirname, '../stubs/booksStub.js'));

const PROTO_PATH = path.join(__dirname, '../protos/customers.proto');
const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
  keepCase: true,
  longs: String,
  enums: String,
  arrays: true,
});
const customersProto = grpc.loadPackageDefinition(packageDefinition);

const server = new grpc.Server();

function GetBookIdAsPromise(bookId, server) {
  return new Promise((resolve, reject) => {
    booksStub.GetBookByID(bookId, (error, response) => {
      if (error) resolve('error');
      booksStub.makeHandShakeWithServer(server, 'GetBookByID');
      resolve({ book: response });
    });
  });
}

// The Horus Server Wrapper "wraps" each server method passed in
// Replace server.addService({ .. methods}) with Const ServerWrapper = new HorusServerWrapper (serverObject, service, {..methods})
// Your preexisting methods can remain entirely the same

const ServerWrapper = new HorusServerWrapper(
  server,
  customersProto.CustomersService.service,
  {
    CreateCustomer: async (call, callback) => {
      const result = await controller.createCustomer(call.request);

      if (result === 'error') {
        return callback({
          code: grpc.status.STATUS_UNKNOWN,
          message: 'There was an error writing to the database',
        });
      }
      callback(null, {
        custId: result.custId,
        name: result.name,
        age: result.age,
        address: result.address,
        favBookId: result.favBookId,
      });
    },
    DeleteCustomer: async (call, callback) => {
      const result = await controller.deleteCustomer(call.request.custId);

      if (result === 'error') {
        return callback({
          code: grpc.status.STATUS_UNKNOWN,
          message: 'There was an error deleting from the database',
        });
      }
      callback(null, {});
    },
    GetCustomer: async (call, callback) => {
      const customer = await controller.getCustomer(call.request);
      if (customer === 'error') {
        return callback({
          code: grpc.status.STATUS_UNKNOWN,
          message: 'There was an error querying the database',
        });
      }

      const responseFromGetBookById = await GetBookIdAsPromise(
        { bookId: customer.favBookId },
        ServerWrapper,
      );

      if (responseFromGetBookById === 'error') {
        return callback({
          code: grpc.status.STATUS_UNKNOWN,
          message: 'There was an error making an intraservice request to books',
        });
      }

      const customerWithFavBook = {};
      customerWithFavBook.custId = customer.custId;
      customerWithFavBook.name = customer.name;
      customerWithFavBook.age = customer.age;
      customerWithFavBook.address = customer.address;
      customerWithFavBook.favBook = responseFromGetBookById.book;
      callback(null, customerWithFavBook);
    },
  },
);

server.bind('127.0.0.1:40043', grpc.ServerCredentials.createInsecure());
console.log('customerServer.js running at http://127.0.0.1:40043');
console.log('call from customer server');

server.start();


<|start_filename|>src/MockFrontEnd/server/server.js<|end_filename|>
/* Because HTTP2 is not compatible with browsers, an express proxy server is required to translate the gRPC requests and responses. */

const path = require('path');
const express = require('express');

const app = express();
const customersRouter = require('./routes/customersRouter.js');
const booksRouter = require('./routes/booksRouter.js');

app.use(express.json());

app.use('/customers', customersRouter);

app.use('/books', booksRouter);

app.use('/build', express.static(path.join(__dirname, '../../build')));

app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, '../index.html'));
});

app.use((req, res) => {
  console.log('Unknown route. Try another route.');
  return res.status(404);
});

app.listen(3000, () => console.log('Listening on port 3000'));


<|start_filename|>src/books/booksController.js<|end_filename|>
const booksModel = require('./booksModel.js');

const booksController = {};

booksController.createBook = async (book) => {
  return await booksModel
    .create(book)
    .then((response) => response)
    .catch((error) => {
      console.log('ERROR from createBook controller : ', error);
      return "error";
    });
};

booksController.deleteBook = async (bookId) => {
  return await booksModel
    .findOneAndDelete(bookId)
    .then((response) => response)
    .catch((error) => {
      console.log('ERROR from deleteBook controller : ', error);
      return 'error';
    });
};

booksController.getBookByID = async (bookId, callback) => {
  return await booksModel
    .findOne(bookId)
    .then((response) => response)
    .catch((error) => {
      console.log('ERROR from getBookbyID controller : ', error);
      return 'error';
    });
};

booksController.getBooks = async () => {
  return await booksModel
    .find({})
    .then((response) => {
      let arr = [];
      for (let i = 0; i < response.length; i++) {
        arr.push({
          title: response[i].title,
          author: response[i].author,
          numberOfPages: response[i].numberOfPages,
          publisher: response[i].publisher,
          bookId: response[i].bookId,
        });
      }
      return arr;
    })
    .catch((error) => {
      console.log('ERROR from the getBooks controller : ', error);
    });
};

module.exports = booksController;


<|start_filename|>src/customers/customersClient.js<|end_filename|>
//client.js files are a way for us to use these functions without using the browser on the front end.
const customersClient = {};
const { resolve } = require('path');

const customerStub = require('../stubs/customersStub.js');

customersClient.createCustomer = (req, res, next) => {
  const customer = {
    custId: req.body.custId,
    name: req.body.name,
    age: req.body.age,
    address: req.body.address,
    favBookId: req.body.favBookId
  };

  const callback = (error, data) => {
    res.locals.customers = data;
    if (error) console.log('sorry, there was an error', error);
    return next();
  };
  customerStub.CreateCustomer(customer, callback);
};

customersClient.getCustomer = (req, res, next) => {
  custId = { custId: req.params.custId };
  const callback = (error, data) => {
    res.locals.customers = data;
    if (error) console.log('sorry, there was in error: ', error);
    return next();
  };
  customerStub.GetCustomer(custId, callback);
};

customersClient.deleteCustomer = (req, res, next) => {
  custId = { custId: req.params.custId };
  const callback = (error, data) => {
    if (error) console.log('sorry, there was an error', error);
    return next();
  };
  customerStub.DeleteCustomer(custId, callback);
};

module.exports = customersClient;


<|start_filename|>horusVisualizerScript.js<|end_filename|>
const HorusVisualizer = require('@horustracer/visualizer');

require('dotenv').config();

HorusVisualizer.mapAveragesToNeo4jBrowser(process.env.HORUS_DB, 'bolt://localhost:11002', 'neo4j', 'password');


<|start_filename|>src/stubs/booksStub.js<|end_filename|>
const path = require('path');
const grpc = require('grpc');
require('dotenv').config();
const protoLoader = require('@grpc/proto-loader');

const HorusClientWrapper = require('@horustracer/clientwrapper');

const PROTO_PATH = path.join(__dirname, '../protos/books.proto');

const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
  keepCase: true,
  longs: String,
  enums: String,
  arrays: true,
});

const BooksService = grpc.loadPackageDefinition(packageDefinition).BooksService;

const client = new BooksService(
  'localhost:30043',
  grpc.credentials.createInsecure(),
);

// The Client Wrapper "wraps" all the methods within the client object
// The first parameter is the actual gRPC client object, the second is the service, and the third is the output file
// Your invocations of the client at whenever you export this module to can remain entirely the same

const ClientWrapper = new HorusClientWrapper(client, BooksService, 'books.txt', 'main', `${process.env.HORUS_DB}`, `${process.env.SLACK_URL}`);

// Export the Client Wrapper rather than the server object
module.exports = ClientWrapper;


<|start_filename|>src/books/booksClient.js<|end_filename|>
const bookStub = require('../stubs/booksStub.js');

const booksClient = {};

booksClient.createBook = (req, res, next) => {
  const book = {
    title: req.body.title, 
    author: req.body.author,
    numberOfPages: req.body.numberOfPages,
    publisher: req.body.publisher,
    bookId: req.body.bookId,
  };
  const callback = (error, data) => {
    res.locals.book = data;
    if (error) console.log('sorry, there was an error', error);
    return next();
  };
  bookStub.CreateBook(book, callback);
};

booksClient.getBooks = (req, res, next) => {
  const callback = (error, data) => {
    res.locals.books = data;
    if (error) console.log('sorry, there was an error', error);
    return next();
  };
  bookStub.GetBooks({}, callback);
};

booksClient.deleteBook = (req, res, next) => {
  bookId = { bookId: req.params.bookId };
  const callback = (error, data) => {
    if (error) console.log('sorry, there was an error', error);
    return next();
  };
  bookStub.DeleteBook(bookId, callback);
};

module.exports = booksClient;
