Hi,

I added an option to our node launcher so that a service can be invoked after the node is started. Now we can launch a node as follows:

java -jar tuscany-node-launcher-<version>.jar -s <serviceName> contribution1 ... contributionN

The service name syntax is <componentName>/<serviceName>/<bindingName>#<operationName(agr0,...,argN). The serviceName and bindingName are optional.

-s CalculatorComponent#add(1.0,2.0)
-s CalculatorComponent/CalculatorService#add(1.0,2.0)

We support primitive (including the boxed ones) and String types for the arguments.

Thanks,
Raymond
--------------------------------------------------
From: <[email protected]>
Sent: Sunday, November 22, 2009 2:18 PM
To: <[email protected]>
Subject: svn commit: r883155 - in /tuscany/sca-java-2.x/trunk/modules/node-launcher/src: main/java/org/apache/tuscany/sca/node/launcher/ test/ test/java/ test/java/org/ test/java/org/apache/ test/java/org/apache/tuscany/ test/java/org/apache/tuscany/sca/ test/j...

Author: rfeng
Date: Sun Nov 22 22:17:59 2009
New Revision: 883155

URL: http://svn.apache.org/viewvc?rev=883155&view=rev
Log:
Add an option to invoke a service after the node is started

Added:
   tuscany/sca-java-2.x/trunk/modules/node-launcher/src/test/
   tuscany/sca-java-2.x/trunk/modules/node-launcher/src/test/java/
   tuscany/sca-java-2.x/trunk/modules/node-launcher/src/test/java/org/

tuscany/sca-java-2.x/trunk/modules/node-launcher/src/test/java/org/apache/

tuscany/sca-java-2.x/trunk/modules/node-launcher/src/test/java/org/apache/tuscany/

tuscany/sca-java-2.x/trunk/modules/node-launcher/src/test/java/org/apache/tuscany/sca/

tuscany/sca-java-2.x/trunk/modules/node-launcher/src/test/java/org/apache/tuscany/sca/node/

tuscany/sca-java-2.x/trunk/modules/node-launcher/src/test/java/org/apache/tuscany/sca/node/launcher/

tuscany/sca-java-2.x/trunk/modules/node-launcher/src/test/java/org/apache/tuscany/sca/node/launcher/ServiceInvocationTestCase.java (with props)
Modified:

tuscany/sca-java-2.x/trunk/modules/node-launcher/src/main/java/org/apache/tuscany/sca/node/launcher/NodeLauncher.java

Modified: tuscany/sca-java-2.x/trunk/modules/node-launcher/src/main/java/org/apache/tuscany/sca/node/launcher/NodeLauncher.java URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/node-launcher/src/main/java/org/apache/tuscany/sca/node/launcher/NodeLauncher.java?rev=883155&r1=883154&r2=883155&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/node-launcher/src/main/java/org/apache/tuscany/sca/node/launcher/NodeLauncher.java (original) +++ tuscany/sca-java-2.x/trunk/modules/node-launcher/src/main/java/org/apache/tuscany/sca/node/launcher/NodeLauncher.java Sun Nov 22 22:17:59 2009
@@ -23,6 +23,8 @@

import java.io.File;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
@@ -134,8 +136,9 @@
        options.addOption(opt2);
        Option opt3 = new Option("t", "ttl", true, "Time to live");
        opt3.setArgName("timeToLiveInMilliseconds");
-        // opt4.setType(long.class);
        options.addOption(opt3);
+ Option opt4 = new Option("s", "service", true, "Service to invoke (componentName/serviceName#operation(arg0,...,argN)");
+        options.addOption(opt4);
        return options;
    }

@@ -181,6 +184,7 @@
                        formatter.setSyntaxPrefix("Usage: ");
formatter.printHelp("java " + NodeLauncher.class.getName()
                                            + " [-c <compositeURI>]"
+                                            + " [-s <service>]"
                                            + " [-t <ttl>]"
+ " contribution1 ... contributionN", options); return;
                    }
@@ -202,6 +206,26 @@
                }
                logger.info("SCA Node is now started.");

+                String service = cli.getOptionValue("service");
+                String regex = "(#|\\(|,|\\))";
+                if (service != null) {
+ // componentName/serviceName/bindingName#methodName(arg0, ..., agrN)
+                    String tokens[] = service.split(regex);
+                    String serviceName = tokens[0];
+                    String operationName = tokens[1];
+                    String params[] = new String[tokens.length - 2];
+ System.arraycopy(tokens, 2, params, 0, params.length);
+                    logger.info("Invoking service: " + service);
+ Method method = node.getClass().getMethod("getService", Class.class, String.class); + Object proxy = method.invoke(node, null, serviceName);
+
+                    Object result = invoke(proxy, operationName, params);
+                    if (result != null) {
+                        logger.info("Result is: " + result);
+                    }
+                    break;
+                }
+
                // Install a shutdown hook
                shutdown = new ShutdownThread(node);
                Runtime.getRuntime().addShutdownHook(shutdown);
