/******************************************************************************* * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2015-2019) * * contact.vitam@culture.gouv.fr * * This software is a computer program whose purpose is to implement a digital archiving back-office system managing * high volumetry securely and efficiently. * * This software is governed by the CeCILL 2.1 license under French law and abiding by the rules of distribution of free * software. You can use, modify and/ or redistribute the software under the terms of the CeCILL 2.1 license as * circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license, * users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the * successive licensors have only limited liability. * * In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or * developing or reproducing the software by the user in light of its specific status of free software, that may mean * that it is complicated to manipulate, and that also therefore means that it is reserved for developers and * experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the * software's suitability as regards their requirements in conditions enabling the security of their systems and/or data * to be ensured and, more generally, to use and operate it in the same conditions as regards security. * * The fact that you are presently reading this means that you have had knowledge of the CeCILL 2.1 license and that you * accept its terms. *******************************************************************************/ package fr.gouv.vitam.storage.engine.client; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.jhades.JHades; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import com.fasterxml.jackson.databind.JsonNode; import com.jayway.restassured.RestAssured; import fr.gouv.vitam.common.PropertiesUtils; import fr.gouv.vitam.common.VitamConfiguration; import fr.gouv.vitam.common.digest.Digest; import fr.gouv.vitam.common.exception.VitamApplicationServerException; import fr.gouv.vitam.common.exception.VitamClientException; import fr.gouv.vitam.common.exception.VitamException; import fr.gouv.vitam.common.logging.VitamLogger; import fr.gouv.vitam.common.logging.VitamLoggerFactory; import fr.gouv.vitam.common.stream.StreamUtils; import fr.gouv.vitam.storage.engine.client.exception.StorageServerClientException; import fr.gouv.vitam.storage.engine.common.exception.StorageNotFoundException; import fr.gouv.vitam.storage.engine.common.model.StorageCollectionType; import fr.gouv.vitam.storage.engine.common.model.request.ObjectDescription; import fr.gouv.vitam.storage.engine.server.rest.StorageApplication; import fr.gouv.vitam.storage.engine.server.rest.StorageConfiguration; import fr.gouv.vitam.workspace.api.exception.ContentAddressableStorageAlreadyExistException; import fr.gouv.vitam.workspace.api.exception.ContentAddressableStorageNotFoundException; import fr.gouv.vitam.workspace.api.exception.ContentAddressableStorageServerException; import fr.gouv.vitam.workspace.client.WorkspaceClient; import fr.gouv.vitam.workspace.client.WorkspaceClientFactory; import fr.gouv.vitam.workspace.rest.WorkspaceApplication; /** * !!! WARNING !!! : in case of modification of class fr.gouv.vitam.driver.fake.FakeDriverImpl, you need to recompile * the storage-offer-mock.jar from the storage-offer-mock module and copy it in src/test/resources in place of the * previous one. */ public class StorageClientIT { private static final VitamLogger LOGGER = VitamLoggerFactory.getInstance(StorageClientIT.class); private static final String SHOULD_NOT_RAIZED_AN_EXCEPTION = "Should not have raized an exception"; private static WorkspaceApplication workspaceApplication; private static final String REST_URI = StorageClientFactory.RESOURCE_PATH; private static final String STORAGE_CONF = "integration-storage/storage-engine.conf"; private static int serverPort = 8583; private static final int workspacePort = 8987; private static StorageClient storageClient; private static WorkspaceClient workspaceClient; private static StorageApplication storageApplication; private static final String CONTAINER_1 = "aeaaaaaaaaaam7mxaaaamakwfnzbudaaaaaq"; private static final String CONTAINER_2 = "aeaaaaaaaaaam7mxaaaamakwfnzbudaaaaaz"; private static final String CONTAINER_3 = "aeaaaaaaaaaam7mxaaaamakwfnzbudaaaapq"; private static final String OBJECT = "integration-storage/e726e114f302c871b64569a00acb3a19badb7ee8ce4aef72cc2a043ace4905b8e8fca6f4771f8d6f67e221a53a4bbe170501af318c8f2c026cc8ea60f66fa804.odp"; private static final String OBJECT_ID = "e726e114f302c871b64569a00acb3a19badb7ee8ce4aef72cc2a043ace4905b8e8fca6f4771f8d6f67e221a53a4bbe170501af318c8f2c026cc8ea60f66fa804"; private static final String REPORT = "e726e114f302c871b64569a00acb3a19badb7ee8ce4aef72cc2a043ace4905b8e8fca6f4771f8d6f67e221a53a4bbe170501af318c8f2c026cc8ea60f66fa803"; private static final String MANIFEST = "e726e114f302c871b64569a00acb3a19badb7ee8ce4aef72cc2a043ace4905b8e8fca6f4771f8d6f67e221a53a4bbe170501af318c8f2c026cc8ea60f66fa802"; @BeforeClass public static void setUpBeforeClass() throws Exception { // Identify overlapping in particular jsr311 new JHades().overlappingJarsReport(); // junitHelper = JunitHelper.getInstance(); // serverPort = junitHelper.findAvailablePort(); // launch workspace workspaceApplication = new WorkspaceApplication("integration-storage/workspace.conf"); workspaceApplication.start(); RestAssured.port = serverPort; RestAssured.basePath = REST_URI; final StorageConfiguration serverConfiguration = PropertiesUtils.readYaml(PropertiesUtils.findFile(STORAGE_CONF), StorageConfiguration.class); final Pattern compiledPattern = Pattern.compile(":(\\d+)"); final Matcher matcher = compiledPattern.matcher(serverConfiguration.getUrlWorkspace()); if (matcher.find()) { final String seg[] = serverConfiguration.getUrlWorkspace().split(":(\\d+)"); serverConfiguration.setUrlWorkspace(seg[0]); } serverConfiguration .setUrlWorkspace(serverConfiguration.getUrlWorkspace() + ":" + Integer.toString(workspacePort)); try { storageApplication = new StorageApplication(serverConfiguration); storageApplication.start(); } catch (final VitamApplicationServerException e) { LOGGER.error(e); throw new IllegalStateException( "Cannot start the Composite Application Server", e); } storageClient = StorageClientFactory.getInstance().getClient(); WorkspaceClientFactory.changeMode("http://localhost:" + workspacePort); workspaceClient = WorkspaceClientFactory.getInstance().getClient(); destroyWorkspaceFiles(); createWorkspaceFiles(); } private static void createWorkspaceFiles() throws ContentAddressableStorageAlreadyExistException, ContentAddressableStorageServerException, FileNotFoundException { try { workspaceClient.createContainer(CONTAINER_1); workspaceClient.createContainer(CONTAINER_2); workspaceClient.createContainer(CONTAINER_3); } catch (final Exception e) { LOGGER.error("Error creating container : " + e); } try { FileInputStream stream = new FileInputStream( PropertiesUtils.findFile( OBJECT)); workspaceClient.putObject(CONTAINER_1, OBJECT_ID, stream); stream = new FileInputStream( PropertiesUtils.findFile( OBJECT)); workspaceClient.putObject(CONTAINER_2, REPORT, stream); StreamUtils.closeSilently(workspaceClient.getObject(CONTAINER_1, OBJECT_ID).readEntity(InputStream.class)); } catch (final Exception e) { LOGGER.error("Error getting or putting object : " + e); } } private static void destroyWorkspaceFiles() throws ContentAddressableStorageNotFoundException, ContentAddressableStorageServerException { try { workspaceClient.deleteObject(CONTAINER_1, OBJECT_ID); workspaceClient.deleteObject(CONTAINER_2, REPORT); workspaceClient.deleteObject(CONTAINER_3, MANIFEST); } catch (final Exception e) { LOGGER.error("Error deleting object : " + e); } try { workspaceClient.deleteContainer(CONTAINER_1, true); workspaceClient.deleteContainer(CONTAINER_2, true); workspaceClient.deleteContainer(CONTAINER_3, true); } catch (final Exception e) { LOGGER.error("Error deleting container : " + e); } } @AfterClass public static void tearDownAfterClass() throws Exception { LOGGER.debug("Ending tests"); destroyWorkspaceFiles(); workspaceApplication.stop(); storageApplication.stop(); // junitHelper.releasePort(workspacePort); // junitHelper.releasePort(serverPort); } // TODO P0 test integration to finish (bug on exiting folder) @Test public final void testStorage() throws VitamClientException, FileNotFoundException { try { final ObjectDescription description = new ObjectDescription(); description.setWorkspaceContainerGUID(CONTAINER_1); description.setWorkspaceObjectURI(OBJECT_ID); final ObjectDescription description1 = new ObjectDescription(); description1.setWorkspaceContainerGUID(CONTAINER_2); description1.setWorkspaceObjectURI(REPORT); final ObjectDescription description2 = new ObjectDescription(); description2.setWorkspaceContainerGUID(CONTAINER_3); description2.setWorkspaceObjectURI(MANIFEST); // status // storageClient.getStatus(); try { final JsonNode node = storageClient.getStorageInformation("default"); assertNotNull(node); // fail(SHOULD_NOT_RAIZED_AN_EXCEPTION); } catch (final VitamException svce) { LOGGER.error(svce); fail(SHOULD_NOT_RAIZED_AN_EXCEPTION); } // TODO P0 : when implemented, uncomment this /* * try { storageClient.exists("0", "default", StorageCollectionType.OBJECTS, "objectId"); * fail(SHOULD_NOT_RAIZED_AN_EXCEPTION); } catch (StorageServerClientException svce) { // not yet * implemented } */ try { storageClient.storeFileFromWorkspace("default", StorageCollectionType.OBJECTS, "objectId", description); storageClient.storeFileFromWorkspace("default2", StorageCollectionType.OBJECTS, "objectId", description); } catch (final StorageServerClientException svce) { LOGGER.error(svce); fail(SHOULD_NOT_RAIZED_AN_EXCEPTION); } try { storageClient.storeFileFromWorkspace("default", StorageCollectionType.REPORTS, "objectId", description1); } catch (final StorageServerClientException svce) { LOGGER.error(svce); fail(SHOULD_NOT_RAIZED_AN_EXCEPTION); } try { storageClient.storeFileFromWorkspace("default", StorageCollectionType.MANIFESTS, "objectId", description2); } catch (final StorageServerClientException svce) { LOGGER.error(svce); fail(SHOULD_NOT_RAIZED_AN_EXCEPTION); } try { final InputStream stream = storageClient.getContainerAsync("default", OBJECT_ID, StorageCollectionType.OBJECTS) .readEntity(InputStream.class); assertNotNull(stream); final InputStream stream2 = storageClient.getContainerAsync("default2", OBJECT_ID, StorageCollectionType.OBJECTS) .readEntity(InputStream.class); assertNotNull(stream2); } catch (StorageServerClientException | StorageNotFoundException svce) { fail(SHOULD_NOT_RAIZED_AN_EXCEPTION); } try { final InputStream stream = storageClient.getContainerAsync("default", REPORT, StorageCollectionType.REPORTS) .readEntity(InputStream.class); assertNotNull(stream); } catch (StorageServerClientException | StorageNotFoundException svce) { LOGGER.error(svce); fail(SHOULD_NOT_RAIZED_AN_EXCEPTION); } try { final InputStream stream = storageClient.getContainerAsync("default", MANIFEST, StorageCollectionType.MANIFESTS) .readEntity(InputStream.class); assertNotNull(stream); } catch (StorageServerClientException | StorageNotFoundException svce) { LOGGER.error(svce); fail(SHOULD_NOT_RAIZED_AN_EXCEPTION); } try { assertTrue(storageClient.exists("default", StorageCollectionType.MANIFESTS, MANIFEST)); } catch (StorageServerClientException svce) { // not yet implemented LOGGER.error(svce); fail(SHOULD_NOT_RAIZED_AN_EXCEPTION); } try { final InputStream stream = storageClient.getContainerAsync("default", MANIFEST, StorageCollectionType.MANIFESTS) .readEntity(InputStream.class); assertNotNull(stream); Digest digest = Digest.digest(stream, VitamConfiguration.getDefaultDigestType()); storageClient.delete("default", StorageCollectionType.OBJECTS, "objectId", digest.toString(), VitamConfiguration.getDefaultDigestType()); } catch (Exception svce) { LOGGER.error(svce); fail(SHOULD_NOT_RAIZED_AN_EXCEPTION); } } catch ( final Exception e) { e.printStackTrace(); fail("should not raized an exception"); } } }