Source: models/services_inbound.js

var fork = require('child_process').fork;


class services_inbound {

  constructor(loggerInstance) {
    // always initialize all instance properties
    this.logIdentifier = "Inbound Service Worker";
    this._logger = loggerInstance;
  }

  serviceStatusRefresh(store) {
    // First refresh list of active services from database
    this.getListOfActiveServicesInbound('','', (req, res, servicesResult) => {
      if (store.length > 0) {
        this._logger.info(this.logIdentifier + ' | Service health check started for ' + store.length + ' active services');
        store.forEach(service => {
          service.send('healthcheck');
        });
      } else {
        this._logger.info(this.logIdentifier + ' | Service health check ignored as no inbound service active');
      }
      if (store.length != servicesResult.length) {
        // database state of services differs from active services
        // TODO
        this._logger.info(this.logIdentifier + ' | Identified change of configured active services - TODO');
      }
    });
  }

  stopInboundServices(store, callback) {
    this._logger.info(this.logIdentifier + ' | Stopping inbound services');
    store.forEach(service => {
      this._logger.info(this.logIdentifier + ' | Sending stop command to process with pId' + service.pId);
      service.send('stop');
    });
  }


  /**
   * Function reads list of active Inbound services (table services_inbound_store with ibSvcState = 1) and starts them as a forked proccess
   *
   * @param {*} callback Callbackfunction
   * @memberof services_inbound
   */
  startUpInboundServices(callback) {
    let processList = [];
    this._logger.info(this.logIdentifier + ' | Starting inbound services');
    this.getListOfActiveServicesInbound('','', (req, res, servicesResult) => {
      servicesResult.forEach(service => {
        this._logger.info(this.logIdentifier + ' | Starting inbound service ' + service.servicename + ' with svcInstanceID ' + service.id);
          // Fork process    
          // hand over tree parameters to forked process
          // Param1 - servicename
          // Param2 - organization ID 
          // Param3 - id from database of service instance (needed to read instance configuration)
          let cp = fork('./modules/services/inbound/' + service.servicename + '/service.js', [service.servicename, service.ibSvcOrganizationId, service.id]);
          this._logger.info(this.logIdentifier + ' | Started fork process with pid: ', cp.pid);
          

          // if Process ends -> write to console
          cp.on('close', function(code) {
              console.log('Process with id ' + cp.pId + ' has ended with code: '+ code);
              this._logger.warn(this.logIdentifier + ' | child process has ended');
              cp.kill();
          })

          // if process sends message -> write to console
          cp.on('message', (m) => {
              //this._logger.info(`${this.logIdentifier} | ${m}`);
              let messageFromService = JSON.parse(m.trim());
              this._logger.info(this.logIdentifier + ' | service with pid ' + cp.pid + ' has reported state ' + messageFromService['state']);
          });

          cp.on('error', function (err) {
            console.log('ERROR: ' + err.message);
            //this._logger.error(this.logIdentifier + ' | with service ' + cp.pid);
          });

          // Push spawned process to process-array
          processList.push(cp);
      });
      return callback(processList);
    })
  }

  setLiveStateOfServiceInbound(servicename, livestate, callback) {
    let query = "UPDATE services_inbound SET livestate = " + livestate + " WHERE servicename = '" + servicename;
    db.query(query, (errServices, resultServices) => {
      if (errServices) {
          // Errror loading Services Inbound
          this._logger.error(this.logIdentifier + ' | Error setting livestate of service ' + servicename + ' to ' + livestate);
          return null;
      } else {
          this._logger.info(this.logIdentifier + ' | Set livestate for service ' + servicename + ' to ' + livestate);
          return callback(req, res, resultServices);
      }
    });
  }

  getListOfServicesInbound(req, res, callback) {
      this._logger.info(this.logIdentifier + ' | Reading Inbound Services');
      let query = "SELECT * FROM `services_inbound`";
      db.query(query, (errServices, resultServices) => {
          if (errServices) {
              // Errror loading Services Inbound
              this._logger.error(this.logIdentifier + ' | Error loading inbound services');
              return null;
          } else {
              this._logger.info(this.logIdentifier + '| Read ' + resultServices.length + ' inbound services');
              return callback(req, res, resultServices);
          }
      });
  }

