]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
2d0ab8e85f9ce704f1ab48a976155cfa9332e9ca
[tmp/jakarta-migration.git] /
1 package org.collectionspace.services.jaxrs;
2
3 import javax.servlet.ServletContextEvent;
4 import javax.ws.rs.core.Response;
5
6 import org.jboss.resteasy.core.Dispatcher;
7 import org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap;
8
9 import org.collectionspace.authentication.CSpaceTenant;
10 import org.collectionspace.services.account.Tenant;
11 import org.collectionspace.services.account.TenantResource;
12 import org.collectionspace.services.authorization.AuthZ;
13 import org.collectionspace.services.client.AuthorityClient;
14
15 import org.collectionspace.services.common.CSWebApplicationException;
16 import org.collectionspace.services.common.ResourceMap;
17 import org.collectionspace.services.common.ServiceMain;
18 import org.collectionspace.services.common.api.RefName;
19 import org.collectionspace.services.common.config.ConfigUtils;
20 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
21 import org.collectionspace.services.common.vocabulary.AuthorityResource;
22
23 import org.collectionspace.services.config.service.AuthorityInstanceType;
24 import org.collectionspace.services.config.service.ServiceBindingType;
25 import org.collectionspace.services.config.service.ServiceBindingType.AuthorityInstanceList;
26 import org.collectionspace.services.config.service.Term;
27 import org.collectionspace.services.config.service.TermList;
28 import org.collectionspace.services.config.tenant.TenantBindingType;
29 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
30
31 import org.nuxeo.elasticsearch.ElasticSearchComponent;
32 import org.nuxeo.elasticsearch.api.ElasticSearchService;
33 import org.nuxeo.runtime.api.Framework;
34
35 import java.lang.reflect.Constructor;
36 import java.util.Date;
37 import java.util.Hashtable;
38 import java.util.List;
39 import java.util.logging.Level;
40
41 public class CSpaceResteasyBootstrap extends ResteasyBootstrap {
42
43         java.util.logging.Logger logger = java.util.logging.Logger.getAnonymousLogger();
44         static final String RESET_AUTHORITIES_PROPERTY = "org.collectionspace.services.authorities.reset";
45         private static final String RESET_ELASTICSEARCH_INDEX_PROPERTY = "org.collectionspace.services.elasticsearch.reset";
46         private static final String QUICK_BOOT_PROPERTY = "org.collectionspace.services.quickboot";
47
48         @Override
49         public void  contextInitialized(ServletContextEvent event) {
50                 try {
51                         //
52                 // This call to super instantiates and initializes our JAX-RS application class.
53                 // The application class is org.collectionspace.services.jaxrs.CollectionSpaceJaxRsApplication.
54                 //
55                         logger.log(Level.INFO, String.format("%tc [INFO] Starting up the CollectionSpace Services' JAX-RS application.", new Date()));
56                         super.contextInitialized(event);
57                         CollectionSpaceJaxRsApplication app = (CollectionSpaceJaxRsApplication)deployment.getApplication();
58                         Dispatcher disp = deployment.getDispatcher();
59                         disp.getDefaultContextObjects().put(ResourceMap.class, app.getResourceMap());
60
61                         String quickBoot = System.getProperty(QUICK_BOOT_PROPERTY, Boolean.FALSE.toString()); // Property can be set in the tomcat/bin/setenv.sh (or setenv.bat) file
62                         if (Boolean.valueOf(quickBoot) == false) {
63                                 String resetAuthsString = System.getProperty(RESET_AUTHORITIES_PROPERTY, Boolean.FALSE.toString()); // Property can be set in the tomcat/bin/setenv.sh (or setenv.bat) file
64                                 initializeAuthorities(app.getResourceMap(), Boolean.valueOf(resetAuthsString));
65
66                                 String resetElasticsearchIndexString = System.getProperty(RESET_ELASTICSEARCH_INDEX_PROPERTY, Boolean.FALSE.toString()); // Property can be set in the tomcat/bin/setenv.sh (or setenv.bat) file
67
68                                 if (Boolean.valueOf(resetElasticsearchIndexString) == true) {
69                                         resetElasticSearchIndex();
70                                 }
71                         }
72
73                         logger.log(Level.INFO, String.format("%tc [INFO] CollectionSpace Services' JAX-RS application started.", new Date()));
74                 } catch (Exception e) {
75                         e.printStackTrace();
76                         throw new RuntimeException(e);
77                 }
78         }
79
80
81         @Override
82         public void contextDestroyed(ServletContextEvent event) {
83                 logger.log(Level.INFO, "[INFO] Shutting down the CollectionSpace Services' JAX-RS application.");
84                 //Do something if needed.
85                 logger.log(Level.INFO, "[INFO] CollectionSpace Services' JAX-RS application stopped.");
86         }
87
88         public void resetElasticSearchIndex() throws Exception {
89                 ElasticSearchComponent es = (ElasticSearchComponent) Framework.getService(ElasticSearchService.class);
90
91                 for (String repositoryName : es.getRepositoryNames()) {
92                         logger.log(Level.INFO, String.format("%tc [INFO] Rebuilding Elasticsearch index for repository %s", new Date(), repositoryName));
93
94                         es.dropAndInitRepositoryIndex(repositoryName);
95                 }
96
97                 TenantBindingConfigReaderImpl tenantBindingConfigReader = ServiceMain.getInstance().getTenantBindingConfigReader();
98                 Hashtable<String, TenantBindingType> tenantBindingsTable = tenantBindingConfigReader.getTenantBindings(false);
99
100                 for (TenantBindingType tenantBinding : tenantBindingsTable.values()) {
101                         CSpaceTenant tenant = new CSpaceTenant(tenantBinding.getId(), tenantBinding.getName());
102
103                         AuthZ.get().login(tenant);
104
105                         for (ServiceBindingType serviceBinding : tenantBinding.getServiceBindings()) {
106                                 Boolean isElasticsearchIndexed = serviceBinding.isElasticsearchIndexed();
107                                 String servicesRepoDomainName = serviceBinding.getRepositoryDomain();
108
109                                 if (isElasticsearchIndexed && servicesRepoDomainName != null && servicesRepoDomainName.trim().isEmpty() == false) {
110                                         String repositoryName = ConfigUtils.getRepositoryName(tenantBinding, servicesRepoDomainName);
111                                         String docType = serviceBinding.getObject().getName();
112                                         String tenantQualifiedDocType = NuxeoUtils.getTenantQualifiedDocType(tenantBinding.getId(), docType);
113
114                                         logger.log(Level.INFO, String.format("%tc [INFO] Starting Elasticsearch reindexing for docType %s in repository %s", new Date(), tenantQualifiedDocType, repositoryName));
115
116                                         es.runReindexingWorker(repositoryName, String.format("SELECT ecm:uuid FROM %s", tenantQualifiedDocType));
117                                 }
118                         }
119                 }
120         }
121
122     /**
123      * Initialize all authorities and vocabularies defined in the service bindings.
124      * @param resourceMap
125      * @throws Exception
126      */
127     public void initializeAuthorities(ResourceMap resourceMap, boolean reset) throws Exception {
128         TenantBindingConfigReaderImpl tenantBindingConfigReader = ServiceMain.getInstance().getTenantBindingConfigReader();
129         Hashtable<String, TenantBindingType> tenantBindingsTable = tenantBindingConfigReader.getTenantBindings(false);
130         for (TenantBindingType tenantBindings : tenantBindingsTable.values()) {
131                         CSpaceTenant tenant = new CSpaceTenant(tenantBindings.getId(), tenantBindings.getName());
132                         if (shouldInitializeAuthorities(tenant, reset) == true) {
133                                 logger.log(Level.INFO, String.format("Initializing vocabularies and authorities of tenant '%s'.",
134                                                 tenant.getId()));
135                         for (ServiceBindingType serviceBinding : tenantBindings.getServiceBindings()) {
136                                 AuthorityInstanceList element = serviceBinding.getAuthorityInstanceList();
137                                 if (element != null && element.getAuthorityInstance() != null) {
138                                         List<AuthorityInstanceType> authorityInstanceList = element.getAuthorityInstance();
139                                         for (AuthorityInstanceType authorityInstance : authorityInstanceList) {
140                                                 try {
141                                                         initializeAuthorityInstance(resourceMap, authorityInstance, serviceBinding, tenant, reset);
142                                                 } catch (Exception e) {
143                                                         logger.log(Level.SEVERE, "Could not initialize authorities and authority terms: " + e.getMessage());
144                                                         throw e;
145                                                 }
146                                         }
147                                 }
148                         }
149                         //
150                         // If we made it this far, we've either created the tenant's authorities and terms or we've reset them.  Either way,
151                         // we should mark the isAuthoritiesInitialized field of the tenant to 'true'.
152                         //
153                         setAuthoritiesInitialized(tenant, true);
154                         }
155         }
156         }
157
158     @SuppressWarnings("rawtypes")
159         private AuthorityClient getAuthorityClient(String classname) throws Exception {
160         Class clazz = Class.forName(classname.trim());
161         Constructor co = clazz.getConstructor(null);
162         Object classInstance = co.newInstance(null);
163         return (AuthorityClient) classInstance;
164     }
165
166     private boolean shouldInitializeAuthorities(CSpaceTenant cspaceTenant, boolean reset) {
167                 AuthZ.get().login(); // login as super admin
168                 TenantResource tenantResource = new TenantResource();
169                 Tenant tenantState = tenantResource.getTenant(cspaceTenant.getId());
170
171                 //
172                 // If the tenant's authorities have been initialized and
173                 // we're not being asked to reset them, we'll return 'false'
174                 // making any changes
175                 //
176                 return tenantState.isAuthoritiesInitialized() == false || reset == true;
177     }
178
179     private void setAuthoritiesInitialized(CSpaceTenant cspaceTenant, boolean initState) {
180                 AuthZ.get().login(); // login as super admin
181                 TenantResource tenantResource = new TenantResource();
182                 Tenant tenantState = tenantResource.getTenant(cspaceTenant.getId());
183
184                 tenantState.setAuthoritiesInitialized(initState);
185                 tenantResource.updateTenant(cspaceTenant.getId(), tenantState);
186         }
187
188
189     /*
190      * Check to see if an an authority instance and its corresponding terms exist.  If not, try to create them.
191      */
192     private void initializeAuthorityInstance(ResourceMap resourceMap,
193                 AuthorityInstanceType authorityInstance,
194                 ServiceBindingType serviceBinding,
195                 CSpaceTenant cspaceTenant,
196                 boolean reset) throws Exception {
197         int status = -1;
198         Response response = null;
199                 String serviceName = serviceBinding.getName();
200
201                 AuthZ.get().login(cspaceTenant);
202                 String clientClassName = serviceBinding.getClientHandler();
203                 AuthorityClient client = getAuthorityClient(clientClassName);
204                 String authoritySpecifier = RefName.shortIdToPath(authorityInstance.getTitleRef());  // e.g., urn:cspace:name(ulan)
205
206                 //
207                 // Test to see if the authority instance exists already.
208                 //
209                 AuthorityResource authorityResource = (AuthorityResource) resourceMap.get(serviceName.toLowerCase());
210                 try {
211                         response = authorityResource.get(null, null, authoritySpecifier);
212                 } catch (CSWebApplicationException e) {
213                         response = e.getResponse();  // If the authority doesn't exist, we expect a 404 error
214                 }
215
216                 //
217                 // If it doesn't exist (status is not 200), then try to create the authority instance
218                 //
219                 status = response.getStatus();
220                 if (status != Response.Status.OK.getStatusCode()) {
221                         String xmlPayload = client.createAuthorityInstance(authorityInstance.getTitleRef(), authorityInstance.getTitle());
222                         response = authorityResource.createAuthority(xmlPayload);
223                         status = response.getStatus();
224                         if (status != Response.Status.CREATED.getStatusCode()) {
225                                 throw new CSWebApplicationException(response);
226                         }
227                 }
228
229                 if (status == Response.Status.OK.getStatusCode()) {
230                         logger.log(Level.FINE, String.format("Authority of type '%s' with the short ID of '%s' existed already.",
231                                         serviceName, authorityInstance.getTitleRef()));
232                 } else if (status == Response.Status.CREATED.getStatusCode()) {
233                         logger.log(Level.FINE, String.format("Created a new authority of type '%s' with the short ID of '%s'.",
234                                         serviceName, authorityInstance.getTitleRef()));
235                 } else {
236                         logger.log(Level.WARNING, String.format("Unknown status '%d' encountered when creating or fetching authority of type '%s' with the short ID of '%s'.",
237                                         serviceName, authorityInstance.getTitleRef()));
238                 }
239
240                 //
241                 // Next, try to create or verify the authority terms.
242                 //
243                 initializeAuthorityInstanceTerms(authorityResource, client, authoritySpecifier, resourceMap, authorityInstance, serviceName, cspaceTenant);
244         }
245
246     private void initializeAuthorityInstanceTerms(
247                 AuthorityResource authorityResource,
248                 AuthorityClient client,
249                 String authoritySpecifier,
250                 ResourceMap resourceMap,
251                 AuthorityInstanceType authorityInstance,
252                 String serviceName,
253                 CSpaceTenant tenant) throws Exception {
254
255         int status = -1;
256         Response response = null;
257
258         TermList termListElement = authorityInstance.getTermList();
259         if (termListElement == null) {
260                 return;
261         }
262
263         for (Term term : termListElement.getTerm()) {
264                 //
265                 // Check to see if the term already exists
266                 //
267                 try {
268                         String termSpecifier = RefName.shortIdToPath(term.getId());
269                         authorityResource.getAuthorityItem(null, null, resourceMap, authoritySpecifier, termSpecifier);
270                         status = Response.Status.OK.getStatusCode();
271                 } catch (CSWebApplicationException e) {
272                         response = e.getResponse();  // If the authority doesn't exist, we expect a 404 error
273                         status = response.getStatus();
274                 }
275
276                 //
277                 // If the term doesn't exist, create it.
278                 //
279                 if (status != Response.Status.OK.getStatusCode()) {
280                         String termShortId = term.getId();
281                         String termDisplayName = term.getContent().trim();
282                         String xmlPayload = client.createAuthorityItemInstance(termShortId, termDisplayName);
283                         try {
284                                 authorityResource.createAuthorityItem(resourceMap, null, authoritySpecifier, xmlPayload);
285                                 logger.log(Level.FINE, String.format("Tenant:%s:Created a new term '%s:%s' in the authority of type '%s' with the short ID of '%s'.",
286                                                 tenant.getName(), termDisplayName, termShortId, serviceName, authorityInstance.getTitleRef()));
287                         } catch (CSWebApplicationException e) {
288                                 response = e.getResponse();
289                                 status = response.getStatus();
290                                 if (status != Response.Status.CREATED.getStatusCode()) {
291                                         throw new CSWebApplicationException(response);
292                                 }
293                         }
294                 }
295         }
296     }
297 }