REPO-3766 Renditions: Simplified Async Rendition Service

REPO-3688 Renditions: Deprecation of public Java APIs
This commit is contained in:
alandavis
2018-09-25 18:31:32 +01:00
committed by GitHub
parent 8dc5c52c9a
commit aa24cc2333
6 changed files with 89 additions and 77 deletions

View File

@@ -37,7 +37,7 @@
<dependency.alfresco-repository.version>7.10</dependency.alfresco-repository.version> <dependency.alfresco-repository.version>7.10</dependency.alfresco-repository.version>
<dependency.alfresco-core.version>7.4</dependency.alfresco-core.version> <dependency.alfresco-core.version>7.4</dependency.alfresco-core.version>
<dependency.alfresco-data-model.version>8.10</dependency.alfresco-data-model.version> <dependency.alfresco-data-model.version>8.15</dependency.alfresco-data-model.version>
<dependency.alfresco-pdf-renderer.version>1.1</dependency.alfresco-pdf-renderer.version> <dependency.alfresco-pdf-renderer.version>1.1</dependency.alfresco-pdf-renderer.version>
<dependency.jackson.version>2.9.5</dependency.jackson.version> <dependency.jackson.version>2.9.5</dependency.jackson.version>

View File

@@ -29,10 +29,10 @@ package org.alfresco.rest.api.impl;
import org.alfresco.heartbeat.RenditionsDataCollector; import org.alfresco.heartbeat.RenditionsDataCollector;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.query.PagingResults; import org.alfresco.query.PagingResults;
import org.alfresco.repo.rendition2.RenditionDefinition2;
import org.alfresco.repo.rendition2.RenditionDefinitionRegistry2;
import org.alfresco.repo.rendition2.RenditionService2;
import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.thumbnail.ThumbnailDefinition;
import org.alfresco.repo.thumbnail.ThumbnailHelper;
import org.alfresco.repo.thumbnail.ThumbnailRegistry;
import org.alfresco.repo.thumbnail.script.ScriptThumbnailService; import org.alfresco.repo.thumbnail.script.ScriptThumbnailService;
import org.alfresco.rest.antlr.WhereClauseParser; import org.alfresco.rest.antlr.WhereClauseParser;
import org.alfresco.rest.api.Nodes; import org.alfresco.rest.api.Nodes;
@@ -45,6 +45,7 @@ import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
import org.alfresco.rest.framework.core.exceptions.DisabledServiceException; import org.alfresco.rest.framework.core.exceptions.DisabledServiceException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException; import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.NotFoundException; import org.alfresco.rest.framework.core.exceptions.NotFoundException;
import org.alfresco.rest.framework.core.exceptions.StaleEntityException;
import org.alfresco.rest.framework.resource.content.BinaryResource; import org.alfresco.rest.framework.resource.content.BinaryResource;
import org.alfresco.rest.framework.resource.content.CacheDirective; import org.alfresco.rest.framework.resource.content.CacheDirective;
import org.alfresco.rest.framework.resource.content.ContentInfoImpl; import org.alfresco.rest.framework.resource.content.ContentInfoImpl;
@@ -57,17 +58,12 @@ import org.alfresco.rest.framework.resource.parameters.where.Query;
import org.alfresco.rest.framework.resource.parameters.where.QueryHelper; import org.alfresco.rest.framework.resource.parameters.where.QueryHelper;
import org.alfresco.rest.workflow.api.impl.MapBasedQueryWalker; import org.alfresco.rest.workflow.api.impl.MapBasedQueryWalker;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.rendition.RenditionService;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.MimetypeService; import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.thumbnail.ThumbnailService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.PropertyCheck; import org.alfresco.util.PropertyCheck;
import org.alfresco.util.TempFileProvider; import org.alfresco.util.TempFileProvider;
@@ -98,15 +94,12 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
private Nodes nodes; private Nodes nodes;
private NodeService nodeService; private NodeService nodeService;
private ThumbnailService thumbnailService;
private ScriptThumbnailService scriptThumbnailService; private ScriptThumbnailService scriptThumbnailService;
private RenditionService renditionService;
private MimetypeService mimetypeService; private MimetypeService mimetypeService;
private ActionService actionService;
private NamespaceService namespaceService;
private ServiceRegistry serviceRegistry; private ServiceRegistry serviceRegistry;
private ResourceLoader resourceLoader; private ResourceLoader resourceLoader;
private TenantService tenantService; private TenantService tenantService;
private RenditionService2 renditionService2;
private RenditionsDataCollector renditionsDataCollector; private RenditionsDataCollector renditionsDataCollector;
public void setNodes(Nodes nodes) public void setNodes(Nodes nodes)
@@ -114,11 +107,6 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
this.nodes = nodes; this.nodes = nodes;
} }
public void setThumbnailService(ThumbnailService thumbnailService)
{
this.thumbnailService = thumbnailService;
}
public void setScriptThumbnailService(ScriptThumbnailService scriptThumbnailService) public void setScriptThumbnailService(ScriptThumbnailService scriptThumbnailService)
{ {
this.scriptThumbnailService = scriptThumbnailService; this.scriptThumbnailService = scriptThumbnailService;
@@ -140,6 +128,11 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
this.tenantService = tenantService; this.tenantService = tenantService;
} }
public void setRenditionService2(RenditionService2 renditionService2)
{
this.renditionService2 = renditionService2;
}
public void setRenditionsDataCollector(RenditionsDataCollector renditionsDataCollector) public void setRenditionsDataCollector(RenditionsDataCollector renditionsDataCollector)
{ {
this.renditionsDataCollector = renditionsDataCollector; this.renditionsDataCollector = renditionsDataCollector;
@@ -148,26 +141,23 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
public void init() public void init()
{ {
PropertyCheck.mandatory(this, "nodes", nodes); PropertyCheck.mandatory(this, "nodes", nodes);
PropertyCheck.mandatory(this, "thumbnailService", thumbnailService);
PropertyCheck.mandatory(this, "scriptThumbnailService", scriptThumbnailService); PropertyCheck.mandatory(this, "scriptThumbnailService", scriptThumbnailService);
PropertyCheck.mandatory(this, "serviceRegistry", serviceRegistry); PropertyCheck.mandatory(this, "serviceRegistry", serviceRegistry);
PropertyCheck.mandatory(this, "tenantService", tenantService); PropertyCheck.mandatory(this, "tenantService", tenantService);
PropertyCheck.mandatory(this, "renditionService2", renditionService2);
PropertyCheck.mandatory(this, "renditionsDataCollector", renditionsDataCollector); PropertyCheck.mandatory(this, "renditionsDataCollector", renditionsDataCollector);
this.nodeService = serviceRegistry.getNodeService(); this.nodeService = serviceRegistry.getNodeService();
this.actionService = serviceRegistry.getActionService();
this.renditionService = serviceRegistry.getRenditionService();
this.mimetypeService = serviceRegistry.getMimetypeService(); this.mimetypeService = serviceRegistry.getMimetypeService();
this.namespaceService = serviceRegistry.getNamespaceService();
} }
@Override @Override
public CollectionWithPagingInfo<Rendition> getRenditions(NodeRef nodeRef, Parameters parameters) public CollectionWithPagingInfo<Rendition> getRenditions(NodeRef nodeRef, Parameters parameters)
{ {
final NodeRef validatedNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId()); final NodeRef validatedNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId());
String contentMimeType = getMimeType(validatedNodeRef); ContentData contentData = getContentData(nodeRef, true);
String sourceMimetype = contentData.getMimetype();
Query query = parameters.getQuery();
boolean includeCreated = true; boolean includeCreated = true;
boolean includeNotCreated = true; boolean includeNotCreated = true;
String status = getStatus(parameters); String status = getStatus(parameters);
@@ -180,15 +170,17 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
Map<String, Rendition> apiRenditions = new TreeMap<>(); Map<String, Rendition> apiRenditions = new TreeMap<>();
if (includeNotCreated) if (includeNotCreated)
{ {
// List all available thumbnail definitions // List all available rendition definitions
List<ThumbnailDefinition> thumbnailDefinitions = thumbnailService.getThumbnailRegistry().getThumbnailDefinitions(contentMimeType, -1); long size = contentData.getSize();
for (ThumbnailDefinition thumbnailDefinition : thumbnailDefinitions) RenditionDefinitionRegistry2 renditionDefinitionRegistry2 = renditionService2.getRenditionDefinitionRegistry2();
Set<String> renditionNames = renditionDefinitionRegistry2.getRenditionNamesFrom(sourceMimetype, size);
for (String renditionName : renditionNames)
{ {
apiRenditions.put(thumbnailDefinition.getName(), toApiRendition(thumbnailDefinition)); apiRenditions.put(renditionName, toApiRendition(renditionName));
} }
} }
List<ChildAssociationRef> nodeRefRenditions = renditionService.getRenditions(validatedNodeRef); List<ChildAssociationRef> nodeRefRenditions = renditionService2.getRenditions(validatedNodeRef);
if (!nodeRefRenditions.isEmpty()) if (!nodeRefRenditions.isEmpty())
{ {
for (ChildAssociationRef childAssociationRef : nodeRefRenditions) for (ChildAssociationRef childAssociationRef : nodeRefRenditions)
@@ -231,21 +223,23 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
// if there is no rendition, then try to find the available/registered rendition (yet to be created). // if there is no rendition, then try to find the available/registered rendition (yet to be created).
if (renditionNodeRef == null && includeNotCreated) if (renditionNodeRef == null && includeNotCreated)
{ {
ThumbnailDefinition thumbnailDefinition = thumbnailService.getThumbnailRegistry().getThumbnailDefinition(renditionId); ContentData contentData = getContentData(validatedNodeRef, true);
if (thumbnailDefinition == null) String sourceMimetype = contentData.getMimetype();
long size = contentData.getSize();
RenditionDefinitionRegistry2 renditionDefinitionRegistry2 = renditionService2.getRenditionDefinitionRegistry2();
RenditionDefinition2 renditionDefinition = renditionDefinitionRegistry2.getRenditionDefinition(renditionId);
if (renditionDefinition == null)
{ {
throw new NotFoundException(renditionId + " is not registered."); throw new NotFoundException(renditionId + " is not registered.");
} }
else else
{ {
String contentMimeType = getMimeType(validatedNodeRef); Set<String> renditionNames = renditionDefinitionRegistry2.getRenditionNamesFrom(sourceMimetype, size);
// List all available thumbnail definitions for the source node
List<ThumbnailDefinition> thumbnailDefinitions = thumbnailService.getThumbnailRegistry().getThumbnailDefinitions(contentMimeType, -1);
boolean found = false; boolean found = false;
for (ThumbnailDefinition td : thumbnailDefinitions) for (String renditionName : renditionNames)
{ {
// Check the registered renditionId is applicable for the node's mimeType // Check the registered renditionId is applicable for the node's mimeType
if (renditionId.equals(td.getName())) if (renditionId.equals(renditionName))
{ {
found = true; found = true;
break; break;
@@ -253,10 +247,10 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
} }
if (!found) if (!found)
{ {
throw new NotFoundException(renditionId + " is not applicable for the node's mimeType " + contentMimeType); throw new NotFoundException(renditionId + " is not applicable for the node's mimeType " + sourceMimetype);
} }
} }
return toApiRendition(thumbnailDefinition); return toApiRendition(renditionId);
} }
if (renditionNodeRef == null) if (renditionNodeRef == null)
@@ -277,9 +271,9 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
public void createRendition(NodeRef nodeRef, Rendition rendition, boolean executeAsync, Parameters parameters) public void createRendition(NodeRef nodeRef, Rendition rendition, boolean executeAsync, Parameters parameters)
{ {
// If thumbnail generation has been configured off, then don't bother. // If thumbnail generation has been configured off, then don't bother.
if (!thumbnailService.getThumbnailsEnabled()) if (!renditionService2.isEnabled())
{ {
throw new DisabledServiceException("Thumbnail generation has been disabled."); throw new DisabledServiceException("Rendition generation has been disabled.");
} }
final NodeRef sourceNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId()); final NodeRef sourceNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId());
@@ -289,29 +283,22 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
throw new ConstraintViolatedException(rendition.getId() + " rendition already exists."); throw new ConstraintViolatedException(rendition.getId() + " rendition already exists.");
} }
// Use the thumbnail registry to get the details of the thumbnail try
ThumbnailRegistry registry = thumbnailService.getThumbnailRegistry();
ThumbnailDefinition thumbnailDefinition = registry.getThumbnailDefinition(rendition.getId());
if (thumbnailDefinition == null)
{ {
throw new NotFoundException(rendition.getId() + " is not registered."); renditionService2.render(sourceNodeRef, rendition.getId());
} }
catch (IllegalArgumentException e)
ContentData contentData = getContentData(sourceNodeRef, true);
// Check if anything is currently available to generate thumbnails for the specified mimeType
String sourceMimetype = contentData.getMimetype();
if (!registry.isThumbnailDefinitionAvailable(contentData.getContentUrl(), sourceMimetype, contentData.getSize(), sourceNodeRef,
thumbnailDefinition))
{ {
throw new InvalidArgumentException("Unable to create thumbnail '" + thumbnailDefinition.getName() + "' for " + throw new NotFoundException(rendition.getId() + " is not registered."); // 404
sourceMimetype + " as no transformer is currently available."); }
catch (UnsupportedOperationException e)
{
throw new IllegalArgumentException((e.getMessage())); // 400
}
catch (IllegalStateException e)
{
throw new StaleEntityException(e.getMessage()); // 409
} }
Action action = ThumbnailHelper.createCreateThumbnailAction(thumbnailDefinition, serviceRegistry);
renditionsDataCollector.recordRenditionRequest(thumbnailDefinition, sourceMimetype);
// Create thumbnail - or else queue for async creation
actionService.executeAction(action, sourceNodeRef, true, executeAsync);
} }
@Override @Override
@@ -423,10 +410,8 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
{ {
throw new InvalidArgumentException("renditionId can't be null or empty."); throw new InvalidArgumentException("renditionId can't be null or empty.");
} }
// Thumbnails have a cm: prefix.
QName renditionQName = QName.resolveToQName(namespaceService, renditionId);
ChildAssociationRef nodeRefRendition = renditionService.getRenditionByName(nodeRef, renditionQName); ChildAssociationRef nodeRefRendition = renditionService2.getRenditionByName(nodeRef, renditionId);
if (nodeRefRendition == null) if (nodeRefRendition == null)
{ {
return null; return null;
@@ -457,12 +442,15 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
return apiRendition; return apiRendition;
} }
protected Rendition toApiRendition(ThumbnailDefinition thumbnailDefinition) protected Rendition toApiRendition(String renditionName)
{ {
ContentInfo contentInfo = new ContentInfo(thumbnailDefinition.getMimetype(), RenditionDefinitionRegistry2 renditionDefinitionRegistry2 = renditionService2.getRenditionDefinitionRegistry2();
getMimeTypeDisplayName(thumbnailDefinition.getMimetype()), null, null); RenditionDefinition2 renditionDefinition = renditionDefinitionRegistry2.getRenditionDefinition(renditionName);
ContentInfo contentInfo = new ContentInfo(renditionDefinition.getTargetMimetype(),
getMimeTypeDisplayName(renditionDefinition.getTargetMimetype()), null, null);
Rendition apiRendition = new Rendition(); Rendition apiRendition = new Rendition();
apiRendition.setId(thumbnailDefinition.getName()); apiRendition.setId(renditionName);
apiRendition.setContent(contentInfo); apiRendition.setContent(contentInfo);
apiRendition.setStatus(RenditionStatus.NOT_CREATED); apiRendition.setStatus(RenditionStatus.NOT_CREATED);

View File

@@ -1359,10 +1359,10 @@
<!-- --> <!-- -->
<bean id="renditions" class="org.alfresco.rest.api.impl.RenditionsImpl" init-method="init"> <bean id="renditions" class="org.alfresco.rest.api.impl.RenditionsImpl" init-method="init">
<property name="nodes" ref="nodes" /> <property name="nodes" ref="nodes" />
<property name="thumbnailService" ref="ThumbnailService" />
<property name="scriptThumbnailService" ref="thumbnailServiceScript" /> <property name="scriptThumbnailService" ref="thumbnailServiceScript" />
<property name="serviceRegistry" ref="ServiceRegistry" /> <property name="serviceRegistry" ref="ServiceRegistry" />
<property name="tenantService" ref="tenantService"/> <property name="tenantService" ref="tenantService"/>
<property name="renditionService2" ref="RenditionService2"/>
<property name="renditionsDataCollector" ref="renditionsDataCollector"/> <property name="renditionsDataCollector" ref="renditionsDataCollector"/>
</bean> </bean>

View File

@@ -36,6 +36,7 @@ import static org.junit.Assert.assertTrue;
import com.google.common.collect.Ordering; import com.google.common.collect.Ordering;
import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.content.transform.ContentTransformer; import org.alfresco.repo.content.transform.ContentTransformer;
import org.alfresco.repo.rendition2.RenditionService2Impl;
import org.alfresco.rest.api.model.Site; import org.alfresco.rest.api.model.Site;
import org.alfresco.rest.api.nodes.NodesEntityResource; import org.alfresco.rest.api.nodes.NodesEntityResource;
import org.alfresco.rest.api.tests.RepoService.TestNetwork; import org.alfresco.rest.api.tests.RepoService.TestNetwork;
@@ -469,9 +470,9 @@ public class RenditionsTest extends AbstractBaseApiTest
multipleRenditionRequest.add(new Rendition().setId("imgpreview")); multipleRenditionRequest.add(new Rendition().setId("imgpreview"));
post(getNodeRenditionsUrl(contentNodeId), toJsonAsString(multipleRenditionRequest), 400); post(getNodeRenditionsUrl(contentNodeId), toJsonAsString(multipleRenditionRequest), 400);
ThumbnailService thumbnailService = applicationContext.getBean("thumbnailService", ThumbnailService.class); RenditionService2Impl renditionService2 = applicationContext.getBean("renditionService2", RenditionService2Impl.class);
// Disable thumbnail generation // Disable thumbnail generation
thumbnailService.setThumbnailsEnabled(false); renditionService2.setThumbnailsEnabled(false);
try try
{ {
// Create multipart request // Create multipart request
@@ -494,7 +495,7 @@ public class RenditionsTest extends AbstractBaseApiTest
} }
finally finally
{ {
thumbnailService.setThumbnailsEnabled(true); renditionService2.setThumbnailsEnabled(true);
} }
} }

View File

@@ -85,6 +85,7 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static java.lang.Thread.sleep;
import static org.alfresco.repo.security.authentication.ResetPasswordServiceImplTest.getWorkflowIdAndKeyFromUrl; import static org.alfresco.repo.security.authentication.ResetPasswordServiceImplTest.getWorkflowIdAndKeyFromUrl;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
@@ -2059,7 +2060,7 @@ public class TestPeople extends AbstractBaseApiTest
{ {
try try
{ {
Thread.sleep(requiredDelay); sleep(requiredDelay);
} }
catch (InterruptedException e) catch (InterruptedException e)
{ {
@@ -2129,7 +2130,7 @@ public class TestPeople extends AbstractBaseApiTest
} }
@Test @Test
public void updateAvatar() throws PublicApiException, IOException public void updateAvatar() throws PublicApiException, IOException, InterruptedException
{ {
final String person1 = account1PersonIt.next(); final String person1 = account1PersonIt.next();
final String person2 = account1PersonIt.next(); final String person2 = account1PersonIt.next();
@@ -2243,7 +2244,8 @@ public class TestPeople extends AbstractBaseApiTest
@Test @Test
public void removeAvatar() throws IOException, PublicApiException{ public void removeAvatar() throws IOException, PublicApiException, InterruptedException
{
final String person1 = account1PersonIt.next(); final String person1 = account1PersonIt.next();
final String person2 = account1PersonIt.next(); final String person2 = account1PersonIt.next();

View File

@@ -1411,17 +1411,17 @@ public class PublicApiClient
remove("people", personId, "activities", String.valueOf(activity.getId()), "Failed to remove activity"); remove("people", personId, "activities", String.valueOf(activity.getId()), "Failed to remove activity");
} }
public HttpResponse getAvatar(String personId, boolean placeholder, int expectedStatus) throws PublicApiException public HttpResponse getAvatar(String personId, boolean placeholder, int expectedStatus) throws PublicApiException, InterruptedException
{ {
return getAvatar(personId, null, placeholder, null, expectedStatus); return getAvatar(personId, null, placeholder, null, expectedStatus);
} }
public HttpResponse getAvatar(String personId, String ifModifiedSince, int expectedStatus) throws PublicApiException public HttpResponse getAvatar(String personId, String ifModifiedSince, int expectedStatus) throws PublicApiException, InterruptedException
{ {
return getAvatar(personId, null, false, ifModifiedSince, expectedStatus); return getAvatar(personId, null, false, ifModifiedSince, expectedStatus);
} }
public HttpResponse getAvatar(String personId, Boolean attachment, boolean placeholder, String ifModifiedSince, int expectedStatus) throws PublicApiException public HttpResponse getAvatar(String personId, Boolean attachment, boolean placeholder, String ifModifiedSince, int expectedStatus) throws PublicApiException, InterruptedException
{ {
// Binary response expected // Binary response expected
Map<String, String> params = new HashMap<>(); Map<String, String> params = new HashMap<>();
@@ -1438,12 +1438,33 @@ public class PublicApiClient
headers.put("If-Modified-Since", ifModifiedSince); headers.put("If-Modified-Since", ifModifiedSince);
} }
HttpResponse response = getSingle("people", personId, "avatar", null, params, headers, "Failed to get avatar", expectedStatus); // As renditions are now done async, we generally need to wait.
HttpResponse response = getSingleWithDelayRetry("people", personId, "avatar",
null, params, headers, "Failed to get avatar", 40, 2500, expectedStatus);
checkStatus("Unexpected response", expectedStatus, response); checkStatus("Unexpected response", expectedStatus, response);
return response; return response;
} }
private HttpResponse getSingleWithDelayRetry(String entityCollectionName, String entityId, String relationCollectionName, String relationId, Map<String, String> params,
Map<String, String> headers, String errorMessage, int repeat, long pauseInMillisecond, int expectedStatus) throws PublicApiException, InterruptedException
{
int retryCount = 0;
while (retryCount < repeat)
{
try
{
return getSingle(entityCollectionName, entityId, relationCollectionName, relationId, params, headers, errorMessage, expectedStatus);
}
catch (PublicApiException ex)
{
retryCount++;
Thread.sleep(pauseInMillisecond);
}
}
return null;
}
public HttpResponse updateAvatar(String personId, File avatar, int expectedStatus) throws PublicApiException public HttpResponse updateAvatar(String personId, File avatar, int expectedStatus) throws PublicApiException
{ {
try try