Package com.kurento.kmf.test.services

Source Code of com.kurento.kmf.test.services.KurentoMediaServerManager

/*
* (C) Copyright 2014 Kurento (http://kurento.org/)
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser General Public License
* (LGPL) version 2.1 which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl-2.1.html
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
*/
package com.kurento.kmf.test.services;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Writer;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.io.CharStreams;
import com.kurento.kmf.common.Address;
import com.kurento.kmf.common.PropertiesManager;
import com.kurento.kmf.test.Shell;
import com.kurento.kmf.thrift.ThriftInterfaceConfiguration;
import com.kurento.kmf.thrift.pool.ClientPoolException;
import com.kurento.kmf.thrift.pool.ThriftClientPoolService;

import freemarker.template.Configuration;
import freemarker.template.Template;

/**
* Initializer/stopper class for Kurento Media Server (KMS).
*
* @author Boni Garcia (bgarcia@gsyc.es)
* @since 4.2.3
*/
public class KurentoMediaServerManager {

  private static final String PROJECT_PATH_PROP = "project.path";
  private static final String PROJECT_PATH_DEFAULT = ".";

  private static final String KURENTO_WORKSPACE_PROP = "kurento.workspace";
  private static final String KURENTO_WORKSPACE_DEFAULT = "/tmp";

  private static final String KURENTO_GST_PLUGINS_PROP = "kms.gst.plugins";
  private static final String KURENTO_GST_PLUGINS_DEFAULT = "";

  private static final String KURENTO_SERVER_COMMAND_PROP = "kms.command";
  private static final String KURENTO_SERVER_COMMAND_DEFAULT = "/usr/bin/kurento";

  private static final String KURENTO_SERVER_DEBUG_PROP = "kms.debug";
  private static final String KURENTO_SERVER_DEBUG_DEFAULT = "2,*media_server*:5,*Kurento*:5,KurentoMediaServerServiceHandler:7";

  public static Logger log = LoggerFactory
      .getLogger(KurentoMediaServerManager.class);

  private static String workspace;

  private Address thriftAddress;
  private int httpPort;
  private String testClassName;
  private String testMethodName;
  private String testDir;
  private String serverCommand;
  private String gstPlugins;
  private String debugOptions;

  private Address rabbitMqAddress;

  public static KurentoMediaServerManager createWithThriftTransport(
      Address thriftAddress, int httpPort) {
    KurentoMediaServerManager manager = new KurentoMediaServerManager();
    manager.thriftAddress = thriftAddress;
    manager.httpPort = httpPort;
    return manager;
  }

  public static KurentoMediaServerManager createWithRabbitMqTransport(
      Address rabbitMqAddress, int httpPort) {
    KurentoMediaServerManager manager = new KurentoMediaServerManager();
    manager.rabbitMqAddress = rabbitMqAddress;
    manager.httpPort = httpPort;
    return manager;
  }

  private KurentoMediaServerManager() {
  }

  public void setTestClassName(String testClassName) {
    this.testClassName = testClassName;
  }

  public void setTestMethodName(String testMethodName) {
    this.testMethodName = testMethodName;
  }

  public void start() {

    serverCommand = PropertiesManager.getProperty(
        KURENTO_SERVER_COMMAND_PROP, KURENTO_SERVER_COMMAND_DEFAULT);

    gstPlugins = PropertiesManager.getProperty(KURENTO_GST_PLUGINS_PROP,
        KURENTO_GST_PLUGINS_DEFAULT);

    try {
      workspace = Files.createTempDirectory("kmf-system-test").toString();
    } catch (IOException e) {
      workspace = PropertiesManager.getProperty(KURENTO_WORKSPACE_PROP,
          KURENTO_WORKSPACE_DEFAULT);
      log.error(
          "Exception loading temporal folder; instead folder {} will be used",
          workspace, e);
    }

    debugOptions = PropertiesManager.getProperty(KURENTO_SERVER_DEBUG_PROP,
        KURENTO_SERVER_DEBUG_DEFAULT);

    testDir = PropertiesManager.getProperty(PROJECT_PATH_PROP,
        PROJECT_PATH_DEFAULT) + "/target/surefire-reports/";

    if (!workspace.endsWith("/")) {
      workspace += "/";
    }
    log.debug("Local folder to store temporal files: {}", workspace);

    KurentoServicesTestHelper.setTestDir(testDir);

    if (rabbitMqAddress != null) {
      log.info("Starting KMS with RabbitMQ: RabbitMQAddress:'{}'"
          + " serverCommand:'{}' gstPlugins:'{}' workspace: '{}'",
          rabbitMqAddress, serverCommand, gstPlugins, workspace);
    } else {
      log.info("Starting KMS with Thrift: thriftAddress:'{}'"
          + " serverCommand:'{}' gstPlugins:'{}' workspace: '{}'",
          thriftAddress, serverCommand, gstPlugins, workspace);
    }

    createKurentoConf();

    // String logFolder = testDir + testClassName;
    // createFolder(logFolder);

    File logFile = new File(workspace, "kms.log");
    KurentoServicesTestHelper.setServerLogFilePath(logFile);

    log.debug("Log file: {}", logFile.getAbsolutePath());

    Shell.runAndWait("sh", "-c",
        workspace + "kurento.sh > " + logFile.getAbsolutePath()
            + " 2>&1");

    waitForKurentoMediaServer();
  }