  setServiceInboundInstanceState(serviceId, state, req, res, callback) {
    this._logger.info(this.logIdentifier + ' | Setting State of service instance ' + serviceId + ' to state ' + state);
    let query = "UPDATE services_inbound_store SET ibSvcState = " + state + " WHERE id = " + serviceId;
    db.query(query, (errServices, resultServices) => {
        if (errServices) {
            this._logger.error(this.logIdentifier + ' | Error setting state of inbound services instance ' + serviceId);
            return null;
        } else {
            this._logger.info(this.logIdentifier + '| Set state of service instance ' + serviceId + ' successfully to ' + state);
            return callback(req, res, resultServices);
        }
    });
  }
  
  getListOfServicesInstancesInbound(req, res, callback) {
    this._logger.info(this.logIdentifier + ' | Reading Inbound Service Instances');
    let query = "SELECT services_inbound_store.*, " +
                        "services_inbound.id AS svcId, " +
                        "services_inbound.servicename AS servicename, " +
                        "services_inbound.servicetitle AS servicetitle " +
                  "FROM `services_inbound_store`  " +
                  "INNER JOIN services_inbound ON " +
                        "services_inbound_store.ibSvcId = services_inbound.id ";
    db.query(query, (errServices, resultServices) => {
        if (errServices) {
            // Errror loading Services Inbound
            this._logger.error(this.logIdentifier + ' | Error loading inbound services instances');
            return null;
        } else {
            this._logger.info(this.logIdentifier + '| Read ' + resultServices.length + ' inbound service instances');
            return callback(req, res, resultServices);
        }
    });
  }


  getListOfActiveServicesInbound(req, res, callback) {
    this._logger.info(this.logIdentifier + ' | Reading only active Inbound Services');
    let query = "SELECT services_inbound_store.*, " +
                        "services_inbound.id AS svcId, " +
                        "services_inbound.servicename AS servicename, " +
                        "services_inbound.servicetitle AS servicetitle " +
                  "FROM `services_inbound_store`  " +
                  "INNER JOIN services_inbound ON " +
                        "services_inbound_store.ibSvcId = services_inbound.id " +
                  "WHERE  " +
                        "services_inbound_store.ibSvcState = 1 " +
                        "AND services_inbound.state = 1";
    db.query(query, (errServices, resultServices) => {
        if (errServices) {
            // Errror loading Services Inbound
            this._logger.error(this.logIdentifier + ' | Error loading active inbound services');
            return null;
        } else {
            this._logger.info(this.logIdentifier + ' | Read ' + resultServices.length + ' active inbound services');
            return callback(req, res, resultServices);
        }
    });
}


  startServiceInbound(req, res, serviceId, callback) {
    // Setting Service to active in database and then start the inbound service
    let query = "UPDATE services_inbound SET state = 1 WHERE id = " + serviceId;
    db.query(query, (errServices, resultServices) => {
      if (errServices) {
          // Errror loading Services Inbound
          this._logger.error(this.logIdentifier + ' | Error setting inbound service state in database');
          return null;
      } else {
          this._logger.info(this.logIdentifier + ' | Set inbound service with id ' + serviceId + ' to active');
          return callback(req, res, resultServices);
      }
    });
  }

  stopServiceInbound(req, res, serviceId, callback) {
    // Setting Service to active in database and then start the inbound service
    let query = "UPDATE services_inbound SET state = 0 WHERE id = " + serviceId;
    db.query(query, (errServices, resultServices) => {
      if (errServices) {
          // Errror loading Services Inbound
          this._logger.error(this.logIdentifier + ' | Error setting inbound service state in database');
          return null;
      } else {
          this._logger.info(this.logIdentifier + ' | Set inbound service with id ' + serviceId + ' to inactive');
          return callback(req, res, resultServices);
      }
    });
  }

  getStateOfServiceInbound(req, res, serviceId, callback) {
    query = "SELECT state FROM services_inbound WHERE id = " + serviceId;
    db.query(query, (errServices, resultServices) => {
      if (errServices) {
          // Errror loading Services Inbound
          this._logger.error(this.logIdentifier + ' | Error getting inbound service state for service with id ' + serviceId + ' from database');
          return null;
      } else {
          this._logger.info(this.logIdentifier + ' | Read inbound service state with id ' + serviceId + ' from database');
          return callback(req, res, resultServices);
      }
    });
  }

}

// export the class
module.exports = services_inbound;