1 /*------------------------------------------------------------------------------
2 Name: XmlBlasterInvocationHandler.java
3 Project: xmlBlaster.org
4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
5 ------------------------------------------------------------------------------*/
6 package org.xmlBlaster.client.jmx;
7
8 import java.lang.reflect.*;
9 import java.util.*;
10
11
12 import java.util.logging.Logger;
13 import java.util.logging.Level;
14 import org.xmlBlaster.client.*;
15 import org.xmlBlaster.client.key.*;
16 import org.xmlBlaster.client.key.UpdateKey;
17 import org.xmlBlaster.client.qos.*;
18 import org.xmlBlaster.client.qos.ConnectQos;
19 import org.xmlBlaster.client.qos.DisconnectQos;
20 import org.xmlBlaster.client.qos.UpdateQos;
21 import org.xmlBlaster.util.Global;
22 import org.xmlBlaster.util.MsgUnit;
23 import org.xmlBlaster.util.admin.extern.*;
24 import org.xmlBlaster.util.qos.address.*;
25
26
27 public class XmlBlasterInvocationHandler implements I_Callback, java.lang.reflect.InvocationHandler {
28
29 static SerializeHelper ser;
30 static long messageID = -1;
31 private SubscribeKey subsKey = null;
32 private final Global global;
33 private static Logger log = Logger.getLogger(XmlBlasterInvocationHandler.class.getName());
34 private I_XmlBlasterAccess xmlBlasterAccess;
35 private String ME = "XmlBlasterInvocationHandler";
36 private static int port = 3424;
37
38 private Map callbackBuffer = Collections.synchronizedMap(new HashMap());
39
40 public XmlBlasterInvocationHandler(String serverName, Global global) {
41 this.global = global;
42 // this.global = Global.instance();
43
44 if (log.isLoggable(Level.FINER))
45 log.severe("Constructor for '" + serverName + "'");
46
47 log.info("XmlBlasterInvocationHandler called");
48
49 try {
50 Address addr = new Address(global);
51
52 Properties prop = new Properties();
53 prop.setProperty("bootstrapHostname",serverName);
54 prop.setProperty("bootstrapPort","3424");
55
56 global.init(prop);
57 this.xmlBlasterAccess = global.getXmlBlasterAccess();
58
59 log.info("Connecting to embedded xmlBlaster on port "+ port +" Address " + addr.getBootstrapUrl());
60 if (!this.xmlBlasterAccess.isConnected()) {
61 ConnectQos qos = new ConnectQos(this.global, "InternalConnector", "connector");
62 this.xmlBlasterAccess.connect(qos, this);
63 }
64 SubscribeKey subKey = new SubscribeKey(this.global, "xmlBlasterMBeans_Return");
65
66 SubscribeQos sQos = new SubscribeQos(this.global);
67 sQos.setWantLocal(false);
68 this.xmlBlasterAccess.subscribe(subKey, sQos);
69 }
70 catch (Exception ex) {
71 ex.printStackTrace();
72 }
73
74 }
75
76 /**
77 * Method Invoke is called by the client,
78 * The MethodName is extracted and wrapped into an MethodInvocation Object
79 * <p>
80 * The MethodInvocation is published to the the server.<br>
81 * The Mapping for the return values after the invocation is done via a callbackbuffer
82 */
83 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
84 String methodName = method.getName();
85 log.info("invoke: within XmlBlasterInvocationHandler called - Method called: " + method);
86 MethodInvocation mi = new MethodInvocation(method);
87 mi.setParams(args);
88
89 String ID = "" + messageID++;
90 mi.setId(ID);
91 log.info("invoke: Put MethodInvocation-ID into callback-buffer in order to rematch again '" + mi.getId() + "' and method '" + method.getName() + "'");
92 Callback cb = new XmlBlasterCallback(ID, mi);
93 callbackBuffer.put(ID, cb);
94
95 if (method.getName().equals("close")) {
96 if (log.isLoggable(Level.FINEST)) {
97 log.finest("invoke 'close': ");
98 Thread.currentThread().dumpStack();
99 }
100 close();
101 return null;
102 }
103
104 ser = new SerializeHelper(this.global);
105 PublishReturnQos rqos = this.xmlBlasterAccess.publish(new MsgUnit("<key oid='xmlBlasterMBeans_Invoke'/>",ser.serializeObject(mi),"<qos/>"));
106 log.info("invoke: Returning callback-object: " + cb);
107 return cb;
108 }
109
110
111 synchronized private void close() {
112 // this.xmlBlasterAccess.disconnect(new DisconnectQos());
113 log.severe("Disconnecting from xmlBlaster.... (not really disconnecting)");
114 }
115
116 /**
117 * Update invoked, when Message on subscribed Topic is received.
118 * Most probably it is the returning Object from a recent MethodInvocation
119 */
120 synchronized public String update(String cbSessionId, UpdateKey updateKey, byte[] content, UpdateQos updateQos)
121 {
122 if (log.isLoggable(Level.FINE)) this.log.fine("update: Received asynchronous message in \"update()\" clientSide '" +
123 updateKey.getOid() + "' state=" + updateQos.getState() + " from xmlBlaster - extracting MethodInvocation...");
124
125 //get MI from byteArray
126 MethodInvocation mi = null;
127 SerializeHelper serHelp = new SerializeHelper(global);
128 try {
129 mi = (MethodInvocation) serHelp.deserializeObject(content);
130 log.info("update: Method received: " + mi.getMethodName());
131 }
132 catch (Exception ex) {
133 log.severe("update: Error when trying to expand MethodInvocationObject " + ex.toString());
134 ex.printStackTrace();
135 }
136 String ID = mi.getId();
137 log.info(" update: ID from MethodInvocation that maps callback-buffer: " + ID);
138 XmlBlasterCallback cb = (XmlBlasterCallback) callbackBuffer.get(ID);
139 if (log.isLoggable(Level.FINE)) {
140 log.fine(" update: Whats in Received Object?? - " + mi.getReturnValue());
141 log.fine("update: the callback with ID '" + ID + "' is '" + cb + "'");
142 }
143 if (cb != null ) cb.setMethodInvocation(mi);
144 return "";
145 }
146 }
syntax highlighted by Code2HTML, v. 0.9.1