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