Source: models/services_outbound.js

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


class services_outbound {
  
  constructor(loggerInstance) {
    // always initialize all instance properties
    this.logIdentifier = "OUTBOUND Service Worker";
    this.logger = loggerInstance;
  }

  serviceStatusRefresh(store) {
    // First refresh list of active services from database
    this.getListOfActiveServicesOutbound('','', (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 outbound 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');
      }
    });
  }

  stopOutboundServices(store, callback) {
   this.logger.info(this.logIdentifier + ' | Stopping outboundservices');
    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 Outbound services (table services_outbound_store with ibSvcState = 1) and starts them as a forked proccess
   *
   * @param {*} callback Callbackfunction
   * @memberof services_outbound
   */
  startUpOutboundServices(callback) {
    let processList = [];
   this.logger.info(this.logIdentifier + ' | Starting outbound services');
    this.getListOfActiveServicesOutbound('','', (req, res, servicesResult) => {
      servicesResult.forEach(service => {
       this.logger.info(this.logIdentifier + ' | Starting outbound service ' + service.servicename);
          // Fork process    
          let cp = fork('./modules/services/outbound/' + 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() {
             this.logger.info(this.logIdentifier + ' | child process has ended');
              cp.kill();
          })

          // if process sends message -> write to console
          cp.on('message', (m) => {
              //logger.log(`${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) {
           this.logger.error(this.logIdentifier + ' | with service ' + cp.pid);
            //sendErr(err);
          });

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

  setLiveStateOfServiceOutbound(servicename, livestate, callback) {
    let query = "UPDATE services_outbound SET livestate = " + livestate + " WHERE servicename = '" + servicename;
    db.query(query, (errServices, resultServices) => {
      if (errServices) {
          // Errror loading Services Outbound
         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);
      }
    });
  }

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

  setServiceOutboundInstanceState(serviceId, state, req, res, callback) {
   this.logger.info('Setting State of service outbound ' + serviceId + ' to state ' + state);
    let query = "UPDATE services_outbound_store SET ibSvcState = " + state + " WHERE id = " + serviceId;
    db.query(query, (errServices, resultServices) => {
        if (errServices) {
           this.logger.error(this.logIdentifier + ' | Error setting state of outbound 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);
        }
    });
  }
  
  getListOfServicesInstancesOutbound(req, res, callback) {
   this.logger.info(this.logIdentifier + ' | Reading Outbound Service Instances');
    let query = "SELECT services_outbound_store.*, " +
                        "services_outbound.id AS svcId, " +
                        "services_outbound.servicename AS servicename, " +
                        "services_outbound.servicetitle AS servicetitle " +
                  "FROM `services_outbound_store`  " +
                  "INNER JOIN services_outbound ON " +
                        "services_outbound_store.ibSvcId = services_outbound.id ";
    db.query(query, (errServices, resultServices) => {
        if (errServices) {
            // Errror loading Services Outbound
           this.logger.error(this.logIdentifier + ' | Error loading outbound services instances');
            return null;
        } else {
           this.logger.info(this.logIdentifier + '| Read ' + resultServices.length + ' outbound service instances');
            return callback(req, res, resultServices);
        }
    });
  }


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


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

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

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

}

// export the class
module.exports = services_outbound;