All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.velasolaris.plugin.controller.rpc.XmlRpcProxy Maven / Gradle / Ivy

The newest version!
package com.velasolaris.plugin.controller.rpc;

import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;

/**
 * Proxy class for XML-RPC function calls using HTTP.
 *
 * XML-RPC standard compatible.
 *
 * One HTTP connection (TCP connection) per request is created.
 *
 * This implementation uses
 * https://ws.apache.org/xmlrpc/client.html
 * where the library is at
 * http://archive.apache.org/dist/ws/xmlrpc/
 *
 * @author rkurmann
 * @since Polysun 9.1
 *
 */
public class XmlRpcProxy extends RpcProxy {

    /** RPC proxy. */
    private XmlRpcClient proxy;
    /** RPC proxy config. */
    private XmlRpcClientConfigImpl config;

    /**
     * Constructor.
     *
     * @param rpcServerURL URL of the RPC server for the function calls, e.g. http://localhost:2102/control
     * @param rpcFunction Name of the RPC function, e.g. controlFlowrate
     * @param connectionTimeout Connection timeout [ms] 0 may mean wait forever.
     * @param readTimeout Read timeout [ms] 0 may mean wait forever.
     * @param verboseLevel Level of verbosity
     */
    protected XmlRpcProxy(URL rpcServerURL, String rpcFunction, int connectionTimeout, int readTimeout, int verboseLevel) {
        super(rpcServerURL, rpcFunction, connectionTimeout, readTimeout, verboseLevel);
    }

    @Override
    public ControlFunctionResponse callRemoteFunction(int simulationTime, boolean status, float[] sensors, boolean[] sensorsUsed,
            float[] properties, String[] propertiesStr, boolean preRun, boolean[] controlSignalsUsed, float[] logValues,
            int stage, int fixedTimestep, int verboseLevel, Map parameters) throws XmlRpcException {
        // def control(simulationTime, status, sensors, sensorsUsed, properties,
        // propertiesStr, preRun, controlSignalsUsed, numLogValues, stage,
        // fixedTimestep, verboseLevel, parameters)
        Object response = getProxy().execute(rpcFunction,
                new Object[] { simulationTime, status, convertFloatsToDoubles(sensors),
                    ArrayUtils.toObject(sensorsUsed), convertFloatsToDoubles(properties), propertiesStr, preRun,
                    ArrayUtils.toObject(controlSignalsUsed), logValues.length, stage, fixedTimestep, verboseLevel,
                    /*parameters != null && false ? parameters :*/ emptyParamters });
        ControlFunctionResponse result;
        if (response instanceof Object[]) {
            Object[] resultArray = (Object[]) response;
            result = new ControlFunctionResponse(
                    resultArray.length > 0 ? ControlFunctionResponse.convertObjectArrayToFloats(resultArray[0]) : ControlFunctionResponse.EMPTY_FLOAT_ARRAY,
                    resultArray.length > 1 ? ControlFunctionResponse.convertObjectArrayToFloats(resultArray[1]) : ControlFunctionResponse.EMPTY_FLOAT_ARRAY,
                    resultArray.length > 2 ? ControlFunctionResponse.convertObjectToInts(resultArray[2]) : ControlFunctionResponse.EMPTY_INT_ARRAY);
        } else {
            result = new ControlFunctionResponse();
        }
        return result;
    }

    @Override
    public void setupRpc(int waitConnected, Map parameters) throws Exception {
        sLog.info("Start connecting to Server...");
        if (config == null) {
            config = new XmlRpcClientConfigImpl();
            config.setServerURL(rpcServerURL);
            config.setEnabledForExtensions(true);
            config.setGzipCompressing(false);
            config.setGzipRequesting(false);
            config.setContentLengthOptional(true);
            config.setConnectionTimeout(connectionTimeout);
            config.setReplyTimeout(readTimeout);
        }

        waitConnected(waitConnected);
        writeMsgToServer("Polysun connected to Server.");
        sLog.info("Connected to Server");
        parameters.put("Plugin.PrintMessage", "Connected to Server");
    }

