1 | // jademx - JADE management using JMX |
2 | // Copyright 2005-2006 Caboodle Networks, Inc. |
3 | // |
4 | // This library is free software; you can redistribute it and/or |
5 | // modify it under the terms of the GNU Lesser General Public |
6 | // License as published by the Free Software Foundation; either |
7 | // version 2.1 of the License, or (at your option) any later version. |
8 | // |
9 | // This library is distributed in the hope that it will be useful, |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | // Lesser General Public License for more details. |
13 | // |
14 | // You should have received a copy of the GNU Lesser General Public |
15 | // License along with this library; if not, write to the Free Software |
16 | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
17 | |
18 | package jade.jademx.agent; |
19 | |
20 | import jade.content.lang.sl.SLCodec; |
21 | import jade.core.Agent; |
22 | import jade.domain.FIPANames; |
23 | import jade.domain.FIPAAgentManagement.FIPAManagementOntology; |
24 | import jade.domain.JADEAgentManagement.JADEManagementOntology; |
25 | import jade.domain.introspection.IntrospectionOntology; |
26 | import jade.jademx.mbean.JadeAgent; |
27 | import jade.jademx.mbean.JadeJMXAgent; |
28 | import jade.jademx.mbean.JadePlatform; |
29 | import jade.jademx.mbean.JadeRuntime; |
30 | import jade.jademx.mbean.JadeRuntimeMBean; |
31 | import jade.jademx.mbean.JademxException; |
32 | import jade.jademx.server.JadeMXServer; |
33 | import jade.jademx.server.JadeMXServerFactory; |
34 | import jade.jademx.unit.UnitTestBehaviour; |
35 | import jade.jademx.unit.UnitTestNotificationListener; |
36 | import jade.jademx.util.AclMsgCmp; |
37 | import jade.jademx.util.MBeanUtil; |
38 | import jade.jademx.util.ThrowableUtil; |
39 | import jade.jademx.util.iso8601.Duration; |
40 | import jade.lang.acl.ACLMessage; |
41 | import jade.lang.acl.ACLCodec.CodecException; |
42 | import jade.util.Logger; |
43 | |
44 | import java.util.Date; |
45 | import java.util.Properties; |
46 | import java.util.logging.Level; |
47 | |
48 | import javax.management.Attribute; |
49 | import javax.management.AttributeList; |
50 | import javax.management.AttributeNotFoundException; |
51 | import javax.management.InvalidAttributeValueException; |
52 | import javax.management.MBeanAttributeInfo; |
53 | import javax.management.MBeanConstructorInfo; |
54 | import javax.management.MBeanException; |
55 | import javax.management.MBeanInfo; |
56 | import javax.management.MBeanNotificationInfo; |
57 | import javax.management.MBeanOperationInfo; |
58 | import javax.management.MBeanParameterInfo; |
59 | import javax.management.MBeanServer; |
60 | import javax.management.Notification; |
61 | import javax.management.ObjectName; |
62 | import javax.management.ReflectionException; |
63 | |
64 | import junit.framework.Assert; |
65 | |
66 | /** |
67 | * base class for agent to be managed by jademx. |
68 | * if you override any of the DynamicMBean methods, then be aware that they |
69 | * may be called by a thread different from the one running regular behaviours |
70 | * and so you need to be careful about field access, deadlock, etc. |
71 | * TODO: make sure don't have multiple threads running unit tests......... |
72 | * @author David Bernstein, <a href="http://www.caboodlenetworks.com" |
73 | * >Caboodle Networks, Inc.</a> |
74 | */ |
75 | public class JademxAgent extends Agent implements JadeJMXAgent { |
76 | |
77 | // |
78 | // ATTRIBUTES |
79 | // |
80 | |
81 | // unit testing attributes |
82 | |
83 | /** expected ACL message attribute name */ |
84 | public static final String ATTR_UNIT_TEST_EXPECTED_MESSAGE_NAME = |
85 | "UnitTestExpectedMessage"; |
86 | /** expected ACL message attribute description */ |
87 | private static final String ATTR_UNIT_TEST_EXPECTED_MESSAGE_DESC = |
88 | "ACL message expected after inject an ACL message, as string"; |
89 | /** expected ACL message attribute type */ |
90 | private final static String ATTR_UNIT_TEST_EXPECTED_MESSAGE_TYPE = |
91 | String.class.getName(); |
92 | |
93 | |
94 | /** inject ACL message attribute name */ |
95 | public static final String ATTR_UNIT_TEST_INJECT_MESSAGE_NAME = |
96 | "UnitTestInjectMessage"; |
97 | /** inject ACL message attribute description */ |
98 | private static final String ATTR_UNIT_TEST_INJECT_MESSAGE_DESC = |
99 | "ACL message to inject for unit testing, as string"; |
100 | /** inject ACL message attribute type */ |
101 | private final static String ATTR_UNIT_TEST_INJECT_MESSAGE_TYPE = |
102 | String.class.getName(); |
103 | |
104 | /** timeout attribute name */ |
105 | public static final String ATTR_UNIT_TEST_TIMEOUT_NAME = |
106 | "UnitTestTimeout"; |
107 | /** timeout attribute description */ |
108 | private static final String ATTR_UNIT_TEST_TIMEOUT_DESC = |
109 | "timeout expressed as ISO8601 duration, e.g. PT1M"; |
110 | /** timeout attribute type */ |
111 | private final static String ATTR_UNIT_TEST_TIMEOUT_TYPE = |
112 | String.class.getName(); |
113 | |
114 | /** actual ACL message attribute name */ |
115 | public static final String ATTR_UNIT_TEST_ACTUAL_MESSAGE_NAME = |
116 | "UnitTestActualMessage"; |
117 | /** actual ACL message attribute description */ |
118 | private static final String ATTR_UNIT_TEST_ACTUAL_MESSAGE_DESC = |
119 | "actual generated ACL message compared after inject an ACL message, as string"; |
120 | /** actual ACL message attribute type */ |
121 | private final static String ATTR_UNIT_TEST_ACTUAL_MESSAGE_TYPE = |
122 | String.class.getName(); |
123 | |
124 | // unit testing flags for governing message comparison |
125 | |
126 | /** compare content attribute name */ |
127 | public static final String ATTR_UNIT_TEST_CMP_CONTENT_NAME = |
128 | "UnitTestCmpContent"; |
129 | /** compare content attribute description */ |
130 | private static final String ATTR_UNIT_TEST_CMP_CONTENT_DESC = |
131 | "compare content"; |
132 | /** compare content attribute type */ |
133 | private final static String ATTR_UNIT_TEST_CMP_CONTENT_TYPE = |
134 | boolean.class.getName(); |
135 | |
136 | /** compare conversation-id attribute name */ |
137 | public static final String ATTR_UNIT_TEST_CMP_CONVERSATION_ID_NAME = |
138 | "UnitTestCmpConversationId"; |
139 | /** compare conversation-id attribute description */ |
140 | private static final String ATTR_UNIT_TEST_CMP_CONVERSATION_ID_DESC = |
141 | "compare conversation-id"; |
142 | /** compare conversation-id attribute type */ |
143 | private final static String ATTR_UNIT_TEST_CMP_CONVERSATION_ID_TYPE = |
144 | boolean.class.getName(); |
145 | |
146 | /** compare encoding attribute name */ |
147 | public static final String ATTR_UNIT_TEST_CMP_ENCODING_NAME = |
148 | "UnitTestCmpEncoding"; |
149 | /** compare encoding attribute description */ |
150 | private static final String ATTR_UNIT_TEST_CMP_ENCODING_DESC = |
151 | "compare encoding"; |
152 | /** compare encoding attribute type */ |
153 | private final static String ATTR_UNIT_TEST_CMP_ENCODING_TYPE = |
154 | boolean.class.getName(); |
155 | |
156 | /** compare envelope attribute name */ |
157 | public static final String ATTR_UNIT_TEST_CMP_ENVELOPE_NAME = |
158 | "UnitTestCmpEnvelope"; |
159 | /** compare envelope attribute description */ |
160 | private static final String ATTR_UNIT_TEST_CMP_ENVELOPE_DESC = |
161 | "compare envelope"; |
162 | /** compare envelope attribute type */ |
163 | private final static String ATTR_UNIT_TEST_CMP_ENVELOPE_TYPE = |
164 | boolean.class.getName(); |
165 | |
166 | /** compare in-reply-to attribute name */ |
167 | public static final String ATTR_UNIT_TEST_CMP_IN_REPLY_TO_NAME = |
168 | "UnitTestCmpInReplyTo"; |
169 | /** compare in-reply-to attribute description */ |
170 | private static final String ATTR_UNIT_TEST_CMP_IN_REPLY_TO_DESC = |
171 | "compare in-reply-to"; |
172 | /** compare in-reply-to attribute type */ |
173 | private final static String ATTR_UNIT_TEST_CMP_IN_REPLY_TO_TYPE = |
174 | boolean.class.getName(); |
175 | |
176 | /** compare language attribute name */ |
177 | public static final String ATTR_UNIT_TEST_CMP_LANGUAGE_NAME = |
178 | "UnitTestCmpLanguage"; |
179 | /** compare language attribute description */ |
180 | private static final String ATTR_UNIT_TEST_CMP_LANGUAGE_DESC = |
181 | "compare language"; |
182 | /** compare language attribute type */ |
183 | private final static String ATTR_UNIT_TEST_CMP_LANGUAGE_TYPE = |
184 | boolean.class.getName(); |
185 | |
186 | /** compare ontology attribute name */ |
187 | public static final String ATTR_UNIT_TEST_CMP_ONTOLOGY_NAME = |
188 | "UnitTestCmpOntology"; |
189 | /** compare ontology attribute description */ |
190 | private static final String ATTR_UNIT_TEST_CMP_ONTOLOGY_DESC = |
191 | "compare ontology"; |
192 | /** compare ontology attribute type */ |
193 | private final static String ATTR_UNIT_TEST_CMP_ONTOLOGY_TYPE = |
194 | boolean.class.getName(); |
195 | |
196 | /** compare performative attribute name */ |
197 | public static final String ATTR_UNIT_TEST_CMP_PERFORMATIVE_NAME = |
198 | "UnitTestCmpPerformative"; |
199 | /** compare performative attribute description */ |
200 | private static final String ATTR_UNIT_TEST_CMP_PERFORMATIVE_DESC = |
201 | "compare performative"; |
202 | /** compare performative attribute type */ |
203 | private final static String ATTR_UNIT_TEST_CMP_PERFORMATIVE_TYPE = |
204 | boolean.class.getName(); |
205 | |
206 | /** compare protocol attribute name */ |
207 | public static final String ATTR_UNIT_TEST_CMP_PROTOCOL_NAME = |
208 | "UnitTestCmpProtocol"; |
209 | /** compare protocol attribute description */ |
210 | private static final String ATTR_UNIT_TEST_CMP_PROTOCOL_DESC = |
211 | "compare protocol"; |
212 | /** compare protocol attribute type */ |
213 | private final static String ATTR_UNIT_TEST_CMP_PROTOCOL_TYPE = |
214 | boolean.class.getName(); |
215 | |
216 | /** compare receiver attribute name */ |
217 | public static final String ATTR_UNIT_TEST_CMP_RECEIVER_NAME = |
218 | "UnitTestCmpReceiver"; |
219 | /** compare receiver attribute description */ |
220 | private static final String ATTR_UNIT_TEST_CMP_RECEIVER_DESC = |
221 | "compare receiver"; |
222 | /** compare receiver attribute type */ |
223 | private final static String ATTR_UNIT_TEST_CMP_RECEIVER_TYPE = |
224 | boolean.class.getName(); |
225 | |
226 | /** compare reply-by attribute name */ |
227 | public static final String ATTR_UNIT_TEST_CMP_REPLY_BY_NAME = |
228 | "UnitTestCmpReplyBy"; |
229 | /** compare reply-by attribute description */ |
230 | private static final String ATTR_UNIT_TEST_CMP_REPLY_BY_DESC = |
231 | "compare reply-by"; |
232 | /** compare reply-by attribute type */ |
233 | private final static String ATTR_UNIT_TEST_CMP_REPLY_BY_TYPE = |
234 | boolean.class.getName(); |
235 | |
236 | /** compare reply-to attribute name */ |
237 | public static final String ATTR_UNIT_TEST_CMP_REPLY_TO_NAME = |
238 | "UnitTestCmpReplyTo"; |
239 | /** compare reply-to attribute description */ |
240 | private static final String ATTR_UNIT_TEST_CMP_REPLY_TO_DESC = |
241 | "compare reply-to"; |
242 | /** compare reply-to attribute type */ |
243 | private final static String ATTR_UNIT_TEST_CMP_REPLY_TO_TYPE = |
244 | boolean.class.getName(); |
245 | |
246 | /** compare reply-with attribute name */ |
247 | public static final String ATTR_UNIT_TEST_CMP_REPLY_WITH_NAME = |
248 | "UnitTestCmpReplyWith"; |
249 | /** compare reply-with attribute description */ |
250 | private static final String ATTR_UNIT_TEST_CMP_REPLY_WITH_DESC = |
251 | "compare reply-with"; |
252 | /** compare reply-with attribute type */ |
253 | private final static String ATTR_UNIT_TEST_CMP_REPLY_WITH_TYPE = |
254 | boolean.class.getName(); |
255 | |
256 | /** compare sender attribute name */ |
257 | public static final String ATTR_UNIT_TEST_CMP_SENDER_NAME = |
258 | "UnitTestCmpSender"; |
259 | /** compare sender attribute description */ |
260 | private static final String ATTR_UNIT_TEST_CMP_SENDER_DESC = |
261 | "compare sender"; |
262 | /** compare sender attribute type */ |
263 | private final static String ATTR_UNIT_TEST_CMP_SENDER_TYPE = |
264 | boolean.class.getName(); |
265 | |
266 | /** compare user-properties attribute name */ |
267 | public static final String ATTR_UNIT_TEST_CMP_USER_PROPERTIES_NAME = |
268 | "UnitTestCmpUserProperties"; |
269 | /** compare user-properties attribute description */ |
270 | private static final String ATTR_UNIT_TEST_CMP_USER_PROPERTIES_DESC = |
271 | "compare user-properties"; |
272 | /** compare user-properties attribute type */ |
273 | private final static String ATTR_UNIT_TEST_CMP_USER_PROPERTIES_TYPE = |
274 | boolean.class.getName(); |
275 | |
276 | /** ignore content AID addresses attribute name */ |
277 | public static final String ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_NAME = |
278 | "UnitTestCmpIgnoreContentAIDAddresses"; |
279 | /** ignore content AID addresses attribute description */ |
280 | private static final String ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_DESC = |
281 | "ignore content AID addresses"; |
282 | /** ignore content AID addresses attribute type */ |
283 | private final static String ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_TYPE = |
284 | boolean.class.getName(); |
285 | |
286 | /** newlines normalized attribute name */ |
287 | public static final String ATTR_UNIT_TEST_NEWLINES_NORMALIZED_NAME = |
288 | "UnitTestNewlinesNormalized"; |
289 | /** newlines normalized attribute description */ |
290 | private static final String ATTR_UNIT_TEST_NEWLINES_NORMALIZED_DESC = |
291 | "newlines normalized"; |
292 | /** newlines normalized attribute type */ |
293 | private final static String ATTR_UNIT_TEST_NEWLINES_NORMALIZED_TYPE = |
294 | boolean.class.getName(); |
295 | |
296 | // |
297 | // OPERATIONS |
298 | // |
299 | |
300 | // |
301 | // unit testing operations |
302 | // |
303 | |
304 | // unitTestInjectAndExpect |
305 | |
306 | /** unitTestInjectAndExpect operation name */ |
307 | public final static String OPER_UNIT_TEST_INJECT_AND_EXPECT_NAME = |
308 | "unitTestInjectAndExpect"; |
309 | /** unitTestInjectAndExpect operation description */ |
310 | private final static String OPER_UNIT_TEST_INJECT_AND_EXPECT_DESC = |
311 | "inject an ACL message to agent and notify based on expected message"; |
312 | /** signature for a unitTestInjectAndExpect operation */ |
313 | public final static String OPER_UNIT_TEST_INJECT_AND_EXPECT_SIGNATURE[] = { |
314 | }; |
315 | /** return type for unitTestInjectAndExpect operation */ |
316 | public final static String OPER_UNIT_TEST_INJECT_AND_EXPECT_TYPE = |
317 | void.class.getName(); |
318 | |
319 | // unitTestAddVariable |
320 | |
321 | /** addVariable operation name */ |
322 | public final static String OPER_UNIT_TEST_ADD_VARIABLE_NAME = |
323 | "unitTestAddVariable"; |
324 | /** addVariable operation description */ |
325 | private final static String OPER_UNIT_TEST_ADD_VARIABLE_DESC = |
326 | "add a message comparison variable"; |
327 | /** variable parameter name */ |
328 | private final static String OPER_UNIT_TEST_ADD_VARIABLE_VARIABLE_PARM_NAME = |
329 | "variable"; |
330 | /** variable parameter type */ |
331 | private final static String OPER_UNIT_TEST_ADD_VARIABLE_VARIABLE_PARM_TYPE = |
332 | String.class.getName(); |
333 | /** variable parameter description */ |
334 | private final static String OPER_UNIT_TEST_ADD_VARIABLE_VARIABLE_PARM_DESC = |
335 | "String expected to be different from one message to next"; |
336 | /** type parameter name */ |
337 | private final static String OPER_UNIT_TEST_ADD_VARIABLE_TYPE_PARM_NAME = |
338 | "type"; |
339 | /** type parameter type */ |
340 | private final static String OPER_UNIT_TEST_ADD_VARIABLE_TYPE_PARM_TYPE = |
341 | String.class.getName(); |
342 | /** type parameter description */ |
343 | private final static String OPER_UNIT_TEST_ADD_VARIABLE_TYPE_PARM_DESC = |
344 | "grouping for variable, see AclMsgCmp.*_MAP"; |
345 | /** signature for a addVariable operation */ |
346 | public final static String OPER_UNIT_TEST_ADD_VARIABLE_SIGNATURE[] = { |
347 | OPER_UNIT_TEST_ADD_VARIABLE_VARIABLE_PARM_TYPE, |
348 | OPER_UNIT_TEST_ADD_VARIABLE_TYPE_PARM_TYPE |
349 | }; |
350 | /** return type for addVariable operation */ |
351 | public final static String OPER_UNIT_TEST_ADD_VARIABLE_TYPE = |
352 | void.class.getName(); |
353 | |
354 | // unitTestClearVariables |
355 | |
356 | /** clearVariables operation name */ |
357 | public final static String OPER_UNIT_TEST_CLEAR_VARIABLES_NAME = |
358 | "unitTestClearVariables"; |
359 | /** clearVariables operation description */ |
360 | private final static String OPER_UNIT_TEST_CLEAR_VARIABLES_DESC = |
361 | "clear message comparison variables"; |
362 | /** signature for a clearVariables operation */ |
363 | public final static String OPER_UNIT_TEST_CLEAR_VARIABLES_SIGNATURE[] = { |
364 | }; |
365 | /** return type for addVariable operation */ |
366 | public final static String OPER_UNIT_TEST_CLEAR_VARIABLES_TYPE = |
367 | void.class.getName(); |
368 | |
369 | |
370 | |
371 | |
372 | // |
373 | // NOTIFICATIONS |
374 | // |
375 | |
376 | |
377 | String NOTIF_INFO_DESCRIPTION = |
378 | "notification set for " + JademxAgent.class.getName(); |
379 | |
380 | // unit testing notifications |
381 | |
382 | /** notification that unit test failed */ |
383 | public final static String NOTIF_UNIT_TEST_FAILURE_NAME = |
384 | "unitTestFailure"; |
385 | /** notification that unit test succeeded */ |
386 | public final static String NOTIF_UNIT_TEST_SUCCESS_NAME = |
387 | "unitTestSuccess"; |
388 | |
389 | // // jademx binding notifications |
390 | // /** notification that jademx bound */ |
391 | // public final static String NOTIF_JADEMX_BOUND = |
392 | // "jademxBound"; |
393 | |
394 | // |
395 | // MBEAN INFO |
396 | // |
397 | |
398 | |
399 | /** local MBeanInfo exposed */ |
400 | private MBeanInfo mBeanInfo = null; |
401 | /** has MBeanInfo changed since JadeAgent last saw it */ |
402 | private Boolean mBeanInfoChanged = Boolean.FALSE; |
403 | /** description for MBeanInfo */ |
404 | private final static String DESCRIPTION = |
405 | "JademxAgent"; |
406 | |
407 | |
408 | // UNIT TESTING |
409 | |
410 | /** default unit test timeout duration string */ |
411 | private final static String DFLT_UNIT_TEST_TIMEOUT_STR = "PT1M"; |
412 | /** test timeout duration */ |
413 | private Duration unitTestTimeout = new Duration( DFLT_UNIT_TEST_TIMEOUT_STR ); |
414 | /** inject message */ |
415 | private ACLMessage unitTestInjectMessage = null; |
416 | /** expected message */ |
417 | private ACLMessage unitTestExpectedMessage = null; |
418 | /** actual message */ |
419 | private ACLMessage unitTestActualMessage = null; |
420 | /** variables */ |
421 | private Properties unitTestVariableProperties = new Properties(); |
422 | |
423 | |
424 | /** |
425 | * construct JADE agent with DynamicMBean capability via jademx. |
426 | */ |
427 | public JademxAgent() { |
428 | super(); |
429 | logger.log( Logger.FINER, "in JademxAgent constructor"); |
430 | } |
431 | |
432 | /** my logger */ |
433 | private static final Logger logger = |
434 | Logger.getMyLogger(JademxAgent.class.getName()); |
435 | |
436 | // attribute values/methods governing message comparison |
437 | |
438 | /** whether to compare content slots */ |
439 | private boolean unitTestCmpContent = true; |
440 | |
441 | /** |
442 | * set content comparison flag (default is true) |
443 | * @param doCompare |
444 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
445 | */ |
446 | public void setUnitTestCmpContent( boolean doCompare ) { |
447 | unitTestCmpContent = doCompare; |
448 | } |
449 | |
450 | /** |
451 | * get content comparison flag (default is true) |
452 | * @return content comparison flag |
453 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
454 | */ |
455 | public boolean isUnitTestCmpContent() { |
456 | return unitTestCmpContent; |
457 | } |
458 | |
459 | /** whether to compare conversation-id slots */ |
460 | private boolean unitTestCmpConversationId = true; |
461 | |
462 | /** |
463 | * set conversation-id comparison flag (default is true) |
464 | * @param doCompare |
465 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
466 | */ |
467 | public void setUnitTestCmpConversationId( boolean doCompare ) { |
468 | unitTestCmpConversationId = doCompare; |
469 | } |
470 | |
471 | /** |
472 | * get conversation-id comparison flag (default is true) |
473 | * @return conversation-id comparison flag |
474 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
475 | */ |
476 | public boolean isUnitTestCmpConversationId() { |
477 | return unitTestCmpConversationId; |
478 | } |
479 | |
480 | /** whether to compare encoding slots */ |
481 | private boolean unitTestCmpEncoding = true; |
482 | |
483 | /** |
484 | * set encoding comparison flag (default is true) |
485 | * @param doCompare |
486 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
487 | */ |
488 | public void setUnitTestCmpEncoding( boolean doCompare ) { |
489 | unitTestCmpEncoding = doCompare; |
490 | } |
491 | |
492 | /** |
493 | * get encoding comparison flag (default is true) |
494 | * @return encoding comparison flag |
495 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
496 | */ |
497 | public boolean isUnitTestCmpEncoding() { |
498 | return unitTestCmpEncoding; |
499 | } |
500 | |
501 | /** whether to compare envelope slots */ |
502 | private boolean unitTestCmpEnvelope = false; |
503 | |
504 | /** |
505 | * set envelope comparison flag (default is false) |
506 | * @param doCompare |
507 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
508 | */ |
509 | public void setUnitTestCmpEnvelope( boolean doCompare ) { |
510 | unitTestCmpEnvelope = doCompare; |
511 | } |
512 | |
513 | /** |
514 | * get envelope comparison flag (default is false) |
515 | * @return envelope comparison flag |
516 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
517 | */ |
518 | public boolean isUnitTestCmpEnvelope() { |
519 | return unitTestCmpEnvelope; |
520 | } |
521 | |
522 | /** whether to compare in-reply-to slots */ |
523 | private boolean unitTestCmpInReplyTo = true; |
524 | |
525 | /** |
526 | * set in-reply-to comparison flag (default is true) |
527 | * @param doCompare |
528 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
529 | */ |
530 | public void setUnitTestCmpInReplyTo( boolean doCompare ) { |
531 | unitTestCmpInReplyTo = doCompare; |
532 | } |
533 | |
534 | /** |
535 | * get in-reply-to comparison flag (default is true) |
536 | * @return in-reply-to comparison flag |
537 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
538 | */ |
539 | public boolean isUnitTestCmpInReplyTo() { |
540 | return unitTestCmpInReplyTo; |
541 | } |
542 | |
543 | /** whether to compare language slots */ |
544 | private boolean unitTestCmpLanguage = true; |
545 | |
546 | /** |
547 | * set language comparison flag (default is true) |
548 | * @param doCompare |
549 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
550 | */ |
551 | public void setUnitTestCmpLanguage( boolean doCompare ) { |
552 | unitTestCmpLanguage = doCompare; |
553 | } |
554 | |
555 | /** |
556 | * get language comparison flag (default is true) |
557 | * @return language comparison flag |
558 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
559 | */ |
560 | public boolean isUnitTestCmpLanguage() { |
561 | return unitTestCmpLanguage; |
562 | } |
563 | |
564 | /** whether to compare ontology slots */ |
565 | private boolean unitTestCmpOntology = true; |
566 | |
567 | /** |
568 | * set ontology comparison flag (default is true) |
569 | * @param doCompare |
570 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
571 | */ |
572 | public void setUnitTestCmpOntology( boolean doCompare ) { |
573 | unitTestCmpOntology = doCompare; |
574 | } |
575 | |
576 | /** |
577 | * get ontology comparison flag (default is true) |
578 | * @return ontology comparison flag |
579 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
580 | */ |
581 | public boolean isUnitTestCmpOntology() { |
582 | return unitTestCmpOntology; |
583 | } |
584 | |
585 | /** whether to compare performative slots */ |
586 | private boolean unitTestCmpPerformative = true; |
587 | |
588 | /** |
589 | * set performative comparison flag (default is true) |
590 | * @param doCompare |
591 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
592 | */ |
593 | public void setUnitTestCmpPerformative( boolean doCompare ) { |
594 | unitTestCmpPerformative = doCompare; |
595 | } |
596 | |
597 | /** |
598 | * get performative comparison flag (default is true) |
599 | * @return performative comparison flag |
600 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
601 | */ |
602 | public boolean isUnitTestCmpPerformative() { |
603 | return unitTestCmpPerformative; |
604 | } |
605 | |
606 | /** whether to compare protocol slots */ |
607 | private boolean unitTestCmpProtocol = true; |
608 | |
609 | /** |
610 | * set protocol comparison flag (default is true) |
611 | * @param doCompare |
612 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
613 | */ |
614 | public void setUnitTestCmpProtocol( boolean doCompare ) { |
615 | unitTestCmpProtocol = doCompare; |
616 | } |
617 | |
618 | /** |
619 | * get protocol comparison flag (default is true) |
620 | * @return protocol comparison flag |
621 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
622 | */ |
623 | public boolean isUnitTestCmpProtocol() { |
624 | return unitTestCmpProtocol; |
625 | } |
626 | |
627 | /** whether to compare receiver slots */ |
628 | private boolean unitTestCmpReceiver = true; |
629 | |
630 | /** |
631 | * set receiver comparison flag (default is true) |
632 | * @param doCompare |
633 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
634 | */ |
635 | public void setUnitTestCmpReceiver( boolean doCompare ) { |
636 | unitTestCmpReceiver = doCompare; |
637 | } |
638 | |
639 | /** |
640 | * get receiver comparison flag (default is true) |
641 | * @return receiver comparison flag |
642 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
643 | */ |
644 | public boolean isUnitTestCmpReceiver() { |
645 | return unitTestCmpReceiver; |
646 | } |
647 | |
648 | /** whether to compare reply-by slots */ |
649 | private boolean unitTestCmpReplyBy = true; |
650 | |
651 | /** |
652 | * set reply-by comparison flag (default is true) |
653 | * @param doCompare |
654 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
655 | */ |
656 | public void setUnitTestCmpReplyBy( boolean doCompare ) { |
657 | unitTestCmpReplyBy = doCompare; |
658 | } |
659 | |
660 | /** |
661 | * get reply-by comparison flag (default is true) |
662 | * @return reply-by comparison flag |
663 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
664 | */ |
665 | public boolean isUnitTestCmpReplyBy() { |
666 | return unitTestCmpReplyBy; |
667 | } |
668 | |
669 | /** whether to compare reply-to slots */ |
670 | private boolean unitTestCmpReplyTo = true; |
671 | |
672 | /** |
673 | * set reply-to comparison flag (default is true) |
674 | * @param doCompare |
675 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
676 | */ |
677 | public void setUnitTestCmpReplyTo( boolean doCompare ) { |
678 | unitTestCmpReplyTo = doCompare; |
679 | } |
680 | |
681 | /** |
682 | * get reply-to comparison flag (default is true) |
683 | * @return reply-to comparison flag |
684 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
685 | */ |
686 | public boolean isUnitTestCmpReplyTo() { |
687 | return unitTestCmpReplyTo; |
688 | } |
689 | |
690 | /** whether to compare reply-with slots */ |
691 | private boolean unitTestCmpReplyWith = true; |
692 | |
693 | /** |
694 | * set reply-with comparison flag (default is true) |
695 | * @param doCompare |
696 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
697 | */ |
698 | public void setUnitTestCmpReplyWith( boolean doCompare ) { |
699 | unitTestCmpReplyWith = doCompare; |
700 | } |
701 | |
702 | /** |
703 | * get reply-with comparison flag (default is true) |
704 | * @return reply-with comparison flag |
705 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
706 | */ |
707 | public boolean isUnitTestCmpReplyWith() { |
708 | return unitTestCmpReplyWith; |
709 | } |
710 | |
711 | /** whether to compare sender slots */ |
712 | private boolean unitTestCmpSender = true; |
713 | |
714 | /** |
715 | * set sender comparison flag (default is true) |
716 | * @param doCompare |
717 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
718 | */ |
719 | public void setUnitTestCmpSender( boolean doCompare ) { |
720 | unitTestCmpSender = doCompare; |
721 | } |
722 | |
723 | /** |
724 | * get sender comparison flag (default is true) |
725 | * @return sender comparison flag |
726 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
727 | */ |
728 | public boolean isUnitTestCmpSender() { |
729 | return unitTestCmpSender; |
730 | } |
731 | |
732 | /** whether to compare user properties slots */ |
733 | private boolean unitTestCmpUserProperties = true; |
734 | |
735 | /** |
736 | * set user properties comparison flag (default is true) |
737 | * @param doCompare |
738 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
739 | */ |
740 | public void setUnitTestCmpUserProperties( boolean doCompare ) { |
741 | unitTestCmpUserProperties = doCompare; |
742 | } |
743 | |
744 | /** |
745 | * get user properties comparison flag (default is true) |
746 | * @return user properties comparison flag |
747 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
748 | */ |
749 | public boolean isUnitTestCmpUserProperties() { |
750 | return unitTestCmpUserProperties; |
751 | } |
752 | |
753 | /** |
754 | * whether to ignore :addresses inside agent-identifier in content. |
755 | * N.B.: no effect if content is byte sequence instead of string. |
756 | */ |
757 | private boolean unitTestIgnoreContentAIDAddresses = true; |
758 | |
759 | /** |
760 | * set content AID address ignoring flag (default is true) |
761 | * @param ignore |
762 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
763 | */ |
764 | public void setUnitTestIgnoreContentAIDAddresses( boolean ignore ) { |
765 | unitTestIgnoreContentAIDAddresses = ignore; |
766 | } |
767 | |
768 | /** |
769 | * get content AID address ignoring flag (default is true) |
770 | * @return content AID address ignoring |
771 | * @see jade.jademx.util.AclMsgCmp#compare( ACLMessage, ACLMessage ) |
772 | */ |
773 | public boolean isUnitTestIgnoreContentAIDAddresses() { |
774 | return unitTestIgnoreContentAIDAddresses; |
775 | } |
776 | |
777 | /** whether to normalize newlines */ |
778 | private boolean unitTestNewlinesNormalized = true; |
779 | |
780 | /** |
781 | * set newline normalization flag (default is true) |
782 | * @param normalize |
783 | * @see jade.jademx.util.AclMsgCmp#setNewlinesNormalized |
784 | */ |
785 | public void setUnitTestNewlinesNormalized( boolean normalize ) { |
786 | unitTestNewlinesNormalized = normalize; |
787 | } |
788 | |
789 | /** |
790 | * get newline normalization flag (default is true) |
791 | * @return newline normalization flag |
792 | * @see jade.jademx.util.AclMsgCmp#isNewlinesNormalized |
793 | */ |
794 | public boolean isUnitTestNewlinesNormalized() { |
795 | return unitTestNewlinesNormalized; |
796 | } |
797 | |
798 | // /** |
799 | // * convenience method to write all system properties to log |
800 | // * @param l logger to use |
801 | // * @param s some message to prepend log message with |
802 | // */ |
803 | // public static void logSysProps( Logger l, String s ) { |
804 | // java.util.Properties p = System.getProperties(); |
805 | // java.io.StringWriter sw = new java.io.StringWriter(); |
806 | // java.io.PrintWriter pw = new java.io.PrintWriter( sw ); |
807 | // p.list( pw ); |
808 | // l.log( Logger.INFO, "system properties "+s+":\n"+sw); |
809 | // } |
810 | |
811 | // SETUP/TAKEDOWN |
812 | |
813 | /** |
814 | * get ready after initialization but before running behaviours. |
815 | * subclasses must make sure to call this method if they expect to |
816 | * expose control as a DynamicMBean. |
817 | */ |
818 | protected void setup() { |
819 | |
820 | logger.log( Logger.FINE, "entering JademxAgent.setup() for "+getName()+ |
821 | " in platform "+getContainerController().getPlatformName() ); |
822 | |
823 | // register languages and ontologies used by UnitTestBehaviour |
824 | |
825 | getContentManager().registerOntology( |
826 | FIPAManagementOntology.getInstance() ); |
827 | getContentManager().registerOntology( |
828 | JADEManagementOntology.getInstance() ); |
829 | getContentManager().registerOntology( |
830 | IntrospectionOntology.getInstance() ); |
831 | |
832 | SLCodec slCodec = new SLCodec(); |
833 | getContentManager().registerLanguage( |
834 | slCodec, FIPANames.ContentLanguage.FIPA_SL ); |
835 | getContentManager().registerLanguage( |
836 | slCodec, FIPANames.ContentLanguage.FIPA_SL0 ); |
837 | getContentManager().registerLanguage( |
838 | slCodec, FIPANames.ContentLanguage.FIPA_SL1 ); |
839 | getContentManager().registerLanguage( |
840 | slCodec, FIPANames.ContentLanguage.FIPA_SL2 ); |
841 | |
842 | // get self talking to jademx system if available |
843 | |
844 | String jadeMXServerClassName = |
845 | System.getProperty(JadeMXServerFactory.SERVER_TYPE_PROPERTY); |
846 | String runtimeMBeanName = |
847 | System.getProperty(JadeRuntimeMBean.MBEAN_SYS_PROP_NAME); |
848 | JadeMXServer jadeMXServer = null; |
849 | String platformName = null; |
850 | if ( ( null != jadeMXServerClassName ) && ( null != runtimeMBeanName )){ |
851 | try { |
852 | jadeMXServer = JadeMXServerFactory.jadeMXServerBySysProp(); |
853 | } |
854 | catch ( Exception e ) { |
855 | logger.log( Logger.WARNING, |
856 | "unable to instantiate JadeMXServer from system property \"" |
857 | +JadeMXServerFactory.SERVER_TYPE_PROPERTY+"\"=\""+ |
858 | System.getProperty(JadeMXServerFactory.SERVER_TYPE_PROPERTY)+ |
859 | "\"", e ); |
860 | } |
861 | logger.log( Logger.FINE, "JadeMXServer:"+jadeMXServer); |
862 | if ( null != jadeMXServer ) { |
863 | MBeanServer mBeanServer = jadeMXServer.getMBeanServer(); |
864 | platformName = getContainerController().getPlatformName(); |
865 | ObjectName runtimeON = null; |
866 | try { |
867 | runtimeON = new ObjectName( runtimeMBeanName ); |
868 | } |
869 | catch ( Exception e ) { |
870 | logger.log( Logger.WARNING, |
871 | "unable to create ObjectName for \""+ |
872 | runtimeMBeanName + "\"", e ); |
873 | } |
874 | JadePlatform jadePlatform = null; |
875 | logger.log( Logger.FINE, "JadeRuntime ObjectName: "+runtimeON); |
876 | if ( null != runtimeON ) { |
877 | try { |
878 | jadePlatform = (JadePlatform)mBeanServer.invoke( |
879 | runtimeON, |
880 | JadeRuntimeMBean.OPER_PLATFORM_FROM_JADE_NAME, |
881 | new Object[] { platformName }, |
882 | JadeRuntime.SIGN_STR ); |
883 | } |
884 | catch ( Exception e ) { |
885 | logger.log( Logger.WARNING, |
886 | "unable to get JadePlatform for \""+ |
887 | platformName + "\"", e ); |
888 | } |
889 | logger.log( Logger.FINE, "JadePlatform:"+jadePlatform); |
890 | if ( null != jadePlatform ) { |
891 | JadeAgent jadeAgent = null; |
892 | try { |
893 | jadeAgent = jadePlatform.getAgent( getLocalName() ); |
894 | } |
895 | catch (JademxException e ) { |
896 | logger.log( Logger.WARNING, |
897 | "unable to get JadeAgent for"+ |
898 | " agent with local name \""+ |
899 | getLocalName() + "\"", e ); |
900 | } |
901 | logger.log( Logger.FINE, "JadeAgent:"+jadeAgent); |
902 | if ( null != jadeAgent ) { |
903 | // finally: exchange references |
904 | setJadeAgent( jadeAgent ); |
905 | changedMBeanInfo(); |
906 | } |
907 | } |
908 | } |
909 | } |
910 | } |
911 | |
912 | // // AID not known during construction, but known now. |
913 | // // this method is called by jademx calling the agent controller's |
914 | // // start method. put my name out as a system property so that jademx |
915 | // // can know that this agent exposes management via JMX. |
916 | // // if controlled by jademx, then this property will be read and cleared. |
917 | // // after reading this property, then jademx will pass a reference to |
918 | // // itself through the O2A queue. create a threaded behaviour that |
919 | // // will wait for that object, and then when it's available, register |
920 | // // this agent with jademx as exposing JMX DynamicMBean interfaces. |
921 | // // a threaded behaviour is used in an attempt to decouple this agent's |
922 | // // intended activity from its JMX activity |
923 | // String jademxAgentSysProp = jademxSysProp( getLocalName() ); |
924 | // setEnabledO2ACommunication( true, 1 ); |
925 | // System.setProperty( jademxAgentSysProp, JADEMX_AGENT_SYSPROP_VALUE ); |
926 | // addBehaviour( new JademxRegistrationBehaviour( this ) ); |
927 | // //logSysProps( logger, "after JademxAgent.setup() for "+getName()); |
928 | } |
929 | |
930 | // /** is the agent shutting down: volatile due to multithread access */ |
931 | // private boolean shuttingDown = false; |
932 | // |
933 | // /** |
934 | // * is the agent shutting down |
935 | // * @return whether agent shutting down |
936 | // */ |
937 | // public boolean isShuttingDown() { |
938 | // return shuttingDown; |
939 | // } |
940 | // |
941 | // /** |
942 | // * clean agent shutdown. |
943 | // * subclasses must make sure to call this method if they have called the |
944 | // * corresponding setup() method. |
945 | // */ |
946 | // protected void takeDown() { |
947 | // shuttingDown = true; |
948 | // } |
949 | |
950 | // BEGIN DynamicMBean IMPLEMENTATION |
951 | |
952 | /** the JadeAgent for this agent - volatile due to multithread access */ |
953 | private volatile JadeAgent jadeAgent = null; |
954 | |
955 | /** |
956 | * set the JademxAgent for this agent |
957 | * @param jadeAgent this agent's JadeAgent |
958 | */ |
959 | void setJadeAgent( JadeAgent jadeAgent ) { |
960 | this.jadeAgent = jadeAgent; |
961 | changedMBeanInfo(); |
962 | } |
963 | |
964 | /** |
965 | * notify listeners - message and userData can be null. |
966 | * sets source, sequence number, timestamp automatically. |
967 | * NOP if no JadeAgent has been set. |
968 | * @param type notification type |
969 | * @param message notification message |
970 | * @param userData user data |
971 | */ |
972 | public void notifyListeners( |
973 | String type, String message, Object userData ) { |
974 | if ( null != jadeAgent ) { |
975 | jadeAgent.notifyListeners( type, message, userData ); |
976 | } |
977 | } |
978 | |
979 | /** |
980 | * create a new MBeanInfo object to describe this agent. |
981 | * @return new MBeanInfo object to describe this agent. |
982 | */ |
983 | private MBeanInfo constructMBeanInfo() { |
984 | |
985 | // attributes |
986 | |
987 | MBeanAttributeInfo aI[] = new MBeanAttributeInfo[] { |
988 | new MBeanAttributeInfo( |
989 | ATTR_UNIT_TEST_EXPECTED_MESSAGE_NAME, |
990 | ATTR_UNIT_TEST_EXPECTED_MESSAGE_TYPE, |
991 | ATTR_UNIT_TEST_EXPECTED_MESSAGE_DESC, |
992 | true, true, false ), |
993 | new MBeanAttributeInfo( |
994 | ATTR_UNIT_TEST_INJECT_MESSAGE_NAME, |
995 | ATTR_UNIT_TEST_INJECT_MESSAGE_TYPE, |
996 | ATTR_UNIT_TEST_INJECT_MESSAGE_DESC, |
997 | true, true, false ), |
998 | new MBeanAttributeInfo( |
999 | ATTR_UNIT_TEST_TIMEOUT_NAME, |
1000 | ATTR_UNIT_TEST_TIMEOUT_TYPE, |
1001 | ATTR_UNIT_TEST_TIMEOUT_DESC, |
1002 | true, true, false ), |
1003 | new MBeanAttributeInfo( |
1004 | ATTR_UNIT_TEST_ACTUAL_MESSAGE_NAME, |
1005 | ATTR_UNIT_TEST_ACTUAL_MESSAGE_TYPE, |
1006 | ATTR_UNIT_TEST_ACTUAL_MESSAGE_DESC, |
1007 | true, false, false ), |
1008 | new MBeanAttributeInfo( |
1009 | ATTR_UNIT_TEST_CMP_CONTENT_NAME, |
1010 | ATTR_UNIT_TEST_CMP_CONTENT_TYPE, |
1011 | ATTR_UNIT_TEST_CMP_CONTENT_DESC, |
1012 | true, true, true ), |
1013 | new MBeanAttributeInfo( |
1014 | ATTR_UNIT_TEST_CMP_CONVERSATION_ID_NAME, |
1015 | ATTR_UNIT_TEST_CMP_CONVERSATION_ID_TYPE, |
1016 | ATTR_UNIT_TEST_CMP_CONVERSATION_ID_DESC, |
1017 | true, true, true ), |
1018 | new MBeanAttributeInfo( |
1019 | ATTR_UNIT_TEST_CMP_ENCODING_NAME, |
1020 | ATTR_UNIT_TEST_CMP_ENCODING_TYPE, |
1021 | ATTR_UNIT_TEST_CMP_ENCODING_DESC, |
1022 | true, true, true ), |
1023 | new MBeanAttributeInfo( |
1024 | ATTR_UNIT_TEST_CMP_ENVELOPE_NAME, |
1025 | ATTR_UNIT_TEST_CMP_ENVELOPE_TYPE, |
1026 | ATTR_UNIT_TEST_CMP_ENVELOPE_DESC, |
1027 | true, true, true ), |
1028 | new MBeanAttributeInfo( |
1029 | ATTR_UNIT_TEST_CMP_IN_REPLY_TO_NAME, |
1030 | ATTR_UNIT_TEST_CMP_IN_REPLY_TO_TYPE, |
1031 | ATTR_UNIT_TEST_CMP_IN_REPLY_TO_DESC, |
1032 | true, true, true ), |
1033 | new MBeanAttributeInfo( |
1034 | ATTR_UNIT_TEST_CMP_LANGUAGE_NAME, |
1035 | ATTR_UNIT_TEST_CMP_LANGUAGE_TYPE, |
1036 | ATTR_UNIT_TEST_CMP_LANGUAGE_DESC, |
1037 | true, true, true ), |
1038 | new MBeanAttributeInfo( |
1039 | ATTR_UNIT_TEST_CMP_ONTOLOGY_NAME, |
1040 | ATTR_UNIT_TEST_CMP_ONTOLOGY_TYPE, |
1041 | ATTR_UNIT_TEST_CMP_ONTOLOGY_DESC, |
1042 | true, true, true ), |
1043 | new MBeanAttributeInfo( |
1044 | ATTR_UNIT_TEST_CMP_PERFORMATIVE_NAME, |
1045 | ATTR_UNIT_TEST_CMP_PERFORMATIVE_TYPE, |
1046 | ATTR_UNIT_TEST_CMP_PERFORMATIVE_DESC, |
1047 | true, true, true ), |
1048 | new MBeanAttributeInfo( |
1049 | ATTR_UNIT_TEST_CMP_PROTOCOL_NAME, |
1050 | ATTR_UNIT_TEST_CMP_PROTOCOL_TYPE, |
1051 | ATTR_UNIT_TEST_CMP_PROTOCOL_DESC, |
1052 | true, true, true ), |
1053 | new MBeanAttributeInfo( |
1054 | ATTR_UNIT_TEST_CMP_RECEIVER_NAME, |
1055 | ATTR_UNIT_TEST_CMP_RECEIVER_TYPE, |
1056 | ATTR_UNIT_TEST_CMP_RECEIVER_DESC, |
1057 | true, true, true ), |
1058 | new MBeanAttributeInfo( |
1059 | ATTR_UNIT_TEST_CMP_REPLY_BY_NAME, |
1060 | ATTR_UNIT_TEST_CMP_REPLY_BY_TYPE, |
1061 | ATTR_UNIT_TEST_CMP_REPLY_BY_DESC, |
1062 | true, true, true ), |
1063 | new MBeanAttributeInfo( |
1064 | ATTR_UNIT_TEST_CMP_REPLY_TO_NAME, |
1065 | ATTR_UNIT_TEST_CMP_REPLY_TO_TYPE, |
1066 | ATTR_UNIT_TEST_CMP_REPLY_TO_DESC, |
1067 | true, true, true ), |
1068 | new MBeanAttributeInfo( |
1069 | ATTR_UNIT_TEST_CMP_REPLY_WITH_NAME, |
1070 | ATTR_UNIT_TEST_CMP_REPLY_WITH_TYPE, |
1071 | ATTR_UNIT_TEST_CMP_REPLY_WITH_DESC, |
1072 | true, true, true ), |
1073 | new MBeanAttributeInfo( |
1074 | ATTR_UNIT_TEST_CMP_SENDER_NAME, |
1075 | ATTR_UNIT_TEST_CMP_SENDER_TYPE, |
1076 | ATTR_UNIT_TEST_CMP_SENDER_DESC, |
1077 | true, true, true ), |
1078 | new MBeanAttributeInfo( |
1079 | ATTR_UNIT_TEST_CMP_USER_PROPERTIES_NAME, |
1080 | ATTR_UNIT_TEST_CMP_USER_PROPERTIES_TYPE, |
1081 | ATTR_UNIT_TEST_CMP_USER_PROPERTIES_DESC, |
1082 | true, true, true ), |
1083 | new MBeanAttributeInfo( |
1084 | ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_NAME, |
1085 | ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_TYPE, |
1086 | ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_DESC, |
1087 | true, true, true ), |
1088 | new MBeanAttributeInfo( |
1089 | ATTR_UNIT_TEST_NEWLINES_NORMALIZED_NAME, |
1090 | ATTR_UNIT_TEST_NEWLINES_NORMALIZED_TYPE, |
1091 | ATTR_UNIT_TEST_NEWLINES_NORMALIZED_DESC, |
1092 | true, true, true ) |
1093 | }; |
1094 | |
1095 | // constructors |
1096 | |
1097 | MBeanConstructorInfo cI[] = new MBeanConstructorInfo[0]; |
1098 | |
1099 | // operations |
1100 | |
1101 | MBeanParameterInfo pIInject[] = { |
1102 | }; |
1103 | MBeanParameterInfo pIAddVariable[] = { |
1104 | new MBeanParameterInfo( |
1105 | OPER_UNIT_TEST_ADD_VARIABLE_VARIABLE_PARM_NAME, |
1106 | OPER_UNIT_TEST_ADD_VARIABLE_VARIABLE_PARM_TYPE, |
1107 | OPER_UNIT_TEST_ADD_VARIABLE_VARIABLE_PARM_DESC), |
1108 | new MBeanParameterInfo( |
1109 | OPER_UNIT_TEST_ADD_VARIABLE_TYPE_PARM_NAME, |
1110 | OPER_UNIT_TEST_ADD_VARIABLE_TYPE_PARM_TYPE, |
1111 | OPER_UNIT_TEST_ADD_VARIABLE_TYPE_PARM_DESC) |
1112 | }; |
1113 | MBeanParameterInfo pIClearVariables[] = { |
1114 | }; |
1115 | MBeanOperationInfo oI[] = new MBeanOperationInfo[] { |
1116 | new MBeanOperationInfo( |
1117 | OPER_UNIT_TEST_INJECT_AND_EXPECT_NAME, |
1118 | OPER_UNIT_TEST_INJECT_AND_EXPECT_DESC, |
1119 | pIInject, |
1120 | OPER_UNIT_TEST_INJECT_AND_EXPECT_TYPE, |
1121 | MBeanOperationInfo.ACTION ), |
1122 | new MBeanOperationInfo( |
1123 | OPER_UNIT_TEST_ADD_VARIABLE_NAME, |
1124 | OPER_UNIT_TEST_ADD_VARIABLE_DESC, |
1125 | pIAddVariable, |
1126 | OPER_UNIT_TEST_ADD_VARIABLE_TYPE, |
1127 | MBeanOperationInfo.ACTION ), |
1128 | new MBeanOperationInfo( |
1129 | OPER_UNIT_TEST_CLEAR_VARIABLES_NAME, |
1130 | OPER_UNIT_TEST_CLEAR_VARIABLES_DESC, |
1131 | pIClearVariables, |
1132 | OPER_UNIT_TEST_CLEAR_VARIABLES_TYPE, |
1133 | MBeanOperationInfo.ACTION ) |
1134 | }; |
1135 | |
1136 | // notifications |
1137 | |
1138 | String notifications[] = { |
1139 | NOTIF_UNIT_TEST_FAILURE_NAME, |
1140 | NOTIF_UNIT_TEST_SUCCESS_NAME |
1141 | }; |
1142 | String myClassName = getClass().getName(); |
1143 | String NOTIF_INFO_DESCRIPTION = |
1144 | "notification set for " + myClassName; |
1145 | MBeanNotificationInfo nI[] = new MBeanNotificationInfo[] { |
1146 | new MBeanNotificationInfo( |
1147 | notifications, |
1148 | Notification.class.getName(), |
1149 | NOTIF_INFO_DESCRIPTION ) |
1150 | }; |
1151 | |
1152 | // now, MBeanInfo for this level of class hierarchy |
1153 | MBeanInfo mBeanInfo = new MBeanInfo( myClassName, |
1154 | DESCRIPTION, |
1155 | aI, cI, oI, nI ); |
1156 | |
1157 | return mBeanInfo; |
1158 | |
1159 | } |
1160 | |
1161 | |
1162 | // /** |
1163 | // * has MBeanInfo changed since last checked |
1164 | // * @return whether MBeanInfo has changed since last checked |
1165 | // */ |
1166 | // public boolean isMBeanInfoChanged() { |
1167 | // boolean infoChanged; |
1168 | // synchronized ( mBeanInfoChanged ) { |
1169 | // infoChanged = mBeanInfoChanged.booleanValue(); |
1170 | // } |
1171 | // return infoChanged; |
1172 | // } |
1173 | |
1174 | /** |
1175 | * mark this agent's MBeanInfo as having been changed. |
1176 | */ |
1177 | protected void changedMBeanInfo() { |
1178 | synchronized ( mBeanInfoChanged ) { |
1179 | mBeanInfoChanged = Boolean.TRUE; |
1180 | //mBeanInfo = null; |
1181 | if ( null != jadeAgent ) { |
1182 | logger.log( Logger.FINE, |
1183 | "calling JadeAgent.setJademxAgent(),JadeAgent="+ |
1184 | jadeAgent+",JadeAgent.hashCode()="+jadeAgent.hashCode()+ |
1185 | ",jademxAgent="+this+",jademxAgent.hashCode()="+ |
1186 | this.hashCode()); |
1187 | jadeAgent.setJademxAgent( this ); |
1188 | } |
1189 | else { |
1190 | logger.log( Logger.WARNING, "jadeAgent is null so can't "+ |
1191 | "inform it about changed MBeanInfo"); |
1192 | } |
1193 | } |
1194 | } |
1195 | |
1196 | /** |
1197 | * set MBeanInfo for JADE side of this agent (excluding jademx). |
1198 | * @deprecated subclasses should call MBeanUtil.mergeMBeanInfo() |
1199 | * on their own MBeanInfo and MBeanInfo obtained for this class |
1200 | * by super.getMBeanInfo() and return the merged MBeanInfo. |
1201 | */ |
1202 | protected void setMBeanInfo( MBeanInfo mBeanInfo ) { |
1203 | throw new RuntimeException( |
1204 | "JademxAgent.setMBeanInfo() is deprecated, "+ |
1205 | "agents should call super.getMBeanInfo() to get "+ |
1206 | "MBeanInfo for JademxAgent and then call "+ |
1207 | "MBeanUtil.mergeMBeanInfo() to get an MBeanInfo "+ |
1208 | "representing MBean capabilities for entire JADE side "+ |
1209 | "of agent. Whenever an agent has changed its own level "+ |
1210 | "MBean information, it should call "+ |
1211 | "JademxAgent.changedMBeanInfo()."); |
1212 | } |
1213 | |
1214 | /** |
1215 | * override this method to do anything meaningful as DynamicMBean. |
1216 | * this is a merge of the agent, this class, and this class's superclass. |
1217 | * @return MBean information for base JADE MBean class |
1218 | */ |
1219 | public MBeanInfo getMBeanInfo() { |
1220 | synchronized ( mBeanInfoChanged ) { |
1221 | // lazy evaluation |
1222 | if ( null == mBeanInfo ) { |
1223 | mBeanInfo = constructMBeanInfo(); |
1224 | mBeanInfoChanged = Boolean.FALSE; |
1225 | logger.log(Logger.FINE,"made MBeanInfo "+mBeanInfo); |
1226 | } |
1227 | } |
1228 | logger.log(Logger.FINE,"returning MBeanInfo "+mBeanInfo+"..."); |
1229 | return mBeanInfo; |
1230 | } |
1231 | |
1232 | |
1233 | /** |
1234 | * get an attribute value: <em>override this method to have an attribute</em>. |
1235 | * @param attribute name of attribute to get |
1236 | * @return attribute value |
1237 | * @throws AttributeNotFoundException no such attribute |
1238 | * @throws MBeanException exception from getter |
1239 | * @throws ReflectionException exception invoking getter |
1240 | */ |
1241 | public Object getAttribute( String attribute ) |
1242 | throws AttributeNotFoundException, |
1243 | MBeanException, |
1244 | ReflectionException { |
1245 | Object o; |
1246 | if ( ATTR_UNIT_TEST_EXPECTED_MESSAGE_NAME.equals( attribute ) ) { |
1247 | o = getUnitTestExpectedMessage(); |
1248 | } |
1249 | else if ( ATTR_UNIT_TEST_INJECT_MESSAGE_NAME.equals( attribute ) ) { |
1250 | o = getUnitTestInjectMessage(); |
1251 | } |
1252 | else if ( ATTR_UNIT_TEST_TIMEOUT_NAME.equals( attribute ) ) { |
1253 | o = getUnitTestTimeout(); |
1254 | } |
1255 | else if ( ATTR_UNIT_TEST_ACTUAL_MESSAGE_NAME.equals( attribute ) ) { |
1256 | o = getUnitTestActualMessage(); |
1257 | } |
1258 | else if ( ATTR_UNIT_TEST_CMP_CONTENT_NAME.equals( attribute ) ) { |
1259 | o = new Boolean( isUnitTestCmpContent() ); |
1260 | } |
1261 | else if ( ATTR_UNIT_TEST_CMP_CONVERSATION_ID_NAME.equals( attribute ) ) { |
1262 | o = new Boolean( isUnitTestCmpConversationId() ); |
1263 | } |
1264 | else if ( ATTR_UNIT_TEST_CMP_ENCODING_NAME.equals( attribute ) ) { |
1265 | o = new Boolean( isUnitTestCmpEncoding() ); |
1266 | } |
1267 | else if ( ATTR_UNIT_TEST_CMP_ENVELOPE_NAME.equals( attribute ) ) { |
1268 | o = new Boolean( isUnitTestCmpEnvelope() ); |
1269 | } |
1270 | else if ( ATTR_UNIT_TEST_CMP_IN_REPLY_TO_NAME.equals( attribute ) ) { |
1271 | o = new Boolean( isUnitTestCmpInReplyTo() ); |
1272 | } |
1273 | else if ( ATTR_UNIT_TEST_CMP_LANGUAGE_NAME.equals( attribute ) ) { |
1274 | o = new Boolean( isUnitTestCmpLanguage() ); |
1275 | } |
1276 | else if ( ATTR_UNIT_TEST_CMP_ONTOLOGY_NAME.equals( attribute ) ) { |
1277 | o = new Boolean( isUnitTestCmpOntology() ); |
1278 | } |
1279 | else if ( ATTR_UNIT_TEST_CMP_PERFORMATIVE_NAME.equals( attribute ) ) { |
1280 | o = new Boolean( isUnitTestCmpPerformative() ); |
1281 | } |
1282 | else if ( ATTR_UNIT_TEST_CMP_PROTOCOL_NAME.equals( attribute ) ) { |
1283 | o = new Boolean( isUnitTestCmpProtocol() ); |
1284 | } |
1285 | else if ( ATTR_UNIT_TEST_CMP_RECEIVER_NAME.equals( attribute ) ) { |
1286 | o = new Boolean( isUnitTestCmpReceiver() ); |
1287 | } |
1288 | else if ( ATTR_UNIT_TEST_CMP_REPLY_BY_NAME.equals( attribute ) ) { |
1289 | o = new Boolean( isUnitTestCmpReplyBy() ); |
1290 | } |
1291 | else if ( ATTR_UNIT_TEST_CMP_REPLY_TO_NAME.equals( attribute ) ) { |
1292 | o = new Boolean( isUnitTestCmpReplyTo() ); |
1293 | } |
1294 | else if ( ATTR_UNIT_TEST_CMP_REPLY_WITH_NAME.equals( attribute ) ) { |
1295 | o = new Boolean( isUnitTestCmpReplyWith() ); |
1296 | } |
1297 | else if ( ATTR_UNIT_TEST_CMP_SENDER_NAME.equals( attribute ) ) { |
1298 | o = new Boolean( isUnitTestCmpSender() ); |
1299 | } |
1300 | else if ( ATTR_UNIT_TEST_CMP_USER_PROPERTIES_NAME.equals( attribute ) ) { |
1301 | o = new Boolean( isUnitTestCmpUserProperties() ); |
1302 | } |
1303 | else if ( ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_NAME.equals( attribute ) ) { |
1304 | o = new Boolean( isUnitTestIgnoreContentAIDAddresses() ); |
1305 | } |
1306 | else if ( ATTR_UNIT_TEST_NEWLINES_NORMALIZED_NAME.equals( attribute ) ) { |
1307 | o = new Boolean( isUnitTestNewlinesNormalized() ); |
1308 | } |
1309 | else { |
1310 | // no parent class to try, subclasses had first crack |
1311 | throw new AttributeNotFoundException( |
1312 | "no such readable attribute \""+attribute+"\""); |
1313 | } |
1314 | return o; |
1315 | } |
1316 | |
1317 | /** |
1318 | * get multiple attribute values |
1319 | * @param attributes attributes to be retrieved |
1320 | * @return retrieved attributes |
1321 | */ |
1322 | public AttributeList getAttributes(String[] attributes) { |
1323 | AttributeList aL = null; |
1324 | int attrCount = attributes.length; |
1325 | if ( attrCount >= 0 ) { |
1326 | aL = new AttributeList( attrCount ); |
1327 | for ( int i = 0; i < attrCount; i++ ) { |
1328 | try { |
1329 | aL.add( getAttribute( attributes[i] ) ); |
1330 | } |
1331 | catch ( Exception e ) { |
1332 | throw new RuntimeException( e ); |
1333 | } |
1334 | } |
1335 | } |
1336 | return aL; |
1337 | } |
1338 | |
1339 | /** |
1340 | * set an attribute |
1341 | * @param attribute |
1342 | * @throws AttributeNotFoundException |
1343 | * @throws InvalidAttributeValueException |
1344 | * @throws MBeanException |
1345 | * @throws ReflectionException |
1346 | */ |
1347 | public void setAttribute( Attribute attribute ) |
1348 | throws AttributeNotFoundException, |
1349 | InvalidAttributeValueException, |
1350 | MBeanException, |
1351 | ReflectionException { |
1352 | |
1353 | String n = attribute.getName(); |
1354 | Object v = attribute.getValue(); |
1355 | // System.err.println("attribute name:"+n); |
1356 | // System.err.println("expected msg attribute name:"+ATTR_UNIT_TEST_EXPECTED_MESSAGE_NAME); |
1357 | // System.err.println("inject msg attribute name:"+ATTR_UNIT_TEST_INJECT_MESSAGE_NAME); |
1358 | // System.err.println("timeout attribute name:"+ATTR_UNIT_TEST_TIMEOUT_NAME); |
1359 | if ( ATTR_UNIT_TEST_EXPECTED_MESSAGE_NAME.equals( n ) ) { |
1360 | String s; |
1361 | try { |
1362 | s = (String) v; |
1363 | } |
1364 | catch ( ClassCastException cce ){ |
1365 | throw new InvalidAttributeValueException( "for attribute "+ |
1366 | " need "+String.class.getName()+" got "+ |
1367 | v.getClass().getName() ); |
1368 | } |
1369 | try { |
1370 | setUnitTestExpectedMessage( s ); |
1371 | // invoking directly, not indirectly, |
1372 | // so can't throw ReflectionException |
1373 | } |
1374 | catch ( Exception e ) { |
1375 | throw new MBeanException( e, |
1376 | "exception setting "+n+" attribute" ); |
1377 | } |
1378 | } |
1379 | else if ( ATTR_UNIT_TEST_INJECT_MESSAGE_NAME.equals( n ) ) { |
1380 | String s; |
1381 | try { |
1382 | s = (String) v; |
1383 | } |
1384 | catch ( ClassCastException cce ){ |
1385 | throw new InvalidAttributeValueException( "for attribute "+ |
1386 | " need "+String.class.getName()+" got "+ |
1387 | v.getClass().getName() ); |
1388 | } |
1389 | try { |
1390 | setUnitTestInjectMessage( s ); |
1391 | // invoking directly, not indirectly, |
1392 | // so can't throw ReflectionException |
1393 | } |
1394 | catch ( Exception e ) { |
1395 | throw new MBeanException( e, |
1396 | "exception setting "+n+" attribute" ); |
1397 | } |
1398 | } |
1399 | else if ( ATTR_UNIT_TEST_TIMEOUT_NAME.equals( n ) ) { |
1400 | String s; |
1401 | try { |
1402 | s = (String) v; |
1403 | } |
1404 | catch ( ClassCastException cce ){ |
1405 | throw new InvalidAttributeValueException( "for attribute "+ |
1406 | " need "+String.class.getName()+" got "+ |
1407 | v.getClass().getName() ); |
1408 | } |
1409 | try { |
1410 | setUnitTestTimeout( s ); |
1411 | // invoking directly, not indirectly, |
1412 | // so can't throw ReflectionException |
1413 | } |
1414 | catch ( Exception e ) { |
1415 | throw new MBeanException( e, |
1416 | "exception setting "+n+" attribute" ); |
1417 | } |
1418 | } |
1419 | else if ( ATTR_UNIT_TEST_CMP_CONTENT_NAME.equals( n ) ) { |
1420 | boolean b; |
1421 | try { |
1422 | b = ((Boolean)v).booleanValue(); |
1423 | } |
1424 | catch ( ClassCastException cce ){ |
1425 | throw new InvalidAttributeValueException( "for attribute "+ |
1426 | " need "+Boolean.class.getName()+" got "+ |
1427 | v.getClass().getName() ); |
1428 | } |
1429 | try { |
1430 | setUnitTestCmpContent( b ); |
1431 | // invoking directly, not indirectly, |
1432 | // so can't throw ReflectionException |
1433 | } |
1434 | catch ( Exception e ) { |
1435 | throw new MBeanException( e, |
1436 | "exception setting "+n+" attribute" ); |
1437 | } |
1438 | } |
1439 | else if ( ATTR_UNIT_TEST_CMP_CONVERSATION_ID_NAME.equals( n ) ) { |
1440 | boolean b; |
1441 | try { |
1442 | b = ((Boolean)v).booleanValue(); |
1443 | } |
1444 | catch ( ClassCastException cce ){ |
1445 | throw new InvalidAttributeValueException( "for attribute "+ |
1446 | " need "+Boolean.class.getName()+" got "+ |
1447 | v.getClass().getName() ); |
1448 | } |
1449 | try { |
1450 | setUnitTestCmpConversationId( b ); |
1451 | // invoking directly, not indirectly, |
1452 | // so can't throw ReflectionException |
1453 | } |
1454 | catch ( Exception e ) { |
1455 | throw new MBeanException( e, |
1456 | "exception setting "+n+" attribute" ); |
1457 | } |
1458 | } |
1459 | else if ( ATTR_UNIT_TEST_CMP_ENCODING_NAME.equals( n ) ) { |
1460 | boolean b; |
1461 | try { |
1462 | b = ((Boolean)v).booleanValue(); |
1463 | } |
1464 | catch ( ClassCastException cce ){ |
1465 | throw new InvalidAttributeValueException( "for attribute "+ |
1466 | " need "+Boolean.class.getName()+" got "+ |
1467 | v.getClass().getName() ); |
1468 | } |
1469 | try { |
1470 | setUnitTestCmpEncoding( b ); |
1471 | // invoking directly, not indirectly, |
1472 | // so can't throw ReflectionException |
1473 | } |
1474 | catch ( Exception e ) { |
1475 | throw new MBeanException( e, |
1476 | "exception setting "+n+" attribute" ); |
1477 | } |
1478 | } |
1479 | else if ( ATTR_UNIT_TEST_CMP_ENVELOPE_NAME.equals( n ) ) { |
1480 | boolean b; |
1481 | try { |
1482 | b = ((Boolean)v).booleanValue(); |
1483 | } |
1484 | catch ( ClassCastException cce ){ |
1485 | throw new InvalidAttributeValueException( "for attribute "+ |
1486 | " need "+Boolean.class.getName()+" got "+ |
1487 | v.getClass().getName() ); |
1488 | } |
1489 | try { |
1490 | setUnitTestCmpEnvelope( b ); |
1491 | // invoking directly, not indirectly, |
1492 | // so can't throw ReflectionException |
1493 | } |
1494 | catch ( Exception e ) { |
1495 | throw new MBeanException( e, |
1496 | "exception setting "+n+" attribute" ); |
1497 | } |
1498 | } |
1499 | else if ( ATTR_UNIT_TEST_CMP_IN_REPLY_TO_NAME.equals( n ) ) { |
1500 | boolean b; |
1501 | try { |
1502 | b = ((Boolean)v).booleanValue(); |
1503 | } |
1504 | catch ( ClassCastException cce ){ |
1505 | throw new InvalidAttributeValueException( "for attribute "+ |
1506 | " need "+Boolean.class.getName()+" got "+ |
1507 | v.getClass().getName() ); |
1508 | } |
1509 | try { |
1510 | setUnitTestCmpInReplyTo( b ); |
1511 | // invoking directly, not indirectly, |
1512 | // so can't throw ReflectionException |
1513 | } |
1514 | catch ( Exception e ) { |
1515 | throw new MBeanException( e, |
1516 | "exception setting "+n+" attribute" ); |
1517 | } |
1518 | } |
1519 | else if ( ATTR_UNIT_TEST_CMP_LANGUAGE_NAME.equals( n ) ) { |
1520 | boolean b; |
1521 | try { |
1522 | b = ((Boolean)v).booleanValue(); |
1523 | } |
1524 | catch ( ClassCastException cce ){ |
1525 | throw new InvalidAttributeValueException( "for attribute "+ |
1526 | " need "+Boolean.class.getName()+" got "+ |
1527 | v.getClass().getName() ); |
1528 | } |
1529 | try { |
1530 | setUnitTestCmpLanguage( b ); |
1531 | // invoking directly, not indirectly, |
1532 | // so can't throw ReflectionException |
1533 | } |
1534 | catch ( Exception e ) { |
1535 | throw new MBeanException( e, |
1536 | "exception setting "+n+" attribute" ); |
1537 | } |
1538 | } |
1539 | else if ( ATTR_UNIT_TEST_CMP_ONTOLOGY_NAME.equals( n ) ) { |
1540 | boolean b; |
1541 | try { |
1542 | b = ((Boolean)v).booleanValue(); |
1543 | } |
1544 | catch ( ClassCastException cce ){ |
1545 | throw new InvalidAttributeValueException( "for attribute "+ |
1546 | " need "+Boolean.class.getName()+" got "+ |
1547 | v.getClass().getName() ); |
1548 | } |
1549 | try { |
1550 | setUnitTestCmpOntology( b ); |
1551 | // invoking directly, not indirectly, |
1552 | // so can't throw ReflectionException |
1553 | } |
1554 | catch ( Exception e ) { |
1555 | throw new MBeanException( e, |
1556 | "exception setting "+n+" attribute" ); |
1557 | } |
1558 | } |
1559 | else if ( ATTR_UNIT_TEST_CMP_PERFORMATIVE_NAME.equals( n ) ) { |
1560 | boolean b; |
1561 | try { |
1562 | b = ((Boolean)v).booleanValue(); |
1563 | } |
1564 | catch ( ClassCastException cce ){ |
1565 | throw new InvalidAttributeValueException( "for attribute "+ |
1566 | " need "+Boolean.class.getName()+" got "+ |
1567 | v.getClass().getName() ); |
1568 | } |
1569 | try { |
1570 | setUnitTestCmpPerformative( b ); |
1571 | // invoking directly, not indirectly, |
1572 | // so can't throw ReflectionException |
1573 | } |
1574 | catch ( Exception e ) { |
1575 | throw new MBeanException( e, |
1576 | "exception setting "+n+" attribute" ); |
1577 | } |
1578 | } |
1579 | else if ( ATTR_UNIT_TEST_CMP_PROTOCOL_NAME.equals( n ) ) { |
1580 | boolean b; |
1581 | try { |
1582 | b = ((Boolean)v).booleanValue(); |
1583 | } |
1584 | catch ( ClassCastException cce ){ |
1585 | throw new InvalidAttributeValueException( "for attribute "+ |
1586 | " need "+Boolean.class.getName()+" got "+ |
1587 | v.getClass().getName() ); |
1588 | } |
1589 | try { |
1590 | setUnitTestCmpProtocol( b ); |
1591 | // invoking directly, not indirectly, |
1592 | // so can't throw ReflectionException |
1593 | } |
1594 | catch ( Exception e ) { |
1595 | throw new MBeanException( e, |
1596 | "exception setting "+n+" attribute" ); |
1597 | } |
1598 | } |
1599 | else if ( ATTR_UNIT_TEST_CMP_RECEIVER_NAME.equals( n ) ) { |
1600 | boolean b; |
1601 | try { |
1602 | b = ((Boolean)v).booleanValue(); |
1603 | } |
1604 | catch ( ClassCastException cce ){ |
1605 | throw new InvalidAttributeValueException( "for attribute "+ |
1606 | " need "+Boolean.class.getName()+" got "+ |
1607 | v.getClass().getName() ); |
1608 | } |
1609 | try { |
1610 | setUnitTestCmpReceiver( b ); |
1611 | // invoking directly, not indirectly, |
1612 | // so can't throw ReflectionException |
1613 | } |
1614 | catch ( Exception e ) { |
1615 | throw new MBeanException( e, |
1616 | "exception setting "+n+" attribute" ); |
1617 | } |
1618 | } |
1619 | else if ( ATTR_UNIT_TEST_CMP_REPLY_BY_NAME.equals( n ) ) { |
1620 | boolean b; |
1621 | try { |
1622 | b = ((Boolean)v).booleanValue(); |
1623 | } |
1624 | catch ( ClassCastException cce ){ |
1625 | throw new InvalidAttributeValueException( "for attribute "+ |
1626 | " need "+Boolean.class.getName()+" got "+ |
1627 | v.getClass().getName() ); |
1628 | } |
1629 | try { |
1630 | setUnitTestCmpReplyBy( b ); |
1631 | // invoking directly, not indirectly, |
1632 | // so can't throw ReflectionException |
1633 | } |
1634 | catch ( Exception e ) { |
1635 | throw new MBeanException( e, |
1636 | "exception setting "+n+" attribute" ); |
1637 | } |
1638 | } |
1639 | else if ( ATTR_UNIT_TEST_CMP_REPLY_TO_NAME.equals( n ) ) { |
1640 | boolean b; |
1641 | try { |
1642 | b = ((Boolean)v).booleanValue(); |
1643 | } |
1644 | catch ( ClassCastException cce ){ |
1645 | throw new InvalidAttributeValueException( "for attribute "+ |
1646 | " need "+Boolean.class.getName()+" got "+ |
1647 | v.getClass().getName() ); |
1648 | } |
1649 | try { |
1650 | setUnitTestCmpReplyTo( b ); |
1651 | // invoking directly, not indirectly, |
1652 | // so can't throw ReflectionException |
1653 | } |
1654 | catch ( Exception e ) { |
1655 | throw new MBeanException( e, |
1656 | "exception setting "+n+" attribute" ); |
1657 | } |
1658 | } |
1659 | else if ( ATTR_UNIT_TEST_CMP_REPLY_WITH_NAME.equals( n ) ) { |
1660 | boolean b; |
1661 | try { |
1662 | b = ((Boolean)v).booleanValue(); |
1663 | } |
1664 | catch ( ClassCastException cce ){ |
1665 | throw new InvalidAttributeValueException( "for attribute "+ |
1666 | " need "+Boolean.class.getName()+" got "+ |
1667 | v.getClass().getName() ); |
1668 | } |
1669 | try { |
1670 | setUnitTestCmpReplyWith( b ); |
1671 | // invoking directly, not indirectly, |
1672 | // so can't throw ReflectionException |
1673 | } |
1674 | catch ( Exception e ) { |
1675 | throw new MBeanException( e, |
1676 | "exception setting "+n+" attribute" ); |
1677 | } |
1678 | } |
1679 | else if ( ATTR_UNIT_TEST_CMP_SENDER_NAME.equals( n ) ) { |
1680 | boolean b; |
1681 | try { |
1682 | b = ((Boolean)v).booleanValue(); |
1683 | } |
1684 | catch ( ClassCastException cce ){ |
1685 | throw new InvalidAttributeValueException( "for attribute "+ |
1686 | " need "+Boolean.class.getName()+" got "+ |
1687 | v.getClass().getName() ); |
1688 | } |
1689 | try { |
1690 | setUnitTestCmpSender( b ); |
1691 | // invoking directly, not indirectly, |
1692 | // so can't throw ReflectionException |
1693 | } |
1694 | catch ( Exception e ) { |
1695 | throw new MBeanException( e, |
1696 | "exception setting "+n+" attribute" ); |
1697 | } |
1698 | } |
1699 | else if ( ATTR_UNIT_TEST_CMP_USER_PROPERTIES_NAME.equals( n ) ) { |
1700 | boolean b; |
1701 | try { |
1702 | b = ((Boolean)v).booleanValue(); |
1703 | } |
1704 | catch ( ClassCastException cce ){ |
1705 | throw new InvalidAttributeValueException( "for attribute "+ |
1706 | " need "+Boolean.class.getName()+" got "+ |
1707 | v.getClass().getName() ); |
1708 | } |
1709 | try { |
1710 | setUnitTestCmpUserProperties( b ); |
1711 | // invoking directly, not indirectly, |
1712 | // so can't throw ReflectionException |
1713 | } |
1714 | catch ( Exception e ) { |
1715 | throw new MBeanException( e, |
1716 | "exception setting "+n+" attribute" ); |
1717 | } |
1718 | } |
1719 | else if ( ATTR_UNIT_TEST_IGNORE_CONTENT_AID_ADDRESSES_NAME.equals( n ) ) { |
1720 | boolean b; |
1721 | try { |
1722 | b = ((Boolean)v).booleanValue(); |
1723 | } |
1724 | catch ( ClassCastException cce ){ |
1725 | throw new InvalidAttributeValueException( "for attribute "+ |
1726 | " need "+Boolean.class.getName()+" got "+ |
1727 | v.getClass().getName() ); |
1728 | } |
1729 | try { |
1730 | setUnitTestIgnoreContentAIDAddresses( b ); |
1731 | // invoking directly, not indirectly, |
1732 | // so can't throw ReflectionException |
1733 | } |
1734 | catch ( Exception e ) { |
1735 | throw new MBeanException( e, |
1736 | "exception setting "+n+" attribute" ); |
1737 | } |
1738 | } |
1739 | else if ( ATTR_UNIT_TEST_NEWLINES_NORMALIZED_NAME.equals( n ) ) { |
1740 | boolean b; |
1741 | try { |
1742 | b = ((Boolean)v).booleanValue(); |
1743 | } |
1744 | catch ( ClassCastException cce ){ |
1745 | throw new InvalidAttributeValueException( "for attribute "+ |
1746 | " need "+Boolean.class.getName()+" got "+ |
1747 | v.getClass().getName() ); |
1748 | } |
1749 | try { |
1750 | setUnitTestNewlinesNormalized( b ); |
1751 | // invoking directly, not indirectly, |
1752 | // so can't throw ReflectionException |
1753 | } |
1754 | catch ( Exception e ) { |
1755 | throw new MBeanException( e, |
1756 | "exception setting "+n+" attribute" ); |
1757 | } |
1758 | } |
1759 | else { |
1760 | // no parent class to try, subclasses had first crack |
1761 | throw new AttributeNotFoundException( |
1762 | "no such writable attribute"+n ); |
1763 | } |
1764 | |
1765 | |
1766 | } |
1767 | |
1768 | /** |
1769 | * set multiple attribute values |
1770 | * @param attributes attribute values to set |
1771 | * @return set attribute values |
1772 | */ |
1773 | public AttributeList setAttributes(AttributeList attributes) { |
1774 | int attrCount = attributes.size(); |
1775 | for ( int i = 0; i < attrCount; i++ ) { |
1776 | try { |
1777 | setAttribute( (Attribute)attributes.get(i) ); |
1778 | } |
1779 | catch ( RuntimeException re ) { |
1780 | throw re; |
1781 | } |
1782 | catch ( Exception e ) { |
1783 | throw new RuntimeException( e ); |
1784 | } |
1785 | } |
1786 | return attributes; |
1787 | } |
1788 | |
1789 | /** |
1790 | * invoke an operation |
1791 | * @param actionName name of action to invoke |
1792 | * @param params action parameters |
1793 | * @param signature action signature |
1794 | * @return object result |
1795 | * @exception MBeanException wrap action exception |
1796 | * @exception ReflectionException wrap action invocation exception |
1797 | */ |
1798 | public Object invoke(String actionName, Object params[], String signature[]) |
1799 | throws MBeanException, ReflectionException { |
1800 | |
1801 | Object o = null; |
1802 | if ( OPER_UNIT_TEST_INJECT_AND_EXPECT_NAME.equals( actionName ) && |
1803 | MBeanUtil.signaturesEqual( |
1804 | OPER_UNIT_TEST_INJECT_AND_EXPECT_SIGNATURE, signature ) ) { |
1805 | try { |
1806 | unitTestInjectAndExpect(); |
1807 | } |
1808 | catch ( Exception e ) { |
1809 | throw new MBeanException( e, |
1810 | "exception invoking "+actionName+" operation"); |
1811 | } |
1812 | } |
1813 | else if ( OPER_UNIT_TEST_ADD_VARIABLE_NAME.equals( actionName ) && |
1814 | MBeanUtil.signaturesEqual( |
1815 | OPER_UNIT_TEST_ADD_VARIABLE_SIGNATURE, signature ) ) { |
1816 | try { |
1817 | unitTestAddVariable( (String)params[0], (String)params[1] ); |
1818 | } |
1819 | catch ( Exception e ) { |
1820 | throw new MBeanException( e, |
1821 | "exception invoking "+actionName+" operation"); |
1822 | } |
1823 | } |
1824 | else if ( OPER_UNIT_TEST_CLEAR_VARIABLES_NAME.equals( actionName ) && |
1825 | MBeanUtil.signaturesEqual( |
1826 | OPER_UNIT_TEST_CLEAR_VARIABLES_SIGNATURE, signature ) ) { |
1827 | try { |
1828 | unitTestClearVariables(); |
1829 | } |
1830 | catch ( Exception e ) { |
1831 | throw new MBeanException( e, |
1832 | "exception invoking "+actionName+" operation"); |
1833 | } |
1834 | } |
1835 | else { |
1836 | // no superclass to try and any subclass already had first crack |
1837 | throw new ReflectionException( new RuntimeException(), |
1838 | "no action named \""+actionName+"\" with given signature"); |
1839 | } |
1840 | return o; |
1841 | } |
1842 | |
1843 | // END DynamicMBean IMPLEMENTATION |
1844 | |
1845 | // |
1846 | // UNIT TESTING |
1847 | // |
1848 | |
1849 | /** |
1850 | * set timeout to use for testing expressed as ISO 8601 duration. |
1851 | * The timeout does have a default which is, however, not guaranteed |
1852 | * to remain the same. |
1853 | * @param timeoutStr timeout for test expressed as ISO 8601 duration |
1854 | */ |
1855 | public void setUnitTestTimeout( String timeoutStr ) { |
1856 | this.unitTestTimeout = new Duration( timeoutStr ); |
1857 | } |
1858 | |
1859 | /** |
1860 | * return unit test timeout as an ISO8601 duration string |
1861 | * @return unit test timeout as an ISO8601 duration string |
1862 | */ |
1863 | public String getUnitTestTimeout() { |
1864 | return unitTestTimeout.toString(); |
1865 | } |
1866 | |
1867 | /** |
1868 | * set the expected message for unit testing |
1869 | * @param expectMsg message to expect to see as result of injecting msg |
1870 | * @throws JademxException wrap any exception thrown |
1871 | */ |
1872 | public void setUnitTestExpectedMessage( String expectMsg ) throws JademxException { |
1873 | try { |
1874 | unitTestExpectedMessage = AclMsgCmp.stringToMessage( expectMsg ); |
1875 | if ( null == unitTestExpectedMessage.getSender() ) { |
1876 | throw new JademxException("expected message has no sender:"+ |
1877 | expectMsg); |
1878 | } |
1879 | } |
1880 | catch ( CodecException e ) { |
1881 | throw new JademxException( |
1882 | "exception converting to ACLMessage from string:"+expectMsg, |
1883 | e ); |
1884 | } |
1885 | } |
1886 | |
1887 | /** |
1888 | * return the expected message for unit testing as a string |
1889 | * @return string representation of expected message for unit testing |
1890 | */ |
1891 | public String getUnitTestExpectedMessage() { |
1892 | String expectedMessageStr = null; |
1893 | if ( null != unitTestExpectedMessage ) { |
1894 | expectedMessageStr = unitTestExpectedMessage.toString(); |
1895 | } |
1896 | return expectedMessageStr; |
1897 | } |
1898 | |
1899 | |
1900 | |
1901 | /** |
1902 | * set the inject message for unit testing |
1903 | * @param injectMsg message to inject |
1904 | * @throws JademxException wrap any exception thrown |
1905 | */ |
1906 | public void setUnitTestInjectMessage( String injectMsg ) throws JademxException { |
1907 | try { |
1908 | unitTestInjectMessage = AclMsgCmp.stringToMessage( injectMsg ); |
1909 | } |
1910 | catch ( CodecException e ) { |
1911 | throw new JademxException( |
1912 | "exception converting to ACLMessage from string:"+injectMsg, |
1913 | e ); |
1914 | } |
1915 | } |
1916 | |
1917 | /** |
1918 | * return the message to inject for unit testing as a string |
1919 | * @return string representation of message to inject for unit testing |
1920 | */ |
1921 | public String getUnitTestInjectMessage() { |
1922 | String injectMessageStr = null; |
1923 | if ( null != unitTestInjectMessage ) { |
1924 | injectMessageStr = unitTestInjectMessage.toString(); |
1925 | } |
1926 | return injectMessageStr; |
1927 | } |
1928 | |
1929 | /** |
1930 | * return the actual message that was compared for unit testing as a string |
1931 | * @return string representation of actual message for unit testing |
1932 | */ |
1933 | public String getUnitTestActualMessage() { |
1934 | String actualMessageStr = null; |
1935 | if ( null != unitTestActualMessage ) { |
1936 | actualMessageStr = unitTestActualMessage.toString(); |
1937 | } |
1938 | return actualMessageStr; |
1939 | } |
1940 | |
1941 | /** |
1942 | * set the actual message |
1943 | * @param unitTestActualMessage actual message to set |
1944 | */ |
1945 | public void setUnitTestActualMessage( ACLMessage unitTestActualMessage ) { |
1946 | this.unitTestActualMessage = unitTestActualMessage; |
1947 | } |
1948 | |
1949 | |
1950 | /** |
1951 | * method to inject a message for unit testing. |
1952 | * will generate either a success or failure (asynchronous) notification. |
1953 | * @throws JademxException wrap any exception thrown |
1954 | */ |
1955 | public void unitTestInjectAndExpect() |
1956 | throws JademxException { |
1957 | |
1958 | Exception e = null; |
1959 | if ( null == unitTestExpectedMessage ) { |
1960 | e = new IllegalStateException("expected message not set"); |
1961 | } |
1962 | else if ( null == unitTestInjectMessage ) { |
1963 | e = new IllegalStateException("inject message not set"); |
1964 | } |
1965 | else if ( null == unitTestTimeout ) { |
1966 | e = new IllegalStateException("timeout not set"); |
1967 | } |
1968 | if ( null != e ) { |
1969 | throw new JademxException( |
1970 | "agent not properly initialized for unit testing", e ); |
1971 | } |
1972 | unitTestActualMessage = null; |
1973 | |
1974 | // add a behaviour to inject test message and cause notification |
1975 | UnitTestBehaviour b = new UnitTestBehaviour( |
1976 | this, |
1977 | unitTestExpectedMessage, |
1978 | unitTestInjectMessage, |
1979 | unitTestTimeout, |
1980 | unitTestVariableProperties ); |
1981 | |
1982 | addBehaviour( b ); |
1983 | } |
1984 | |
1985 | /** |
1986 | * add a variable |
1987 | * @param variable string that can vary one message to next |
1988 | * @param type type of string (see AclMsgCmp.*_MAP) |
1989 | */ |
1990 | public void unitTestAddVariable( String variable, String type ) { |
1991 | unitTestVariableProperties.setProperty( variable, type ); |
1992 | } |
1993 | |
1994 | /** |
1995 | * clear all variables |
1996 | */ |
1997 | public void unitTestClearVariables() { |
1998 | unitTestVariableProperties.clear(); |
1999 | } |
2000 | |
2001 | /** |
2002 | * see if unit testing part of agent yet visible via JMX |
2003 | * @param agentObjectName ObjectName for agent MBean |
2004 | * @param mBeanServer MBeanServer with agent MBean |
2005 | * @return whether unit test mbean stuff yet visible |
2006 | */ |
2007 | private static boolean isUnitTestVisible( |
2008 | ObjectName agentObjectName, |
2009 | MBeanServer mBeanServer ) { |
2010 | boolean visible = false; |
2011 | MBeanInfo mBeanInfo = null; |
2012 | try { |
2013 | mBeanInfo = mBeanServer.getMBeanInfo( agentObjectName ); |
2014 | } |
2015 | catch ( Exception e ) { |
2016 | // ignore, will return false |
2017 | } |
2018 | if ( null != mBeanInfo ) { |
2019 | visible = MBeanUtil.mBeanHasOper( mBeanInfo, |
2020 | OPER_UNIT_TEST_INJECT_AND_EXPECT_NAME, |
2021 | OPER_UNIT_TEST_INJECT_AND_EXPECT_SIGNATURE ); |
2022 | } |
2023 | return visible; |
2024 | } |
2025 | |
2026 | /** how long to sleep waiting for unit testing visibility */ |
2027 | private final static long UNIT_TEST_VISIBILITY_SLEEP_MS = 1000; // 1,000ms = 1sec |
2028 | /** how long to wait for unit testing visibility */ |
2029 | private final static long UNIT_TEST_VISIBILITY_PATIENCE_MS = 60 * 1000; // 60,000ms = 1min |
2030 | |
2031 | |
2032 | /** |
2033 | * see if agent MBean is currently bound to a JademxAgent |
2034 | * @return whether arg is currently bound to a JademxAgent |
2035 | */ |
2036 | public static boolean isJademxBound( |
2037 | ObjectName agentObjectName, |
2038 | MBeanServer mBeanServer) { |
2039 | // do this by being able to see unitTestInvoke operation |
2040 | boolean bound = isUnitTestVisible( agentObjectName, mBeanServer ); |
2041 | return bound; |
2042 | } |
2043 | |
2044 | |
2045 | /** |
2046 | * assert that MBean bound to JademxAgent |
2047 | * @param agentObjectName ObjectName for agent |
2048 | * @param mBeanServer MBeanServer for agent MBean |
2049 | * @param sleepMS interval sleep time while checking in milliseconds |
2050 | * @param patienceMS maximum time to wait in milliseconds |
2051 | */ |
2052 | public static void assertIsJademxAgent( |
2053 | ObjectName agentObjectName, |
2054 | MBeanServer mBeanServer, |
2055 | long sleepMS, |
2056 | long patienceMS ) { |
2057 | // make sure the agent is bound to jademx |
2058 | if ( !isJademxBound( agentObjectName, mBeanServer ) ) { |
2059 | boolean visible = false; |
2060 | Date now = new Date(); |
2061 | long nowMS = now.getTime(); |
2062 | long stopMS = nowMS + patienceMS; |
2063 | while ( !visible && ( nowMS < stopMS ) ) { |
2064 | try { |
2065 | Thread.sleep( sleepMS ); |
2066 | } |
2067 | catch ( Exception e ) { |
2068 | // don't care why sleep stopped |
2069 | } |
2070 | visible = isJademxBound( agentObjectName, mBeanServer ); |
2071 | } |
2072 | if ( !visible ) { |
2073 | Assert.fail("unit testing capability not visible within "+ |
2074 | UNIT_TEST_VISIBILITY_PATIENCE_MS+"ms"); |
2075 | } |
2076 | } |
2077 | } |
2078 | |
2079 | |
2080 | /** |
2081 | * using default timeout values, assert that MBean bound to JademxAgent |
2082 | * @param agentObjectName ObjectName for agent |
2083 | * @param mBeanServer MBeanServer for agent MBean |
2084 | */ |
2085 | public static void assertIsJademxAgent( |
2086 | ObjectName agentObjectName, |
2087 | MBeanServer mBeanServer) { |
2088 | assertIsJademxAgent( agentObjectName, mBeanServer, |
2089 | UNIT_TEST_VISIBILITY_SLEEP_MS, |
2090 | UNIT_TEST_VISIBILITY_PATIENCE_MS ); |
2091 | } |
2092 | |
2093 | /** |
2094 | * do a JUnit assertion that expected message seen after a message injected. |
2095 | * This method is similar in concept to a synchronous version of |
2096 | * the <code>unitTestInjectAndExpect</code> JadeAgentMBeanDef MBean operation. |
2097 | * It is not accessible as an MBean operation so that the MBeanServer |
2098 | * does not hang waiting for its return. It intended to be used in |
2099 | * a JUnit test like Junit.Assert methods. It is a static method |
2100 | * rather than an instance method because JMX users are only expected to |
2101 | * have JMX access rather than direct access. |
2102 | * @param junitFailureMessage the string to use for junit failure message |
2103 | * @param agentObjectName ObjectName for agent MBean |
2104 | * @param mBeanServer MBeanServer with agent MBean |
2105 | */ |
2106 | public static void assertExpectedMessage( |
2107 | String junitFailureMessage, |
2108 | ObjectName agentObjectName, |
2109 | MBeanServer mBeanServer ) { |
2110 | |
2111 | logger.log( Level.FINE, "entering"); |
2112 | |
2113 | // make sure the agent is bound to jademx (can see unitTestInvoke oper) |
2114 | assertIsJademxAgent( agentObjectName, mBeanServer ); |
2115 | logger.log( Level.FINE, "unit test visible"); |
2116 | |
2117 | // register notification listener for agent mbean |
2118 | UnitTestNotificationListener nListener = |
2119 | new UnitTestNotificationListener(); |
2120 | try { |
2121 | mBeanServer.addNotificationListener( |
2122 | agentObjectName, nListener, null, null ); |
2123 | } |
2124 | catch ( Exception e ) { |
2125 | Assert.fail( ThrowableUtil.errMsg( |
2126 | "problem adding notification listener to "+agentObjectName, |
2127 | e ) ); |
2128 | } |
2129 | |
2130 | logger.log( Level.FINE, "notification listener added"); |
2131 | |
2132 | // try block for removing notification listener finally |
2133 | try { |
2134 | |
2135 | // invoke the unitTestInvoke operation |
2136 | |
2137 | Notification notification = null; |
2138 | String actionMsgStr = null; |
2139 | logger.log( Level.FINE, "entering block synchronized on listener"); |
2140 | synchronized( nListener ) { |
2141 | |
2142 | long timeoutMS = 0; |
2143 | try { |
2144 | logger.log( Level.FINE, "invoking "+OPER_UNIT_TEST_INJECT_AND_EXPECT_NAME); |
2145 | mBeanServer.invoke( |
2146 | agentObjectName, |
2147 | OPER_UNIT_TEST_INJECT_AND_EXPECT_NAME, |
2148 | new Object[] {}, |
2149 | OPER_UNIT_TEST_INJECT_AND_EXPECT_SIGNATURE ); |
2150 | logger.log( Level.FINE, "returned from "+OPER_UNIT_TEST_INJECT_AND_EXPECT_NAME); |
2151 | logger.log( Level.FINE, "getting attribute "+ATTR_UNIT_TEST_TIMEOUT_NAME); |
2152 | String timeoutStr = (String)mBeanServer.getAttribute( |
2153 | agentObjectName, ATTR_UNIT_TEST_TIMEOUT_NAME ); |
2154 | logger.log( Level.FINE, "got attribute "+ATTR_UNIT_TEST_TIMEOUT_NAME); |
2155 | Duration timeoutDuration = new Duration( timeoutStr ); |
2156 | timeoutMS = timeoutDuration.toMilliseconds(); |
2157 | |
2158 | } |
2159 | catch ( Throwable t ) { |
2160 | Assert.fail( |
2161 | ThrowableUtil.errMsg("problem invoking test injection", t ) ); |
2162 | } |
2163 | |
2164 | // wait until get a notification or time out |
2165 | |
2166 | logger.log( Level.FINE, "waiting for notification or timeout"); |
2167 | Date now = new Date(); |
2168 | long nowMS = now.getTime(); |
2169 | long startMS = nowMS; |
2170 | long stopMS = startMS + timeoutMS; |
2171 | boolean doneWaiting = false; |
2172 | while ( !doneWaiting ) { |
2173 | long timeLeftMS = stopMS - nowMS; |
2174 | try { |
2175 | logger.log( Level.FINE, "calling wait on listener"); |
2176 | nListener.wait( timeLeftMS ); |
2177 | logger.log( Level.FINE, "returned from wait on listener"); |
2178 | } |
2179 | catch ( InterruptedException ie ) { |
2180 | // interrupted while waiting, try waiting again |
2181 | logger.log( Level.FINE, |
2182 | "interrupted waiting for unit test invocation"); |
2183 | } |
2184 | notification = nListener.getNotification(); |
2185 | if ( null != notification ) { |
2186 | doneWaiting = true; |
2187 | } |
2188 | else { |
2189 | now = new Date(); |
2190 | nowMS = now.getTime(); |
2191 | if ( nowMS >= stopMS ) { |
2192 | doneWaiting = true; |
2193 | actionMsgStr = |
2194 | "timeout waiting for unit test notification"; |
2195 | } |
2196 | } |
2197 | } |
2198 | logger.log( Level.FINE, "done waiting for notification or timeout"); |
2199 | |
2200 | } |
2201 | |
2202 | // if timed out or saw exception |
2203 | // junitAssert with a timeout/exception message or |
2204 | // else |
2205 | // if success |
2206 | // junitAssert true |
2207 | // else |
2208 | // junitAssert failure |
2209 | |
2210 | if ( null == notification ) { |
2211 | Assert.fail( actionMsgStr ); |
2212 | } |
2213 | else { |
2214 | if ( NOTIF_UNIT_TEST_SUCCESS_NAME.equals( notification.getType() ) ) { |
2215 | Assert.assertTrue( true ); |
2216 | } |
2217 | else { |
2218 | String notificationMessage = notification.getMessage(); |
2219 | StringBuffer failureMsgSB = new StringBuffer(); |
2220 | if ( null != junitFailureMessage ) { |
2221 | failureMsgSB.append( junitFailureMessage ); |
2222 | } |
2223 | if ( null != notificationMessage ) { |
2224 | if ( null != junitFailureMessage ) { |
2225 | failureMsgSB.append( "(" ); |
2226 | } |
2227 | failureMsgSB.append( notificationMessage ); |
2228 | if ( null != junitFailureMessage ) { |
2229 | failureMsgSB.append( ")" ); |
2230 | } |
2231 | } |
2232 | String failureMsg = failureMsgSB.toString(); |
2233 | Assert.fail( failureMsg ); |
2234 | } |
2235 | } |
2236 | |
2237 | } |
2238 | finally { |
2239 | // make sure notification listener removed |
2240 | try { |
2241 | logger.log( Level.FINE, "removing notification listener"); |
2242 | mBeanServer.removeNotificationListener( |
2243 | agentObjectName, nListener ); |
2244 | logger.log( Level.FINE, "notification listener removed"); |
2245 | } |
2246 | catch ( Exception e ) { |
2247 | logger.warning(ThrowableUtil.errMsg( |
2248 | "problem removing notification listener:",e)); |
2249 | } |
2250 | logger.log( Level.FINE, "exiting"); |
2251 | } |
2252 | |
2253 | |
2254 | } |
2255 | |
2256 | /** |
2257 | * do a JUnit assertion that expected message seen after a message injected. |
2258 | * This method is similar in concept to a synchronous version of |
2259 | * the <code>unitTestInjectAndExpect</code> JadeAgentMBeanDef MBean operation. |
2260 | * It is not accessible as an MBean operation so that the MBeanServer |
2261 | * does not hang waiting for its return. It intended to be used in |
2262 | * a JUnit test like other Junit.Assert methods. It is a static method |
2263 | * rather than an instance method because JMX users are expected to have |
2264 | * JMX access rather than direct access. |
2265 | * @param agentObjectName ObjectName for agent MBean |
2266 | * @param mBeanServer MBeanServer with agent MBean |
2267 | */ |
2268 | public static void assertExpectedMessage( |
2269 | ObjectName agentObjectName, |
2270 | MBeanServer mBeanServer ) { |
2271 | assertExpectedMessage( null, agentObjectName, mBeanServer ); |
2272 | } |
2273 | |
2274 | // END UNIT TESTING |
2275 | |
2276 | } |