source: branches/supervisor/src/main/java/omq/server/RemoteObject.java @ 100

Last change on this file since 100 was 100, checked in by stoda, 11 years ago

Idea of thread supervisor done

TODO test the idea, change the remote properties, etc

File size: 5.5 KB
Line 
1package omq.server;
2
3import java.io.IOException;
4import java.lang.reflect.Method;
5import java.util.ArrayList;
6import java.util.HashMap;
7import java.util.List;
8import java.util.Map;
9import java.util.Properties;
10
11import omq.Remote;
12import omq.common.broker.Broker;
13import omq.common.util.ParameterQueue;
14
15import org.apache.log4j.Logger;
16
17/**
18 * A RemoteObject when it's started will be waiting for requests and will invoke
19 * them. When a RemoteObject is started it listens two queues, the first one has
20 * the same name as its reference and the second one is its multiqueue -this
21 * name can be set using a property, be aware to use a name not used by another
22 * object!!!-.
23 *
24 * @author Sergi Toda <sergi.toda@estudiants.urv.cat>
25 *
26 */
27public abstract class RemoteObject implements Remote {
28
29        private static final long serialVersionUID = -1778953938739846450L;
30        private static final Logger logger = Logger.getLogger(RemoteObject.class.getName());
31
32        private String UID;
33        private Properties env;
34        private transient Broker broker;
35        private transient RemoteThreadPool pool;
36        private transient Map<String, List<Class<?>>> params;
37        private transient List<InvocationThread> invocationList;
38
39        private static final Map<String, Class<?>> primitiveClasses = new HashMap<String, Class<?>>();
40
41        static {
42                primitiveClasses.put("byte", Byte.class);
43                primitiveClasses.put("short", Short.class);
44                primitiveClasses.put("char", Character.class);
45                primitiveClasses.put("int", Integer.class);
46                primitiveClasses.put("long", Long.class);
47                primitiveClasses.put("float", Float.class);
48                primitiveClasses.put("double", Double.class);
49        }
50
51        /**
52         * This method starts a remoteObject.
53         *
54         * @param reference
55         *            - broker's binding referece
56         * @param broker
57         *            - broker that binds this remoteObject
58         * @param env
59         *            - properties of this remoteObject
60         * @throws Exception
61         */
62        public void startRemoteObject(String reference, Broker broker, Properties env) throws Exception {
63                this.broker = broker;
64                this.UID = reference;
65                this.env = env;
66
67                this.params = new HashMap<String, List<Class<?>>>();
68                for (Method m : this.getClass().getMethods()) {
69                        List<Class<?>> list = new ArrayList<Class<?>>();
70                        for (Class<?> clazz : m.getParameterTypes()) {
71                                list.add(clazz);
72                        }
73                        this.params.put(m.getName(), list);
74                }
75
76                // Get num threads to use
77                int numThreads = Integer.parseInt(env.getProperty(ParameterQueue.NUM_THREADS, "1"));
78                invocationList = new ArrayList<InvocationThread>(numThreads);
79
80                // Start invocation threads
81                for (int i = 0; i < numThreads; i++) {
82                        InvocationThread iThread = new InvocationThread(this, broker);
83                        invocationList.add(iThread);
84                        iThread.start();
85                }
86
87        }
88
89        @Override
90        public String getRef() {
91                return UID;
92        }
93
94        /**
95         * This method kills all the threads waiting for requests
96         *
97         * @throws IOException
98         *             - If an operation failed.
99         */
100        public void kill() throws IOException {
101                logger.info("Killing objectmq: " + this.getRef());
102                for (InvocationThread iThread : invocationList) {
103                        iThread.kill();
104                }
105        }
106
107        /**
108         * This method invokes the method specified by methodName and arguments
109         *
110         * @param methodName
111         * @param arguments
112         * @return result
113         * @throws Exception
114         */
115        public Object invokeMethod(String methodName, Object[] arguments) throws Exception {
116
117                // Get the specific method identified by methodName and its arguments
118                Method method = loadMethod(methodName, arguments);
119
120                return method.invoke(this, arguments);
121        }
122
123        /**
124         * This method loads the method specified by methodName and args
125         *
126         * @param methodName
127         * @param args
128         * @return method
129         * @throws NoSuchMethodException
130         *             - If the method cannot be found
131         */
132        private Method loadMethod(String methodName, Object[] args) throws NoSuchMethodException {
133                Method m = null;
134
135                // Obtain the class reference
136                Class<?> clazz = this.getClass();
137                Class<?>[] argArray = null;
138
139                if (args != null) {
140                        argArray = new Class<?>[args.length];
141                        for (int i = 0; i < args.length; i++) {
142                                argArray[i] = args[i].getClass();
143                        }
144                }
145
146                try {
147                        m = clazz.getMethod(methodName, argArray);
148                } catch (NoSuchMethodException nsm) {
149                        m = loadMethodWithPrimitives(methodName, argArray);
150                }
151                return m;
152        }
153
154        /**
155         * This method loads a method which uses primitives as arguments
156         *
157         * @param methodName
158         *            - name of the method wanted to invoke
159         * @param argArray
160         *            - arguments
161         * @return method
162         * @throws NoSuchMethodException
163         *             - If the method cannot be found
164         */
165        private Method loadMethodWithPrimitives(String methodName, Class<?>[] argArray) throws NoSuchMethodException {
166                if (argArray != null) {
167                        Method[] methods = this.getClass().getMethods();
168                        int length = argArray.length;
169
170                        for (Method method : methods) {
171                                String name = method.getName();
172                                int argsLength = method.getParameterTypes().length;
173
174                                if (name.equals(methodName) && length == argsLength) {
175                                        // This array can have primitive types inside
176                                        Class<?>[] params = method.getParameterTypes();
177
178                                        boolean found = true;
179
180                                        for (int i = 0; i < length; i++) {
181                                                if (params[i].isPrimitive()) {
182                                                        Class<?> paramWrapper = primitiveClasses.get(params[i].getName());
183
184                                                        if (!paramWrapper.equals(argArray[i])) {
185                                                                found = false;
186                                                                break;
187                                                        }
188                                                }
189                                        }
190                                        if (found) {
191                                                return method;
192                                        }
193                                }
194                        }
195                }
196                throw new NoSuchMethodException(methodName);
197        }
198
199        public List<Class<?>> getParams(String methodName) {
200                return params.get(methodName);
201        }
202
203        public Broker getBroker() {
204                return broker;
205        }
206
207        public Properties getEnv() {
208                return env;
209        }
210
211}
Note: See TracBrowser for help on using the repository browser.