    /**
     * Returns a proxy to communicate with XML-RPC server.
     *
     * @return the proxy
     */
    protected XmlRpcClient getProxy() {
        if (proxy == null) {
            if (verboseLevel >= SimpleRpcPluginController.VERBOSE_LEVEL_DEBUG) {
                sLog.fine("Create XmlRpcClient");
            }
            proxy = new XmlRpcClient();
            proxy.setConfig(config);
        }
        return proxy;
    }

    @Override
    public void writeMsgToServer(String str) throws XmlRpcException {
        if (verboseLevel >= SimpleRpcPluginController.VERBOSE_LEVEL_DEBUG) {
            sLog.fine("Write Message to Server: " + str);
        }
        getProxy().execute("print", new Object[] { str });
    }

    @Override
    public boolean ping() {
        try {
            Object response = getProxy().execute("ping", new Object[0]);
            return "pong".equals(response);
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public void disconnectProxy() {
        if (proxy != null) {
            if (sLog.isLoggable(Level.INFO))
                sLog.info("Disconnect proxy");
            proxy = null;
            config = null;
        }
    }

    @Override
    public void stopServer() throws Exception {
        getProxy().execute("stop", new Object[0]);
    }


    /**
     * Test call.
     *
     * @param args program arguments
     *
     * @throws Exception
     *             For any problems
     */
    public static void main(String... args) throws Exception {
        System.out.println("Start");
        XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
        config.setServerURL(new URL("http://localhost:2101/control"));
        config.setEnabledForExtensions(true);
        config.setEnabledForExceptions(true);
        XmlRpcClient client = new XmlRpcClient();
        client.setConfig(config);
        String result = (String) client.execute("ping", new Object[] {});
        System.out.println(result);

        int num = 1000;
        long start = System.nanoTime();
        for (int i = 0; i < num; i++) {
            result = (String) client.execute("ping", new Object[] {});
        }
        long stop = System.nanoTime();
        System.out.println("Avg. ping: " + ((stop - start) / 10000 / num) / 100f + "ms");

        client.execute("print", new Object[] { "Polysun connected to Server." });
        // def controlFlowrate(simulationTime, status, sensors, sensorsUsed,
        // properties, propertiesStr, preRun, controlSignalsUsed, numLogValues,
        // stage, fixedTimestep, verboseLevel, parameters):
        Object[] ret = (Object[]) client.execute("controlTest", new Object[] { 1, true, new Double[] { 1d } });
        System.out.println("Response length: " + ret.length);
        // ret = (Object[]) client.execute("controlFlowrate", new Object[] {1,
        // true, new Float[] {1f, 1f}, new Float[] {1f, 1f}, new Float[] {1f},
        // new String[] {"X"}, true, new Float[] {1f}, 1, FUNCTION_STAGE_INIT,
        // 120, 3, new Object[0]});
        Map parameters = new HashMap<>();
        parameters.put("Polysun.UserLevel", 1);
        //		parameters.put("Polysun.Version", 1l);
        parameters.put("Polysun.DataPath", "~/dev/java/polysun/polysun/production/commons");

        ret = (Object[]) client.execute("controlFlowrate",
                new Object[] { 1, true, new Double[] { 1d, 1d }, new Double[] { 1d, 1d }, new Double[] { 1d },
                    new String[] { "X" }, true, new Double[] { 1d }, 1,
                    SimpleRpcPluginController.FUNCTION_STAGE_INIT, 120, 3, parameters });
        long start2 = System.nanoTime() / 1000000;
        ret = (Object[]) client.execute("controlFlowrate",
                new Object[] { 1, true, new Double[] { 1d, 1d, 1d }, new Double[] { 1d, 1d, 1d },
                    new Double[] { 1d, 1d, 1d }, new String[] { "X", "Y", "Z" }, true, new Double[] { 1d, 1d, 1d },
                    1, SimpleRpcPluginController.FUNCTION_STAGE_SIMULATION, 120, 3, new Object[0] });
        long stop2 = System.nanoTime() / 1000000;
        System.out.println("controlTest: " + (stop2 - start2) + "ms");
        System.out.println("End");
        System.exit(0);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy