diff --git a/data-model/src/main/java/org/alfresco/service/cmr/repository/ArchivedIOException.java b/data-model/src/main/java/org/alfresco/service/cmr/repository/ArchivedIOException.java
new file mode 100644
index 0000000000..14afa5cd6d
--- /dev/null
+++ b/data-model/src/main/java/org/alfresco/service/cmr/repository/ArchivedIOException.java
@@ -0,0 +1,53 @@
+/*
+ * #%L
+ * Alfresco Data model classes
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.service.cmr.repository;
+
+import org.alfresco.api.AlfrescoPublicApi;
+import org.alfresco.service.Experimental;
+
+/**
+ * Unable to access as content is in an Archived state.
+ * Default status is Precondition Failed Client Error = 412
+ *
+ * @author David Edwards
+ */
+@Experimental
+@AlfrescoPublicApi
+public class ArchivedIOException extends ContentIOException
+{
+ private static final long serialVersionUID = 3258135874596276087L;
+
+ public ArchivedIOException(String msg)
+ {
+ super(msg);
+ }
+
+ public ArchivedIOException(String msg, Throwable cause)
+ {
+ super(msg, cause);
+ }
+
+}
diff --git a/remote-api/src/main/java/org/alfresco/repo/web/scripts/content/ContentStreamer.java b/remote-api/src/main/java/org/alfresco/repo/web/scripts/content/ContentStreamer.java
index efbd743aa4..74d5f80c6e 100644
--- a/remote-api/src/main/java/org/alfresco/repo/web/scripts/content/ContentStreamer.java
+++ b/remote-api/src/main/java/org/alfresco/repo/web/scripts/content/ContentStreamer.java
@@ -44,6 +44,7 @@ import org.alfresco.repo.content.filestore.FileContentReader;
import org.alfresco.sync.repo.events.EventPublisher;
import org.alfresco.repo.web.util.HttpRangeProcessor;
import org.alfresco.rest.framework.resource.content.CacheDirective;
+import org.alfresco.service.cmr.repository.ArchivedIOException;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
@@ -449,7 +450,11 @@ public class ContentStreamer implements ResourceLoaderAware
if (logger.isInfoEnabled())
logger.info("Client aborted stream read:\n\tcontent: " + reader);
}
- catch (ContentIOException e2)
+ catch (ArchivedIOException e2)
+ {
+ throw e2;
+ }
+ catch (ContentIOException e3)
{
if (logger.isInfoEnabled())
logger.info("Client aborted stream read:\n\tcontent: " + reader);
diff --git a/remote-api/src/main/java/org/alfresco/rest/framework/core/exceptions/ApiException.java b/remote-api/src/main/java/org/alfresco/rest/framework/core/exceptions/ApiException.java
index ade50b818c..321d8bd208 100644
--- a/remote-api/src/main/java/org/alfresco/rest/framework/core/exceptions/ApiException.java
+++ b/remote-api/src/main/java/org/alfresco/rest/framework/core/exceptions/ApiException.java
@@ -64,6 +64,18 @@ public class ApiException extends PlatformRuntimeException
super(msgId, cause);
this.msgId = msgId;
}
+
+ public ApiException(String msgId, String message)
+ {
+ super(message);
+ this.msgId = msgId;
+ }
+
+ public ApiException(String msgId, String message, Throwable cause)
+ {
+ super(message, cause);
+ this.msgId = msgId;
+ }
public ApiException(String msgId, Throwable cause, Map additionalState)
{
diff --git a/remote-api/src/main/java/org/alfresco/rest/framework/core/exceptions/ArchivedContentException.java b/remote-api/src/main/java/org/alfresco/rest/framework/core/exceptions/ArchivedContentException.java
new file mode 100644
index 0000000000..0112377572
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/framework/core/exceptions/ArchivedContentException.java
@@ -0,0 +1,72 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rest.framework.core.exceptions;
+
+import org.alfresco.service.Experimental;
+
+/**
+ * Thrown when the content is archived and not readily accessible.
+ * Status is Precondition Failed client error = 412.
+ *
+ * @author David Edwards
+ */
+@Experimental
+public class ArchivedContentException extends ApiException
+{
+
+ public static String DEFAULT_MESSAGE_ID = "framework.exception.ArchivedContent";
+
+ public ArchivedContentException()
+ {
+ super(DEFAULT_MESSAGE_ID);
+ }
+
+ public ArchivedContentException(String message)
+ {
+ this(DEFAULT_MESSAGE_ID, message);
+ }
+
+ private ArchivedContentException(String msgId, String message)
+ {
+ super(msgId, message);
+ }
+
+ public ArchivedContentException(Throwable cause)
+ {
+ this(DEFAULT_MESSAGE_ID, cause.getLocalizedMessage(), cause);
+ }
+
+ public ArchivedContentException(String message, Throwable cause)
+ {
+ this(DEFAULT_MESSAGE_ID, message, cause);
+ }
+
+ private ArchivedContentException(String msgId, String message, Throwable cause)
+ {
+ super(msgId, message, cause);
+ }
+
+}
diff --git a/remote-api/src/main/java/org/alfresco/rest/framework/webscripts/AbstractResourceWebScript.java b/remote-api/src/main/java/org/alfresco/rest/framework/webscripts/AbstractResourceWebScript.java
index a6b3285226..bb2a547ab9 100644
--- a/remote-api/src/main/java/org/alfresco/rest/framework/webscripts/AbstractResourceWebScript.java
+++ b/remote-api/src/main/java/org/alfresco/rest/framework/webscripts/AbstractResourceWebScript.java
@@ -42,6 +42,7 @@ import org.alfresco.rest.framework.core.ResourceLocator;
import org.alfresco.rest.framework.core.ResourceOperation;
import org.alfresco.rest.framework.core.ResourceWithMetadata;
import org.alfresco.rest.framework.core.exceptions.ApiException;
+import org.alfresco.rest.framework.core.exceptions.ArchivedContentException;
import org.alfresco.rest.framework.resource.actions.ActionExecutor;
import org.alfresco.rest.framework.resource.actions.interfaces.BinaryResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceBinaryAction;
@@ -52,6 +53,8 @@ import org.alfresco.rest.framework.resource.content.FileBinaryResource;
import org.alfresco.rest.framework.resource.content.NodeBinaryResource;
import org.alfresco.rest.framework.resource.parameters.Params;
import org.alfresco.rest.framework.tools.ResponseWriter;
+import org.alfresco.service.cmr.repository.ArchivedIOException;
+import org.alfresco.service.cmr.repository.ContentIOException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -84,6 +87,8 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
private ContentStreamer streamer;
protected ResourceWebScriptHelper helper;
+ private static final String HEADER_CONTENT_LENGTH = "Content-Length";
+
@SuppressWarnings("rawtypes")
@Override
public void execute(final Api api, final WebScriptRequest req, final WebScriptResponse res) throws IOException
@@ -173,6 +178,10 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
}
}
+ catch (ContentIOException cioe)
+ {
+ handleContentIOException(res, cioe);
+ }
catch (AlfrescoRuntimeException | ApiException | WebScriptException xception )
{
renderException(xception, res, assistant);
@@ -215,6 +224,20 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
return toReturn;
}
+ private void handleContentIOException(final WebScriptResponse res, ContentIOException exception) throws IOException
+ {
+ // If the Content-Length is not set back to -1 any client will expect to receive binary and will hang until it times out
+ res.setHeader(HEADER_CONTENT_LENGTH, String.valueOf(-1));
+ if (exception instanceof ArchivedIOException)
+ {
+ renderException(new ArchivedContentException(exception.getMsgId(), exception), res, assistant);
+ }
+ else
+ {
+ renderException(exception, res, assistant);
+ }
+ }
+
protected RetryingTransactionHelper getTransactionHelper(String api)
{
RetryingTransactionHelper transHelper = transactionService.getRetryingTransactionHelper();
diff --git a/remote-api/src/main/resources/alfresco/public-rest-context.xml b/remote-api/src/main/resources/alfresco/public-rest-context.xml
index 540019fa74..825eff0312 100644
--- a/remote-api/src/main/resources/alfresco/public-rest-context.xml
+++ b/remote-api/src/main/resources/alfresco/public-rest-context.xml
@@ -174,6 +174,7 @@
+
diff --git a/repository/src/main/java/org/alfresco/repo/content/AbstractContentReader.java b/repository/src/main/java/org/alfresco/repo/content/AbstractContentReader.java
index c117bbb3e9..000cd7d89a 100644
--- a/repository/src/main/java/org/alfresco/repo/content/AbstractContentReader.java
+++ b/repository/src/main/java/org/alfresco/repo/content/AbstractContentReader.java
@@ -47,6 +47,7 @@ import org.alfresco.api.AlfrescoPublicApi;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.content.filestore.FileContentWriter;
import org.alfresco.repo.content.transform.TransformerDebug;
+import org.alfresco.service.cmr.repository.ArchivedIOException;
import org.alfresco.service.cmr.repository.ContentAccessor;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
@@ -429,6 +430,7 @@ public abstract class AbstractContentReader extends AbstractContentAccessor impl
}
catch (Throwable e)
{
+ if (e instanceof ArchivedIOException) throw e;
throw new ContentIOException("Failed to open stream onto channel: \n" +
" accessor: " + this,
e);