1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.miloss.fgsms.agents;
23
24 import com.sun.net.httpserver.HttpExchange;
25 import java.io.ByteArrayOutputStream;
26 import java.io.IOException;
27 import java.net.InetAddress;
28 import java.net.UnknownHostException;
29 import java.util.Map.Entry;
30 import java.util.*;
31 import javax.servlet.http.HttpServletRequest;
32 import javax.xml.namespace.QName;
33 import javax.xml.soap.SOAPMessage;
34 import javax.xml.ws.handler.soap.SOAPMessageContext;
35 import org.miloss.fgsms.agentcore.DependencyHelper;
36 import org.miloss.fgsms.agentcore.MessageProcessor;
37 import org.miloss.fgsms.agentcore.OneWayJudge;
38 import org.miloss.fgsms.common.Utility;
39 import org.apache.log4j.Level;
40 import org.miloss.fgsms.agentcore.IMessageProcessor;
41 import org.miloss.fgsms.common.Constants;
42 import org.miloss.fgsms.common.Logger;;
43
44
45
46
47
48
49 public class JbossWSCommonMessageHandler {
50
51 static final Logger log = Logger.getLogger(org.miloss.fgsms.common.Constants.LoggerName);
52
53 public static void ProcessRequest(SOAPMessageContext messageContext, boolean client, String classname) {
54 long now = System.currentTimeMillis();
55 boolean isoneway = false;
56
57
58
59
60
61
62
63
64
65
66 IMessageProcessor mp;
67 log.log(Level.TRACE, "JbossWSCommonMessageHandler.ProcessRequest1 timer: " + 0 + " thread:" + Thread.currentThread().getId());
68
69 log.log(Level.DEBUG, "Current VM Memory : total = " + Runtime.getRuntime().totalMemory() + " free = " + Runtime.getRuntime().freeMemory());
70 try {
71 mp = MessageProcessor.getSingletonObject();
72 } catch (Exception ex) {
73 log.log(Level.ERROR, "Unable to get a reference to the Message Processor singleton object. monitoring is not possible", ex);
74 return;
75 }
76 UUID id = UUID.randomUUID();
77 messageContext.put(org.miloss.fgsms.common.Constants.key, id);
78 SOAPMessage msg = messageContext.getMessage();
79
80
81 log.log(Level.DEBUG, "fgsms context is of type " + messageContext.getClass().getName() + " client=" + client + " class = " + classname);
82
83 String transactionthreadid = "";
84
85 HttpServletRequest ctx = null;
86 org.jboss.ws.core.jaxws.handler.SOAPMessageContextJAXWS ctx2 = null;
87 try {
88 ctx = (HttpServletRequest) messageContext.get(SOAPMessageContext.SERVLET_REQUEST);
89 } catch (Exception ex) {
90 }
91 try {
92 ctx2 = (org.jboss.ws.core.jaxws.handler.SOAPMessageContextJAXWS) messageContext;
93 } catch (Exception ex) {
94 }
95
96 String action = org.miloss.fgsms.common.Constants.Undetermineable;
97 java.util.Map<java.lang.String, java.util.List<java.lang.String>> headers = null;
98 try {
99 headers = (Map<String, List<String>>) messageContext.get(SOAPMessageContext.HTTP_REQUEST_HEADERS);
100 if (headers != null) {
101 List l = headers.get("SOAPAction");
102 if (l != null && !l.isEmpty()) {
103 action = (String) l.get(0);
104 }
105 }
106 } catch (Exception ex) {
107 log.log(Level.WARN, "error getting outbound soap action", ex);
108 }
109 if (action.equals(org.miloss.fgsms.common.Constants.Undetermineable)) {
110 try {
111
112 action = ctx.getHeader("SOAPAction");
113 if (Utility.stringIsNullOrEmpty(action)) {
114 action = org.miloss.fgsms.common.Constants.Undetermineable;
115 }
116 action = action.replace("\"", "");
117 action = action.replace("'", "");
118 if (Utility.stringIsNullOrEmpty(action)) {
119 action = org.miloss.fgsms.common.Constants.Undetermineable;
120 }
121
122
123
124
125 } catch (Exception ex) {
126 if (!client) {
127 log.log(Level.INFO, "fgsms error getting servlet context object " + ex.getLocalizedMessage() + ". For transactions monitored from the client, this is normal. IsClient? " + client);
128 }
129 }
130 }
131 if (action.equals(org.miloss.fgsms.common.Constants.Undetermineable) && ctx2 != null) {
132 Object j = ctx2.get(ctx2.WSDL_OPERATION);
133 if (j != null) {
134 QName q = (QName) j;
135 action = (String) q.toString();
136 if (Utility.stringIsNullOrEmpty(action)) {
137 action = org.miloss.fgsms.common.Constants.Undetermineable;
138 }
139 action = action.replace("\"", "");
140 action = action.replace("'", "");
141 if (Utility.stringIsNullOrEmpty(action)) {
142 action = org.miloss.fgsms.common.Constants.Undetermineable;
143 }
144 }
145 }
146
147 if (action.equals(org.miloss.fgsms.common.Constants.Undetermineable)) {
148 try {
149 Object j = messageContext.get(messageContext.WSDL_OPERATION);
150 if (j != null) {
151 action = (String) j;
152 action = action.replace("\"", "");
153 action = action.replace("'", "");
154 if (Utility.stringIsNullOrEmpty(action)) {
155 action = org.miloss.fgsms.common.Constants.Undetermineable;
156 }
157 }
158 } catch (Exception ex) {
159 }
160 }
161
162 if (action.toLowerCase().trim().equals(org.miloss.fgsms.common.Constants.DCSaction3.toLowerCase().trim())) {
163 log.log(Level.DEBUG, "fgsms, skipping the request for DCS AddData to prevent recursive looping. This is normal and no action is required.");
164 return;
165 }
166
167 if (action.toLowerCase().trim().equals(org.miloss.fgsms.common.Constants.DCSaction4.toLowerCase().trim())) {
168 log.log(Level.DEBUG, "fgsms, skipping the request for DCS AddData to prevent recursive looping. This is normal and no action is required.");
169 return;
170 }
171
172 if (action.toLowerCase().trim().equals(org.miloss.fgsms.common.Constants.DCSaction.toLowerCase().trim())) {
173 log.log(Level.DEBUG, "fgsms, skipping the request for DCS AddData to prevent recursive looping. This is normal and no action is required.");
174 return;
175 }
176
177 if (action.toLowerCase().trim().equals(org.miloss.fgsms.common.Constants.PCSaction.toLowerCase().trim())) {
178 log.log(Level.DEBUG, "fgsms, skipping the request for PCS GetServicePolicy to prevent recursive looping. This is normal and no action is required.");
179 return;
180 }
181
182 if (action.toLowerCase().trim().equals(org.miloss.fgsms.common.Constants.DCSaction2.toLowerCase().trim())) {
183 log.log(Level.DEBUG, "fgsms, skipping the request for DCS AddData to prevent recursive looping. This is normal and no action is required.");
184 return;
185 }
186
187 if (action.toLowerCase().trim().equals(org.miloss.fgsms.common.Constants.PCSaction2.toLowerCase().trim())) {
188 log.log(Level.DEBUG, "fgsms, skipping the request for PCS GetServicePolicy to prevent recursive looping. This is normal and no action is required.");
189 return;
190 }
191
192
193 ByteArrayOutputStream b = new ByteArrayOutputStream();
194 String messagexml = "";
195 try {
196 msg.writeTo(b);
197 messagexml = b.toString();
198 } catch (Exception ex) {
199 log.log(Level.WARN, "fgsms, error obtaining request message.", ex);
200 messagexml = "fgsms was unable to obtain the request message.";
201 } finally {
202 try {
203 b.close();
204 } catch (Exception ex) {
205 }
206 }
207 log.log(Level.TRACE, "JbossWSCommonMessageHandler.ProcessRequest2 timer: " + (System.currentTimeMillis() - now) + " thread:" + Thread.currentThread().getId());
208 if (action.equals(org.miloss.fgsms.common.Constants.Undetermineable)) {
209 action = Utility.getActionNameFromXML(messagexml);
210 if (Utility.stringIsNullOrEmpty(action)) {
211 action = org.miloss.fgsms.common.Constants.Undetermineable;
212 }
213 action = action.replace("\"", "");
214 action = action.replace("'", "");
215 if (Utility.stringIsNullOrEmpty(action)) {
216 action = org.miloss.fgsms.common.Constants.Undetermineable;
217 }
218 }
219 if (action.equals(org.miloss.fgsms.common.Constants.Undetermineable)) {
220 Object j = messageContext.get(messageContext.HTTP_REQUEST_METHOD);
221 if (j != null) {
222 action = (String) j;
223 if (Utility.stringIsNullOrEmpty(action)) {
224 action = org.miloss.fgsms.common.Constants.Undetermineable;
225 }
226 action = action.replace("\"", "");
227 action = action.replace("'", "");
228 if (Utility.stringIsNullOrEmpty(action)) {
229 action = org.miloss.fgsms.common.Constants.Undetermineable;
230 }
231 }
232 }
233
234 if (ctx == null && !client) {
235 log.log(Level.WARN, "ctx object is unexpectedly null" + client);
236 }
237
238 String requestURL = "";
239 if (Utility.stringIsNullOrEmpty(requestURL)) {
240 try {
241 Object j = messageContext.get("javax.xml.ws.service.endpoint.address");
242 if (j != null) {
243 requestURL = (String) j;
244 }
245 } catch (Exception ex) {
246 log.log(Level.WARN, "fgsms error getting request url " + ex.getLocalizedMessage());
247 }
248 }
249 if ((Utility.stringIsNullOrEmpty(requestURL)) && ctx != null) {
250 try {
251 StringBuffer buff = ctx.getRequestURL();
252 requestURL = buff.toString();
253 } catch (Exception ex) {
254 log.log(Level.WARN, "fgsms error getting request url " + ex.getLocalizedMessage());
255
256 }
257 }
258
259
260 if (Utility.stringIsNullOrEmpty(requestURL) && messageContext.containsKey("com.sun.xml.internal.ws.http.exchange")) {
261 try {
262 HttpExchange exchg = (HttpExchange) messageContext.get("com.sun.xml.internal.ws.http.exchange");
263 requestURL = ((exchg.getProtocol().toLowerCase().startsWith("https")) ? "https:/" : "http:/") + exchg.getLocalAddress().toString() + exchg.getRequestURI().toString();
264
265 } catch (Exception ex) {
266 }
267 }
268
269
270 if (Utility.stringIsNullOrEmpty(requestURL)) {
271 requestURL = "urn:" + MessageProcessor.getSingletonObject().getHostName() + ":undeterminable";
272 }
273 if (Utility.stringIsNullOrEmpty(action)) {
274 action = org.miloss.fgsms.common.Constants.Undetermineable;
275 }
276
277 action = action.replace("\"", "");
278 action = action.replace("'", "");
279
280
281 log.log(Level.TRACE, "JbossWSCommonMessageHandler.ProcessRequest3 timer: " + (System.currentTimeMillis() - now) + " thread:" + Thread.currentThread().getId());
282 String user = "";
283
284
285 try {
286 if (ctx != null && ctx.getAuthType() != null && ctx.getUserPrincipal() != null) {
287 user = ctx.getUserPrincipal().getName();
288 }
289 } catch (Exception ex) {
290 log.log(Level.WARN, "fgsms error getting user principal " + ex.getLocalizedMessage());
291 }
292
293
294 String ipaddress = "";
295 if (client) {
296
297
298 transactionthreadid = MessageProcessor.getSingletonObject().getTransactionThreadId(Thread.currentThread().getId());
299 if (Utility.stringIsNullOrEmpty(transactionthreadid)) {
300
301 try {
302 transactionthreadid = UUID.randomUUID().toString();
303
304 } catch (Exception ex) {
305 log.log(Level.WARN, "error caught build transaction thread id", ex);
306 }
307
308 }
309
310
311
312
313 if (headers == null) {
314 headers = new HashMap<String, List<String>>();
315 }
316 if (MessageProcessor.getSingletonObject().isDependencyInjectionEnabled()) {
317 ArrayList t = new ArrayList();
318 t.add(transactionthreadid);
319 headers.put(org.miloss.fgsms.common.Constants.transactionthreadKey, t);
320 t = new ArrayList();
321 t.add(id.toString());
322 headers.put(org.miloss.fgsms.common.Constants.relatedtransactionKey, t);
323
324
325 messageContext.remove(messageContext.HTTP_REQUEST_HEADERS);
326 messageContext.put(messageContext.HTTP_REQUEST_HEADERS, headers);
327
328 DependencyHelper.insertRelatedMessageHeader(id.toString(), messageContext);
329 DependencyHelper.insertThreadIdHeader(transactionthreadid, messageContext);
330 }
331
332 try {
333 InetAddress addr = InetAddress.getLocalHost();
334 ipaddress = addr.getHostAddress();
335 } catch (UnknownHostException ex) {
336 log.log(Level.ERROR, "error obtaining local ip address", ex);
337 }
338 } else {
339 if (ctx != null) {
340 ipaddress = ctx.getRemoteAddr();
341 }
342
343 }
344 log.log(Level.TRACE, "JbossWSCommonMessageHandler.ProcessRequest4 timer: " + (System.currentTimeMillis() - now) + " thread:" + Thread.currentThread().getId());
345 String relatedTransaction = null;
346
347 if (!client) {
348
349
350
351
352
353
354 if (headers.containsKey(org.miloss.fgsms.common.Constants.relatedtransactionKey)) {
355 relatedTransaction = ((List<String>) headers.get(org.miloss.fgsms.common.Constants.relatedtransactionKey)).get(0);
356 }
357 if (headers.containsKey(org.miloss.fgsms.common.Constants.transactionthreadKey)) {
358 transactionthreadid = ((List<String>) headers.get(org.miloss.fgsms.common.Constants.transactionthreadKey)).get(0);
359 }
360 if (Utility.stringIsNullOrEmpty(transactionthreadid)) {
361 transactionthreadid = DependencyHelper.getThreadIdFromSoapHeader(messageContext);
362 }
363 if (Utility.stringIsNullOrEmpty(relatedTransaction)) {
364 relatedTransaction = DependencyHelper.getRelatedMessageIdFromSoapHeader(messageContext);
365 }
366 if (Utility.stringIsNullOrEmpty(transactionthreadid)) {
367 transactionthreadid = UUID.randomUUID().toString();
368 }
369 try {
370 MessageProcessor.getSingletonObject().setTransactionThreadId(Thread.currentThread().getId(), transactionthreadid);
371 } catch (Exception ex) {
372 }
373 }
374 log.log(Level.TRACE, "JbossWSCommonMessageHandler.ProcessRequest5 timer: " + (System.currentTimeMillis() - now) + " thread:" + Thread.currentThread().getId());
375 HashMap headervalues = new HashMap();
376 if (ctx != null && headers == null) {
377 try {
378 Enumeration<String> headersnames = ctx.getHeaderNames();
379
380 while (headersnames.hasMoreElements()) {
381 String s = headersnames.nextElement();
382 headervalues.put(s, ctx.getHeader(s));
383
384 }
385 } catch (Exception ex) {
386 log.log(Level.WARN, "fgsms error getting http headers " + ex.getLocalizedMessage());
387 }
388 } else {
389 if (headers != null) {
390 Iterator<Entry<String, List<String>>> headersnames = headers.entrySet().iterator();
391
392 while (headersnames.hasNext()) {
393 Entry<String, List<String>> s = headersnames.next();
394 headervalues.put(s.getKey(), s.getValue());
395
396 }
397
398 }
399
400 }
401
402 if (ctx != null) {
403 try {
404 String query = ctx.getQueryString();
405 if (query != null && (query == null ? "null" != null : !query.equals("null"))) {
406 requestURL += "?" + query;
407 }
408 } catch (Exception ex) {
409 log.log(Level.WARN, "fgsms error getting request query string " + ex.getLocalizedMessage());
410 }
411 }
412
413 messageContext.put(org.miloss.fgsms.common.Constants.urlKEY, requestURL);
414 log.log(Level.DEBUG, "fgsms Message intercepted, this is a request message to " + requestURL + " with the SOAPAction of " + action + ". Assigning message id:" + id.toString() + " " + classname + " thread " + transactionthreadid);
415
416 log.log(Level.TRACE, "JbossWSCommonMessageHandler.ProcessRequest6 timer: " + (System.currentTimeMillis() - now) + " thread:" + Thread.currentThread().getId());
417 try {
418 MessageProcessor.getSingletonObject().processMessageInput(messagexml, messagexml.length(), requestURL, action, user, id.toString(), headervalues, ipaddress, classname, relatedTransaction, transactionthreadid);
419 } catch (Exception ex) {
420 log.log(Level.ERROR, "Unable to get a reference to the MessageProcessor.ProcessMessageInput", ex);
421 }
422 isoneway = isoneway || DetermineOneWay(requestURL, messageContext, action);
423 if (isoneway) {
424 messageContext.put(org.miloss.fgsms.common.Constants.oneway, true);
425 ProcessResponse(messageContext, false, client, classname);
426 }
427 log.log(Level.TRACE, "JbossWSCommonMessageHandler.ProcessRequest6 timer: " + (System.currentTimeMillis() - now) + " thread:" + Thread.currentThread().getId());
428
429 }
430
431 public static void ProcessResponse(SOAPMessageContext messageContext, boolean fault, boolean client, String classname) {
432 long now = System.currentTimeMillis();
433 log.log(Level.TRACE, "JbossWSCommonMessageHandler.ProcessResponse0 timer: " + (System.currentTimeMillis() - now) + " thread:" + Thread.currentThread().getId());
434
435 boolean isoneway = messageContext.containsKey(org.miloss.fgsms.common.Constants.oneway);
436
437
438 log.log(Level.DEBUG, "Current VM Memory : total = " + Runtime.getRuntime().totalMemory() + " free = " + Runtime.getRuntime().freeMemory());
439
440 UUID id = (UUID) messageContext.get(org.miloss.fgsms.common.Constants.key);
441 String requrl = (String) messageContext.get(org.miloss.fgsms.common.Constants.urlKEY);
442 boolean ok = true;
443 if (id == null) {
444 log.log(Level.DEBUG, "fgsms reply message did not have context variable " + org.miloss.fgsms.common.Constants.key + " added. This transaction will be ignored.");
445 ok = false;
446 }
447 if (Utility.stringIsNullOrEmpty(requrl)) {
448 log.log(Level.DEBUG, "fgsms reply message did not have context variable " + org.miloss.fgsms.common.Constants.urlKEY + " added. This transaction will be ignored.");
449 ok = false;
450 }
451 String relatedTransaction = null;
452 if (!ok) {
453 if (id != null) {
454 MessageProcessor.getSingletonObject().removeFromQueue(id);
455 }
456 return;
457 }
458 log.log(Level.TRACE, "JbossWSCommonMessageHandler.ProcessResponse1 timer: " + (System.currentTimeMillis() - now) + " thread:" + Thread.currentThread().getId());
459 HashMap headervalues = new HashMap();
460
461
462 if (client && !isoneway) {
463 try {
464 Map headers = (Map) messageContext.get(messageContext.HTTP_RESPONSE_HEADERS);
465 if (headers != null) {
466 log.log(Level.DEBUG, "client received " + headers.size() + " transaction " + id.toString());
467
468 Iterator<Entry<String, List<String>>> it = headers.entrySet().iterator();
469 while (it.hasNext()) {
470 Entry<String, List<String>> s = (Entry<String, List<String>>) it.next();
471
472 headervalues.put(s.getKey(), s.getValue());
473 }
474 if (headers.containsKey(org.miloss.fgsms.common.Constants.relatedtransactionKey)) {
475 relatedTransaction = (String) headers.get(org.miloss.fgsms.common.Constants.relatedtransactionKey);
476 }
477 }
478
479
480
481
482
483
484
485
486
487 } catch (Exception ex) {
488 log.log(Level.ERROR, "Unexpected error caught when searching for fgsms soap header", ex);
489 }
490 if (Utility.stringIsNullOrEmpty(relatedTransaction)) {
491 relatedTransaction = DependencyHelper.getRelatedMessageIdFromSoapHeader(messageContext);
492 }
493 }
494 log.log(Level.TRACE, "JbossWSCommonMessageHandler.ProcessResponse2 timer: " + (System.currentTimeMillis() - now) + " thread:" + Thread.currentThread().getId());
495 if (!client && !isoneway) {
496
497 ArrayList<String> l = new ArrayList<String>();
498 l.add(id.toString());
499 ArrayList<String> threadlist = new ArrayList<String>();
500 threadlist.add(MessageProcessor.getSingletonObject().getTransactionThreadId(Thread.currentThread().getId()));
501 java.util.Map<java.lang.String, java.util.List<java.lang.String>> headers = (Map<String, List<String>>) messageContext.get(messageContext.HTTP_RESPONSE_HEADERS);
502 if (MessageProcessor.getSingletonObject().isDependencyInjectionEnabled()) {
503 DependencyHelper.insertRelatedMessageHeader(id.toString(), messageContext);
504 DependencyHelper.insertThreadIdHeader(threadlist.get(0), messageContext);
505 if (headers != null) {
506 headers.put(org.miloss.fgsms.common.Constants.relatedtransactionKey, l);
507 } else {
508 headers = new HashMap<String, List<String>>();
509 headers.put(org.miloss.fgsms.common.Constants.relatedtransactionKey, l);
510 headers.put(org.miloss.fgsms.common.Constants.transactionthreadKey, threadlist);
511 messageContext.put(messageContext.HTTP_RESPONSE_HEADERS, headers);
512
513 }
514 }
515 Iterator<Entry<String, List<String>>> it = headers.entrySet().iterator();
516 while (it.hasNext()) {
517 Entry<String, List<String>> s = (Entry<String, List<String>>) it.next();
518
519 headervalues.put(s.getKey(), s.getValue());
520 }
521 }
522
523
524
525 SOAPMessage msg = messageContext.getMessage();
526 ByteArrayOutputStream b = new ByteArrayOutputStream();
527 String messagexml = "";
528 if (!isoneway) {
529 try {
530 msg.writeTo(b);
531 messagexml = b.toString(Constants.CHARSET);
532 } catch (Exception ex) {
533 log.log(Level.WARN, "fgsms, error obtaining response message.", ex);
534 messagexml = "fgsms was unable to obtain response message.";
535 } finally {
536 try {
537 b.close();
538 } catch (IOException ex) {
539 }
540 }
541 }
542
543 log.log(Level.TRACE, "JbossWSCommonMessageHandler.ProcessResponse3 timer: " + (System.currentTimeMillis() - now) + " thread:" + Thread.currentThread().getId());
544 String code2 = "200";
545 try {
546 Object j = messageContext.get(messageContext.HTTP_RESPONSE_CODE).toString();
547 if (j != null) {
548 code2 = j.toString();
549 if (!code2.contains("200")) {
550 log.log(Level.DEBUG, "fgsms response code is " + code2 + " id = " + id.toString() + " fault was " + fault + " is now true");
551 fault = true;
552 } else {
553 log.log(Level.DEBUG, "fgsms soap framework states that the response fault=" + fault);
554 }
555 headervalues.put("RESPONSE_CODE", code2);
556 }
557 } catch (Exception ex) {
558 }
559
560
561 log.log(Level.DEBUG, "fgsms Message intercepted, this is a response message transaction id:" + id.toString() + " fault=" + fault + " " + classname);
562
563 log.log(Level.TRACE, "JbossWSCommonMessageHandler.ProcessResponse4 timer: " + (System.currentTimeMillis() - now) + " thread:" + Thread.currentThread().getId());
564 MessageProcessor.getSingletonObject().processMessageOutput(id.toString(), messagexml, messagexml.length(), fault, Long.valueOf(System.currentTimeMillis()), headervalues, relatedTransaction);
565
566 log.log(Level.TRACE, "JbossWSCommonMessageHandler.ProcessResponse5 timer: " + (System.currentTimeMillis() - now) + " thread:" + Thread.currentThread().getId());
567 if (!client) {
568 MessageProcessor.getSingletonObject().clearTransactionThreadId(Thread.currentThread().getId());
569 }
570 log.log(Level.TRACE, "JbossWSCommonMessageHandler.ProcessResponse6 timer: " + (System.currentTimeMillis() - now) + " thread:" + Thread.currentThread().getId());
571
572 }
573
574 private static boolean DetermineOneWay(String requestURL, SOAPMessageContext messageContext, String action) {
575 return OneWayJudge.determineOneWay(requestURL, messageContext, action);
576 }
577
578
579 }