From f757a02c40eec4419e2c3cc56fd837d30c0fc06c Mon Sep 17 00:00:00 2001
From: pkupczyk <pkupczyk>
Date: Thu, 26 May 2016 07:32:43 +0000
Subject: [PATCH] SSDM-3686 : V3 AS API - archiveDataSets/unarchiveDataSets
 methods

SVN: 36583
---
 .../AbstractArchiveUnarchiveDataSetTest.java  | 107 ++++++++++++++++++
 .../systemtest/api/v3/AbstractFileTest.java   |  15 ++-
 .../systemtest/api/v3/ArchiveDataSetTest.java |  89 +++++++++++++++
 .../systemtest/api/v3/DownloadFileTest.java   |  16 ++-
 .../dss/systemtest/api/v3/SearchFileTest.java |  10 ++
 .../api/v3/UnarchiveDataSetTest.java          |  77 +++++++++++++
 .../systemtests/SystemTestCase.java           |   7 +-
 .../server/asapi/v3/ApplicationServerApi.java |  28 +++++
 .../asapi/v3/ApplicationServerApiLogger.java  |  14 +++
 ...stractArchiveUnarchiveDataSetExecutor.java |  98 ++++++++++++++++
 .../dataset/ArchiveDataSetExecutor.java       |  48 ++++++++
 .../dataset/IArchiveDataSetExecutor.java      |  33 ++++++
 .../dataset/IUnarchiveDataSetExecutor.java    |  33 ++++++
 .../dataset/UnarchiveDataSetExecutor.java     |  48 ++++++++
 .../method/ArchiveDataSetMethodExecutor.java  |  53 +++++++++
 .../method/IArchiveDataSetMethodExecutor.java |  32 ++++++
 .../IUnarchiveDataSetMethodExecutor.java      |  32 ++++++
 .../UnarchiveDataSetMethodExecutor.java       |  53 +++++++++
 .../dataset/archive/DataSetArchiveOptions.js  |  19 ++++
 .../unarchive/DataSetUnarchiveOptions.js      |  12 ++
 .../asapi/v3/IApplicationServerApi.java       |   6 +
 .../archive/DataSetArchiveOptions.java        |  44 +++++++
 .../unarchive/DataSetUnarchiveOptions.java    |  32 ++++++
 .../generic/sharedapi/v3/dictionary.txt       |   8 +-
 24 files changed, 907 insertions(+), 7 deletions(-)
 create mode 100644 datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/AbstractArchiveUnarchiveDataSetTest.java
 create mode 100644 datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/ArchiveDataSetTest.java
 create mode 100644 datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UnarchiveDataSetTest.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/AbstractArchiveUnarchiveDataSetExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ArchiveDataSetExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/IArchiveDataSetExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/IUnarchiveDataSetExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/UnarchiveDataSetExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/ArchiveDataSetMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/IArchiveDataSetMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/IUnarchiveDataSetMethodExecutor.java
 create mode 100644 openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/UnarchiveDataSetMethodExecutor.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/dataset/archive/DataSetArchiveOptions.js
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/dataset/unarchive/DataSetUnarchiveOptions.js
 create mode 100644 openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/archive/DataSetArchiveOptions.java
 create mode 100644 openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/unarchive/DataSetUnarchiveOptions.java

diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/AbstractArchiveUnarchiveDataSetTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/AbstractArchiveUnarchiveDataSetTest.java
new file mode 100644
index 00000000000..76474f912ce
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/AbstractArchiveUnarchiveDataSetTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 ch.ethz.sis.openbis.generic.dss.systemtest.api.v3;
+
+import java.util.Arrays;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.testng.annotations.BeforeClass;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.ArchivingStatus;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetFetchOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.DataSetPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+import ch.systemsx.cisd.common.logging.LogCategory;
+import ch.systemsx.cisd.common.logging.LogFactory;
+import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
+
+/**
+ * @author pkupczyk
+ */
+public class AbstractArchiveUnarchiveDataSetTest extends AbstractFileTest
+{
+
+    private final Logger log = LogFactory.getLogger(LogCategory.OPERATION, getClass());
+
+    protected IApplicationServerApi v3;
+
+    @Override
+    @BeforeClass
+    public void beforeClass() throws Exception
+    {
+        super.beforeClass();
+        v3 = ServiceProvider.getV3ApplicationService();
+    }
+
+    protected void waitUntilDataSetStatus(String dataSetCodeToBeFound, ArchivingStatus expectedStatus)
+    {
+        final long timeoutMillis = 120 * 1000;
+        final long finishMillis = System.currentTimeMillis() + timeoutMillis;
+        final long intervalMillis = 100;
+
+        String sessionToken = v3.login(TEST_USER, PASSWORD);
+
+        DataSetPermId dataSetId = new DataSetPermId(dataSetCodeToBeFound);
+        DataSetFetchOptions fetchOptions = new DataSetFetchOptions();
+        fetchOptions.withPhysicalData();
+
+        ArchivingStatus actualStatus = null;
+
+        while (System.currentTimeMillis() < finishMillis)
+        {
+            Map<IDataSetId, DataSet> dataSets = v3.getDataSets(sessionToken, Arrays.asList(dataSetId), fetchOptions);
+            DataSet dataSet = dataSets.get(dataSetId);
+
+            if (dataSet == null)
+            {
+                fail("Data set '" + dataSetCodeToBeFound + "' was not found.");
+            } else
+            {
+                actualStatus = dataSet.getPhysicalData().getStatus();
+
+                if (expectedStatus.equals(actualStatus))
+                {
+                    log.info("Waiting for data set '" + dataSetCodeToBeFound + "' to have archiving status " + expectedStatus
+                            + ". Current archiving status is " + actualStatus);
+                    return;
+                } else
+                {
+                    log.info("Stopped waiting. Dataset '" + dataSetCodeToBeFound + "' has reached the expected archiving status " + expectedStatus);
+                    try
+                    {
+                        Thread.sleep(intervalMillis);
+                    } catch (InterruptedException e)
+                    {
+
+                    }
+                }
+            }
+        }
+
+        throw new RuntimeException(
+                "Waited for data set '" + dataSetCodeToBeFound + "' to have archiving status '" + expectedStatus + "'. Timed out after "
+                        + (timeoutMillis / 1000) + " second(s). Last status was " + actualStatus);
+    }
+
+    protected void assertDataSetStatus(String dataSetCodeToBeFound, ArchivingStatus expectedStatus)
+    {
+    }
+
+}
diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/AbstractFileTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/AbstractFileTest.java
index be6ca44cfcc..901089d5633 100644
--- a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/AbstractFileTest.java
+++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/AbstractFileTest.java
@@ -22,12 +22,16 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService
 public class AbstractFileTest extends SystemTestCase
 {
 
+    public static final String TEST_USER = "test";
+    
+    public static final String TEST_SPACE_USER = "test_space";
+
+    public static final String PASSWORD = "password";
+
     protected IGeneralInformationService gis;
 
     protected IDataStoreServerApi dss;
 
-    protected String sessionToken;
-
     protected String dataSetCode;
 
     protected Set<String> directories;
@@ -53,9 +57,10 @@ public class AbstractFileTest extends SystemTestCase
     {
         gis = ServiceProvider.getGeneralInformationService();
         dss = (IDataStoreServerApi) ServiceProvider.getDssServiceV3().getService();
+    }
 
-        sessionToken = gis.tryToAuthenticateForAllServices("test", "test");
-
+    protected String registerDataSet() throws Exception
+    {
         dataSetCode = UUID.randomUUID().toString().toUpperCase();
 
         File dataSetDir = new File(workingDirectory, dataSetCode);
@@ -76,6 +81,8 @@ public class AbstractFileTest extends SystemTestCase
         waitUntilDataSetImported();
         waitUntilIndexUpdaterIsIdle();
         waitUntilDataSetPostRegistrationCompleted(dataSetCode);
+
+        return dataSetCode;
     }
 
     private void createDirectories(File dataSetDir, @SuppressWarnings("hiding") Set<String> directories)
diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/ArchiveDataSetTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/ArchiveDataSetTest.java
new file mode 100644
index 00000000000..c8affc5ae60
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/ArchiveDataSetTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 ch.ethz.sis.openbis.generic.dss.systemtest.api.v3;
+
+import java.util.Arrays;
+
+import org.testng.annotations.Test;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.ArchivingStatus;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.archive.DataSetArchiveOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.DataSetPermId;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+
+/**
+ * @author pkupczyk
+ */
+public class ArchiveDataSetTest extends AbstractArchiveUnarchiveDataSetTest
+{
+
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = ".*Object with DataSetPermId = \\[IDONTEXIST\\] has not been found.*")
+    public void testArchiveWithNonexistentDataSet() throws Exception
+    {
+        DataSetPermId dataSetId = new DataSetPermId("IDONTEXIST");
+        DataSetArchiveOptions options = new DataSetArchiveOptions();
+
+        String sessionToken = v3.login(TEST_USER, PASSWORD);
+        v3.archiveDataSets(sessionToken, Arrays.asList(dataSetId), options);
+    }
+
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = ".*Access denied to object with DataSetPermId.*")
+    public void testArchiveWithUnauthorizedDataSet() throws Exception
+    {
+        registerDataSet();
+
+        DataSetPermId dataSetId = new DataSetPermId(dataSetCode);
+        DataSetArchiveOptions options = new DataSetArchiveOptions();
+
+        String sessionToken = v3.login(TEST_SPACE_USER, PASSWORD);
+        v3.archiveDataSets(sessionToken, Arrays.asList(dataSetId), options);
+    }
+
+    @Test
+    public void testArchiveWithRemoveFromStoreTrue() throws Exception
+    {
+        String sessionToken = v3.login(TEST_USER, PASSWORD);
+
+        registerDataSet();
+
+        DataSetPermId dataSetId = new DataSetPermId(dataSetCode);
+        DataSetArchiveOptions options = new DataSetArchiveOptions();
+
+        waitUntilDataSetStatus(dataSetCode, ArchivingStatus.AVAILABLE);
+        v3.archiveDataSets(sessionToken, Arrays.asList(dataSetId), options);
+        waitUntilDataSetStatus(dataSetCode, ArchivingStatus.ARCHIVE_PENDING);
+        waitUntilDataSetStatus(dataSetCode, ArchivingStatus.ARCHIVED);
+    }
+
+    @Test
+    public void testArchiveWithRemoveFromStoreFalse() throws Exception
+    {
+        String sessionToken = v3.login(TEST_USER, PASSWORD);
+
+        registerDataSet();
+
+        DataSetPermId dataSetId = new DataSetPermId(dataSetCode);
+        DataSetArchiveOptions options = new DataSetArchiveOptions();
+        options.setRemoveFromDataStore(false);
+
+        waitUntilDataSetStatus(dataSetCode, ArchivingStatus.AVAILABLE);
+        v3.archiveDataSets(sessionToken, Arrays.asList(dataSetId), options);
+        waitUntilDataSetStatus(dataSetCode, ArchivingStatus.BACKUP_PENDING);
+        waitUntilDataSetStatus(dataSetCode, ArchivingStatus.AVAILABLE);
+    }
+
+}
diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/DownloadFileTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/DownloadFileTest.java
index 844d018ae2e..ea36db8594f 100644
--- a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/DownloadFileTest.java
+++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/DownloadFileTest.java
@@ -7,6 +7,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.io.IOUtils;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.DataSetPermId;
@@ -19,10 +20,18 @@ import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.id.IDataSetFileId;
 public class DownloadFileTest extends AbstractFileTest
 {
 
+    @Override
+    @BeforeClass
+    protected void beforeClass() throws Exception
+    {
+        super.beforeClass();
+        registerDataSet();
+    }
+
     @Test
     public void testDownloadUnauthorized()
     {
-        String spaceSessionToken = gis.tryToAuthenticateForAllServices("test_space", "password");
+        String spaceSessionToken = gis.tryToAuthenticateForAllServices(TEST_SPACE_USER, PASSWORD);
 
         InputStream stream = dss.downloadFiles(spaceSessionToken, Arrays.asList(new DataSetFilePermId(new DataSetPermId(dataSetCode))),
                 new DataSetFileDownloadOptions());
@@ -95,6 +104,7 @@ public class DownloadFileTest extends AbstractFileTest
         IDataSetFileId file2 = new DataSetFilePermId(new DataSetPermId(dataSetCode), getPath("file2.txt"));
         DataSetFileDownloadOptions options = new DataSetFileDownloadOptions();
 
+        String sessionToken = gis.tryToAuthenticateForAllServices(TEST_USER, PASSWORD);
         InputStream stream = dss.downloadFiles(sessionToken, Arrays.asList(file1, file2), options);
         DataSetFileDownloadReader reader = new DataSetFileDownloadReader(stream);
 
@@ -113,6 +123,7 @@ public class DownloadFileTest extends AbstractFileTest
 
         DataSetFileDownloadOptions options = new DataSetFileDownloadOptions();
 
+        String sessionToken = gis.tryToAuthenticateForAllServices(TEST_USER, PASSWORD);
         InputStream stream = dss.downloadFiles(sessionToken, Arrays.asList(file1, file2, file3), options);
         DataSetFileDownloadReader reader = new DataSetFileDownloadReader(stream);
 
@@ -131,6 +142,7 @@ public class DownloadFileTest extends AbstractFileTest
 
         DataSetFileDownloadOptions options = new DataSetFileDownloadOptions();
 
+        String sessionToken = gis.tryToAuthenticateForAllServices(TEST_USER, PASSWORD);
         InputStream stream = dss.downloadFiles(sessionToken, Arrays.asList(file1, file2), options);
         DataSetFileDownloadReader reader = new DataSetFileDownloadReader(stream);
 
@@ -145,6 +157,8 @@ public class DownloadFileTest extends AbstractFileTest
     {
         try
         {
+            String sessionToken = gis.tryToAuthenticateForAllServices(TEST_USER, PASSWORD);
+
             InputStream stream = dss.downloadFiles(sessionToken, files, options);
             DataSetFileDownloadReader reader = new DataSetFileDownloadReader(stream);
 
diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/SearchFileTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/SearchFileTest.java
index 7ccd6982ca5..6db5c47d487 100644
--- a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/SearchFileTest.java
+++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/SearchFileTest.java
@@ -5,6 +5,7 @@ import static org.hamcrest.Matchers.is;
 
 import java.util.List;
 
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult;
@@ -15,12 +16,21 @@ import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.search.DataSetFileS
 public class SearchFileTest extends AbstractFileTest
 {
 
+    @Override
+    @BeforeClass
+    protected void beforeClass() throws Exception
+    {
+        super.beforeClass();
+        registerDataSet();
+    }
+
     @Test
     public void allFilesOfGivenDatasetsAreReturned() throws Exception
     {
         DataSetFileSearchCriteria sc = new DataSetFileSearchCriteria();
         sc.withDataSet().withPermId().thatEquals(dataSetCode);
 
+        String sessionToken = gis.tryToAuthenticateForAllServices(TEST_USER, PASSWORD);
         SearchResult<DataSetFile> searchResult = dss.searchFiles(sessionToken, sc, new DataSetFileFetchOptions());
         List<DataSetFile> searchFiles = searchResult.getObjects();
 
diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UnarchiveDataSetTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UnarchiveDataSetTest.java
new file mode 100644
index 00000000000..1827c872fc2
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UnarchiveDataSetTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 ch.ethz.sis.openbis.generic.dss.systemtest.api.v3;
+
+import java.util.Arrays;
+
+import org.testng.annotations.Test;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.ArchivingStatus;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.archive.DataSetArchiveOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.DataSetPermId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.unarchive.DataSetUnarchiveOptions;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+
+/**
+ * @author pkupczyk
+ */
+public class UnarchiveDataSetTest extends AbstractArchiveUnarchiveDataSetTest
+{
+
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = ".*Object with DataSetPermId = \\[IDONTEXIST\\] has not been found.*")
+    public void testUnarchiveWithNonexistentDataSet() throws Exception
+    {
+        DataSetPermId dataSetId = new DataSetPermId("IDONTEXIST");
+        DataSetUnarchiveOptions options = new DataSetUnarchiveOptions();
+
+        String sessionToken = v3.login(TEST_USER, PASSWORD);
+        v3.unarchiveDataSets(sessionToken, Arrays.asList(dataSetId), options);
+    }
+
+    @Test(expectedExceptions = UserFailureException.class, expectedExceptionsMessageRegExp = ".*Access denied to object with DataSetPermId.*")
+    public void testUnarchiveWithUnauthorizedDataSet() throws Exception
+    {
+        registerDataSet();
+
+        DataSetPermId dataSetId = new DataSetPermId(dataSetCode);
+        DataSetUnarchiveOptions options = new DataSetUnarchiveOptions();
+
+        String sessionToken = v3.login(TEST_SPACE_USER, PASSWORD);
+        v3.unarchiveDataSets(sessionToken, Arrays.asList(dataSetId), options);
+    }
+
+    @Test
+    public void testUnarchive() throws Exception
+    {
+        registerDataSet();
+
+        DataSetPermId dataSetId = new DataSetPermId(dataSetCode);
+        DataSetArchiveOptions archiveOptions = new DataSetArchiveOptions();
+        DataSetUnarchiveOptions unarchiveOptions = new DataSetUnarchiveOptions();
+
+        String sessionToken = v3.login(TEST_USER, PASSWORD);
+
+        waitUntilDataSetStatus(dataSetCode, ArchivingStatus.AVAILABLE);
+        v3.archiveDataSets(sessionToken, Arrays.asList(dataSetId), archiveOptions);
+        waitUntilDataSetStatus(dataSetCode, ArchivingStatus.ARCHIVE_PENDING);
+        waitUntilDataSetStatus(dataSetCode, ArchivingStatus.ARCHIVED);
+        v3.unarchiveDataSets(sessionToken, Arrays.asList(dataSetId), unarchiveOptions);
+        waitUntilDataSetStatus(dataSetCode, ArchivingStatus.UNARCHIVE_PENDING);
+        waitUntilDataSetStatus(dataSetCode, ArchivingStatus.AVAILABLE);
+    }
+
+}
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/SystemTestCase.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/SystemTestCase.java
index b1c265aec97..23b247f4ebd 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/SystemTestCase.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/SystemTestCase.java
@@ -106,6 +106,8 @@ public abstract class SystemTestCase extends AssertJUnit
 
     protected File store;
 
+    protected File archive;
+
     protected BufferedAppender logAppender;
 
     static
@@ -118,6 +120,8 @@ public abstract class SystemTestCase extends AssertJUnit
         rootDir = new File(workingDirectory, "dss-root");
         store = new File(rootDir, "store");
         store.mkdirs();
+        archive = new File(rootDir, "archive");
+        archive.mkdirs();
     }
 
     private static void createWorkingDirectory()
@@ -201,7 +205,7 @@ public abstract class SystemTestCase extends AssertJUnit
                 rootDir.getAbsolutePath());
         System.setProperty(OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX
                 + DssPropertyParametersUtil.DSS_REGISTRATION_LOG_DIR_PATH, getRegistrationLogDir()
-                .getAbsolutePath());
+                        .getAbsolutePath());
         System.setProperty(OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX + "dss-rpc.put-default", "test");
         System.setProperty(OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX + SERVER_URL_KEY,
                 TestInstanceHostUtils.getOpenBISUrl());
@@ -212,6 +216,7 @@ public abstract class SystemTestCase extends AssertJUnit
         System.setProperty(SERVER_URL_KEY, TestInstanceHostUtils.getOpenBISUrl());
         System.setProperty("port", Integer.toString(TestInstanceHostUtils.getDSSPort()));
         System.setProperty(DOWNLOAD_URL_KEY, TestInstanceHostUtils.getDSSUrl());
+        System.setProperty(OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX + "archiver.destination", archive.getAbsolutePath());
 
         QueueingPathRemoverService.start(rootDir, ETLDaemon.shredderQueueFile);
         DataStoreServer.main(new String[0]);
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java
index 0b61ec9b0af..77cc6c316d8 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApi.java
@@ -27,6 +27,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetType;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.archive.DataSetArchiveOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.create.DataSetCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.delete.DataSetDeletionOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetFetchOptions;
@@ -35,6 +36,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.DataSetPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.DataSetSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.DataSetTypeSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.unarchive.DataSetUnarchiveOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.update.DataSetUpdate;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.deletion.Deletion;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.deletion.fetchoptions.DeletionFetchOptions;
@@ -116,6 +118,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.IVocabularyTermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id.VocabularyTermPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.search.VocabularyTermSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.update.VocabularyTermUpdate;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.IArchiveDataSetMethodExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.IConfirmDeletionMethodExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.ICreateDataSetMethodExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.ICreateExperimentMethodExecutor;
@@ -159,6 +162,7 @@ import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.ISearchSample
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.ISearchSpaceMethodExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.ISearchTagMethodExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.ISearchVocabularyTermMethodExecutor;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.IUnarchiveDataSetMethodExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.IUpdateDataSetMethodExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.IUpdateExperimentMethodExecutor;
 import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method.IUpdateMaterialMethodExecutor;
@@ -348,6 +352,12 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
     @Autowired
     private IGlobalSearchMethodExecutor globalSearchExecutor;
 
+    @Autowired
+    private IArchiveDataSetMethodExecutor archiveDataSetExecutor;
+
+    @Autowired
+    private IUnarchiveDataSetMethodExecutor unarchiveDataSetExecutor;
+
     // Default constructor needed by Spring
     public ApplicationServerApi()
     {
@@ -864,6 +874,24 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi>
         return globalSearchExecutor.search(sessionToken, searchCriteria, fetchOptions);
     }
 
+    @Override
+    @Transactional
+    @RolesAllowed({ RoleWithHierarchy.SPACE_POWER_USER, RoleWithHierarchy.SPACE_ETL_SERVER })
+    @Capability("ARCHIVE_DATASET")
+    public void archiveDataSets(String sessionToken, List<? extends IDataSetId> dataSetIds, DataSetArchiveOptions options)
+    {
+        archiveDataSetExecutor.archive(sessionToken, dataSetIds, options);
+    }
+
+    @Override
+    @Transactional
+    @RolesAllowed({ RoleWithHierarchy.SPACE_USER, RoleWithHierarchy.SPACE_ETL_SERVER })
+    @Capability("UNARCHIVE_DATASET")
+    public void unarchiveDataSets(String sessionToken, List<? extends IDataSetId> dataSetIds, DataSetUnarchiveOptions options)
+    {
+        unarchiveDataSetExecutor.unarchive(sessionToken, dataSetIds, options);
+    }
+
     @Override
     public IApplicationServerApi createLogger(IInvocationLoggerContext context)
     {
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java
index 5a1596ae4a8..aba10d2a215 100644
--- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/ApplicationServerApiLogger.java
@@ -23,6 +23,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetType;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.archive.DataSetArchiveOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.create.DataSetCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.delete.DataSetDeletionOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetFetchOptions;
@@ -31,6 +32,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.DataSetPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.DataSetSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.DataSetTypeSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.unarchive.DataSetUnarchiveOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.update.DataSetUpdate;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.deletion.Deletion;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.deletion.fetchoptions.DeletionFetchOptions;
@@ -513,4 +515,16 @@ public class ApplicationServerApiLogger extends AbstractServerLogger implements
         return null;
     }
 
+    @Override
+    public void archiveDataSets(String sessionToken, List<? extends IDataSetId> dataSetIds, DataSetArchiveOptions options)
+    {
+        logAccess(sessionToken, "archive-data-sets", "DATA_SET_IDS(%s) ARCHIVE_OPTIONS(%s)", abbreviate(dataSetIds), options);
+    }
+
+    @Override
+    public void unarchiveDataSets(String sessionToken, List<? extends IDataSetId> dataSetIds, DataSetUnarchiveOptions options)
+    {
+        logAccess(sessionToken, "unarchive-data-sets", "DATA_SET_IDS(%s) UNARCHIVE_OPTIONS(%s)", abbreviate(dataSetIds), options);
+    }
+
 }
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/AbstractArchiveUnarchiveDataSetExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/AbstractArchiveUnarchiveDataSetExecutor.java
new file mode 100644
index 00000000000..5ac5efb0b9b
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/AbstractArchiveUnarchiveDataSetExecutor.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 ch.ethz.sis.openbis.generic.server.asapi.v3.executor.dataset;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Resource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+import ch.ethz.sis.openbis.generic.asapi.v3.exceptions.ObjectNotFoundException;
+import ch.ethz.sis.openbis.generic.asapi.v3.exceptions.UnauthorizedObjectAccessException;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.systemsx.cisd.openbis.generic.server.ComponentNames;
+import ch.systemsx.cisd.openbis.generic.server.authorization.validator.DataSetPEByExperimentOrSampleIdentifierValidator;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.ICommonBusinessObjectFactory;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.IDataSetTable;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
+
+/**
+ * @author pkupczyk
+ */
+public class AbstractArchiveUnarchiveDataSetExecutor
+{
+
+    @Autowired
+    protected IMapDataSetByIdExecutor mapDataSetByIdExecutor;
+
+    @Resource(name = ComponentNames.COMMON_BUSINESS_OBJECT_FACTORY)
+    protected ICommonBusinessObjectFactory businessObjectFactory;
+
+    protected void doArchiveUnarchive(IOperationContext context, List<? extends IDataSetId> dataSetIds, Object options,
+            IArchiveUnarchiveAction action)
+    {
+        if (context == null)
+        {
+            throw new IllegalArgumentException("Context cannot be null");
+        }
+        if (dataSetIds == null)
+        {
+            throw new IllegalArgumentException("Data set ids cannot be null");
+        }
+        if (options == null)
+        {
+            throw new IllegalArgumentException("Options cannot be null");
+        }
+
+        Map<IDataSetId, DataPE> dataSetMap = mapDataSetByIdExecutor.map(context, dataSetIds);
+        Set<String> dataSetCodes = new HashSet<String>();
+
+        for (IDataSetId dataSetId : dataSetIds)
+        {
+            DataPE dataSet = dataSetMap.get(dataSetId);
+            if (dataSet == null)
+            {
+                throw new ObjectNotFoundException(dataSetId);
+            } else if (false == dataSetCodes.contains(dataSet.getCode()))
+            {
+                if (false == new DataSetPEByExperimentOrSampleIdentifierValidator().doValidation(context.getSession().tryGetPerson(), dataSet))
+                {
+                    throw new UnauthorizedObjectAccessException(dataSetId);
+                }
+                dataSetCodes.add(dataSet.getCode());
+            }
+        }
+
+        IDataSetTable dataSetTable = businessObjectFactory.createDataSetTable(context.getSession());
+        dataSetTable.loadByDataSetCodes(new ArrayList<String>(dataSetCodes), false, true);
+        action.execute(dataSetTable);
+    }
+
+    public static interface IArchiveUnarchiveAction
+    {
+
+        public void execute(IDataSetTable dataSetTable);
+
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ArchiveDataSetExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ArchiveDataSetExecutor.java
new file mode 100644
index 00000000000..91194d5b6a8
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/ArchiveDataSetExecutor.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 ch.ethz.sis.openbis.generic.server.asapi.v3.executor.dataset;
+
+import java.util.List;
+
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.archive.DataSetArchiveOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.IDataSetTable;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class ArchiveDataSetExecutor extends AbstractArchiveUnarchiveDataSetExecutor implements IArchiveDataSetExecutor
+{
+
+    @Override
+    public void archive(final IOperationContext context, final List<? extends IDataSetId> dataSetIds, final DataSetArchiveOptions options)
+    {
+        doArchiveUnarchive(context, dataSetIds, options, new IArchiveUnarchiveAction()
+            {
+                @Override
+                public void execute(IDataSetTable dataSetTable)
+                {
+                    dataSetTable.archiveDatasets(options.isRemoveFromDataStore());
+                }
+            });
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/IArchiveDataSetExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/IArchiveDataSetExecutor.java
new file mode 100644
index 00000000000..ce4ce472683
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/IArchiveDataSetExecutor.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 ch.ethz.sis.openbis.generic.server.asapi.v3.executor.dataset;
+
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.archive.DataSetArchiveOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+
+/**
+ * @author pkupczyk
+ */
+public interface IArchiveDataSetExecutor
+{
+
+    public void archive(IOperationContext context, List<? extends IDataSetId> dataSetIds, DataSetArchiveOptions options);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/IUnarchiveDataSetExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/IUnarchiveDataSetExecutor.java
new file mode 100644
index 00000000000..ccf00b02bd2
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/IUnarchiveDataSetExecutor.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 ch.ethz.sis.openbis.generic.server.asapi.v3.executor.dataset;
+
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.unarchive.DataSetUnarchiveOptions;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+
+/**
+ * @author pkupczyk
+ */
+public interface IUnarchiveDataSetExecutor
+{
+
+    public void unarchive(IOperationContext context, List<? extends IDataSetId> dataSetIds, DataSetUnarchiveOptions options);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/UnarchiveDataSetExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/UnarchiveDataSetExecutor.java
new file mode 100644
index 00000000000..f89365ee50e
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/dataset/UnarchiveDataSetExecutor.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 ch.ethz.sis.openbis.generic.server.asapi.v3.executor.dataset;
+
+import java.util.List;
+
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.unarchive.DataSetUnarchiveOptions;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.IDataSetTable;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class UnarchiveDataSetExecutor extends AbstractArchiveUnarchiveDataSetExecutor implements IUnarchiveDataSetExecutor
+{
+
+    @Override
+    public void unarchive(final IOperationContext context, final List<? extends IDataSetId> dataSetIds, final DataSetUnarchiveOptions options)
+    {
+        doArchiveUnarchive(context, dataSetIds, options, new IArchiveUnarchiveAction()
+            {
+                @Override
+                public void execute(IDataSetTable dataSetTable)
+                {
+                    dataSetTable.unarchiveDatasets();
+                }
+            });
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/ArchiveDataSetMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/ArchiveDataSetMethodExecutor.java
new file mode 100644
index 00000000000..21191f509af
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/ArchiveDataSetMethodExecutor.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.archive.DataSetArchiveOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.dataset.IArchiveDataSetExecutor;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class ArchiveDataSetMethodExecutor extends AbstractMethodExecutor implements IArchiveDataSetMethodExecutor
+{
+
+    @Autowired
+    private IArchiveDataSetExecutor executor;
+
+    @Override
+    public void archive(String sessionToken, final List<? extends IDataSetId> dataSetIds, final DataSetArchiveOptions options)
+    {
+        executeInContext(sessionToken, new IMethodAction<Void>()
+            {
+                @Override
+                public Void execute(IOperationContext context)
+                {
+                    executor.archive(context, dataSetIds, options);
+                    return null;
+                }
+            });
+    }
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/IArchiveDataSetMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/IArchiveDataSetMethodExecutor.java
new file mode 100644
index 00000000000..c4f6c9d6bdf
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/IArchiveDataSetMethodExecutor.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method;
+
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.archive.DataSetArchiveOptions;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+
+/**
+ * @author pkupczyk
+ */
+public interface IArchiveDataSetMethodExecutor
+{
+
+    public void archive(String sessionToken, List<? extends IDataSetId> dataSetIds, DataSetArchiveOptions options);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/IUnarchiveDataSetMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/IUnarchiveDataSetMethodExecutor.java
new file mode 100644
index 00000000000..1972444a2c1
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/IUnarchiveDataSetMethodExecutor.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2015 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method;
+
+import java.util.List;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.unarchive.DataSetUnarchiveOptions;
+
+/**
+ * @author pkupczyk
+ */
+public interface IUnarchiveDataSetMethodExecutor
+{
+
+    public void unarchive(String sessionToken, List<? extends IDataSetId> dataSetIds, DataSetUnarchiveOptions options);
+
+}
diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/UnarchiveDataSetMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/UnarchiveDataSetMethodExecutor.java
new file mode 100644
index 00000000000..6cd6b667449
--- /dev/null
+++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/method/UnarchiveDataSetMethodExecutor.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 ch.ethz.sis.openbis.generic.server.asapi.v3.executor.method;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.unarchive.DataSetUnarchiveOptions;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.IOperationContext;
+import ch.ethz.sis.openbis.generic.server.asapi.v3.executor.dataset.IUnarchiveDataSetExecutor;
+
+/**
+ * @author pkupczyk
+ */
+@Component
+public class UnarchiveDataSetMethodExecutor extends AbstractMethodExecutor implements IUnarchiveDataSetMethodExecutor
+{
+
+    @Autowired
+    private IUnarchiveDataSetExecutor executor;
+
+    @Override
+    public void unarchive(String sessionToken, final List<? extends IDataSetId> dataSetIds, final DataSetUnarchiveOptions options)
+    {
+        executeInContext(sessionToken, new IMethodAction<Void>()
+            {
+                @Override
+                public Void execute(IOperationContext context)
+                {
+                    executor.unarchive(context, dataSetIds, options);
+                    return null;
+                }
+            });
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/dataset/archive/DataSetArchiveOptions.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/dataset/archive/DataSetArchiveOptions.js
new file mode 100644
index 00000000000..901afc918f4
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/dataset/archive/DataSetArchiveOptions.js
@@ -0,0 +1,19 @@
+/**
+ * @author pkupczyk
+ */
+define([ "stjs" ], function(stjs) {
+	var DataSetArchiveOptions = function() {
+	};
+	stjs.extend(DataSetArchiveOptions, null, [], function(constructor, prototype) {
+		prototype['@type'] = 'as.dto.dataset.archive.DataSetArchiveOptions';
+		constructor.serialVersionUID = 1;
+		prototype.removeFromDataStore = true;
+		prototype.isRemoveFromDataStore = function() {
+			return this.removeFromDataStore;
+		};
+		prototype.setRemoveFromDataStore = function(removeFromDataStore) {
+			this.removeFromDataStore = removeFromDataStore;
+		};
+	}, {});
+	return DataSetArchiveOptions;
+})
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/dataset/unarchive/DataSetUnarchiveOptions.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/dataset/unarchive/DataSetUnarchiveOptions.js
new file mode 100644
index 00000000000..640d3c5c229
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/api/v3/as/dto/dataset/unarchive/DataSetUnarchiveOptions.js
@@ -0,0 +1,12 @@
+/**
+ * @author pkupczyk
+ */
+define([ "stjs" ], function(stjs) {
+	var DataSetUnarchiveOptions = function() {
+	};
+	stjs.extend(DataSetUnarchiveOptions, null, [], function(constructor, prototype) {
+		prototype['@type'] = 'as.dto.dataset.unarchive.DataSetUnarchiveOptions';
+		constructor.serialVersionUID = 1;
+	}, {});
+	return DataSetUnarchiveOptions;
+})
\ No newline at end of file
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java
index a04cd3d4e9c..957ffd8d7ed 100644
--- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/IApplicationServerApi.java
@@ -22,6 +22,7 @@ import java.util.Map;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSetType;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.archive.DataSetArchiveOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.create.DataSetCreation;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.delete.DataSetDeletionOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetFetchOptions;
@@ -30,6 +31,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.DataSetPermId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.id.IDataSetId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.DataSetSearchCriteria;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.search.DataSetTypeSearchCriteria;
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.unarchive.DataSetUnarchiveOptions;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.update.DataSetUpdate;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.deletion.Deletion;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.deletion.fetchoptions.DeletionFetchOptions;
@@ -253,4 +255,8 @@ public interface IApplicationServerApi extends IRpcService
 
     public Object executeCustomASService(String sessionToken, ICustomASServiceId serviceId, CustomASServiceExecutionOptions options);
 
+    public void archiveDataSets(String sessionToken, List<? extends IDataSetId> dataSetIds, DataSetArchiveOptions options);
+
+    public void unarchiveDataSets(String sessionToken, List<? extends IDataSetId> dataSetIds, DataSetUnarchiveOptions options);
+
 }
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/archive/DataSetArchiveOptions.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/archive/DataSetArchiveOptions.java
new file mode 100644
index 00000000000..26866aae942
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/archive/DataSetArchiveOptions.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.archive;
+
+import java.io.Serializable;
+
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author pkupczyk
+ */
+@JsonObject("as.dto.dataset.archive.DataSetArchiveOptions")
+public class DataSetArchiveOptions implements Serializable
+{
+
+    private static final long serialVersionUID = 1L;
+
+    private boolean removeFromDataStore = true;
+
+    public void setRemoveFromDataStore(boolean removeFromDataStore)
+    {
+        this.removeFromDataStore = removeFromDataStore;
+    }
+
+    public boolean isRemoveFromDataStore()
+    {
+        return removeFromDataStore;
+    }
+
+}
diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/unarchive/DataSetUnarchiveOptions.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/unarchive/DataSetUnarchiveOptions.java
new file mode 100644
index 00000000000..3594a55bf54
--- /dev/null
+++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/dataset/unarchive/DataSetUnarchiveOptions.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2016 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.unarchive;
+
+import java.io.Serializable;
+
+import ch.systemsx.cisd.base.annotation.JsonObject;
+
+/**
+ * @author pkupczyk
+ */
+@JsonObject("as.dto.dataset.unarchive.DataSetUnarchiveOptions")
+public class DataSetUnarchiveOptions implements Serializable
+{
+
+    private static final long serialVersionUID = 1L;
+
+}
diff --git a/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt b/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt
index e05445f9faf..401e8934364 100644
--- a/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt
+++ b/openbis_api/sourceTest/java/ch/ethz/sis/openbis/generic/sharedapi/v3/dictionary.txt
@@ -1150,4 +1150,10 @@ get Set
 I Material Properties Holder
 set Material Property
 I Creation
-I Update
\ No newline at end of file
+I Update
+archive Data Sets
+Data Set Archive Options
+Data Set Unarchive Options
+is Remove From Data Store
+set Remove From Data Store
+unarchive Data Sets
-- 
GitLab