1 package org.apache.fulcrum.yaafi.framework.container;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.InputStream;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Properties;
28
29 import org.apache.avalon.framework.configuration.Configuration;
30 import org.apache.avalon.framework.configuration.ConfigurationException;
31 import org.apache.avalon.framework.configuration.DefaultConfiguration;
32 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
33 import org.apache.avalon.framework.container.ContainerUtil;
34 import org.apache.avalon.framework.context.Context;
35 import org.apache.avalon.framework.context.ContextException;
36 import org.apache.avalon.framework.context.DefaultContext;
37 import org.apache.avalon.framework.logger.Logger;
38 import org.apache.avalon.framework.parameters.ParameterException;
39 import org.apache.avalon.framework.parameters.Parameters;
40 import org.apache.avalon.framework.service.ServiceException;
41 import org.apache.avalon.framework.service.ServiceManager;
42 import org.apache.fulcrum.yaafi.framework.component.AvalonServiceComponentImpl;
43 import org.apache.fulcrum.yaafi.framework.component.ServiceComponent;
44 import org.apache.fulcrum.yaafi.framework.configuration.ComponentConfigurationPropertiesResolver;
45 import org.apache.fulcrum.yaafi.framework.configuration.ComponentConfigurationPropertiesResolverImpl;
46 import org.apache.fulcrum.yaafi.framework.constant.AvalonYaafiConstants;
47 import org.apache.fulcrum.yaafi.framework.context.AvalonToYaafiContextMapper;
48 import org.apache.fulcrum.yaafi.framework.context.YaafiToAvalonContextMapper;
49 import org.apache.fulcrum.yaafi.framework.crypto.CryptoStreamFactory;
50 import org.apache.fulcrum.yaafi.framework.role.RoleConfigurationParser;
51 import org.apache.fulcrum.yaafi.framework.role.RoleConfigurationParserImpl;
52 import org.apache.fulcrum.yaafi.framework.role.RoleEntry;
53 import org.apache.fulcrum.yaafi.framework.util.ConfigurationUtil;
54 import org.apache.fulcrum.yaafi.framework.util.InputStreamLocator;
55 import org.apache.fulcrum.yaafi.framework.util.ToStringBuilder;
56 import org.apache.fulcrum.yaafi.framework.util.Validate;
57
58 import org.apache.commons.lang3.StringUtils;
59
60
61
62
63
64
65
66 public class ServiceContainerImpl implements ServiceContainer, ServiceConstants {
67
68 private static final int DISPOSAL_DELAY_DEFAULT = 0;
69
70
71 private static final int RECONFIGURATION_DELAY_DEFAULT = 2000;
72
73
74 private String componentRolesLocation;
75
76
77 private String isComponentRolesEncrypted;
78
79
80 private String componentRolesFlavour;
81
82
83 private String componentConfigurationLocation;
84
85
86 private String isComponentConfigurationEncrypted;
87
88
89 private String parametersLocation;
90
91
92 private String isParametersEncrypted;
93
94
95 private File applicationRootDir;
96
97
98 private File tempRootDir;
99
100
101 private Logger logger;
102
103
104 private ServiceManager parentServiceManager;
105
106
107 private List<ServiceComponent> serviceList;
108
109
110 private HashMap<String, ServiceComponent> serviceMap;
111
112
113 private Configuration roleConfiguration;
114
115
116 private Configuration serviceConfiguration;
117
118
119 private Context callerContext;
120
121
122 private Context context;
123
124
125 private Parameters parameters;
126
127
128 private volatile boolean isAlreadyDisposed;
129
130
131 private volatile boolean isCurrentlyDisposing;
132
133
134 private String containerFlavour;
135
136
137
138
139
140 private int reconfigurationDelay;
141
142
143 private int disposalDelay;
144
145
146 private boolean hasDynamicProxies;
147
148
149 private ArrayList<String> defaultInterceptorServiceList;
150
151
152 private ArrayList<String> fallbackServiceManagerList;
153
154
155
156
157 private Configuration componentConfigurationPropertiesResolverConfig;
158
159
160
161
162
163
164
165
166 public ServiceContainerImpl() {
167 super();
168
169 this.containerFlavour = COMPONENT_CONTAINERFLAVOUR_VALUE;
170 this.componentRolesFlavour = COMPONENT_ROLECONFIGFLAVOUR_VALUE;
171
172 this.componentRolesLocation = COMPONENT_ROLE_VALUE;
173 this.componentConfigurationLocation = COMPONENT_CONFIG_VALUE;
174 this.parametersLocation = COMPONENT_PARAMETERS_VALUE;
175
176 this.isComponentConfigurationEncrypted = "false";
177 this.isComponentRolesEncrypted = "false";
178 this.isParametersEncrypted = "false";
179
180 this.isAlreadyDisposed = false;
181 this.isCurrentlyDisposing = false;
182
183 this.serviceList = new ArrayList<ServiceComponent>();
184 this.serviceMap = new HashMap<String, ServiceComponent>();
185
186 this.applicationRootDir = new File(new File("").getAbsolutePath());
187 this.tempRootDir = new File(System.getProperty("java.io.tmpdir", "."));
188
189 this.fallbackServiceManagerList = new ArrayList<String>();
190 this.defaultInterceptorServiceList = new ArrayList<String>();
191
192 this.disposalDelay = DISPOSAL_DELAY_DEFAULT;
193 this.reconfigurationDelay = RECONFIGURATION_DELAY_DEFAULT;
194 }
195
196
197
198
199 public void enableLogging(Logger logger) {
200 Validate.notNull(logger, "logger");
201 this.logger = logger;
202 }
203
204
205
206
207 public void contextualize(Context context) throws ContextException {
208 Validate.notNull(context, "context");
209
210 this.callerContext = context;
211 }
212
213
214
215
216 public void service(ServiceManager serviceManager) throws ServiceException {
217 this.parentServiceManager = serviceManager;
218 }
219
220
221
222
223 public void configure(Configuration configuration) throws ConfigurationException {
224 Validate.notNull(configuration, "configuration");
225
226
227
228 this.reconfigurationDelay = configuration.getChild(RECONFIGURATION_DELAY_KEY)
229 .getValueAsInteger(RECONFIGURATION_DELAY_DEFAULT);
230
231
232
233 this.disposalDelay = configuration.getChild(DISPOSAL_DELAY_KEY).getValueAsInteger(DISPOSAL_DELAY_DEFAULT);
234
235
236
237 this.hasDynamicProxies = configuration.getChild(DYNAMICPROXY_ENABLED_KEY).getValueAsBoolean(false);
238
239
240
241 this.setContainerFlavour(
242 configuration.getChild(CONTAINERFLAVOUR_CONFIG_KEY).getValue(COMPONENT_CONTAINERFLAVOUR_VALUE));
243
244 this.getLogger().debug("Using the following container type : " + this.getContainerFlavour());
245
246
247
248 try {
249
250
251
252 AvalonToYaafiContextMapper mapper = new AvalonToYaafiContextMapper(this.getTempRootDir(),
253 this.callerContext, this.getClassLoader());
254
255
256
257 this.context = mapper.mapFrom(this.callerContext, this.getContainerFlavour());
258
259
260
261 this.callerContext = null;
262 } catch (ContextException e) {
263 String msg = "Failed to parse the caller-supplied context";
264 this.getLogger().error(msg, e);
265 throw new ConfigurationException(msg);
266 }
267
268
269
270 Configuration currComponentRoles = configuration.getChild(COMPONENT_ROLE_KEYS);
271
272 this.setComponentRolesLocation(
273 currComponentRoles.getChild(COMPONENT_LOCATION_KEY).getValue(COMPONENT_ROLE_VALUE));
274
275 this.setComponentRolesFlavour(
276 currComponentRoles.getChild(CONTAINERFLAVOUR_CONFIG_KEY).getValue(COMPONENT_ROLECONFIGFLAVOUR_VALUE));
277
278 this.setComponentRolesEncrypted(currComponentRoles.getChild(COMPONENT_ISENCRYPTED_KEY).getValue("false"));
279
280
281
282 Configuration currComponentConfiguration = configuration.getChild(COMPONENT_CONFIG_KEY);
283
284 this.setComponentConfigurationLocation(
285 currComponentConfiguration.getChild(COMPONENT_LOCATION_KEY).getValue(COMPONENT_CONFIG_VALUE));
286
287 this.setComponentConfigurationEncrypted(
288 currComponentConfiguration.getChild(COMPONENT_ISENCRYPTED_KEY).getValue("false"));
289
290
291
292 this.componentConfigurationPropertiesResolverConfig = configuration.getChild(COMPONENT_CONFIG_PROPERTIES_KEY);
293
294
295
296 Configuration currParameters = configuration.getChild(COMPONENT_PARAMETERS_KEY);
297
298 this.setParametersLocation(
299 currParameters.getChild(COMPONENT_LOCATION_KEY).getValue(COMPONENT_PARAMETERS_VALUE));
300
301 this.setParametersEncrypted(currParameters.getChild(COMPONENT_ISENCRYPTED_KEY).getValue("false"));
302
303
304
305 Configuration currInterceptorList = configuration.getChild(INTERCEPTOR_LIST_KEY);
306
307 Configuration[] interceptorConfigList = currInterceptorList.getChildren(INTERCEPTOR_KEY);
308
309 for (int i = 0; i < interceptorConfigList.length; i++) {
310 String interceptorServiceName = interceptorConfigList[i].getValue(null);
311
312 if (!StringUtils.isEmpty(interceptorServiceName) && this.hasDynamicProxies()) {
313 this.defaultInterceptorServiceList.add(interceptorServiceName);
314
315 this.getLogger().debug("Using the following default interceptor service : " + interceptorServiceName);
316 }
317 }
318
319
320
321
322
323 Configuration currServiceManagerList = configuration.getChild(SERVICEMANAGER_LIST_KEY);
324
325 Configuration[] serviceManagerConfigList = currServiceManagerList.getChildren(SERVICEMANAGER_KEY);
326
327 for (int i = 0; i < serviceManagerConfigList.length; i++) {
328 String serviceManagerName = serviceManagerConfigList[i].getValue(null);
329
330 if (!StringUtils.isEmpty(serviceManagerName)) {
331 this.fallbackServiceManagerList.add(serviceManagerName);
332
333 this.getLogger().debug("Using the following fallback service manager : " + serviceManagerName);
334 }
335 }
336 }
337
338
339
340
341 public void parameterize(Parameters parameters) throws ParameterException {
342 this.parameters = parameters;
343 }
344
345
346
347
348 public void initialize() throws Exception {
349 this.getLogger().debug("YAAFI Service Framework is starting up");
350
351
352
353 this.setApplicationRootDir((File) this.getContext().get(AvalonYaafiConstants.URN_AVALON_HOME));
354
355 this.setTempRootDir((File) this.getContext().get(AvalonYaafiConstants.URN_AVALON_TEMP));
356
357
358
359 this.roleConfiguration = loadConfiguration(this.componentRolesLocation, this.isComponentRolesEncrypted());
360
361 if (this.roleConfiguration == null) {
362 String msg = "Unable to locate the role configuration : " + this.componentRolesLocation;
363 this.getLogger().error(msg);
364 throw new ConfigurationException(msg);
365 }
366
367 this.serviceConfiguration = loadConfiguration(this.componentConfigurationLocation,
368 this.isComponentConfigurationEncrypted());
369
370
371
372 Properties componentConfigurationProperties = this.loadComponentConfigurationProperties();
373
374
375
376 ConfigurationUtil.expand(this.getLogger(), (DefaultConfiguration) this.serviceConfiguration,
377 componentConfigurationProperties);
378
379
380
381 if (this.getParameters() == null) {
382 this.parameters = this.loadParameters(this.parametersLocation, this.isParametersEncrypted());
383 }
384
385
386
387 List<ServiceComponent> currServiceList = this.createServiceComponents(this.roleConfiguration, this.getLogger());
388
389 this.setServiceList(currServiceList);
390
391
392
393 for (int i = 0; i < this.getServiceList().size(); i++) {
394 ServiceComponent serviceComponent = (ServiceComponent) this.getServiceList().get(i);
395 this.getServiceMap().put(serviceComponent.getName(), serviceComponent);
396 }
397
398
399
400 for (int i = 0; i < this.fallbackServiceManagerList.size(); i++) {
401 String currServiceManagerName = (String) this.fallbackServiceManagerList.get(i);
402 if (this.getServiceMap().get(currServiceManagerName) == null) {
403 String msg = "The following fallback service manager was not found : " + currServiceManagerName;
404 throw new IllegalArgumentException(msg);
405 }
406 }
407
408
409
410 this.incarnateAll(this.getServiceList());
411
412
413
414 this.isCurrentlyDisposing = false;
415 this.isAlreadyDisposed = false;
416 this.getLogger().debug("YAAFI Avalon Service Container is up and running");
417 }
418
419
420
421
422
423
424 public void dispose() {
425 if (this.isCurrentlyDisposing() || this.isAlreadyDisposed()) {
426 return;
427 }
428
429 this.isCurrentlyDisposing = true;
430
431 if (this.getLogger() != null) {
432 this.getLogger().debug("Disposing all services");
433 }
434
435
436
437 waitForDisposal();
438
439 synchronized (this) {
440
441
442 this.decommissionAll(this.getServiceList());
443
444
445
446 this.disposeAll(this.getServiceList());
447
448
449
450 this.getServiceList().clear();
451 this.getServiceMap().clear();
452
453 this.componentRolesLocation = null;
454 this.componentConfigurationLocation = null;
455 this.context = null;
456 this.parametersLocation = null;
457 this.roleConfiguration = null;
458 this.serviceConfiguration = null;
459 this.parameters = null;
460 this.fallbackServiceManagerList = null;
461 this.defaultInterceptorServiceList = null;
462 this.isCurrentlyDisposing = false;
463 this.isAlreadyDisposed = true;
464
465 if (this.getLogger() != null) {
466 this.getLogger().debug("All services are disposed");
467 }
468 }
469 }
470
471
472
473
474
475
476
477
478 public synchronized void reconfigure(Configuration configuration) throws ConfigurationException {
479 Validate.notNull(configuration, "configuration");
480
481 int exceptionCounter = 0;
482 ServiceComponent serviceComponent;
483
484 this.getLogger().warn("Reconfiguring all services ...");
485
486
487
488 this.waitForReconfiguration();
489
490
491
492 this.serviceConfiguration = configuration;
493
494 Properties componentConfigurationProperties = this.loadComponentConfigurationProperties();
495
496 ConfigurationUtil.expand(this.getLogger(), (DefaultConfiguration) this.serviceConfiguration,
497 componentConfigurationProperties);
498
499
500
501 for (int i = 0; i < this.getServiceList().size(); i++) {
502 serviceComponent = (ServiceComponent) this.getServiceList().get(i);
503
504 Configuration serviceComponentConfiguration = this.serviceConfiguration
505 .getChild(serviceComponent.getShorthand());
506
507 try {
508 serviceComponent.setConfiguration(serviceComponentConfiguration);
509 serviceComponent.reconfigure();
510 } catch (Throwable t) {
511 String msg = "Reconfiguring of " + serviceComponent.getShorthand() + " failed";
512 this.getLogger().error(msg);
513 exceptionCounter++;
514 }
515 }
516
517
518
519 if (exceptionCounter > 0) {
520 String msg = "The reconfiguration failed with " + exceptionCounter + " exception(s)";
521 this.getLogger().error(msg);
522 throw new ConfigurationException(msg);
523 }
524 }
525
526
527
528
529
530
531
532
533 public synchronized RoleEntry getRoleEntry(String name) throws ServiceException {
534 return this.getServiceComponentEx(name).getRoleEntry();
535 }
536
537
538
539
540 public synchronized RoleEntry[] getRoleEntries() {
541 ServiceComponent serviceComponent;
542 List<ServiceComponent> serviceList = this.getServiceList();
543 RoleEntry[] result = new RoleEntry[serviceList.size()];
544
545 for (int i = 0; i < result.length; i++) {
546 serviceComponent = (ServiceComponent) serviceList.get(i);
547 result[i] = serviceComponent.getRoleEntry();
548 }
549
550 return result;
551 }
552
553
554
555
556 public synchronized void reconfigure(String[] names) throws ServiceException, ConfigurationException {
557 Validate.notNull(names, "names");
558 Validate.noNullElements(names, "names");
559
560 this.waitForReconfiguration();
561
562 for (int i = 0; i < names.length; i++) {
563
564
565
566 if (this.getServiceMap().get(names[i]) != null) {
567 this.reconfigure(names[i]);
568 }
569 }
570 }
571
572
573
574
575 public boolean hasService(String name) {
576 Validate.notEmpty(name, "name");
577
578 boolean result;
579
580 if (this.isCurrentlyDisposing() || this.isAlreadyDisposed()) {
581 return false;
582 }
583
584 synchronized (this) {
585
586 result = this.getLocalServiceComponent(name) != null;
587
588
589 if (!result)
590 result = this.hasFallbackService(name);
591 }
592
593
594 if (!result && this.hasParentServiceManager())
595 result = this.getParentServiceManager().hasService(name);
596
597 return result;
598 }
599
600
601
602
603
604
605
606
607
608
609
610 public Object lookup(String name) throws ServiceException {
611 Validate.notEmpty(name, "name");
612
613 Object result = null;
614 ServiceComponent serviceManagerComponent;
615
616 if (this.isAlreadyDisposed()) {
617 String msg = "The container is disposed an no services are available";
618 this.getLogger().error(msg);
619 throw new ServiceException(name, msg);
620 }
621
622 try {
623 synchronized (this) {
624
625 serviceManagerComponent = this.getLocalServiceComponent(name);
626
627 if (serviceManagerComponent != null) {
628 result = serviceManagerComponent.getInstance();
629
630 if (result != null && this.getLogger().isDebugEnabled()) {
631 String msg = "Located the service '" + name + "' in the local container";
632 this.getLogger().debug(msg);
633 }
634 }
635
636
637 if (result == null) {
638 result = this.getFallbackService(name);
639 }
640 }
641 } catch (ServiceException e) {
642 String msg = "Failed to lookup a service " + name;
643 this.getLogger().error(msg, e);
644 throw e;
645 } catch (Throwable t) {
646 String msg = "Failed to lookup a service " + name;
647 this.getLogger().error(msg, t);
648 throw new ServiceException(name, msg, t);
649 }
650
651
652 if (result == null && this.hasParentServiceManager()) {
653 result = this.getParentServiceManager().lookup(name);
654
655 if (result != null && this.getLogger().isDebugEnabled()) {
656 String msg = "Located the service '" + name + "' using the parent service manager";
657 this.getLogger().debug(msg);
658 }
659 }
660
661
662
663 if (result == null) {
664 String msg = "The following component does not exist : " + name;
665 this.getLogger().error(msg);
666 throw new ServiceException(AvalonYaafiConstants.AVALON_CONTAINER_YAAFI, name);
667 }
668
669 return result;
670 }
671
672
673
674
675 public void release(Object object) {
676
677
678 }
679
680
681
682
683 public synchronized void decommission(String name) throws ServiceException {
684 this.waitForReconfiguration();
685 ServiceComponent serviceComponent = this.getServiceComponentEx(name);
686 this.decommission(serviceComponent);
687 }
688
689
690
691
692 public Parameters getParameters() {
693 return this.parameters;
694 }
695
696
697
698
699
700
701
702
703 public String toString() {
704 ToStringBuilder toStringBuilder = new ToStringBuilder(this);
705 toStringBuilder.append("applicationRootDir", this.getApplicationRootDir());
706 toStringBuilder.append("tempRootDir", this.getTempRootDir());
707 toStringBuilder.append("componentRolesLocation", this.componentRolesLocation);
708 toStringBuilder.append("componentConfigurationLocation", this.componentConfigurationLocation);
709 toStringBuilder.append("parametersLocation", parametersLocation);
710 toStringBuilder.append("logger", this.getLogger().getClass().getName());
711 toStringBuilder.append("hasDynamicProxies", this.hasDynamicProxies);
712 toStringBuilder.append("containerFlavour", this.containerFlavour);
713 toStringBuilder.append("componentRolesFlavour", this.componentRolesFlavour);
714 toStringBuilder.append("isComponentRolesEncrypted", this.isComponentRolesEncrypted);
715 toStringBuilder.append("isComponentConfigurationEncrypted", this.isComponentConfigurationEncrypted);
716 toStringBuilder.append("isParametersEncrypted", this.isParametersEncrypted);
717
718 return toStringBuilder.toString();
719 }
720
721
722
723
724
725
726 private RoleConfigurationParser createRoleConfigurationParser() {
727 return new RoleConfigurationParserImpl(this.getComponentRolesFlavour());
728 }
729
730
731
732
733
734
735
736
737 private void reconfigure(String name) throws ServiceException, ConfigurationException {
738 Validate.notEmpty(name, "name");
739 ServiceComponent serviceComponent = this.getServiceComponentEx(name);
740
741
742
743 try {
744 serviceComponent.reconfigure();
745 } catch (ConfigurationException e) {
746 String msg = "Reconfiguring failed : " + serviceComponent.getShorthand();
747 this.getLogger().error(msg, e);
748 throw new ConfigurationException(msg, e);
749 } catch (Throwable t) {
750 String msg = "Reconfiguring failed : " + serviceComponent.getShorthand();
751 this.getLogger().error(msg, t);
752 throw new ConfigurationException(msg, t);
753 }
754 }
755
756
757
758
759
760
761
762
763 private ServiceComponent getServiceComponentEx(String name) throws ServiceException {
764 Validate.notEmpty(name, "name");
765 ServiceComponent result = (ServiceComponent) this.getServiceMap().get(name);
766
767 if (result == null) {
768 String msg = "The following component does not exist : " + name;
769 this.getLogger().error(msg);
770 throw new ServiceException(AvalonYaafiConstants.AVALON_CONTAINER_YAAFI, name);
771 }
772
773 return result;
774 }
775
776
777
778
779
780
781
782 private ServiceComponent getLocalServiceComponent(String name) {
783 Validate.notEmpty(name, "name");
784 ServiceComponent result = (ServiceComponent) this.getServiceMap().get(name);
785 return result;
786 }
787
788
789
790
791
792
793
794
795 private Object getFallbackService(String name) throws Exception {
796
797 Validate.notEmpty(name, "name");
798
799 Object result = null;
800 ServiceComponent serviceManagerComponent;
801
802 for (int i = 0; i < this.fallbackServiceManagerList.size(); i++) {
803 String serviceManagerComponentName = (String) fallbackServiceManagerList.get(i);
804 serviceManagerComponent = this.getLocalServiceComponent(serviceManagerComponentName);
805
806 if (serviceManagerComponent != null) {
807 ServiceManager currServiceManager = (ServiceManager) serviceManagerComponent.getInstance();
808
809 if (currServiceManager.hasService(name)) {
810 result = currServiceManager.lookup(name);
811
812 if (result != null && this.getLogger().isDebugEnabled()) {
813 String msg = "Located the service '" + name + "' using the fallback service manager '"
814 + serviceManagerComponentName + "'";
815 this.getLogger().debug(msg);
816 }
817 }
818 }
819 }
820
821 return result;
822 }
823
824
825
826
827
828
829
830 private boolean hasFallbackService(String name) {
831 Validate.notEmpty(name, "name");
832
833 ServiceComponent serviceManagerComponent;
834
835 for (int i = 0; i < this.fallbackServiceManagerList.size(); i++) {
836 String serviceManagerComponentName = (String) fallbackServiceManagerList.get(i);
837 serviceManagerComponent = this.getLocalServiceComponent(serviceManagerComponentName);
838
839 if (serviceManagerComponent != null) {
840 ServiceManager currServiceManager;
841
842 try {
843 currServiceManager = (ServiceManager) serviceManagerComponent.getInstance();
844 if (currServiceManager.hasService(name)) {
845 return true;
846 }
847 } catch (Exception e) {
848 String msg = "Unable to invoke fallback service manager '" + serviceManagerComponentName + "'";
849 this.getLogger().error(msg, e);
850 throw new RuntimeException(msg);
851 }
852 }
853 }
854
855 return false;
856 }
857
858
859
860
861 private void setComponentConfigurationLocation(String string) {
862 this.componentConfigurationLocation = string;
863 }
864
865
866
867
868 private void setComponentRolesLocation(String string) {
869 this.componentRolesLocation = string;
870 }
871
872
873
874
875 private void setParametersLocation(String string) {
876 this.parametersLocation = string;
877 }
878
879
880
881
882 private Logger getLogger() {
883 return this.logger;
884 }
885
886
887
888
889 private HashMap<String, ServiceComponent> getServiceMap() {
890 return this.serviceMap;
891 }
892
893
894
895
896
897
898
899 private void incarnateAll(List<ServiceComponent> serviceList) throws Exception {
900 ServiceComponent serviceComponent;
901
902
903
904 for (int i = 0; i < serviceList.size(); i++) {
905 serviceComponent = (ServiceComponent) this.getServiceList().get(i);
906 this.configure(serviceComponent);
907 }
908
909
910
911 for (int i = 0; i < serviceList.size(); i++) {
912 serviceComponent = (ServiceComponent) this.getServiceList().get(i);
913 this.incarnate(serviceComponent);
914 }
915
916 }
917
918
919
920
921
922
923
924
925 private void configure(ServiceComponent serviceComponent) throws Exception {
926 this.getLogger().debug("Configuring the service component " + serviceComponent.getShorthand());
927
928
929
930 YaafiToAvalonContextMapper mapper = new YaafiToAvalonContextMapper(serviceComponent.getName(),
931 this.getClassLoader());
932
933 RoleEntry roleEntry = serviceComponent.getRoleEntry();
934 String componentFlavour = roleEntry.getComponentFlavour();
935
936 DefaultContext serviceComponentContext = mapper.mapTo(this.getContext(), componentFlavour);
937
938
939
940 Logger serviceComponentLogger = this.getLogger().getChildLogger(roleEntry.getLogCategory());
941
942 Configuration serviceComponentConfiguration = this.serviceConfiguration.getChild(roleEntry.getShorthand());
943
944 Parameters serviceComponentParameters = this.getParameters();
945
946
947
948 serviceComponent.setLogger(serviceComponentLogger);
949 serviceComponent.setServiceManager(this);
950 serviceComponent.setContext(serviceComponentContext);
951 serviceComponent.setConfiguration(serviceComponentConfiguration);
952 serviceComponent.setParameters(serviceComponentParameters);
953
954
955
956 serviceComponent.loadImplemtationClass(this.getClassLoader());
957 }
958
959
960
961
962
963
964
965
966 private void incarnate(ServiceComponent serviceComponent) throws Exception {
967 this.getLogger().debug("Incarnating the service " + serviceComponent.getShorthand());
968
969 serviceComponent.incarnate();
970 }
971
972
973
974
975
976
977 private void decommissionAll(List<ServiceComponent> serviceList) {
978 for (int i = serviceList.size() - 1; i >= 0; i--) {
979 ServiceComponent serviceComponent = (ServiceComponent) serviceList.get(i);
980 this.decommission(serviceComponent);
981 }
982 }
983
984
985
986
987
988
989
990
991
992
993 private void decommission(ServiceComponent serviceComponent) {
994 this.getLogger().debug("Decommission the service " + serviceComponent.getShorthand());
995
996 try {
997 serviceComponent.decommision();
998 } catch (Throwable e) {
999 String msg = "Decommissioning the following service failed : " + serviceComponent.getName();
1000 this.getLogger().error(msg, e);
1001 }
1002 }
1003
1004
1005
1006
1007
1008
1009 private void disposeAll(List<ServiceComponent> serviceList) {
1010 for (int i = serviceList.size() - 1; i >= 0; i--) {
1011 ServiceComponent serviceComponent = (ServiceComponent) serviceList.get(i);
1012 this.dispose(serviceComponent);
1013 }
1014 }
1015
1016
1017
1018
1019
1020
1021 private void dispose(ServiceComponent serviceComponent) {
1022 this.getLogger().debug("Disposing the service " + serviceComponent.getShorthand());
1023
1024 try {
1025 serviceComponent.dispose();
1026 } catch (Throwable e) {
1027 String msg = "Disposing the following service failed : " + serviceComponent.getName();
1028 this.getLogger().error(msg, e);
1029 }
1030 }
1031
1032 private boolean isCurrentlyDisposing() {
1033 return isCurrentlyDisposing;
1034 }
1035
1036 private boolean isAlreadyDisposed() {
1037 return isAlreadyDisposed;
1038 }
1039
1040
1041
1042
1043 private List<ServiceComponent> getServiceList() {
1044 return this.serviceList;
1045 }
1046
1047
1048
1049
1050 private void setServiceList(List<ServiceComponent> list) {
1051 this.serviceList = list;
1052 }
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063 private List<ServiceComponent> createServiceComponents(Configuration roleConfiguration, Logger logger)
1064 throws ConfigurationException {
1065 Validate.notNull(roleConfiguration, "roleConfiguration");
1066 Validate.notNull(logger, "logger");
1067
1068 ArrayList<ServiceComponent> result = new ArrayList<ServiceComponent>();
1069 ServiceComponent serviceComponent = null;
1070
1071
1072
1073 RoleConfigurationParser roleConfigurationParser = this.createRoleConfigurationParser();
1074
1075
1076
1077 RoleEntry[] roleEntryList = roleConfigurationParser.parse(roleConfiguration);
1078
1079
1080
1081 ArrayList<String> defaultInterceptorList = this.getDefaultInterceptorServiceList();
1082
1083
1084
1085 for (int i = 0; i < roleEntryList.length; i++) {
1086 try {
1087
1088
1089 RoleEntry roleEntry = roleEntryList[i];
1090
1091 if (this.hasDynamicProxies()) {
1092 roleEntry.addInterceptors(defaultInterceptorList);
1093 } else {
1094 roleEntry.setHasDynamicProxy(false);
1095 }
1096
1097 serviceComponent = new AvalonServiceComponentImpl(roleEntry, this.getLogger(), logger);
1098
1099 result.add(serviceComponent);
1100 } catch (Throwable t) {
1101 String serviceComponentName = (serviceComponent != null ? serviceComponent.getName() : "unknown");
1102 String msg = "Failed to load the service " + serviceComponentName;
1103 this.getLogger().error(msg, t);
1104 throw new ConfigurationException(msg, t);
1105 }
1106 }
1107
1108 return result;
1109 }
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119 private Configuration loadConfiguration(String location, String isEncrypted) throws Exception {
1120 Configuration result = null;
1121 InputStreamLocator locator = this.createInputStreamLocator();
1122 InputStream is = locator.locate(location);
1123 DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
1124
1125 if (is != null) {
1126 try {
1127 is = this.getDecryptingInputStream(is, isEncrypted);
1128 result = builder.build(is);
1129 } catch (Exception e) {
1130 String msg = "Unable to parse the following file : " + location;
1131 this.getLogger().error(msg, e);
1132 throw e;
1133 } finally {
1134 safeClose(is);
1135 }
1136 }
1137
1138 return result;
1139 }
1140
1141
1142
1143
1144
1145
1146
1147
1148 private Properties loadComponentConfigurationProperties() throws ConfigurationException {
1149 Properties result;
1150 ComponentConfigurationPropertiesResolver resolver;
1151
1152 String className = this.componentConfigurationPropertiesResolverConfig.getChild("resolver")
1153 .getValue(ComponentConfigurationPropertiesResolverImpl.class.getName());
1154
1155 try {
1156 Class<?> resolverClass = this.getClassLoader().loadClass(className);
1157 resolver = (ComponentConfigurationPropertiesResolver) resolverClass.newInstance();
1158 ContainerUtil.enableLogging(resolver, this.getLogger());
1159 ContainerUtil.contextualize(resolver, this.getContext());
1160 ContainerUtil.configure(resolver, this.componentConfigurationPropertiesResolverConfig);
1161
1162 result = resolver.resolve(null);
1163
1164 this.getLogger().debug("Using the following componentConfigurationProperties: " + result);
1165 } catch (Exception e) {
1166 String msg = "Resolving componentConfigurationProperties failed using the following class : " + className;
1167 this.getLogger().error(msg, e);
1168 throw new ConfigurationException(msg, e);
1169 }
1170
1171 return result;
1172 }
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182 private Parameters loadParameters(String location, String isEncrypted) throws Exception {
1183 InputStreamLocator locator = this.createInputStreamLocator();
1184 InputStream is = locator.locate(location);
1185 Parameters result = new Parameters();
1186
1187 if (is != null) {
1188 try {
1189 is = this.getDecryptingInputStream(is, isEncrypted);
1190 Properties props = new Properties();
1191 props.load(is);
1192 result = Parameters.fromProperties(props);
1193 } finally {
1194 safeClose(is);
1195 }
1196 }
1197
1198 return result;
1199 }
1200
1201
1202
1203
1204
1205
1206
1207 private InputStreamLocator createInputStreamLocator() {
1208 return new InputStreamLocator(this.getApplicationRootDir(), this.getLogger());
1209 }
1210
1211
1212
1213
1214
1215
1216 private void setApplicationRootDir(File dir) {
1217 this.getLogger().debug("Setting applicationRootDir to " + dir.getAbsolutePath());
1218
1219 Validate.notNull(dir, "applicationRootDir is <null>");
1220 Validate.isTrue(dir.exists(), "applicationRootDir does not exist");
1221
1222 this.applicationRootDir = dir;
1223 }
1224
1225
1226
1227
1228 private File getApplicationRootDir() {
1229 return this.applicationRootDir;
1230 }
1231
1232
1233
1234
1235 private ServiceManager getParentServiceManager() {
1236 return this.parentServiceManager;
1237 }
1238
1239
1240
1241
1242 private boolean hasParentServiceManager() {
1243 return this.getParentServiceManager() != null;
1244 }
1245
1246
1247
1248
1249
1250
1251 private void setTempRootDir(File dir) {
1252 this.getLogger().debug("Setting tempRootDir to " + dir.getAbsolutePath());
1253
1254 Validate.notNull(dir, "tempRootDir is <null>");
1255 Validate.isTrue(dir.exists(), "tempRootDir does not exist");
1256 Validate.isTrue(dir.canWrite(), "tempRootDir is not writeable");
1257
1258 this.tempRootDir = dir;
1259 }
1260
1261
1262
1263
1264 private File getTempRootDir() {
1265 return tempRootDir;
1266 }
1267
1268
1269
1270
1271 private String isComponentConfigurationEncrypted() {
1272 return isComponentConfigurationEncrypted;
1273 }
1274
1275
1276
1277
1278
1279
1280 private void setComponentConfigurationEncrypted(String isComponentConfigurationEncrypted) {
1281 this.isComponentConfigurationEncrypted = isComponentConfigurationEncrypted;
1282 }
1283
1284
1285
1286
1287 private String isComponentRolesEncrypted() {
1288 return isComponentRolesEncrypted;
1289 }
1290
1291
1292
1293
1294 private void setComponentRolesEncrypted(String isComponentRolesEncrypted) {
1295 this.isComponentRolesEncrypted = isComponentRolesEncrypted;
1296 }
1297
1298
1299
1300
1301 private String isParametersEncrypted() {
1302 return isParametersEncrypted;
1303 }
1304
1305
1306
1307
1308 private void setParametersEncrypted(String isParametersEncrypted) {
1309 this.isParametersEncrypted = isParametersEncrypted;
1310 }
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320 private InputStream getDecryptingInputStream(InputStream is, String isEncrypted) throws Exception {
1321 return CryptoStreamFactory.getDecryptingInputStream(is, isEncrypted);
1322 }
1323
1324
1325
1326
1327 private String getContainerFlavour() {
1328 return containerFlavour;
1329 }
1330
1331
1332
1333
1334 private void setContainerFlavour(String containerFlavour) {
1335 this.containerFlavour = containerFlavour;
1336 }
1337
1338
1339
1340
1341 private String getComponentRolesFlavour() {
1342 return componentRolesFlavour;
1343 }
1344
1345
1346
1347
1348 private void setComponentRolesFlavour(String componentRolesFlavour) {
1349 this.componentRolesFlavour = componentRolesFlavour;
1350 }
1351
1352
1353
1354
1355 private Context getContext() {
1356 return context;
1357 }
1358
1359
1360
1361
1362 private boolean hasDynamicProxies() {
1363 return this.hasDynamicProxies;
1364 }
1365
1366
1367
1368
1369 private ArrayList<String> getDefaultInterceptorServiceList() {
1370 return defaultInterceptorServiceList;
1371 }
1372
1373
1374
1375
1376 private ClassLoader getClassLoader() {
1377 return this.getClass().getClassLoader();
1378 }
1379
1380
1381
1382
1383
1384 private void waitForReconfiguration() {
1385 try {
1386 Thread.sleep(this.reconfigurationDelay);
1387 } catch (InterruptedException e) {
1388
1389 }
1390 }
1391
1392
1393
1394
1395
1396 private void waitForDisposal() {
1397 try {
1398 Thread.sleep(this.disposalDelay);
1399 } catch (InterruptedException e) {
1400
1401 }
1402 }
1403
1404 private void safeClose(InputStream is) {
1405 if (is != null) {
1406 try {
1407 is.close();
1408 } catch (Exception e) {
1409 getLogger().error("Failed to close an input stream", e);
1410 }
1411 }
1412 }
1413 }