diff --git a/remote-api/src/main/java/org/alfresco/rest/api/ContentStorageInformation.java b/remote-api/src/main/java/org/alfresco/rest/api/ContentStorageInformation.java
new file mode 100644
index 0000000000..454dc8ea68
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/ContentStorageInformation.java
@@ -0,0 +1,51 @@
+/*
+ * #%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.api;
+
+import org.alfresco.rest.api.model.ContentStorageInfo;
+import org.alfresco.rest.framework.resource.parameters.Parameters;
+import org.alfresco.service.Experimental;
+
+/**
+ * Storage information for content API.
+ * Note: Currently marked as experimental and subject to change.
+ *
+ * @author mpichura
+ */
+@Experimental
+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
+ * @return {@link ContentStorageInfo} object consisting of qualified name of content property and a map of storage properties
+ */
+ @Experimental
+ ContentStorageInfo getStorageInfo(String nodeId, String contentPropName, Parameters parameters);
+}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/ContentStorageInformationImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/ContentStorageInformationImpl.java
new file mode 100644
index 0000000000..164b0927a4
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/ContentStorageInformationImpl.java
@@ -0,0 +1,83 @@
+/*
+ * #%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.api.impl;
+
+import org.alfresco.rest.api.ContentStorageInformation;
+import org.alfresco.rest.api.model.ContentStorageInfo;
+import org.alfresco.rest.framework.resource.parameters.Parameters;
+import org.alfresco.service.Experimental;
+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.alfresco.service.namespace.QName;
+
+import java.util.Map;
+/**
+ * Default implementation for {@link ContentStorageInformation}
+ * Note: Currently marked as experimental and subject to change.
+ *
+ * @author mpichura
+ */
+@Experimental
+public class ContentStorageInformationImpl implements ContentStorageInformation
+{
+
+ public static final char PREFIX_SEPARATOR = '_';
+
+ private final ContentService contentService;
+ private final NamespaceService namespaceService;
+
+ public ContentStorageInformationImpl(ContentService contentService, NamespaceService namespaceService)
+ {
+ this.contentService = contentService;
+ this.namespaceService = namespaceService;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @Experimental
+ public ContentStorageInfo getStorageInfo(String nodeId, String contentPropName, Parameters parameters)
+ {
+ final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
+ final QName propQName = getQName(contentPropName);
+ final Map storageProperties = contentService.getStorageProperties(nodeRef, propQName);
+ final ContentStorageInfo storageInfo = new ContentStorageInfo();
+ storageInfo.setId(propQName.toPrefixString(namespaceService));
+ storageInfo.setStorageProperties(storageProperties);
+ return storageInfo;
+ }
+
+ private QName getQName(final String contentPropName)
+ {
+ final String properContentPropName = contentPropName.replace(PREFIX_SEPARATOR, QName.NAMESPACE_PREFIX);
+ return QName.resolveToQName(namespaceService, properContentPropName);
+ }
+
+}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/ContentStorageInfo.java b/remote-api/src/main/java/org/alfresco/rest/api/model/ContentStorageInfo.java
new file mode 100644
index 0000000000..d5d3329990
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/ContentStorageInfo.java
@@ -0,0 +1,71 @@
+/*
+ * #%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.api.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Representation of storage information for content.
+ *
+ * @author mpichura
+ */
+public class ContentStorageInfo
+{
+
+ /**
+ * Qualified name of content property
+ */
+ private String id;
+ /**
+ * Key-value (String-String) collection representing storage properties of given content
+ */
+ private Map storageProperties;
+
+ public String getId()
+ {
+ return id;
+ }
+
+ public void setId(String id)
+ {
+ this.id = id;
+ }
+
+ public Map getStorageProperties()
+ {
+ if (storageProperties == null) {
+ storageProperties = new HashMap<>();
+ }
+ return storageProperties;
+ }
+
+ public void setStorageProperties(Map storageProperties)
+ {
+ this.storageProperties = storageProperties;
+ }
+}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeStorageInfoRelation.java b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeStorageInfoRelation.java
new file mode 100644
index 0000000000..78dca635f0
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/nodes/NodeStorageInfoRelation.java
@@ -0,0 +1,75 @@
+/*
+ * #%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.api.nodes;
+
+import org.alfresco.rest.api.ContentStorageInformation;
+import org.alfresco.rest.api.model.ContentStorageInfo;
+import org.alfresco.rest.framework.WebApiDescription;
+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.service.Experimental;
+import org.alfresco.util.PropertyCheck;
+import org.springframework.beans.factory.InitializingBean;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Node storage information.
+ * Note: Currently marked as experimental and subject to change.
+ *
+ * @author mpichura
+ */
+@Experimental
+@RelationshipResource(name = "storage-info", entityResource = NodesEntityResource.class, title = "Node's content storage information")
+public class NodeStorageInfoRelation implements RelationshipResourceAction.ReadById, InitializingBean
+{
+
+ private final ContentStorageInformation storageInformation;
+
+ public NodeStorageInfoRelation(ContentStorageInformation storageInformation)
+ {
+ this.storageInformation = storageInformation;
+ }
+
+ @WebApiDescription(title = "Get storage properties",
+ description = "Retrieves storage properties for given node's content",
+ successStatus = HttpServletResponse.SC_OK)
+ @Override
+ public ContentStorageInfo readById(String entityResourceId, String id, Parameters parameters)
+ throws RelationshipResourceNotFoundException
+ {
+ return storageInformation.getStorageInfo(entityResourceId, id, parameters);
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception
+ {
+ PropertyCheck.mandatory(this, "storageInformation", storageInformation);
+ }
+}
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 825eff0312..1c642a8323 100644
--- a/remote-api/src/main/resources/alfresco/public-rest-context.xml
+++ b/remote-api/src/main/resources/alfresco/public-rest-context.xml
@@ -606,6 +606,26 @@
+
+
+
+
+
+
+
+
+ org.alfresco.rest.api.ContentStorageInformation
+
+
+
+
+
+
+
+
+
+
+
@@ -977,7 +997,11 @@
-
+
+
+
+
+
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/impl/ContentStorageInformationImplTest.java b/remote-api/src/test/java/org/alfresco/rest/api/impl/ContentStorageInformationImplTest.java
new file mode 100644
index 0000000000..bddec6f0ca
--- /dev/null
+++ b/remote-api/src/test/java/org/alfresco/rest/api/impl/ContentStorageInformationImplTest.java
@@ -0,0 +1,96 @@
+/*
+ * #%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.api.impl;
+
+import org.alfresco.rest.api.model.ContentStorageInfo;
+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.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.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ContentStorageInformationImplTest
+{
+ @Mock
+ private ContentService contentService;
+ @Mock
+ private NamespaceService namespaceService;
+
+ @InjectMocks
+ private ContentStorageInformationImpl objectUnderTest;
+
+ @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 Map 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))
+ .thenReturn(List.of(NamespaceService.CONTENT_MODEL_PREFIX));
+
+ final ContentStorageInfo storageInfo = objectUnderTest.getStorageInfo(nodeId, contentPropName, null);
+
+ Assert.assertEquals(storageProps, storageInfo.getStorageProperties());
+ Assert.assertEquals(storageInfo.getId(), contentPropName);
+ }
+
+ @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";
+
+ 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))
+ .thenReturn(List.of(NamespaceService.CONTENT_MODEL_PREFIX));
+
+ final ContentStorageInfo storageInfo = objectUnderTest.getStorageInfo(nodeId, contentPropName, null);
+
+ Assert.assertEquals(Collections.emptyMap(), storageInfo.getStorageProperties());
+ Assert.assertEquals(storageInfo.getId(), contentPropName);
+ }
+}