ACS-2336 POST endpoints for archive/archive-restore content (#826)

* ACS-2200: Java API for archive/archive-restore content + unit tests.

* Bump restapi from 1.64 to 1.65 (#795)

* Bump utility from 3.0.45 to 3.0.47 (#794)

* ACS-2200: Applying review comments.

* ACS-2200: Applying review comments.

* ACS-2200: Adding new unit test to suite.

* ACS-2200: Adding optional archive params to archive operation.

* ACS-2236: Archive + archive-restore operations and unit tests.

* ACS-2236: Addressing review comments. Small refactor in unit tests.
This commit is contained in:
mpichura
2021-12-10 16:06:54 +01:00
committed by GitHub
parent 84f8481714
commit 0034f53b5f
9 changed files with 514 additions and 26 deletions

View File

@@ -26,7 +26,9 @@
package org.alfresco.rest.api;
import org.alfresco.rest.api.model.ArchiveContentRequest;
import org.alfresco.rest.api.model.ContentStorageInfo;
import org.alfresco.rest.api.model.RestoreArchivedContentRequest;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.service.Experimental;
@@ -41,6 +43,7 @@ public interface ContentStorageInformation
{
/**
* Note: Currently marked as experimental and subject to change.
*
* @param nodeId Identifier of the node
* @param contentPropName Qualified name of content property (e.g. 'cm_content')
* @param parameters {@link Parameters} object to get the parameters passed into the request
@@ -48,4 +51,27 @@ public interface ContentStorageInformation
*/
@Experimental
ContentStorageInfo getStorageInfo(String nodeId, String contentPropName, Parameters parameters);
/**
* Note: Currently marked as experimental and subject to change.
*
* @param nodeId Identifier of the node
* @param contentPropName Qualified name of content property (e.g. 'cm_content')
* @param archiveContentRequest {@link ArchiveContentRequest} object holding parameters for archive content request
* @return true when request successful, false when unsuccessful
*/
@Experimental
boolean requestArchiveContent(String nodeId, String contentPropName, ArchiveContentRequest archiveContentRequest);
/**
* Note: Currently marked as experimental and subject to change.
*
* @param nodeId Identifier of the node
* @param contentPropName Qualified name of content property (e.g. 'cm_content')
* @param restoreArchivedContentRequest {@link RestoreArchivedContentRequest} object holding parameters for restore from archive request
* @return true when request successful, false when unsuccessful
*/
@Experimental
boolean requestRestoreContentFromArchive(String nodeId, String contentPropName,
RestoreArchivedContentRequest restoreArchivedContentRequest);
}

View File

@@ -26,8 +26,11 @@
package org.alfresco.rest.api.impl;
import org.alfresco.repo.content.ContentRestoreParams;
import org.alfresco.rest.api.ContentStorageInformation;
import org.alfresco.rest.api.model.ArchiveContentRequest;
import org.alfresco.rest.api.model.ContentStorageInfo;
import org.alfresco.rest.api.model.RestoreArchivedContentRequest;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.service.Experimental;
import org.alfresco.service.cmr.repository.ContentService;
@@ -36,7 +39,10 @@ import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import java.io.Serializable;
import java.util.Collections;
import java.util.Map;
/**
* Default implementation for {@link ContentStorageInformation}
* Note: Currently marked as experimental and subject to change.
@@ -74,6 +80,33 @@ public class ContentStorageInformationImpl implements ContentStorageInformation
return storageInfo;
}
/**
* {@inheritDoc}
*/
@Override
public boolean requestArchiveContent(String nodeId, String contentPropName,
ArchiveContentRequest archiveContentRequest)
{
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
final QName propQName = getQName(contentPropName);
return contentService.requestSendContentToArchive(nodeRef, propQName, archiveContentRequest.getArchiveParams());
}
/**
* {@inheritDoc}
*/
@Override
public boolean requestRestoreContentFromArchive(String nodeId, String contentPropName,
RestoreArchivedContentRequest restoreArchivedContentRequest)
{
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
final QName propQName = getQName(contentPropName);
final Map<String, Serializable> restoreParams = restoreArchivedContentRequest.getRestorePriority() == null ?
Collections.emptyMap() :
Map.of(ContentRestoreParams.RESTORE_PRIORITY.name(), restoreArchivedContentRequest.getRestorePriority());
return contentService.requestRestoreContentFromArchive(nodeRef, propQName, restoreParams);
}
private QName getQName(final String contentPropName)
{
final String properContentPropName = contentPropName.replace(PREFIX_SEPARATOR, QName.NAMESPACE_PREFIX);

View File

@@ -0,0 +1,63 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.model;
import org.alfresco.service.Experimental;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* Request for content archive.
* Marked as experimental and subject to change.
*
* @author mpichura
*/
@Experimental
public class ArchiveContentRequest
{
/**
* A map (String-Serializable) of parameters specific for request to archive content.
* This object is optional.
*/
private Map<String, Serializable> archiveParams;
public Map<String, Serializable> getArchiveParams()
{
if (archiveParams == null)
{
archiveParams = new HashMap<>();
}
return archiveParams;
}
public void setArchiveParams(Map<String, Serializable> archiveParams)
{
this.archiveParams = archiveParams;
}
}

View File

@@ -0,0 +1,55 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.model;
import org.alfresco.service.Experimental;
/**
* Request for restore content from archive.
* Marked as experimental and subject to change.
*
* @author mpichura
*/
@Experimental
public class RestoreArchivedContentRequest
{
/**
* Restore priority. Possible values: Standard/High.
* This field is optional.
*/
private String restorePriority;
public String getRestorePriority()
{
return restorePriority;
}
public void setRestorePriority(String restorePriority)
{
this.restorePriority = restorePriority;
}
}

View File

@@ -27,12 +27,18 @@
package org.alfresco.rest.api.nodes;
import org.alfresco.rest.api.ContentStorageInformation;
import org.alfresco.rest.api.model.ArchiveContentRequest;
import org.alfresco.rest.api.model.ContentStorageInfo;
import org.alfresco.rest.api.model.RestoreArchivedContentRequest;
import org.alfresco.rest.framework.Operation;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.WebApiParam;
import org.alfresco.rest.framework.core.ResourceParameter;
import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException;
import org.alfresco.rest.framework.resource.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.framework.webscripts.WithResponse;
import org.alfresco.service.Experimental;
import org.alfresco.util.PropertyCheck;
import org.springframework.beans.factory.InitializingBean;
@@ -61,10 +67,10 @@ public class NodeStorageInfoRelation implements RelationshipResourceAction.ReadB
description = "Retrieves storage properties for given node's content",
successStatus = HttpServletResponse.SC_OK)
@Override
public ContentStorageInfo readById(String entityResourceId, String id, Parameters parameters)
public ContentStorageInfo readById(String nodeId, String contentPropName, Parameters parameters)
throws RelationshipResourceNotFoundException
{
return storageInformation.getStorageInfo(entityResourceId, id, parameters);
return storageInformation.getStorageInfo(nodeId, contentPropName, parameters);
}
@Override
@@ -72,4 +78,44 @@ public class NodeStorageInfoRelation implements RelationshipResourceAction.ReadB
{
PropertyCheck.mandatory(this, "storageInformation", storageInformation);
}
@Experimental
@Operation("archive")
@WebApiParam(name = "archiveContentRequest", title = "Request for archive content",
description = "Optional parameters for archive content", kind = ResourceParameter.KIND.HTTP_BODY_OBJECT)
@WebApiDescription(title = "Request send content to archive",
description = "Submits a request to send content to archive",
successStatus = HttpServletResponse.SC_OK)
public void requestArchiveContent(String nodeId, String contentPropName, ArchiveContentRequest archiveContentRequest, Parameters parameters,
WithResponse withResponse)
{
final boolean result = storageInformation.requestArchiveContent(nodeId, contentPropName, archiveContentRequest);
if (result)
{
withResponse.setStatus(HttpServletResponse.SC_OK);
} else
{
withResponse.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
}
}
@Experimental
@Operation("archive-restore")
@WebApiParam(name = "restoreArchivedContentRequest", title = "Request for restore content from archive",
description = "Optional parameters for restore content from archive", kind = ResourceParameter.KIND.HTTP_BODY_OBJECT)
@WebApiDescription(title = "Request restore content from archive",
description = "Submits a request to restore content from archive",
successStatus = HttpServletResponse.SC_ACCEPTED)
public void requestRestoreContentFromArchive(String nodeId, String contentPropName, RestoreArchivedContentRequest restoreArchivedContentRequest,
Parameters parameters, WithResponse withResponse)
{
final boolean result = storageInformation.requestRestoreContentFromArchive(nodeId, contentPropName, restoreArchivedContentRequest);
if (result)
{
withResponse.setStatus(HttpServletResponse.SC_ACCEPTED);
} else
{
withResponse.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
}
}
}

View File

@@ -47,6 +47,8 @@ import org.junit.runners.Suite;
org.alfresco.repo.webdav.RenameShuffleDetectionTest.class,
org.alfresco.repo.webdav.WebDAVHelperTest.class,
org.alfresco.repo.webdav.WebDAVLockServiceImplTest.class,
org.alfresco.rest.api.impl.ContentStorageInformationImplTest.class,
org.alfresco.rest.api.nodes.NodeStorageInfoRelationTest.class,
org.alfresco.rest.api.search.ResultMapperTests.class,
org.alfresco.rest.api.search.SearchApiWebscriptTests.class,
org.alfresco.rest.api.search.SearchMapperTests.class,

View File

@@ -26,26 +26,39 @@
package org.alfresco.rest.api.impl;
import org.alfresco.repo.content.ContentRestoreParams;
import org.alfresco.rest.api.model.ArchiveContentRequest;
import org.alfresco.rest.api.model.ContentStorageInfo;
import org.alfresco.rest.api.model.RestoreArchivedContentRequest;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.NamespaceService;
import org.junit.Assert;
import org.alfresco.service.namespace.QName;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class ContentStorageInformationImplTest
{
private static final String DUMMY_NODE_ID = "dummy-node-id";
private static final String CONTENT_PROP_NAME = "cm:content";
private static final String STANDARD_PRIORITY = "Standard";
@Mock
private ContentService contentService;
@Mock
@@ -57,40 +70,132 @@ public class ContentStorageInformationImplTest
@Test
public void shouldReturnStorageInfoResponseWithNonEmptyStorageProps()
{
final String nodeId = "dummy-node-id";
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
final String contentPropName = "cm:content";
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID);
final Map<String, String> storageProps = Map.of("x-amz-storage-class", "INTELLIGENT_TIERING", "x-alf-archived", "false");
Mockito.when(contentService.getStorageProperties(Mockito.eq(nodeRef), Mockito.any())).thenReturn(storageProps);
Mockito.when(namespaceService.getNamespaceURI(NamespaceService.CONTENT_MODEL_PREFIX))
.thenReturn(NamespaceService.CONTENT_MODEL_1_0_URI);
Mockito.when(namespaceService.getPrefixes(NamespaceService.CONTENT_MODEL_1_0_URI))
when(contentService.getStorageProperties(eq(nodeRef), any())).thenReturn(storageProps);
when(namespaceService.getNamespaceURI(NamespaceService.CONTENT_MODEL_PREFIX)).thenReturn(NamespaceService.CONTENT_MODEL_1_0_URI);
when(namespaceService.getPrefixes(NamespaceService.CONTENT_MODEL_1_0_URI))
.thenReturn(List.of(NamespaceService.CONTENT_MODEL_PREFIX));
final ContentStorageInfo storageInfo = objectUnderTest.getStorageInfo(nodeId, contentPropName, null);
final ContentStorageInfo storageInfo = objectUnderTest.getStorageInfo(DUMMY_NODE_ID, CONTENT_PROP_NAME, null);
Assert.assertEquals(storageProps, storageInfo.getStorageProperties());
Assert.assertEquals(storageInfo.getId(), contentPropName);
assertEquals(storageProps, storageInfo.getStorageProperties());
assertEquals(CONTENT_PROP_NAME, storageInfo.getId());
}
@Test
public void shouldReturnStorageInfoResponseWithEmptyStorageProps()
{
final String nodeId = "dummy-node-id";
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
final String contentPropName = "cm:content";
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID);
Mockito.when(contentService.getStorageProperties(Mockito.eq(nodeRef), Mockito.any())).thenCallRealMethod();
Mockito.when(namespaceService.getNamespaceURI(NamespaceService.CONTENT_MODEL_PREFIX))
.thenReturn(NamespaceService.CONTENT_MODEL_1_0_URI);
Mockito.when(namespaceService.getPrefixes(NamespaceService.CONTENT_MODEL_1_0_URI))
when(contentService.getStorageProperties(eq(nodeRef), any())).thenCallRealMethod();
when(namespaceService.getNamespaceURI(NamespaceService.CONTENT_MODEL_PREFIX)).thenReturn(NamespaceService.CONTENT_MODEL_1_0_URI);
when(namespaceService.getPrefixes(NamespaceService.CONTENT_MODEL_1_0_URI))
.thenReturn(List.of(NamespaceService.CONTENT_MODEL_PREFIX));
final ContentStorageInfo storageInfo = objectUnderTest.getStorageInfo(nodeId, contentPropName, null);
final ContentStorageInfo storageInfo = objectUnderTest.getStorageInfo(DUMMY_NODE_ID, CONTENT_PROP_NAME, null);
Assert.assertEquals(Collections.emptyMap(), storageInfo.getStorageProperties());
Assert.assertEquals(storageInfo.getId(), contentPropName);
assertEquals(Collections.emptyMap(), storageInfo.getStorageProperties());
assertEquals(CONTENT_PROP_NAME, storageInfo.getId());
}
@Test
public void shouldSucceedOnArchiveContent()
{
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID);
final Map<String, Serializable> archiveProps = Collections.emptyMap();
final ArchiveContentRequest archiveParamsRequest = new ArchiveContentRequest();
archiveParamsRequest.setArchiveParams(archiveProps);
final boolean expectedResult = true;
when(contentService.requestSendContentToArchive(eq(nodeRef), any(QName.class), eq(archiveProps))).thenReturn(expectedResult);
when(namespaceService.getNamespaceURI(NamespaceService.CONTENT_MODEL_PREFIX)).thenReturn(NamespaceService.CONTENT_MODEL_1_0_URI);
final boolean requestArchiveContent = objectUnderTest.requestArchiveContent(DUMMY_NODE_ID, CONTENT_PROP_NAME, archiveParamsRequest);
assertEquals(expectedResult, requestArchiveContent);
}
@Test
public void shouldNotSucceedOnArchiveContent()
{
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID);
final Map<String, Serializable> archiveProps = Collections.emptyMap();
final ArchiveContentRequest archiveParamsRequest = new ArchiveContentRequest();
archiveParamsRequest.setArchiveParams(archiveProps);
final boolean expectedResult = false;
when(contentService.requestSendContentToArchive(eq(nodeRef), any(QName.class), eq(archiveProps))).thenReturn(expectedResult);
when(namespaceService.getNamespaceURI(NamespaceService.CONTENT_MODEL_PREFIX)).thenReturn(NamespaceService.CONTENT_MODEL_1_0_URI);
final boolean requestArchiveContent = objectUnderTest.requestArchiveContent(DUMMY_NODE_ID, CONTENT_PROP_NAME, archiveParamsRequest);
assertEquals(expectedResult, requestArchiveContent);
}
@Test
public void shouldThrowExceptionOnArchiveContent()
{
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID);
final Map<String, Serializable> archiveProps = Collections.emptyMap();
final ArchiveContentRequest archiveParamsRequest = new ArchiveContentRequest();
archiveParamsRequest.setArchiveParams(archiveProps);
when(contentService.requestSendContentToArchive(eq(nodeRef), any(QName.class), eq(archiveProps))).thenCallRealMethod();
when(namespaceService.getNamespaceURI(NamespaceService.CONTENT_MODEL_PREFIX)).thenReturn(NamespaceService.CONTENT_MODEL_1_0_URI);
assertThrows(UnsupportedOperationException.class,
() -> objectUnderTest.requestArchiveContent(DUMMY_NODE_ID, CONTENT_PROP_NAME, archiveParamsRequest));
}
@Test
public void shouldSucceedOnRestoreContentFromArchive()
{
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID);
final Map<String, Serializable> restoreParams = Map.of(ContentRestoreParams.RESTORE_PRIORITY.name(), STANDARD_PRIORITY);
final RestoreArchivedContentRequest restoreArchivedContentRequest = new RestoreArchivedContentRequest();
restoreArchivedContentRequest.setRestorePriority(STANDARD_PRIORITY);
final boolean expectedResult = true;
when(contentService.requestRestoreContentFromArchive(eq(nodeRef), any(QName.class), eq(restoreParams))).thenReturn(expectedResult);
when(namespaceService.getNamespaceURI(NamespaceService.CONTENT_MODEL_PREFIX)).thenReturn(NamespaceService.CONTENT_MODEL_1_0_URI);
final boolean requestArchiveContent = objectUnderTest.requestRestoreContentFromArchive(DUMMY_NODE_ID, CONTENT_PROP_NAME, restoreArchivedContentRequest);
assertEquals(expectedResult, requestArchiveContent);
}
@Test
public void shouldNotSucceedOnRestoreContentFromArchive()
{
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID);
final Map<String, Serializable> restoreParams = Map.of(ContentRestoreParams.RESTORE_PRIORITY.name(), STANDARD_PRIORITY);
final RestoreArchivedContentRequest restoreArchivedContentRequest = new RestoreArchivedContentRequest();
restoreArchivedContentRequest.setRestorePriority(STANDARD_PRIORITY);
final boolean expectedResult = false;
when(contentService.requestRestoreContentFromArchive(eq(nodeRef), any(QName.class), eq(restoreParams))).thenReturn(expectedResult);
when(namespaceService.getNamespaceURI(NamespaceService.CONTENT_MODEL_PREFIX)).thenReturn(NamespaceService.CONTENT_MODEL_1_0_URI);
final boolean requestArchiveContent = objectUnderTest.requestRestoreContentFromArchive(DUMMY_NODE_ID, CONTENT_PROP_NAME, restoreArchivedContentRequest);
assertEquals(expectedResult, requestArchiveContent);
}
@Test
public void shouldThrowExceptionRestoreContentFromArchive()
{
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, DUMMY_NODE_ID);
final Map<String, Serializable> restoreParams = Map.of(ContentRestoreParams.RESTORE_PRIORITY.name(), STANDARD_PRIORITY);
final RestoreArchivedContentRequest restoreArchivedContentRequest = new RestoreArchivedContentRequest();
restoreArchivedContentRequest.setRestorePriority(STANDARD_PRIORITY);
final boolean expectedResult = false;
when(contentService.requestRestoreContentFromArchive(eq(nodeRef), any(QName.class), eq(restoreParams))).thenCallRealMethod();
when(namespaceService.getNamespaceURI(NamespaceService.CONTENT_MODEL_PREFIX)).thenReturn(NamespaceService.CONTENT_MODEL_1_0_URI);
assertThrows(UnsupportedOperationException.class,
() -> objectUnderTest.requestRestoreContentFromArchive(DUMMY_NODE_ID, CONTENT_PROP_NAME, restoreArchivedContentRequest));
}
}

