/******************************************************************************* * Copyright (c) 2010-2013, Embraer S.A., Budapest University of Technology and Economics * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Rodrigo Rizzi Starr, Lincoln Nascimento - initial API and implementation *******************************************************************************/ package br.com.embraer.massif.commandevaluation.server; import java.io.File; import java.io.IOException; import java.net.ServerSocket; import java.net.URISyntaxException; import java.net.URL; import java.rmi.RMISecurityManager; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIServerSocketFactory; import java.rmi.server.RMISocketFactory; import java.rmi.server.UnicastRemoteObject; import br.com.embraer.massif.commandevaluation.base.MatlabRemoteInterface; import br.com.embraer.massif.commandevaluation.exception.MatlabError; import br.com.embraer.massif.commandevaluation.exception.MatlabPropertiesException; import br.com.embraer.massif.commandevaluation.exception.MatlabRMIException; import br.com.embraer.massif.commandevaluation.util.MatlabProviderProperties; import br.com.embraer.massif.commandevaluation.util.TimeLimitedClientSocketFactory; /** * Entry point for the matlab RMI server execution * * @author ldnascim */ public class ServerEntryPoint { /** RMI Server Host address and port **/ private static String hostAddress; private static int hostPort; /** RMI service name */ private static String serviceName; private static boolean debug; /** RMI server registry */ private Registry registry; private MatlabRemoteInterface matlabRemote; /** * Reads the host address and host port from the properties file * * @throws MatlabPropertiesException */ private static void readProperties(String filePath) throws MatlabPropertiesException { String _filePath = filePath; // if path was not given, try to load from the jar directory if (_filePath.isEmpty()) { try { File jarFile = new File(ServerEntryPoint.class.getProtectionDomain().getCodeSource().getLocation() .toURI()); String jarFolder = jarFile.getParent(); _filePath = jarFolder + File.separator + MatlabProviderProperties.MATLAB_DEFAULT_CONFIG_FILE_NAME; printMessage("Configuration path not provided, " + "considering the following path: " + _filePath); } catch (URISyntaxException e1) { MatlabPropertiesException exception = new MatlabPropertiesException( MatlabError.RETRIEVE_JAR_LOCATION_ERROR, e1); throw exception; } } MatlabProviderProperties serverProperties = new MatlabProviderProperties(_filePath); // get host address hostAddress = serverProperties.getProperty(MatlabProviderProperties.MATLAB_SERVER_ADDRESS); printMessage("Host address = " + hostAddress); // if host address was not provided, thrown an exception if (hostAddress == null || hostAddress.isEmpty()) { MatlabPropertiesException exception = new MatlabPropertiesException( MatlabError.INVALID_PROPERTY_CONTENT_ERROR, null); exception.set("Config file", serverProperties.getConfigPath()); exception.set(MatlabProviderProperties.MATLAB_SERVER_ADDRESS, hostAddress); throw exception; } // get host port String hostPortStr = serverProperties.getProperty(MatlabProviderProperties.MATLAB_SERVER_PORT); printMessage("Host port: " + hostPortStr); try { hostPort = Integer.valueOf(hostPortStr); } catch (NumberFormatException e) { MatlabPropertiesException exception = new MatlabPropertiesException( MatlabError.INVALID_PROPERTY_CONTENT_ERROR, e); exception.set("Config file", serverProperties.getConfigPath()); exception.set(MatlabProviderProperties.MATLAB_SERVER_PORT, hostPortStr); throw exception; } // get debug mode String debugStr = serverProperties.getProperty(MatlabProviderProperties.MATLAB_SERVER_DEBUG_MODE); printMessage("Debug mode: " + debugStr); debug = Boolean.valueOf(debugStr); serviceName = MatlabProviderProperties.MATLAB_SERVER_DEFAULT_SERVICE_NAME; } /** * Starts the RMI server using as parameter the matlab version * * @param matlabVersion * Matlab version * @throws MatlabPropertiesException * @throws MatlabRMIException */ public void startRMIServer(String matlabVersion, String matlabPid, String configFilePath) throws MatlabPropertiesException, MatlabRMIException { readProperties(configFilePath); String _matlabVersion = matlabVersion.toLowerCase(); // if matlab version was provided concatenates with prefix if (!_matlabVersion.isEmpty()) { serviceName = serviceName + _matlabVersion + matlabPid; } StringBuilder sb = new StringBuilder("Starting Matlab RMI Server...\n"); sb.append("-----------------------------\n"); sb.append("Address = " + hostAddress + "\n"); sb.append("port = " + hostPort + "\n"); sb.append("serviceName = " + serviceName + "\n"); sb.append("-----------------------------\n"); printMessage(sb.toString()); // Reads server policy from file URL url = ServerEntryPoint.class.getResource("/server.policy"); if (url != null) { System.setProperty("java.security.policy", url.toString()); } // sets RMI security manager if (System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); } // creates RMI server registry try { // Create the remote object and keep a hard reference to it in order to avoid garbage collection. matlabRemote = new MatlabRemoteImpl(debug); // Add custom socket factory - the answer time is limited for the server (time limit is set in the // implementation of the client socket factory) RMIClientSocketFactory csf = new TimeLimitedClientSocketFactory(); // Export the remote object and set the custom client and the default server socket factories MatlabRemoteInterface stub = (MatlabRemoteInterface) UnicastRemoteObject.exportObject(matlabRemote, 0, csf, new RMIServerSocketFactory() { @Override public ServerSocket createServerSocket(int arg0) throws IOException { return RMISocketFactory.getDefaultSocketFactory().createServerSocket(arg0); } }); // Bind the remote object to the corresponding service name registry = LocateRegistry.createRegistry(hostPort); registry.rebind(serviceName, stub); printMessage("Matlab RMI Server Started!"); } catch (RemoteException e) { MatlabRMIException exception = new MatlabRMIException(MatlabError.CREATE_RMI_SERVER_ERROR, e); exception.set("Host port", hostPort); exception.set("Service name", serviceName); throw exception; } } private static void printMessage(String message) { System.out.println(message); } }