@@ -266,6 +290,43 @@
            }
        }
    }
+
+ static Object invoke(Object proxy, String operationName, String... params) throws IllegalAccessException,
+        InvocationTargetException {
+        for (Method m : proxy.getClass().getMethods()) {
+ if (m.getName().equals(operationName) && m.getParameterTypes().length == params.length) {
+                Object parameters[] = new Object[params.length];
+                int i = 0;
+                for (Class<?> type : m.getParameterTypes()) {
+                    if (type == byte.class || type == Byte.class) {
+                        parameters[i] = Byte.valueOf(params[i]);
+ } else if (type == char.class || type == Character.class) {
+                        parameters[i] = params[i].charAt(0);
+ } else if (type == boolean.class || type == Boolean.class) {
+                        parameters[i] = Boolean.valueOf(params[i]);
+ } else if (type == short.class || type == Short.class) {
+                        parameters[i] = Short.valueOf(params[i]);
+ } else if (type == int.class || type == Integer.class) {
+                        parameters[i] = Integer.valueOf(params[i]);
+ } else if (type == long.class || type == Long.class) {
+                        parameters[i] = Long.valueOf(params[i]);
+ } else if (type == float.class || type == Float.class) {
+                        parameters[i] = Float.valueOf(params[i]);
+ } else if (type == double.class || type == Double.class) {
+                        parameters[i] = Double.valueOf(params[i]);
+                    } else if (type == String.class) {
+                        parameters[i] = params[i];
+                    } else {
+ throw new IllegalArgumentException("Parameter type is not supported: " + type);
+                    }
+                    i++;
+                }
+                Object result = m.invoke(proxy, parameters);
+                return result;
+            }
+        }
+ throw new IllegalArgumentException("Invalid service operation: " + operationName);
+    }

    /**
     * Stop the given node.

Added: tuscany/sca-java-2.x/trunk/modules/node-launcher/src/test/java/org/apache/tuscany/sca/node/launcher/ServiceInvocationTestCase.java URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/node-launcher/src/test/java/org/apache/tuscany/sca/node/launcher/ServiceInvocationTestCase.java?rev=883155&view=auto
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/node-launcher/src/test/java/org/apache/tuscany/sca/node/launcher/ServiceInvocationTestCase.java (added) +++ tuscany/sca-java-2.x/trunk/modules/node-launcher/src/test/java/org/apache/tuscany/sca/node/launcher/ServiceInvocationTestCase.java Sun Nov 22 22:17:59 2009
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.node.launcher;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class ServiceInvocationTestCase {
+
+    /**
+     * @throws java.lang.Exception
+     */
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+    }
+
+    public float add(float x, float y) {
+        return x + y;
+    }
+
+    @Test
+    public void testInvoke() throws Exception {
+        String service = "component1/service1#add(1.0, 2.0)";
+        Object proxy = this;
+        invoke(service, proxy);
+    }
+
+ private Object invoke(String service, Object proxy) throws IllegalAccessException, InvocationTargetException {
+        String regex = "(#|\\(|,|\\))";
+        if (service != null) {
+ // componentName/serviceName/bindingName#methodName(arg0, ..., agrN)
+            String tokens[] = service.split(regex);
+            String serviceName = tokens[0];
+            Assert.assertEquals("component1/service1", serviceName);
+            String operationName = tokens[1];
+            Assert.assertEquals("add", operationName);
+            String params[] = new String[tokens.length - 2];
+            System.arraycopy(tokens, 2, params, 0, params.length);
+ Object result = NodeLauncher.invoke(proxy, operationName, params);
+            Assert.assertEquals(new Float(3.0f), result);
+            return result;
+        }
+        return null;
+    }
+
+    /**
+     * @throws java.lang.Exception
+     */
+    @AfterClass
+    public static void tearDownAfterClass() throws Exception {
+    }
+
+}

Propchange: tuscany/sca-java-2.x/trunk/modules/node-launcher/src/test/java/org/apache/tuscany/sca/node/launcher/ServiceInvocationTestCase.java
------------------------------------------------------------------------------
   svn:eol-style = native

Propchange: tuscany/sca-java-2.x/trunk/modules/node-launcher/src/test/java/org/apache/tuscany/sca/node/launcher/ServiceInvocationTestCase.java
------------------------------------------------------------------------------
   svn:keywords = Rev Date


Reply via email to