View File

@@ -0,0 +1,158 @@
/*
* #%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 <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.api.nodes;
import junit.framework.TestCase;
import org.alfresco.rest.api.ContentStorageInformation;
import org.alfresco.rest.api.model.ArchiveContentRequest;
import org.alfresco.rest.api.model.ContentStorageInfo;
import org.alfresco.rest.api.model.RestoreArchivedContentRequest;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.framework.webscripts.WithResponse;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class NodeStorageInfoRelationTest extends TestCase
{
private static final String DUMMY_NODE_ID = "dummy-node-id";
private static final String CONTENT_PROP_NAME = "cm:content";
@Mock
private ContentStorageInformation storageInformation;
@Mock
private Parameters params;
@Mock
private WithResponse withResponse;
@InjectMocks
private NodeStorageInfoRelation objectUnderTest;
@Test
public void shouldProperlyReturnStorageInfo()
{
final ContentStorageInfo expectedStorageInfo = new ContentStorageInfo();
final Map<String, String> storageProps = Map.of("x-amz-storage-class", "INTELLIGENT_TIERING", "x-alf-archived", "false");
expectedStorageInfo.setStorageProperties(storageProps);
expectedStorageInfo.setId(CONTENT_PROP_NAME);
when(storageInformation.getStorageInfo(DUMMY_NODE_ID, CONTENT_PROP_NAME, params)).thenReturn(expectedStorageInfo);
final ContentStorageInfo storageInfo = objectUnderTest.readById(DUMMY_NODE_ID, CONTENT_PROP_NAME, params);
Assert.assertEquals(storageProps, storageInfo.getStorageProperties());
Assert.assertEquals(CONTENT_PROP_NAME, storageInfo.getId());
}
@Test
public void shouldProperlyRequestArchiveContent()
{
final ArchiveContentRequest archiveContentRequest = new ArchiveContentRequest();
when(storageInformation.requestArchiveContent(DUMMY_NODE_ID, CONTENT_PROP_NAME, archiveContentRequest)).thenReturn(true);
objectUnderTest.requestArchiveContent(DUMMY_NODE_ID, CONTENT_PROP_NAME, archiveContentRequest, params, withResponse);
verify(withResponse, times(1)).setStatus(HttpServletResponse.SC_OK);
}
@Test
public void shouldFailsOnRequestArchiveContent()
{
final ArchiveContentRequest archiveContentRequest = new ArchiveContentRequest();
when(storageInformation.requestArchiveContent(DUMMY_NODE_ID, CONTENT_PROP_NAME, archiveContentRequest)).thenReturn(false);
objectUnderTest.requestArchiveContent(DUMMY_NODE_ID, CONTENT_PROP_NAME, archiveContentRequest, params, withResponse);
verify(withResponse, times(1)).setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
}
@Test
public void shouldThrowExceptionOnRequestArchiveContent()
{
final ArchiveContentRequest archiveContentRequest = new ArchiveContentRequest();
when(storageInformation.requestArchiveContent(DUMMY_NODE_ID, CONTENT_PROP_NAME, archiveContentRequest))
.thenThrow(UnsupportedOperationException.class);
assertThrows(UnsupportedOperationException.class,
() -> objectUnderTest.requestArchiveContent(DUMMY_NODE_ID, CONTENT_PROP_NAME, archiveContentRequest, params, withResponse));
verify(withResponse, never()).setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
verify(withResponse, never()).setStatus(HttpServletResponse.SC_OK);
}
@Test
public void shouldProperlyRequestRestoreContentFromArchive()
{
final RestoreArchivedContentRequest restoreArchivedContentRequest = new RestoreArchivedContentRequest();
when(storageInformation.requestRestoreContentFromArchive(DUMMY_NODE_ID, CONTENT_PROP_NAME, restoreArchivedContentRequest))
.thenReturn(true);
objectUnderTest
.requestRestoreContentFromArchive(DUMMY_NODE_ID, CONTENT_PROP_NAME, restoreArchivedContentRequest, params, withResponse);
verify(withResponse, times(1)).setStatus(HttpServletResponse.SC_ACCEPTED);
}
@Test
public void shouldFailsOnRequestRestoreContentFromArchive()
{
final RestoreArchivedContentRequest restoreArchivedContentRequest = new RestoreArchivedContentRequest();
when(storageInformation.requestRestoreContentFromArchive(DUMMY_NODE_ID, CONTENT_PROP_NAME, restoreArchivedContentRequest))
.thenReturn(false);
objectUnderTest
.requestRestoreContentFromArchive(DUMMY_NODE_ID, CONTENT_PROP_NAME, restoreArchivedContentRequest, params, withResponse);
verify(withResponse, times(1)).setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
}
@Test
public void shouldThrowExceptionOnRequestRestoreContentFromArchive()
{
final RestoreArchivedContentRequest restoreArchivedContentRequest = new RestoreArchivedContentRequest();
when(storageInformation.requestRestoreContentFromArchive(DUMMY_NODE_ID, CONTENT_PROP_NAME, restoreArchivedContentRequest))
.thenThrow(UnsupportedOperationException.class);
assertThrows(UnsupportedOperationException.class, () -> objectUnderTest
.requestRestoreContentFromArchive(DUMMY_NODE_ID, CONTENT_PROP_NAME, restoreArchivedContentRequest, params, withResponse));
verify(withResponse, never()).setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
verify(withResponse, never()).setStatus(HttpServletResponse.SC_ACCEPTED);
}
}

View File

@@ -278,7 +278,7 @@ public interface ContentService
* @return true when request successful, false when unsuccessful.
* @throws UnsupportedOperationException when method not implemented
*/
@Auditable(parameters = {"nodeRef", "propertyQName"})
@Auditable(parameters = {"nodeRef", "propertyQName", "archiveParams"})
@Experimental
default boolean requestSendContentToArchive(NodeRef nodeRef, QName propertyQName,
Map<String, Serializable> archiveParams)