From: Patrick Schmitz Date: Wed, 10 Mar 2010 01:01:13 +0000 (+0000) Subject: CSPACE-1079. Work towards supporting search for documents by a field value. Some... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=b7f4349533b33d80c086f7f7c51ac5c1be93f597;p=tmp%2Fjakarta-migration.git CSPACE-1079. Work towards supporting search for documents by a field value. Some refactoring of the ServiceBinding and TenantBinding support, and some new utility methods. --- diff --git a/services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/AcquisitionResource.java b/services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/AcquisitionResource.java index 910b733f2..68cfb54eb 100644 --- a/services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/AcquisitionResource.java +++ b/services/acquisition/service/src/main/java/org/collectionspace/services/acquisition/AcquisitionResource.java @@ -53,6 +53,7 @@ import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.query.IQueryManager; import org.collectionspace.services.common.query.QueryManager; import org.collectionspace.services.common.security.UnauthorizedException; +import org.collectionspace.services.common.vocabulary.RefNameServiceUtils; import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl; import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput; @@ -330,9 +331,8 @@ public class AcquisitionResource getRepositoryClient(ctx).getDoc(ctx, csid); RemoteDocumentModelHandlerImpl handler = (RemoteDocumentModelHandlerImpl)createDocumentHandler(ctx); - List authRefFields = ((MultipartServiceContextImpl)ctx).getCommonPartPropertyValues("authRef"); - String prefix = ctx.getCommonPartLabel()+":"; - authRefList = handler.getAuthorityRefs(docWrapper, prefix, authRefFields); + List authRefFields = ((MultipartServiceContextImpl)ctx).getCommonPartPropertyValues(RefNameServiceUtils.AUTH_REF_PROP); + authRefList = handler.getAuthorityRefs(docWrapper, authRefFields); } catch (UnauthorizedException ue) { Response response = Response.status( Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build(); diff --git a/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/CollectionObjectResource.java b/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/CollectionObjectResource.java index ac027467a..dad878dc1 100644 --- a/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/CollectionObjectResource.java +++ b/services/collectionobject/service/src/main/java/org/collectionspace/services/collectionobject/CollectionObjectResource.java @@ -57,6 +57,7 @@ import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.query.IQueryManager; import org.collectionspace.services.common.query.QueryManager; import org.collectionspace.services.common.security.UnauthorizedException; +import org.collectionspace.services.common.vocabulary.RefNameServiceUtils; import org.collectionspace.services.intake.IntakeResource; import org.collectionspace.services.intake.IntakesCommonList; import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl; @@ -405,9 +406,8 @@ public class CollectionObjectResource getRepositoryClient(ctx).getDoc(ctx, csid); RemoteDocumentModelHandlerImpl handler = (RemoteDocumentModelHandlerImpl)createDocumentHandler(ctx); - List authRefFields = ((MultipartServiceContextImpl)ctx).getCommonPartPropertyValues("authRef"); - String prefix = ctx.getCommonPartLabel()+":"; - authRefList = handler.getAuthorityRefs(docWrapper, prefix, authRefFields); + List authRefFields = ((MultipartServiceContextImpl)ctx).getCommonPartPropertyValues(RefNameServiceUtils.AUTH_REF_PROP); + authRefList = handler.getAuthorityRefs(docWrapper, authRefFields); } catch (UnauthorizedException ue) { Response response = Response.status( Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build(); diff --git a/services/common/src/main/config/services/tenant-bindings.xml b/services/common/src/main/config/services/tenant-bindings.xml index fd6177686..294577b9b 100644 --- a/services/common/src/main/config/services/tenant-bindings.xml +++ b/services/common/src/main/config/services/tenant-bindings.xml @@ -13,7 +13,7 @@ - + nuxeo-java @@ -66,7 +66,7 @@ - + nuxeo-java @@ -327,7 +327,7 @@ - + nuxeo-java diff --git a/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReaderImpl.java b/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReaderImpl.java index f2131416f..347bbf100 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReaderImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/config/TenantBindingConfigReaderImpl.java @@ -24,7 +24,10 @@ package org.collectionspace.services.common.config; import java.io.File; +import java.util.ArrayList; import java.util.Hashtable; +import java.util.List; + import org.collectionspace.services.common.ClientType; import org.collectionspace.services.common.RepositoryClientConfigType; import org.collectionspace.services.common.ServiceMain; @@ -215,6 +218,28 @@ public class TenantBindingConfigReaderImpl return serviceBindings.get(key); } + /** + * getServiceBinding gets service binding for given tenant for a given service + * @param tenantId + * @param serviceName + * @return + */ + public List getServiceBindingsByType( + String tenantId, String serviceType) { + ArrayList list = null; + TenantBindingType tenant = tenantBindings.get(tenantId); + if(tenant!=null) { + for(ServiceBindingType sb:tenant.getServiceBindings()) { + if(sb.getType().equals(serviceType)) { + if(list==null) + list = new ArrayList(); + list.add(sb); + } + } + } + return list; + } + /** * getWorkspaceId retrieves workspace id for given tenant for given service * @param tenantId diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java b/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java index b0746f57e..448a0cf19 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java @@ -121,12 +121,7 @@ public abstract class AbstractServiceContextImpl if (objectPartMap.size() != 0) { return objectPartMap; } - ServiceBindingType serviceBinding = getServiceBinding(); - ServiceObjectType objectType = serviceBinding.getObject(); - List objectPartTypes = objectType.getPart(); - for (ObjectPartType objectPartType : objectPartTypes) { - objectPartMap.put(objectPartType.getLabel(), objectPartType); - } + ServiceBindingUtils.getPartsMetadata(getServiceBinding(), objectPartMap); return objectPartMap; } @@ -141,21 +136,13 @@ public abstract class AbstractServiceContextImpl public List getPropertyValuesForPart(String partLabel, String propName) { List allProps = getPropertiesForPart(partLabel); - List values = new ArrayList(); - if(allProps.size()>0) { - List propItems = allProps.get(0).getItem(); - for(PropertyItemType propItem:propItems) { - if(propName.equals(propItem.getKey())) { - String value = propItem.getValue(); - if(value!=null) { - values.add(value); - } - } - } - } - return values; + return ServiceBindingUtils.getPropertyValuesByName(allProps, propName); } + public List getPropertyValues(String propName) { + return ServiceBindingUtils.getPropertyValues(getServiceBinding(), propName); + } + public List getCommonPartProperties() { return getPropertiesForPart(getCommonPartLabel()); } diff --git a/services/common/src/main/java/org/collectionspace/services/common/context/ServiceBindingUtils.java b/services/common/src/main/java/org/collectionspace/services/common/context/ServiceBindingUtils.java new file mode 100644 index 000000000..f9c39ef9a --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/common/context/ServiceBindingUtils.java @@ -0,0 +1,81 @@ +package org.collectionspace.services.common.context; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.collectionspace.services.common.service.ObjectPartType; +import org.collectionspace.services.common.service.ServiceBindingType; +import org.collectionspace.services.common.service.ServiceObjectType; +import org.collectionspace.services.common.types.PropertyItemType; +import org.collectionspace.services.common.types.PropertyType; + +public class ServiceBindingUtils { + + public static void getPartsMetadata(ServiceBindingType serviceBinding, + Map objectPartMap) { + ServiceObjectType objectType = serviceBinding.getObject(); + List objectPartTypes = objectType.getPart(); + for (ObjectPartType objectPartType : objectPartTypes) { + objectPartMap.put(objectPartType.getLabel(), objectPartType); + } + } + + public static List getPropertiesForPart(ServiceBindingType serviceBinding, + String partLabel) { + ServiceObjectType objectType = serviceBinding.getObject(); + List objectPartTypes = objectType.getPart(); + for (ObjectPartType objectPartType : objectPartTypes) { + if(partLabel.equals(objectPartType.getLabel())) { + return objectPartType.getProperties(); + } + } + throw new RuntimeException("No such part found: "+partLabel); + } + + public static List getPropertyValuesForPart(ServiceBindingType serviceBinding, + String partLabel, String propName) { + List partProps = getPropertiesForPart(serviceBinding, partLabel); + return getPropertyValuesByName(partProps, propName); + } + + public static List getPropertyValuesByName(List partProps, String propName) { + List values = new ArrayList(); + if(partProps.size()>0) { + List propItems = partProps.get(0).getItem(); + for(PropertyItemType propItem:propItems) { + if(propName.equals(propItem.getKey())) { + String value = propItem.getValue(); + if(value!=null) { + values.add(value); + } + } + } + } + return values; + } + + public static List getPropertyValues(ServiceBindingType serviceBinding, + String propName) { + List values = new ArrayList(); + ServiceObjectType objectType = serviceBinding.getObject(); + List objectPartTypes = objectType.getPart(); + for (ObjectPartType objectPartType : objectPartTypes) { + List partProps = objectPartType.getProperties(); + if(partProps.size()>0) { + List propItems = partProps.get(0).getItem(); + for(PropertyItemType propItem:propItems) { + if(propName.equals(propItem.getKey())) { + String value = propItem.getValue(); + if(value!=null) { + values.add(value); + } + } + } + } + } + return values; + } + + +} diff --git a/services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java b/services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java index 892fb70ba..c6078f479 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java +++ b/services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java @@ -23,12 +23,15 @@ */ package org.collectionspace.services.common.repository; +import java.util.List; + import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.document.DocumentException; import org.collectionspace.services.common.document.DocumentNotFoundException; import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.storage.StorageClient; import org.nuxeo.ecm.core.api.DocumentModel; +import org.nuxeo.ecm.core.api.DocumentModelList; /** * RepositoryClient is a generic Document Repository client @@ -51,7 +54,7 @@ public interface RepositoryClient extends StorageClient { */ public String createWorkspace(String tenantDomain, String workspaceName) throws Exception; - /** + /** * getWorkspaceId gets an id of given workspace in default repository under given domain * @param tenantDomain domain representing tenant * @param workspaceName name of the workspace @@ -72,7 +75,7 @@ public interface RepositoryClient extends StorageClient { throws DocumentNotFoundException, DocumentException; /** - * find wrapped documentModel from the Nuxeo repository + * Find wrapped documentModel from the Nuxeo repository * @param ctx service context under which this method is invoked * @param specifies docType. If null, uses ctx.getDocumentType() * @param where NXQL where clause to get the document @@ -83,7 +86,7 @@ public interface RepositoryClient extends StorageClient { throws DocumentNotFoundException, DocumentException; /** - * find doc and return CSID from the Nuxeo repository + * Find doc and return CSID from the Nuxeo repository * @param ctx service context under which this method is invoked * @param specifies docType. If null, uses ctx.getDocumentType() * @param where NXQL where clause to get the document @@ -93,4 +96,15 @@ public interface RepositoryClient extends StorageClient { ServiceContext ctx, String where) throws DocumentNotFoundException, DocumentException; + /** + * Find a list of documentModels from the Nuxeo repository + * @param docTypes a list of DocType names to match + * @param where the clause to qualify on + * @param domain the domain for the associated services + * @return + */ + public DocumentWrapper findDocs( + List docTypes, String where, String domain, + int pageSize, int pageNum, boolean computeTotal ) + throws DocumentNotFoundException, DocumentException; } diff --git a/services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java b/services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java new file mode 100644 index 000000000..83c0ec18b --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java @@ -0,0 +1,87 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + + * http://www.collectionspace.org + * http://wiki.collectionspace.org + + * Copyright 2009 University of California at Berkeley + + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + + * You may obtain a copy of the ECL 2.0 License at + + * https://source.collectionspace.org/collection-space/LICENSE.txt + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.collectionspace.services.common.vocabulary; + +import java.util.ArrayList; +import java.util.List; + +import org.nuxeo.ecm.core.api.DocumentModelList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.collectionspace.services.common.ServiceMain; +import org.collectionspace.services.common.authorityref.AuthorityRefDocList; +import org.collectionspace.services.common.authorityref.AuthorityRefList; +import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl; +import org.collectionspace.services.common.context.ServiceBindingUtils; +import org.collectionspace.services.common.document.DocumentException; +import org.collectionspace.services.common.document.DocumentNotFoundException; +import org.collectionspace.services.common.document.DocumentWrapper; +import org.collectionspace.services.common.repository.RepositoryClient; +import org.collectionspace.services.common.service.ServiceBindingType; + +/** + * RefNameServiceUtils is a collection of services utilities related to refName usage. + * + * $LastChangedRevision: $ + * $LastChangedDate: $ + */ +public class RefNameServiceUtils { + + public static final String AUTH_REF_PROP = "authRef"; + + private final Logger logger = LoggerFactory.getLogger(RefNameServiceUtils.class); + + public AuthorityRefDocList getAuthorityRefDocs(RepositoryClient repoClient, + String tenantId, String serviceType, String refName, + int pageSize, int pageNum, boolean computeTotal ) + throws DocumentException, DocumentNotFoundException { + AuthorityRefDocList wrapperList = new AuthorityRefDocList(); + List list = + wrapperList.getAuthorityRefDocItem(); + TenantBindingConfigReaderImpl tReader = + ServiceMain.getInstance().getTenantBindingConfigReader(); + List servicebindings = tReader.getServiceBindingsByType(tenantId, serviceType); + if(servicebindings==null || servicebindings.size()>0) + return null; + String domain = tReader.getTenantBinding(tenantId).getRepositoryDomain(); + ArrayList docTypes = new ArrayList(); + StringBuilder whereClause = new StringBuilder(); + for(ServiceBindingType sb:servicebindings) { + List authRefFields = ServiceBindingUtils.getPropertyValues(sb, AUTH_REF_PROP); + String docType = sb.getObject().getName(); + docTypes.add(docType); + for(String field:authRefFields) { + // Build up the where clause for each authRef field + throw new UnsupportedOperationException(); + } + } + // Now we have to issue the search + DocumentWrapper docListWrapper = repoClient.findDocs( + docTypes, whereClause.toString(), domain, pageSize, pageNum, computeTotal ); + return null; + } + + +} + diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java index 6efb988a7..435e2ae1d 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java @@ -191,7 +191,6 @@ public abstract class RemoteDocumentModelHandlerImpl public AuthorityRefList getAuthorityRefs( DocumentWrapper docWrapper, - String pathPrefix, List authRefFields) { AuthorityRefList authRefList = new AuthorityRefList(); try { @@ -200,7 +199,7 @@ public abstract class RemoteDocumentModelHandlerImpl authRefList.getAuthorityRefItem(); for(String field:authRefFields){ - String refName = (String)docModel.getPropertyValue(pathPrefix+field); + String refName = (String)docModel.getPropertyValue(field); if(refName==null) continue; try{ diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java index 98ca8e7aa..9ce6d6d77 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java @@ -378,6 +378,53 @@ public class RepositoryJavaClientImpl implements RepositoryClient { return csid; } + /** + * Find a list of documentModels from the Nuxeo repository + * @param docTypes a list of DocType names to match + * @param where the clause to qualify on + * @param domain the domain for the associated services + * @return + */ + @Override + public DocumentWrapper findDocs( + List docTypes, String where, String domain, + int pageSize, int pageNum, boolean computeTotal ) + throws DocumentNotFoundException, DocumentException { + RepositoryInstance repoSession = null; + DocumentWrapper wrapDoc = null; + + try { + if (docTypes == null || docTypes.size()<1) { + throw new DocumentNotFoundException( + "findDocs must specify at least one DocumentType."); + } + if (domain == null) { + throw new DocumentNotFoundException("findDocs must specify Domain."); + } + repoSession = getRepositorySession(); + DocumentModelList docList = null; + // force limit to 1, and ignore totalSize + String query = buildNXQLQuery(docTypes, where, domain ); + docList = repoSession.query( query, null, pageSize, pageNum, computeTotal); + wrapDoc = new DocumentWrapperImpl(docList); + } catch (IllegalArgumentException iae) { + throw iae; + } catch (DocumentException de) { + throw de; + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("Caught exception ", e); + } + throw new DocumentException(e); + } finally { + if (repoSession != null) { + releaseRepositorySession(repoSession); + } + } + return wrapDoc; + } + + @Override public void get(ServiceContext ctx, List csidList, DocumentHandler handler) throws DocumentNotFoundException, DocumentException { @@ -693,9 +740,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient { return workspaceId; } - private final String buildNXQLQuery(String docType, String where, String domain ) { - StringBuilder query = new StringBuilder("SELECT * FROM "); - query.append(docType); + private final void appendNXQLWhere(StringBuilder query, String where, String domain ) { // TODO This is a slow method for tenant-filter // We should make this a property that is indexed. query.append(" WHERE ecm:path STARTSWITH '/" + domain + "'"); @@ -704,6 +749,26 @@ public class RepositoryJavaClientImpl implements RepositoryClient { // into SQL, we need to parenthesize our 'where' clause query.append(" AND " + "(" + where +")" + "AND ecm:isProxy = 0"); } + } + + private final String buildNXQLQuery(String docType, String where, String domain ) { + StringBuilder query = new StringBuilder("SELECT * FROM "); + query.append(docType); + appendNXQLWhere(query, where, domain ); + return query.toString(); + } + + private final String buildNXQLQuery(List docTypes, String where, String domain ) { + StringBuilder query = new StringBuilder("SELECT * FROM "); + boolean fFirst = true; + for(String docType:docTypes) { + if(fFirst) { + query.append(","); + fFirst = false; + } + query.append(docType); + } + appendNXQLWhere(query, where, domain ); return query.toString(); } diff --git a/services/common/src/main/resources/service.xsd b/services/common/src/main/resources/service.xsd index 78e85f2fe..c6d97a40c 100644 --- a/services/common/src/main/resources/service.xsd +++ b/services/common/src/main/resources/service.xsd @@ -46,6 +46,7 @@ + diff --git a/services/intake/client/src/test/java/org/collectionspace/services/client/test/IntakeAuthRefsTest.java b/services/intake/client/src/test/java/org/collectionspace/services/client/test/IntakeAuthRefsTest.java index 3693342d2..6efbcc25d 100644 --- a/services/intake/client/src/test/java/org/collectionspace/services/client/test/IntakeAuthRefsTest.java +++ b/services/intake/client/src/test/java/org/collectionspace/services/client/test/IntakeAuthRefsTest.java @@ -268,7 +268,7 @@ public class IntakeAuthRefsTest extends BaseServiceTest { * at any point during testing, even if some of those resources * may be expected to be deleted by certain tests. */ - // @AfterClass(alwaysRun=true) + @AfterClass(alwaysRun=true) public void cleanUp() { if (logger.isDebugEnabled()) { logger.debug("Cleaning up temporary resources created for testing ..."); diff --git a/services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeResource.java b/services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeResource.java index 159d79696..718b520bf 100644 --- a/services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeResource.java +++ b/services/intake/service/src/main/java/org/collectionspace/services/intake/IntakeResource.java @@ -55,6 +55,7 @@ import org.collectionspace.services.common.document.DocumentWrapper; import org.collectionspace.services.common.query.IQueryManager; import org.collectionspace.services.common.query.QueryManager; import org.collectionspace.services.common.security.UnauthorizedException; +import org.collectionspace.services.common.vocabulary.RefNameServiceUtils; import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl; import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput; @@ -212,9 +213,8 @@ public class IntakeResource extends AbstractCollectionSpaceResourceImpl { getRepositoryClient(ctx).getDoc(ctx, csid); RemoteDocumentModelHandlerImpl handler = (RemoteDocumentModelHandlerImpl)createDocumentHandler(ctx); - List authRefFields = ((MultipartServiceContextImpl)ctx).getCommonPartPropertyValues("authRef"); - String prefix = ctx.getCommonPartLabel()+":"; - authRefList = handler.getAuthorityRefs(docWrapper, prefix, authRefFields); + List authRefFields = ((MultipartServiceContextImpl)ctx).getCommonPartPropertyValues(RefNameServiceUtils.AUTH_REF_PROP); + authRefList = handler.getAuthorityRefs(docWrapper, authRefFields); } catch (UnauthorizedException ue) { Response response = Response.status( Response.Status.UNAUTHORIZED).entity("Index failed reason " + ue.getErrorReason()).type("text/plain").build();