]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
adf2ccfc4ecc502bff18bcf867d3ea0309429c02
[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.PathSegment;
7 import javax.ws.rs.core.Response;
8 import javax.ws.rs.core.UriInfo;
9
10 import org.jboss.resteasy.core.Dispatcher;
11 import org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap;
12 import org.jboss.resteasy.specimpl.PathSegmentImpl;
13 import org.apache.commons.io.IOUtils;
14 import org.collectionspace.authentication.AuthN;
15 import org.collectionspace.authentication.CSpaceTenant;
16 import org.collectionspace.services.account.Tenant;
17 import org.collectionspace.services.account.TenantResource;
18 import org.collectionspace.services.authorization.AuthZ;
19 import org.collectionspace.services.batch.BatchResource;
20 import org.collectionspace.services.client.AbstractCommonListUtils;
21 import org.collectionspace.services.client.AuthorityClient;
22 import org.collectionspace.services.client.BatchClient;
23 import org.collectionspace.services.client.CollectionSpaceClient;
24 import org.collectionspace.services.client.PayloadOutputPart;
25 import org.collectionspace.services.client.PoxPayloadOut;
26 import org.collectionspace.services.client.ReportClient;
27 import org.collectionspace.services.client.workflow.WorkflowClient;
28 import org.collectionspace.services.common.CSWebApplicationException;
29 import org.collectionspace.services.common.ResourceMap;
30 import org.collectionspace.services.common.ServiceMain;
31 import org.collectionspace.services.common.api.RefName;
32 import org.collectionspace.services.common.config.ConfigUtils;
33 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
34 import org.collectionspace.services.common.query.UriInfoImpl;
35 import org.collectionspace.services.common.vocabulary.AuthorityResource;
36
37 import org.collectionspace.services.config.service.AuthorityInstanceType;
38 import org.collectionspace.services.config.service.ServiceBindingType;
39 import org.collectionspace.services.config.service.ServiceBindingType.AuthorityInstanceList;
40 import org.collectionspace.services.config.service.Term;
41 import org.collectionspace.services.config.service.TermList;
42 import org.collectionspace.services.config.tenant.TenantBindingType;
43 import org.collectionspace.services.config.types.PropertyItemType;
44 import org.collectionspace.services.config.types.PropertyType;
45 import org.collectionspace.services.jaxb.AbstractCommonList;
46 import org.collectionspace.services.jaxb.AbstractCommonList.ListItem;
47 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
48 import org.collectionspace.services.report.ReportResource;
49 import org.nuxeo.elasticsearch.ElasticSearchComponent;
50 import org.nuxeo.elasticsearch.api.ElasticSearchService;
51 import org.nuxeo.runtime.api.Framework;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 import java.io.File;
56 import java.io.InputStream;
57 import java.lang.reflect.Constructor;
58 import java.net.URI;
59 import java.net.URLEncoder;
60 import java.nio.charset.StandardCharsets;
61 import java.nio.file.Files;
62 import java.util.Arrays;
63 import java.util.HashSet;
64 import java.util.Hashtable;
65 import java.util.List;
66 import java.util.Set;
67
68 public class CSpaceResteasyBootstrap extends ResteasyBootstrap {
69         private static final Logger logger = LoggerFactory.getLogger(CSpaceResteasyBootstrap.class);
70
71         private static final String RESET_AUTHORITIES_PROPERTY = "org.collectionspace.services.authorities.reset";
72         private static final String RESET_ELASTICSEARCH_INDEX_PROPERTY = "org.collectionspace.services.elasticsearch.reset";
73         private static final String RESET_REPORTS_PROPERTY = "org.collectionspace.services.reports.reset";
74         private static final String RESET_BATCH_JOBS_PROPERTY = "org.collectionspace.services.batch.reset";
75         private static final String QUICK_BOOT_PROPERTY = "org.collectionspace.services.quickboot";
76         private static final String REPORT_PROPERTY = "report";
77         private static final String BATCH_PROPERTY = "batch";
78
79         @Override
80         public void contextInitialized(ServletContextEvent event) {
81                 try {
82                         //
83                         // This call to super instantiates and initializes our JAX-RS application class.
84                         // The application class is org.collectionspace.services.jaxrs.CollectionSpaceJaxRsApplication.
85                         //
86                         logger.info("Starting up the CollectionSpace Services JAX-RS application.");
87                         super.contextInitialized(event);
88                         CollectionSpaceJaxRsApplication app = (CollectionSpaceJaxRsApplication)deployment.getApplication();
89                         Dispatcher disp = deployment.getDispatcher();
90                         disp.getDefaultContextObjects().put(ResourceMap.class, app.getResourceMap());
91
92                         // Property can be set in the tomcat/bin/setenv.sh (or setenv.bat) file
93                         String quickBoot = System.getProperty(QUICK_BOOT_PROPERTY, Boolean.FALSE.toString());
94
95                         if (Boolean.valueOf(quickBoot) == false) {
96                                 // The below properties can be set in the tomcat/bin/setenv.sh (or setenv.bat) file.
97                                 String resetAuthsString = System.getProperty(RESET_AUTHORITIES_PROPERTY, Boolean.FALSE.toString());
98                                 String resetElasticsearchIndexString = System.getProperty(RESET_ELASTICSEARCH_INDEX_PROPERTY, Boolean.FALSE.toString());
99                                 String resetBatchJobsString = System.getProperty(RESET_BATCH_JOBS_PROPERTY, Boolean.TRUE.toString());
100                                 String resetReportsString = System.getProperty(RESET_REPORTS_PROPERTY, Boolean.TRUE.toString());
101
102                                 initializeAuthorities(app.getResourceMap(), Boolean.valueOf(resetAuthsString));
103
104                                 if (Boolean.valueOf(resetElasticsearchIndexString) == true) {
105                                         resetElasticSearchIndex();
106                                 }
107
108                                 if (Boolean.valueOf(resetReportsString) == true) {
109                                         resetReports();
110                                 }
111
112                                 if (Boolean.valueOf(resetBatchJobsString) == true) {
113                                         resetBatchJobs();
114                                 }
115                         }
116
117                         logger.info("CollectionSpace Services JAX-RS application started.");
118                 } catch (Exception e) {
119                         e.printStackTrace();
120                         throw new RuntimeException(e);
121                 }
122         }
123
124
125         @Override
126         public void contextDestroyed(ServletContextEvent event) {
127                 logger.info("Shutting down the CollectionSpace Services JAX-RS application.");
128                 //Do something if needed.
129                 logger.info("CollectionSpace Services JAX-RS application stopped.");
130         }
131
132         public void resetReports() throws Exception {
133                 logger.info("Resetting reports");
134
135                 TenantBindingConfigReaderImpl tenantBindingConfigReader = ServiceMain.getInstance().getTenantBindingConfigReader();
136                 Hashtable<String, TenantBindingType> tenantBindingsTable = tenantBindingConfigReader.getTenantBindings(false);
137
138                 for (TenantBindingType tenantBinding : tenantBindingsTable.values()) {
139                         ServiceBindingType reportServiceBinding = null;
140
141                         for (ServiceBindingType serviceBinding : tenantBinding.getServiceBindings()) {
142                                 if (serviceBinding.getName().toLowerCase().trim().equals(ReportClient.SERVICE_NAME)) {
143                                         reportServiceBinding = serviceBinding;
144
145                                         break;
146                                 }
147                         }
148
149                         Set<String> reportNames = new HashSet<String>();
150
151                         if (reportServiceBinding != null) {
152                                 for (PropertyType property : reportServiceBinding.getProperties()) {
153                                         for (PropertyItemType item : property.getItem()) {
154                                                 if (item.getKey().equals(REPORT_PROPERTY)) {
155                                                         reportNames.add(item.getValue());
156                                                 }
157                                         }
158                                 }
159                         }
160
161                         if (reportNames.size() > 0) {
162                                 CSpaceTenant tenant = new CSpaceTenant(tenantBinding.getId(), tenantBinding.getName());
163
164                                 resetTenantReports(tenant, reportNames);
165                         }
166                 }
167         }
168
169         private void resetTenantReports(CSpaceTenant tenant, Set<String> reportNames) throws Exception {
170                 logger.info("Resetting reports for tenant {}", tenant.getId());
171
172                 AuthZ.get().login(tenant);
173
174                 CollectionSpaceJaxRsApplication app = (CollectionSpaceJaxRsApplication) deployment.getApplication();
175                 ResourceMap resourceMap = app.getResourceMap();
176                 ReportResource reportResource = (ReportResource) resourceMap.get(ReportClient.SERVICE_NAME);
177
178                 for (String reportName : reportNames) {
179                         File reportMetadataFile = ReportResource.getReportMetadataFile(reportName);
180
181                         if (!reportMetadataFile.exists()) {
182                                 logger.warn(
183                                         "Metadata file not found for report {} at {}",
184                                         reportName, reportMetadataFile.getAbsolutePath());
185
186                                 continue;
187                         }
188
189                         String payload = new String(Files.readAllBytes(reportMetadataFile.toPath()));
190                         String reportFilename = reportName + ".jrxml";
191
192                         UriInfo uriInfo = new UriInfoImpl(
193                                 new URI(""),
194                                 new URI(""),
195                                 "",
196                                 "pgSz=0&filename=" + URLEncoder.encode(reportFilename, StandardCharsets.UTF_8.toString()),
197                                 Arrays.asList((PathSegment) new PathSegmentImpl("", false))
198                         );
199
200                         AbstractCommonList list = reportResource.getList(uriInfo);
201
202                         if (list.getTotalItems() == 0) {
203                                 logger.info("Adding report " + reportName);
204
205                                 try {
206                                         reportResource.create(resourceMap, null, payload);
207                                 } catch(Exception e) {
208                                         logger.error(e.getMessage(), e);
209                                 }
210                         } else {
211                                 for (ListItem item : list.getListItem()) {
212                                         String csid = AbstractCommonListUtils.ListItemGetCSID(item);
213
214                                         // Update an existing report iff:
215                                         // - it was created autmatically (i.e., by the SPRING_ADMIN user)
216                                         // - it was last updated automatically (i.e., by the SPRING_ADMIN user)
217                                         // - it is not soft-deleted
218
219                                         PoxPayloadOut reportPayload = reportResource.getResourceFromCsid(null, null, csid);
220                                         PayloadOutputPart corePart = reportPayload.getPart(CollectionSpaceClient.COLLECTIONSPACE_CORE_SCHEMA);
221
222                                         String createdBy = corePart.asElement().selectSingleNode(CollectionSpaceClient.COLLECTIONSPACE_CORE_CREATED_BY).getText();
223                                         String updatedBy = corePart.asElement().selectSingleNode(CollectionSpaceClient.COLLECTIONSPACE_CORE_UPDATED_BY).getText();
224                                         String workflowState = corePart.asElement().selectSingleNode(CollectionSpaceClient.COLLECTIONSPACE_CORE_WORKFLOWSTATE).getText();
225
226                                         if (
227                                                 createdBy.equals(AuthN.SPRING_ADMIN_USER)
228                                                 && updatedBy.equals(AuthN.SPRING_ADMIN_USER)
229                                                 && !workflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)
230                                         ) {
231                                                 logger.info("Updating report {} with csid {}", reportName, csid);
232
233                                                 try {
234                                                         reportResource.update(resourceMap, null, csid, payload);
235                                                 } catch (Exception e) {
236                                                         logger.error(e.getMessage(), e);
237                                                 }
238                                         } else {
239                                                 logger.info(
240                                                         "Not updating report {} with csid {} - it was not auto-created, or was updated or soft-deleted",
241                                                         reportName, csid);
242                                         }
243                                 }
244                         }
245                 }
246         }
247
248         public void resetBatchJobs() throws Exception {
249                 logger.info("Resetting batch jobs");
250
251                 TenantBindingConfigReaderImpl tenantBindingConfigReader = ServiceMain.getInstance().getTenantBindingConfigReader();
252                 Hashtable<String, TenantBindingType> tenantBindingsTable = tenantBindingConfigReader.getTenantBindings(false);
253
254                 for (TenantBindingType tenantBinding : tenantBindingsTable.values()) {
255                         ServiceBindingType batchServiceBinding = null;
256
257                         for (ServiceBindingType serviceBinding : tenantBinding.getServiceBindings()) {
258                                 if (serviceBinding.getName().toLowerCase().trim().equals(BatchClient.SERVICE_NAME)) {
259                                         batchServiceBinding = serviceBinding;
260
261                                         break;
262                                 }
263                         }
264
265                         Set<String> batchNames = new HashSet<String>();
266
267                         if (batchServiceBinding != null) {
268                                 for (PropertyType property : batchServiceBinding.getProperties()) {
269                                         for (PropertyItemType item : property.getItem()) {
270                                                 if (item.getKey().equals(BATCH_PROPERTY)) {
271                                                         batchNames.add(item.getValue());
272                                                 }
273                                         }
274                                 }
275                         }
276
277                         if (batchNames.size() > 0) {
278                                 CSpaceTenant tenant = new CSpaceTenant(tenantBinding.getId(), tenantBinding.getName());
279
280                                 resetTenantBatchJobs(tenant, batchNames);
281                         }
282                 }
283         }
284
285         private void resetTenantBatchJobs(CSpaceTenant tenant, Set<String> batchNames) throws Exception {
286                 logger.info("Resetting batch jobs for tenant {}", tenant.getId());
287
288                 AuthZ.get().login(tenant);
289
290                 CollectionSpaceJaxRsApplication app = (CollectionSpaceJaxRsApplication) deployment.getApplication();
291                 ResourceMap resourceMap = app.getResourceMap();
292                 BatchResource batchResource = (BatchResource) resourceMap.get(BatchClient.SERVICE_NAME);
293
294                 for (String batchName : batchNames) {
295                         InputStream batchMetadataInputStream = BatchResource.getBatchMetadataInputStream(batchName);
296
297                         if (batchMetadataInputStream == null) {
298                                 logger.warn(
299                                         "Metadata file not found for batch {}", batchName);
300
301                                 continue;
302                         }
303
304                         String payload = IOUtils.toString(batchMetadataInputStream, StandardCharsets.UTF_8);
305
306                         batchMetadataInputStream.close();
307
308                         UriInfo uriInfo = new UriInfoImpl(
309                                 new URI(""),
310                                 new URI(""),
311                                 "",
312                                 "pgSz=0&classname=" + URLEncoder.encode(batchName, StandardCharsets.UTF_8.toString()),
313                                 Arrays.asList((PathSegment) new PathSegmentImpl("", false))
314                         );
315
316                         AbstractCommonList list = batchResource.getList(uriInfo);
317
318                         if (list.getTotalItems() == 0) {
319                                 logger.info("Adding batch job " + batchName);
320
321                                 try {
322                                         batchResource.create(resourceMap, null, payload);
323                                 } catch(Exception e) {
324                                         logger.error(e.getMessage(), e);
325                                 }
326                         } else {
327                                 for (ListItem item : list.getListItem()) {
328                                         String csid = AbstractCommonListUtils.ListItemGetCSID(item);
329
330                                         // Update an existing batch job iff:
331                                         // - it was created autmatically (i.e., by the SPRING_ADMIN user)
332                                         // - it was last updated automatically (i.e., by the SPRING_ADMIN user)
333                                         // - it is not soft-deleted
334
335                                         PoxPayloadOut batchPayload = batchResource.getResourceFromCsid(null, null, csid);
336                                         PayloadOutputPart corePart = batchPayload.getPart(CollectionSpaceClient.COLLECTIONSPACE_CORE_SCHEMA);
337
338                                         String createdBy = corePart.asElement().selectSingleNode(CollectionSpaceClient.COLLECTIONSPACE_CORE_CREATED_BY).getText();
339                                         String updatedBy = corePart.asElement().selectSingleNode(CollectionSpaceClient.COLLECTIONSPACE_CORE_UPDATED_BY).getText();
340                                         String workflowState = corePart.asElement().selectSingleNode(CollectionSpaceClient.COLLECTIONSPACE_CORE_WORKFLOWSTATE).getText();
341
342                                         if (
343                                                 createdBy.equals(AuthN.SPRING_ADMIN_USER)
344                                                 && updatedBy.equals(AuthN.SPRING_ADMIN_USER)
345                                                 && !workflowState.equals(WorkflowClient.WORKFLOWSTATE_DELETED)
346                                         ) {
347                                                 logger.info("Updating batch job {} with csid {}", batchName, csid);
348
349                                                 try {
350                                                         batchResource.update(resourceMap, null, csid, payload);
351                                                 } catch (Exception e) {
352                                                         logger.error(e.getMessage(), e);
353                                                 }
354                                         } else {
355                                                 logger.info(
356                                                         "Not updating batch job {} with csid {} - it was not auto-created, or was updated or soft-deleted",
357                                                         batchName, csid);
358                                         }
359                                 }
360                         }
361                 }
362         }
363
364         public void resetElasticSearchIndex() throws Exception {
365                 boolean isEnabled = Boolean.parseBoolean(Framework.getProperty(ES_ENABLED_PROPERTY, "true"));
366
367                 if (!isEnabled) {
368                         return;
369                 }
370
371                 ElasticSearchComponent es = (ElasticSearchComponent) Framework.getService(ElasticSearchService.class);
372
373                 for (String repositoryName : es.getRepositoryNames()) {
374                         logger.info("Rebuilding Elasticsearch index for repository {}", repositoryName);
375
376                         es.dropAndInitRepositoryIndex(repositoryName);
377                 }
378
379                 TenantBindingConfigReaderImpl tenantBindingConfigReader = ServiceMain.getInstance().getTenantBindingConfigReader();
380                 Hashtable<String, TenantBindingType> tenantBindingsTable = tenantBindingConfigReader.getTenantBindings(false);
381
382                 for (TenantBindingType tenantBinding : tenantBindingsTable.values()) {
383                         CSpaceTenant tenant = new CSpaceTenant(tenantBinding.getId(), tenantBinding.getName());
384
385                         AuthZ.get().login(tenant);
386
387                         for (ServiceBindingType serviceBinding : tenantBinding.getServiceBindings()) {
388                                 Boolean isElasticsearchIndexed = serviceBinding.isElasticsearchIndexed();
389                                 String servicesRepoDomainName = serviceBinding.getRepositoryDomain();
390
391                                 if (isElasticsearchIndexed && servicesRepoDomainName != null && servicesRepoDomainName.trim().isEmpty() == false) {
392                                         String repositoryName = ConfigUtils.getRepositoryName(tenantBinding, servicesRepoDomainName);
393                                         String docType = NuxeoUtils.getTenantQualifiedDocType(tenantBinding.getId(), serviceBinding.getObject().getName());
394
395                                         logger.info("Starting Elasticsearch reindexing for docType {} in repository {}", docType, repositoryName);
396
397                                         es.runReindexingWorker(repositoryName, String.format("SELECT ecm:uuid FROM %s", docType));
398                                 }
399                         }
400                 }
401         }
402
403     /**
404      * Initialize all authorities and vocabularies defined in the service bindings.
405      * @param resourceMap
406      * @throws Exception
407      */
408     public void initializeAuthorities(ResourceMap resourceMap, boolean reset) throws Exception {
409         TenantBindingConfigReaderImpl tenantBindingConfigReader = ServiceMain.getInstance().getTenantBindingConfigReader();
410         Hashtable<String, TenantBindingType> tenantBindingsTable = tenantBindingConfigReader.getTenantBindings(false);
411         for (TenantBindingType tenantBindings : tenantBindingsTable.values()) {
412                         CSpaceTenant tenant = new CSpaceTenant(tenantBindings.getId(), tenantBindings.getName());
413                         if (shouldInitializeAuthorities(tenant, reset) == true) {
414                                 logger.info("Initializing vocabularies and authorities of tenant '{}'.", tenant.getId());
415                         for (ServiceBindingType serviceBinding : tenantBindings.getServiceBindings()) {
416                                 AuthorityInstanceList element = serviceBinding.getAuthorityInstanceList();
417                                 if (element != null && element.getAuthorityInstance() != null) {
418                                         List<AuthorityInstanceType> authorityInstanceList = element.getAuthorityInstance();
419                                         for (AuthorityInstanceType authorityInstance : authorityInstanceList) {
420                                                 try {
421                                                         initializeAuthorityInstance(resourceMap, authorityInstance, serviceBinding, tenant, reset);
422                                                 } catch (Exception e) {
423                                                         logger.error("Could not initialize authorities and authority terms: " + e.getMessage());
424                                                         throw e;
425                                                 }
426                                         }
427                                 }
428                         }
429                         //
430                         // If we made it this far, we've either created the tenant's authorities and terms or we've reset them.  Either way,
431                         // we should mark the isAuthoritiesInitialized field of the tenant to 'true'.
432                         //
433                         setAuthoritiesInitialized(tenant, true);
434                         }
435         }
436         }
437
438     @SuppressWarnings("rawtypes")
439         private AuthorityClient getAuthorityClient(String classname) throws Exception {
440         Class clazz = Class.forName(classname.trim());
441         Constructor co = clazz.getConstructor(null);
442         Object classInstance = co.newInstance(null);
443         return (AuthorityClient) classInstance;
444     }
445
446     private boolean shouldInitializeAuthorities(CSpaceTenant cspaceTenant, boolean reset) {
447                 AuthZ.get().login(); // login as super admin
448                 TenantResource tenantResource = new TenantResource();
449                 Tenant tenantState = tenantResource.getTenant(cspaceTenant.getId());
450
451                 //
452                 // If the tenant's authorities have been initialized and
453                 // we're not being asked to reset them, we'll return 'false'
454                 // making any changes
455                 //
456                 return tenantState.isAuthoritiesInitialized() == false || reset == true;
457     }
458
459     private void setAuthoritiesInitialized(CSpaceTenant cspaceTenant, boolean initState) {
460                 AuthZ.get().login(); // login as super admin
461                 TenantResource tenantResource = new TenantResource();
462                 Tenant tenantState = tenantResource.getTenant(cspaceTenant.getId());
463
464                 tenantState.setAuthoritiesInitialized(initState);
465                 tenantResource.updateTenant(cspaceTenant.getId(), tenantState);
466         }
467
468
469     /*
470      * Check to see if an an authority instance and its corresponding terms exist.  If not, try to create them.
471      */
472     private void initializeAuthorityInstance(ResourceMap resourceMap,
473                 AuthorityInstanceType authorityInstance,
474                 ServiceBindingType serviceBinding,
475                 CSpaceTenant cspaceTenant,
476                 boolean reset) throws Exception {
477         int status = -1;
478         Response response = null;
479                 String serviceName = serviceBinding.getName();
480
481                 AuthZ.get().login(cspaceTenant);
482                 String clientClassName = serviceBinding.getClientHandler();
483                 AuthorityClient client = getAuthorityClient(clientClassName);
484                 String authoritySpecifier = RefName.shortIdToPath(authorityInstance.getTitleRef());  // e.g., urn:cspace:name(ulan)
485
486                 //
487                 // Test to see if the authority instance exists already.
488                 //
489                 AuthorityResource authorityResource = (AuthorityResource) resourceMap.get(serviceName.toLowerCase());
490                 try {
491                         response = authorityResource.get(null, null, null, authoritySpecifier);
492                 } catch (CSWebApplicationException e) {
493                         response = e.getResponse();  // If the authority doesn't exist, we expect a 404 error
494                 }
495
496                 //
497                 // If it doesn't exist (status is not 200), then try to create the authority instance
498                 //
499                 status = response.getStatus();
500                 if (status != Response.Status.OK.getStatusCode()) {
501                         String xmlPayload = client.createAuthorityInstance(authorityInstance.getTitleRef(), authorityInstance.getTitle());
502                         response = authorityResource.createAuthority(xmlPayload);
503                         status = response.getStatus();
504                         if (status != Response.Status.CREATED.getStatusCode()) {
505                                 throw new CSWebApplicationException(response);
506                         }
507                 }
508
509                 if (status == Response.Status.OK.getStatusCode()) {
510                         logger.debug("Authority of type '{}' with the short ID of '{}' existed already.",
511                                         serviceName, authorityInstance.getTitleRef());
512                 } else if (status == Response.Status.CREATED.getStatusCode()) {
513                         logger.debug("Created a new authority of type '{}' with the short ID of '{}'.",
514                                         serviceName, authorityInstance.getTitleRef());
515                 } else {
516                         logger.warn("Unknown status '{}' encountered when creating or fetching authority of type '{}' with the short ID of '{}'.",
517                                         status, serviceName, authorityInstance.getTitleRef());
518                 }
519
520                 //
521                 // Next, try to create or verify the authority terms.
522                 //
523                 initializeAuthorityInstanceTerms(authorityResource, client, authoritySpecifier, resourceMap, authorityInstance, serviceName, cspaceTenant);
524         }
525
526     private void initializeAuthorityInstanceTerms(
527                 AuthorityResource authorityResource,
528                 AuthorityClient client,
529                 String authoritySpecifier,
530                 ResourceMap resourceMap,
531                 AuthorityInstanceType authorityInstance,
532                 String serviceName,
533                 CSpaceTenant tenant) throws Exception {
534
535         int status = -1;
536         Response response = null;
537
538         TermList termListElement = authorityInstance.getTermList();
539         if (termListElement == null) {
540                 return;
541         }
542
543         for (Term term : termListElement.getTerm()) {
544                 //
545                 // Check to see if the term already exists
546                 //
547                 try {
548                         String termSpecifier = RefName.shortIdToPath(term.getId());
549                         authorityResource.getAuthorityItem(null, null, resourceMap, authoritySpecifier, termSpecifier);
550                         status = Response.Status.OK.getStatusCode();
551                 } catch (CSWebApplicationException e) {
552                         response = e.getResponse();  // If the authority doesn't exist, we expect a 404 error
553                         status = response.getStatus();
554                 }
555
556                 //
557                 // If the term doesn't exist, create it.
558                 //
559                 if (status != Response.Status.OK.getStatusCode()) {
560                         String termShortId = term.getId();
561                         String termDisplayName = term.getContent().trim();
562                         String xmlPayload = client.createAuthorityItemInstance(termShortId, termDisplayName);
563                         try {
564                                 authorityResource.createAuthorityItem(resourceMap, null, authoritySpecifier, xmlPayload);
565                                 logger.debug("Tenant:{}:Created a new term '{}:{}' in the authority of type '{}' with the short ID of '{}'.",
566                                                 tenant.getName(), termDisplayName, termShortId, serviceName, authorityInstance.getTitleRef());
567                         } catch (CSWebApplicationException e) {
568                                 response = e.getResponse();
569                                 status = response.getStatus();
570                                 if (status != Response.Status.CREATED.getStatusCode()) {
571                                         throw new CSWebApplicationException(response);
572                                 }
573                         }
574                 }
575         }
576     }
577 }