1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 package org.ogf.graap.wsag.server.monitoring;
36
37 import java.text.MessageFormat;
38 import java.text.ParseException;
39 import java.util.Arrays;
40 import java.util.Date;
41 import java.util.Iterator;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Observable;
45 import java.util.Observer;
46 import java.util.Vector;
47
48 import org.apache.log4j.Logger;
49 import org.apache.xmlbeans.XmlBoolean;
50 import org.apache.xmlbeans.XmlInt;
51 import org.apache.xmlbeans.XmlObject;
52 import org.apache.xmlbeans.XmlString;
53 import org.ogf.graap.wsag.api.Agreement;
54 import org.ogf.graap.wsag.api.logging.LogMessage;
55 import org.ogf.graap.wsag.api.types.AbstractAgreementType;
56 import org.ogf.graap.wsag.server.accounting.IAccountingSystem;
57 import org.ogf.graap.wsag.server.accounting.SimpleAccountingSystemLogger;
58 import org.ogf.graap.wsag.server.api.IAgreementContext;
59 import org.ogf.graap.wsag.server.api.impl.AgreementContext;
60 import org.ogf.graap.wsag.server.persistence.impl.PersistentAgreementContainer;
61 import org.ogf.schemas.graap.wsAgreement.AgreementContextType;
62 import org.ogf.schemas.graap.wsAgreement.AgreementStateType;
63 import org.ogf.schemas.graap.wsAgreement.GuaranteeTermStateType;
64 import org.ogf.schemas.graap.wsAgreement.ServiceTermStateType;
65 import org.ogf.schemas.graap.wsAgreement.TermTreeType;
66 import org.ogf.schemas.graap.wsAgreement.TerminateInputType;
67 import org.quartz.CronExpression;
68 import org.quartz.CronTrigger;
69 import org.quartz.JobDetail;
70 import org.quartz.Scheduler;
71 import org.quartz.SchedulerException;
72 import org.quartz.SchedulerFactory;
73 import org.quartz.Trigger;
74 import org.quartz.impl.StdSchedulerFactory;
75
76
77
78
79
80
81
82
83
84 public class MonitorableAgreement extends Observable
85 implements Agreement, Observer
86 {
87
88 private static final Logger LOG = Logger.getLogger( MonitorableAgreement.class );
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 public static final String MONITORING_ACTIVE = "org.wsag4j.monitoring.isActive";
105
106
107
108
109
110
111
112
113
114
115 public static final String MONITORING_CRON = "org.wsag4j.monitoring.cron";
116
117
118
119
120
121
122
123
124
125
126
127
128
129 public static final String MONITORING_HANDLER = "org.wsag4j.monitoring.handler";
130
131
132
133
134
135
136
137
138
139
140 public static final String MONITORING_HANDLER_COUNT = "org.wsag4j.monitoring.handler.count";
141
142
143
144
145 private AbstractAgreementType agreementInstance;
146
147 private IAgreementContext executionContext = new AgreementContext( this );
148
149 private final List<IServiceTermMonitoringHandler> monitoringHandler =
150 new Vector<IServiceTermMonitoringHandler>();
151
152 private Scheduler scheduler;
153
154 private String jobName;
155
156 private static final String JOB_GROUP = "WSAG4J";
157
158 private IAccountingSystem accountingSystem = new SimpleAccountingSystemLogger();
159
160 private boolean monitoring = false;
161
162
163
164
165 public boolean isMonitoring()
166 {
167 return monitoring;
168 }
169
170
171
172
173 private static final String DEFAULT_SCHEDULE = "0 0/1 * * * ?";
174
175 private String cronExpression = DEFAULT_SCHEDULE;
176
177
178
179
180
181
182
183
184
185 public MonitorableAgreement( AbstractAgreementType agreement )
186 {
187 this.agreementInstance = agreement;
188
189
190
191
192 agreement.addObserver( this );
193
194
195
196
197 executionContext.getExecutionProperties().putAll( agreement.getExecutionContext() );
198 executionContext.getTransientExecutionProperties().putAll( agreement.getTransientExecutionContext() );
199
200 initializeScheduler();
201 }
202
203
204
205
206
207
208
209
210
211 public MonitorableAgreement( PersistentAgreementContainer persistentAgreementContainer )
212 {
213
214 throw new UnsupportedOperationException( "Not supported yet." );
215 }
216
217 private void initializeScheduler()
218 {
219
220
221
222 synchronized ( SchedulerFactory.class )
223 {
224
225 SchedulerFactory factory = new StdSchedulerFactory();
226
227 try
228 {
229 scheduler = factory.getScheduler();
230
231 if ( !scheduler.isStarted() )
232 {
233 scheduler.start();
234 }
235 }
236 catch ( SchedulerException e )
237 {
238 throw new IllegalStateException( "Failed to instantiate Quartz scheduler.", e );
239 }
240
241 }
242
243 }
244
245 private IMonitoringContext initializeMonitoringContext()
246 {
247
248 IMonitoringContext monitoringContext = new MonitoringContext();
249
250
251
252
253 monitoringContext.setProperties( executionContext.getExecutionProperties() );
254
255
256
257
258 monitoringContext.setTransientProperties( executionContext.getTransientExecutionProperties() );
259
260
261
262
263
264
265
266
267
268
269 monitoringContext.setMonitoringHandler( new IServiceTermMonitoringHandler[0] );
270
271 for ( int i = 0; i < monitoringHandler.size(); i++ )
272 {
273 monitoringContext.addMonitoringHandler( monitoringHandler.get( i ) );
274 }
275
276 monitoringContext.setAccountingSystem( accountingSystem );
277
278
279
280
281 monitoringContext.getTransientProperties().put(
282 IMonitoringContext.WSAG4J_AGREEMENT_EXECUTION_CONTEXT, getExecutionContext() );
283
284 return monitoringContext;
285 }
286
287 private synchronized void scheduleMonitoringJobs( IMonitoringContext monitoringContext ) throws Exception
288 {
289
290
291
292
293
294
295
296 jobName = initializeJobName();
297
298 Trigger agreementMonitoringTrigger = createCronTrigger( jobName );
299
300
301
302
303 JobDetail agreementMonitoringDetail = new JobDetail( jobName, JOB_GROUP, AgreementMonitorJob.class );
304
305 agreementMonitoringDetail.getJobDataMap().put( AgreementMonitorJob.WSAG4J_AGREEMENT_INSTANCE,
306 agreementInstance );
307 agreementMonitoringDetail.getJobDataMap().put( AgreementMonitorJob.WSAG4J_MONITORING_CONTEXT,
308 monitoringContext );
309
310 scheduler.scheduleJob( agreementMonitoringDetail, agreementMonitoringTrigger );
311
312
313
314
315
316 }
317
318 private String initializeJobName() throws SchedulerException
319 {
320 List<String> names = Arrays.asList( scheduler.getJobNames( JOB_GROUP ) );
321
322 String name =
323 MessageFormat.format( "WSAG4J_MONITORING_JOB_{0}", new Object[] { new Date().getTime() } );
324
325 while ( names.contains( name ) )
326 {
327 name = MessageFormat.format( "WSAG4J_MONITORING_JOB_{0}", new Object[] { new Date().getTime() } );
328 try
329 {
330 wait( 10 );
331 }
332 catch ( InterruptedException e )
333 {
334
335 }
336 }
337
338 return name;
339 }
340
341
342
343
344 private void saveHandlerToExecutionContext()
345 {
346 int handlerCount = 0;
347 Iterator<IServiceTermMonitoringHandler> handler = monitoringHandler.iterator();
348
349 while ( handler.hasNext() )
350 {
351
352 String handlerClass = handler.next().getClass().getName();
353
354 String key = MONITORING_HANDLER + "." + handlerCount;
355 XmlString value = XmlString.Factory.newValue( handlerClass );
356
357 getExecutionContext().getExecutionProperties().put( key, value );
358
359 handlerCount++;
360 }
361
362 XmlInt value = XmlInt.Factory.newValue( Integer.valueOf( handlerCount ) );
363 getExecutionContext().getExecutionProperties().put( MONITORING_HANDLER_COUNT, value );
364 }
365
366
367
368
369
370 private void initializeHandlerFromExecutionContext()
371 {
372 int handlerCount = 0;
373 monitoringHandler.clear();
374
375 XmlInt count = (XmlInt) getExecutionContext().getExecutionProperties().get( MONITORING_HANDLER_COUNT );
376 if ( count != null )
377 {
378 handlerCount = count.getIntValue();
379 }
380
381 while ( handlerCount > 0 )
382 {
383 handlerCount--;
384
385 String key = MONITORING_HANDLER + "." + handlerCount;
386 XmlString value = (XmlString) getExecutionContext().getExecutionProperties().get( key );
387
388 LOG.debug( "initialize agreement monitoring handler" );
389
390
391
392
393 try
394 {
395 String className = value.getStringValue();
396 LOG.debug( LogMessage.getMessage( "instantiate monitoring handler ''{0}''", className ) );
397
398 Class<IServiceTermMonitoringHandler> clazz;
399 try
400 {
401
402
403
404 @SuppressWarnings( "unchecked" )
405 Class<IServiceTermMonitoringHandler> convert =
406 (Class<IServiceTermMonitoringHandler>) this.getClass().getClassLoader()
407 .loadClass( className );
408
409 clazz = convert;
410 }
411 catch ( ClassCastException e )
412 {
413 final String msgNotRequiredInterface =
414 "monitoring handler must implement the 'IServiceTermMonitoringHandler' interface.";
415 throw new Exception( msgNotRequiredInterface, e );
416 }
417
418
419
420
421 addMonitoringHandler( clazz.newInstance() );
422
423 LOG.debug( LogMessage.getMessage( "successfully instantiated monitoring handler ''{0}''",
424 className ) );
425 }
426 catch ( Exception e )
427 {
428 String msgText = "re-initializing monitorable agreement failed: {0}";
429 LogMessage message = LogMessage.getMessage( msgText, e.getMessage() );
430 LOG.error( message, e );
431 }
432 }
433
434 }
435
436
437
438
439 public IAgreementContext getExecutionContext()
440 {
441 return executionContext;
442 }
443
444
445
446
447
448 public void setExecutionContext( IAgreementContext executionContext )
449 {
450 this.executionContext = executionContext;
451 }
452
453
454
455
456
457
458 public void addMonitoringHandler( IServiceTermMonitoringHandler handler )
459 {
460 monitoringHandler.add( handler );
461 }
462
463
464
465
466
467
468 public IServiceTermMonitoringHandler[] getMonitoringHandler()
469 {
470 return monitoringHandler.toArray( new IServiceTermMonitoringHandler[monitoringHandler.size()] );
471 }
472
473
474
475
476 public String getCronExpression()
477 {
478 return cronExpression;
479 }
480
481
482
483
484
485 public void setCronExpression( String cronExpression )
486 {
487 this.cronExpression = cronExpression;
488 }
489
490 private Trigger createCronTrigger( String name ) throws Exception
491 {
492
493
494
495 CronTrigger trigger = new CronTrigger();
496
497 try
498 {
499 if ( CronExpression.isValidExpression( cronExpression ) )
500 {
501 trigger.setCronExpression( cronExpression );
502 }
503 else
504 {
505 LOG.error( LogMessage.getMessage(
506 "Invalid cron expression ({0}). Using default monitoring schedule ({1}).",
507 cronExpression, DEFAULT_SCHEDULE ) );
508 trigger.setCronExpression( DEFAULT_SCHEDULE );
509 }
510 }
511 catch ( ParseException e )
512 {
513 String msgText = "Invalid default schedule <{0}>. Monitoring not scheduled.";
514 String message = LogMessage.format( msgText, DEFAULT_SCHEDULE );
515 throw new Exception( message, e );
516 }
517
518 trigger.setGroup( JOB_GROUP );
519 trigger.setName( name );
520
521 return trigger;
522 }
523
524
525
526
527
528
529
530 public void startMonitoring() throws Exception
531 {
532
533
534
535 XmlBoolean isMonitoring = XmlBoolean.Factory.newValue( true );
536 XmlString cron = XmlString.Factory.newValue( cronExpression );
537 getExecutionContext().getExecutionProperties().put( MONITORING_ACTIVE, isMonitoring );
538 getExecutionContext().getExecutionProperties().put( MONITORING_CRON, cron );
539
540
541
542
543 saveHandlerToExecutionContext();
544
545
546
547
548 IMonitoringContext monitoringContext = initializeMonitoringContext();
549
550
551
552
553 try
554 {
555 scheduleMonitoringJobs( monitoringContext );
556 }
557 catch ( Exception e )
558 {
559 final String msgText = "Error scheduling monitoring jobs. Reason: {0}";
560 String message = LogMessage.format( msgText, e.getMessage() );
561 LOG.error( message, e );
562
563 throw new Exception( message, e );
564 }
565
566 this.monitoring = true;
567 }
568
569
570
571
572
573
574
575 public void stopMonitoring() throws Exception
576 {
577 try
578 {
579 XmlBoolean isMonitoring = XmlBoolean.Factory.newValue( false );
580 getExecutionContext().getExecutionProperties().put( MONITORING_ACTIVE, isMonitoring );
581 getAgreementInstance().getAgreementInstance().getExecutionContext()
582 .put( MONITORING_ACTIVE, isMonitoring );
583
584
585
586
587
588
589
590 scheduler.unscheduleJob( jobName, JOB_GROUP );
591 }
592 catch ( SchedulerException e )
593 {
594 String message = "Error stoping the agreement monitoring. Reason: " + e.getMessage();
595 LOG.error( message );
596
597 throw new Exception( message, e );
598 }
599
600 this.monitoring = false;
601 }
602
603
604
605
606 public void terminate( TerminateInputType reason )
607 {
608 try
609 {
610 stopMonitoring();
611 }
612 catch ( Exception ex )
613 {
614 LOG.error( "The agreement monitoring scheduler was not stoped" );
615
616 if ( LOG.isDebugEnabled() )
617 {
618 LOG.debug( ex );
619 }
620 }
621
622 try
623 {
624 agreementInstance.terminate( reason );
625 }
626 catch ( Exception ex )
627 {
628 LOG.error( "The agreement could not be terminated." );
629
630 if ( LOG.isDebugEnabled() )
631 {
632 LOG.debug( ex );
633 }
634 }
635
636 }
637
638
639
640
641
642
643
644
645
646
647
648 public void notifyReload() throws Exception
649 {
650 agreementInstance.notifyReload( executionContext.getExecutionProperties() );
651
652
653
654
655 initializeHandlerFromExecutionContext();
656
657 Map<String, XmlObject> executionProperties = getExecutionContext().getExecutionProperties();
658 XmlString cron = (XmlString) executionProperties.get( MonitorableAgreement.MONITORING_CRON );
659
660 if ( cron != null )
661 {
662 cronExpression = cron.getStringValue();
663 }
664 else
665 {
666 cronExpression = DEFAULT_SCHEDULE;
667 }
668
669 boolean isActive = false;
670 if ( executionProperties.containsKey( MONITORING_ACTIVE ) )
671 {
672 isActive =
673 ( (XmlBoolean) executionProperties.get( MonitorableAgreement.MONITORING_ACTIVE ) ).getBooleanValue();
674 }
675
676 if ( isActive )
677 {
678 startMonitoring();
679 }
680 }
681
682
683
684
685
686 public String getAgreementId()
687 {
688 return agreementInstance.getAgreementId();
689 }
690
691
692
693
694
695 public AgreementContextType getContext()
696 {
697 return agreementInstance.getContext();
698 }
699
700
701
702
703
704 public GuaranteeTermStateType[] getGuaranteeTermStates()
705 {
706 return agreementInstance.getGuaranteeTermStates();
707 }
708
709
710
711
712
713 public String getName()
714 {
715 return agreementInstance.getName();
716 }
717
718
719
720
721
722 public ServiceTermStateType[] getServiceTermStates()
723 {
724 return agreementInstance.getServiceTermStates();
725 }
726
727
728
729
730
731 public AgreementStateType getState()
732 {
733 return agreementInstance.getState();
734 }
735
736
737
738
739
740 public TermTreeType getTerms()
741 {
742 return agreementInstance.getTerms();
743 }
744
745
746
747
748 public AbstractAgreementType getAgreementInstance()
749 {
750 return agreementInstance;
751 }
752
753
754
755
756
757 public void setAccountingSystem( IAccountingSystem accountingSystem )
758 {
759 if ( accountingSystem != null )
760 {
761 this.accountingSystem = accountingSystem;
762 }
763 }
764
765
766
767
768 public IAccountingSystem getAccountingSystem()
769 {
770 return accountingSystem;
771 }
772
773
774
775
776
777
778
779
780
781
782 public void update( Observable o, Object arg )
783 {
784 if ( o == agreementInstance )
785 {
786 setChanged();
787 notifyObservers();
788 }
789 }
790 }