View Javadoc

1   /*
2    * #%L
3    * Bitrepository Protocol
4    * *
5    * $Id$
6    * $HeadURL$
7    * %%
8    * Copyright (C) 2010 - 2011 The State and University Library, The Royal Library and The State Archives, Denmark
9    * %%
10   * This program is free software: you can redistribute it and/or modify
11   * it under the terms of the GNU Lesser General Public License as 
12   * published by the Free Software Foundation, either version 2.1 of the 
13   * License, or (at your option) any later version.
14   * 
15   * This program is distributed in the hope that it will be useful,
16   * but WITHOUT ANY WARRANTY; without even the implied warranty of
17   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18   * GNU General Lesser Public License for more details.
19   * 
20   * You should have received a copy of the GNU General Lesser Public 
21   * License along with this program.  If not, see
22   * <http://www.gnu.org/licenses/lgpl-2.1.html>.
23   * #L%
24   */
25  package org.bitrepository.integrityservice;
26  
27  import org.bitrepository.access.AccessComponentFactory;
28  import org.bitrepository.common.settings.Settings;
29  import org.bitrepository.common.settings.XMLFileSettingsLoader;
30  import org.bitrepository.common.utils.SettingsUtils;
31  import org.bitrepository.integrityservice.alerter.IntegrityAlarmDispatcher;
32  import org.bitrepository.integrityservice.alerter.IntegrityAlerter;
33  import org.bitrepository.integrityservice.cache.IntegrityCache;
34  import org.bitrepository.integrityservice.cache.IntegrityDatabase;
35  import org.bitrepository.integrityservice.cache.IntegrityModel;
36  import org.bitrepository.integrityservice.collector.DelegatingIntegrityInformationCollector;
37  import org.bitrepository.integrityservice.collector.IntegrityInformationCollector;
38  import org.bitrepository.integrityservice.workflow.IntegrityWorkflowContext;
39  import org.bitrepository.integrityservice.workflow.IntegrityWorkflowManager;
40  import org.bitrepository.protocol.ProtocolComponentFactory;
41  import org.bitrepository.protocol.messagebus.MessageBus;
42  import org.bitrepository.protocol.security.BasicMessageAuthenticator;
43  import org.bitrepository.protocol.security.BasicMessageSigner;
44  import org.bitrepository.protocol.security.BasicOperationAuthorizor;
45  import org.bitrepository.protocol.security.BasicSecurityManager;
46  import org.bitrepository.protocol.security.MessageAuthenticator;
47  import org.bitrepository.protocol.security.MessageSigner;
48  import org.bitrepository.protocol.security.OperationAuthorizor;
49  import org.bitrepository.protocol.security.PermissionStore;
50  import org.bitrepository.service.LifeCycledService;
51  import org.bitrepository.service.ServiceSettingsProvider;
52  import org.bitrepository.service.audit.AuditDatabaseManager;
53  import org.bitrepository.service.audit.AuditTrailContributerDAO;
54  import org.bitrepository.service.audit.AuditTrailManager;
55  import org.bitrepository.service.contributor.ContributorMediator;
56  import org.bitrepository.service.contributor.SimpleContributorMediator;
57  import org.bitrepository.service.database.DatabaseManager;
58  import org.bitrepository.service.scheduler.TimerbasedScheduler;
59  import org.bitrepository.service.workflow.WorkflowManager;
60  import org.bitrepository.settings.referencesettings.AlarmLevel;
61  import org.bitrepository.settings.referencesettings.ServiceType;
62  import org.slf4j.Logger;
63  import org.slf4j.LoggerFactory;
64  
65  import java.io.BufferedReader;
66  import java.io.File;
67  import java.io.FileReader;
68  import java.io.IOException;
69  import java.util.Properties;
70  
71  /**
72   * Provides access to the different component in the integrity module.
73   */
74  public final class IntegrityServiceManager {
75      private static final Logger log = LoggerFactory.getLogger(IntegrityServiceManager.class);
76      private static String privateKeyFile;
77      private static File integrityReportStorageDir;
78  
79      /** The properties file holding implementation specifics for the integrity service. */
80      private static final String CONFIGFILE = "integrity.properties";
81      /** Property key to tell where to locate the path and filename to the private key file. */
82      private static final String PRIVATE_KEY_FILE = "org.bitrepository.integrity-service.privateKeyFile";
83      private static Settings settings;
84      private static BasicSecurityManager securityManager;
85      private static IntegrityWorkflowManager workFlowManager;
86      private static String confDir;
87      private static IntegrityLifeCycleHandler lifeCycleHandler;
88      private static IntegrityModel model;
89      private static ContributorMediator contributor;
90      private static MessageBus messageBus;
91      private static IntegrityInformationCollector collector;
92      private static AuditTrailManager auditManager;
93      private static IntegrityAlerter alarmDispatcher;
94  
95      /**
96       * Returns the single instance of the intergity service.
97       * @return A new integrity service instance.
98       */
99      public static LifeCycledService getIntegrityLifeCycleHandler() {
100         if (lifeCycleHandler == null) {
101             lifeCycleHandler = new IntegrityLifeCycleHandler();
102         }
103         return lifeCycleHandler;
104     }
105 
106     /**
107      * Initializes the integrity service
108      * Should only be run at initialization time.
109      */
110     public static synchronized void initialize(String configurationDir) {
111         confDir = configurationDir;
112         loadSettings();
113         createSecurityManager();
114         messageBus = ProtocolComponentFactory.getInstance().getMessageBus(settings, securityManager);
115         DatabaseManager auditDatabaseManager = new AuditDatabaseManager(
116                 settings.getReferenceSettings().getIntegrityServiceSettings().getAuditTrailContributerDatabase());
117         auditManager = new AuditTrailContributerDAO(settings, auditDatabaseManager);
118 
119         alarmDispatcher = new IntegrityAlarmDispatcher(settings, messageBus, AlarmLevel.ERROR);
120         model = new IntegrityCache(new IntegrityDatabase(settings));
121 
122         collector = new DelegatingIntegrityInformationCollector(
123                 AccessComponentFactory.getInstance().createGetFileIDsClient(settings, securityManager,
124                         settings.getReferenceSettings().getIntegrityServiceSettings().getID()),
125                 AccessComponentFactory.getInstance().createGetChecksumsClient(settings, securityManager,
126                         settings.getReferenceSettings().getIntegrityServiceSettings().getID()));
127 
128         workFlowManager = new IntegrityWorkflowManager(
129                 new IntegrityWorkflowContext(settings, collector, model, alarmDispatcher, auditManager),
130                 new TimerbasedScheduler());
131         contributor = new SimpleContributorMediator(messageBus, settings, auditManager);
132         contributor.start();
133     }
134 
135     /**
136      * Retrieves the shared settings based on the directory specified in the {@link #initialize(String)} method.
137      * @return The settings to used for the integrity service.
138      */
139     private static void loadSettings() {
140         if(confDir == null) {
141             throw new IllegalStateException("No configuration directory has been set!");
142         }
143         loadProperties();
144         ServiceSettingsProvider settingsLoader =
145                 new ServiceSettingsProvider(new XMLFileSettingsLoader(confDir), ServiceType.INTEGRITY_SERVICE);
146         settings = settingsLoader.getSettings();
147         SettingsUtils.initialize(settings);
148         integrityReportStorageDir = new File(
149                 settings.getReferenceSettings().getIntegrityServiceSettings().getIntegrityReportsDir());
150         if(!(integrityReportStorageDir.isDirectory() 
151                 && integrityReportStorageDir.canRead() 
152                 && integrityReportStorageDir.canWrite())) {
153             throw new IllegalStateException(integrityReportStorageDir.getAbsolutePath() 
154                     + " is either not a directory, can't be read or written to.");
155         }        
156     }
157 
158     /**
159      * Loads the properties.
160      */
161     private static void loadProperties() {
162         try {
163             Properties properties = new Properties();
164             String propertiesFile = confDir + "/" + CONFIGFILE;
165             BufferedReader propertiesReader = null;
166             try {
167                 propertiesReader = new BufferedReader(new FileReader(propertiesFile));
168                 properties.load(propertiesReader);
169                 privateKeyFile = properties.getProperty(PRIVATE_KEY_FILE);
170             } finally {
171                 if(propertiesReader != null) {
172                     propertiesReader.close();
173                 }
174             }
175         } catch (IOException e) {
176             throw new IllegalStateException("Could not instantiate the properties.", e);
177         }
178     }
179 
180     /**
181      * Instantiated the security manager for the integrity service.
182      * @see {@link BasicSecurityManager}
183      */
184     private static void createSecurityManager() {
185             PermissionStore permissionStore = new PermissionStore();
186             MessageAuthenticator authenticator = new BasicMessageAuthenticator(permissionStore);
187             MessageSigner signer = new BasicMessageSigner();
188             OperationAuthorizor authorizer = new BasicOperationAuthorizor(permissionStore);
189             securityManager = new BasicSecurityManager(settings.getRepositorySettings(), privateKeyFile,
190                     authenticator, signer, authorizer, permissionStore,
191                     settings.getReferenceSettings().getIntegrityServiceSettings().getID());
192     }
193 
194     /**
195      * Gets you the <code>IntegrityModel</code> that contains the data needed to perform integrity operations.
196      * @return the <code>IntegrityModel</code> that contains integrity information.
197      */
198     public static IntegrityModel getIntegrityModel() {
199         return model;
200     }
201     
202     /**
203      *  Gets the directory for integrity report storage. 
204      */
205     public static File getIntegrityReportStorageDir() {
206         return integrityReportStorageDir;
207     }
208 
209     /**
210      * Gets you the <code>WorkflowManager</code> exposing the workflow model.
211      */
212     public static WorkflowManager getWorkflowManager() {
213         return workFlowManager;
214     }
215 
216     public static class IntegrityLifeCycleHandler implements LifeCycledService {
217         @Override
218         public void start() {}
219 
220         @Override
221         public void shutdown() {
222             if(messageBus != null) {
223                 try {
224                     messageBus.close();
225                 } catch (Exception e) {
226                     log.warn("Encountered issues when closing down the messagebus.", e);
227                 }
228             }
229             if(contributor != null) {
230                 contributor.close();
231             }
232 
233             if(model != null) {
234                 model.close();
235             }
236         }
237     }
238 }