  private void waitForKurentoMediaServer() {

    // Only wait if KMS uses Thrift
    if (thriftAddress != null) {

      long startWaiting = System.currentTimeMillis();

      ThriftClientPoolService clientPool = new ThriftClientPoolService(
          new ThriftInterfaceConfiguration(thriftAddress.getHost(),
              thriftAddress.getPort()));

      // Wait for a max of 20 seconds
      long timeout = System.currentTimeMillis() + 20000;
      while (true) {
        try {
          clientPool.acquireSync();
          break;
        } catch (ClientPoolException e) {
          try {
            Thread.sleep(100);
            if (System.currentTimeMillis() > timeout) {
              throw new RuntimeException(
                  "Timeout (20 sec) waiting for ThriftClientPoolService");
            }
          } catch (InterruptedException e1) {
          }
        }
      }

      long waitingTime = System.currentTimeMillis() - startWaiting;

      log.info("KMS started in {} millis", waitingTime);

    } else {
      try {
        Thread.sleep(2000);
      } catch (InterruptedException e) {
        log.error("InterruptedException {}", e.getMessage());
      }
    }
  }

  private void createFolder(String folder) {
    File folderFile = new File(folder);
    if (!folderFile.exists()) {
      folderFile.mkdirs();
    }
  }

  private void createKurentoConf() {

    Configuration cfg = new Configuration();

    // Data-model
    Map<String, Object> data = new HashMap<String, Object>();

    if (rabbitMqAddress != null) {
      data.put("transport", "RabbitMQ");
      data.put("serverAddress", rabbitMqAddress.getHost());
      data.put("serverPort", String.valueOf(rabbitMqAddress.getPort()));
    } else {
      data.put("transport", "Thrift");
      data.put("serverAddress", thriftAddress.getHost());
      data.put("serverPort", String.valueOf(thriftAddress.getPort()));
    }

    data.put("gstPlugins", gstPlugins);
    data.put("debugOptions", debugOptions);
    data.put("serverCommand", serverCommand);
    data.put("workspace", workspace);
    data.put("httpEndpointPort", String.valueOf(httpPort));

    cfg.setClassForTemplateLoading(KurentoMediaServerManager.class,
        "/templates/");

    createFileFromTemplate(cfg, data, "kurento.conf");
    createFileFromTemplate(cfg, data, "pattern.sdp");
    createFileFromTemplate(cfg, data, "kurento.sh");
    Shell.runAndWait("chmod", "+x", workspace + "kurento.sh");
  }

  private void createFileFromTemplate(Configuration cfg,
      Map<String, Object> data, String filename) {

    try {

      Template template = cfg.getTemplate(filename + ".ftl");
      Writer writer = new FileWriter(new File(workspace + filename));
      template.process(data, writer);
      writer.flush();
      writer.close();

    } catch (Exception e) {
      throw new RuntimeException(
          "Exception while creating file from template", e);
    }
  }

  public void stop() {
    int numKmsProcesses = 0;
    // Max timeout waiting kms ending: 5 seconds
    long timeout = System.currentTimeMillis() + 5000;
    do {
      // If timeout, break the loop
      if (System.currentTimeMillis() > timeout) {
        break;
      }

      // Sending SIGTERM signal to KMS process
      kmsSigTerm();

      // Wait 100 msec to order kms termination
      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      numKmsProcesses = countKmsProcesses();

    } while (numKmsProcesses > 0);

    if (numKmsProcesses > 0) {
      // If at this point there is still kms process (after trying to
      // kill it with SIGTERM during 5 seconds), we send the SIGKILL
      // signal to the process
      kmsSigKill();
    }
  }

  private void kmsSigTerm() {
    log.trace("Sending SIGTERM to KMS process");
    Shell.runAndWait("sh", "-c", "kill `cat " + workspace + "kms-pid`");
  }

  private void kmsSigKill() {
    log.trace("Sending SIGKILL to KMS process");
    Shell.runAndWait("sh", "-c", "kill -9 `cat " + workspace + "kms-pid`");
  }

  public String getDebugOptions() {
    return debugOptions;
  }

  public void setDebugOptions(String debugOptions) {
    this.debugOptions = debugOptions;
  }

  public void setHttpPort(int httpPort) {
    this.httpPort = httpPort;
  }

  public int countKmsProcesses() {
    int result = 0;
    try {
      // This command counts number of process (given its PID, stored in
      // kms-pid file)
      String[] command = {
          "sh",
          "-c",
          "ps --pid `cat " + workspace
              + "kms-pid` --no-headers | wc -l" };
      Process countKms = Runtime.getRuntime().exec(command);

      String stringFromStream = CharStreams
          .toString(new InputStreamReader(countKms.getInputStream(),
              "UTF-8"));
      result = Integer.parseInt(stringFromStream.trim());
    } catch (IOException e) {
      log.error("Exception counting KMS processes", e);
    }

    return result;
  }

  public static String getWorkspace() {
    return workspace;
  }
}
TOP

Related Classes of com.kurento.kmf.test.services.KurentoMediaServerManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.