001/**
002 * Copyright 2015 DuraSpace, Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.fcrepo.client.impl;
017
018import com.hp.hpl.jena.graph.NodeFactory;
019import com.hp.hpl.jena.graph.Triple;
020
021import org.apache.commons.io.IOUtils;
022import org.fcrepo.client.FedoraContent;
023import org.fcrepo.client.FedoraDatastream;
024import org.fcrepo.client.FedoraException;
025import org.fcrepo.client.FedoraObject;
026import org.fcrepo.client.FedoraRepository;
027import org.fcrepo.client.FedoraResource;
028import org.fcrepo.client.NotFoundException;
029import org.fcrepo.kernel.api.RdfLexicon;
030import org.junit.Assert;
031import org.junit.Before;
032import org.junit.Test;
033import org.slf4j.Logger;
034
035import java.io.ByteArrayInputStream;
036import java.io.ByteArrayOutputStream;
037import java.io.IOException;
038import java.io.UnsupportedEncodingException;
039import java.util.Collection;
040import java.util.Iterator;
041import java.util.UUID;
042
043import static org.slf4j.LoggerFactory.getLogger;
044
045/**
046 * @author Mike Durbin
047 * @author Hélder Silva
048 */
049public class FedoraRepositoryImplIT {
050
051    final static Logger LOGGER = getLogger(FedoraRepositoryImplTest.class);
052
053    public static String FEDORA_CONTEXT = "fcrepo-webapp";
054
055    private static String CARGO_PORT = System.getProperty("fcrepo.dynamic.test.port", "8080");
056
057    private static String getFedoraBaseUrl() {
058        return "http://localhost:" + CARGO_PORT + "/" + FEDORA_CONTEXT;
059    }
060
061    private FedoraRepository repo;
062
063    @Before
064    public void setUp() throws FedoraException {
065        repo = new FedoraRepositoryImpl(getFedoraBaseUrl() + "/rest/");
066    }
067
068    @Test
069    public void testBasicResourceCreation() throws IOException, FedoraException {
070        final String path = getRandomUniqueId();
071
072        repo.createObject(path);
073
074        final FedoraObject object = repo.getObject(path);
075
076        final String content = "Test String";
077        final String dsid = getRandomUniqueId();
078        final String dsPath = path + "/" + dsid;
079
080        repo.createDatastream(dsPath, getStringTextContent(content));
081
082        final FedoraDatastream datastream = repo.getDatastream(dsPath);
083    }
084
085    @Test
086    public void testPidMintedResourceCreation() throws IOException, FedoraException {
087        final FedoraObject object = repo.createResource("");
088        Assert.assertTrue("A newly created object should exist at the path given by the createObject() call.",
089                repo.exists(object.getPath()));
090
091        final FedoraObject containedObject = object.createObject();
092        Assert.assertTrue("A newly created object should exist at the path given by the createObject() call.",
093                repo.exists(containedObject.getPath()));
094        Assert.assertTrue("The new object's path should start with the containing object's path.",
095                containedObject.getPath().startsWith(object.getPath()));
096    }
097
098    @Test
099    public void testPidMintedResourceCreationWithNullArgument() throws IOException, FedoraException {
100        final FedoraObject object = repo.createResource(null);
101        Assert.assertTrue("A newly created object should exist at the path given by the createObject() call.",
102                repo.exists(object.getPath()));
103    }
104
105    @Test
106    public void testBasicPropertiesCreation() throws IOException, FedoraException {
107        final String objectPath = getRandomUniqueId();
108        final FedoraObject object = repo.createObject(objectPath);
109        final String sparqlUpdate = "INSERT DATA { <> <" + RdfLexicon.DC_NAMESPACE + "identifier> 'test' . } ";
110        object.updateProperties(sparqlUpdate);
111        final Iterator<Triple> tripleIt = object.getProperties();
112        while (tripleIt.hasNext()) {
113            final Triple t = tripleIt.next();
114            if (t.objectMatches(NodeFactory.createLiteral("test"))
115                    && t.predicateMatches(NodeFactory.createURI(RdfLexicon.DC_NAMESPACE + "identifier"))) {
116                return;
117            }
118        }
119        Assert.fail("Unable to verify added object property!");
120    }
121
122    @Test
123    public void testBasicDatastreamPropertiesCreation() throws IOException, FedoraException {
124        final String objectPath = getRandomUniqueId();
125        final FedoraObject object = repo.createObject(objectPath);
126        final String datastreamPath = objectPath + "/" + getRandomUniqueId();
127        final FedoraDatastream datastream = repo.createDatastream(datastreamPath, getStringTextContent("test"));
128        final String sparqlUpdate = "INSERT DATA { <> <" + RdfLexicon.DC_NAMESPACE + "identifier> 'test' . } ";
129        datastream.updateProperties(sparqlUpdate);
130        final Iterator<Triple> tripleIt = datastream.getProperties();
131        while (tripleIt.hasNext()) {
132            final Triple t = tripleIt.next();
133            if (t.objectMatches(NodeFactory.createLiteral("test"))
134                    && t.predicateMatches(NodeFactory.createURI(RdfLexicon.DC_NAMESPACE + "identifier"))) {
135                return;
136            }
137        }
138        Assert.fail("Unable to verify added datastream property!");
139    }
140
141    @Test
142    public void testCreateOrUpdateRedirectDatastream() throws FedoraException, IOException {
143        final String objectPath = getRandomUniqueId();
144        repo.createObject(objectPath);
145        final String value = "Value of first datastream.";
146
147        // create a text datastream with the value "test"
148        final String datastreamPath1 = objectPath + "/" + getRandomUniqueId();
149        final FedoraDatastream datastream1 = repo.createDatastream(datastreamPath1, getStringTextContent(value));
150
151        // create a second datastream that is a redirect to the first
152        final String datastreamPath2 = objectPath + "/" + getRandomUniqueId();
153        final FedoraDatastream datastream2
154                = repo.createOrUpdateRedirectDatastream(datastreamPath2, repo.getRepositoryUrl() + datastreamPath1);
155
156        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
157        IOUtils.copy(datastream2.getContent(), baos);
158        Assert.assertEquals("Second datastream should be a redirect to the first!", value, baos.toString("UTF-8"));
159
160    }
161
162    @Test
163    public void testMoveResource() throws FedoraException {
164        final String originResourcePath = getRandomUniqueId();
165        final String destinyResourcePath = getRandomUniqueId();
166
167        // create origin resource
168        FedoraObject originResource = repo.createObject(originResourcePath);
169        Assert.assertNotNull(originResource);
170        Assert.assertEquals(originResourcePath, originResource.getPath());
171
172        // move resource to another location
173        originResource.move(destinyResourcePath);
174        final FedoraObject destinyResource = repo.getObject(destinyResourcePath);
175        Assert.assertNotNull(destinyResource);
176
177        // try to obtain, from origin, the object that was moved
178        try {
179            originResource = repo.getObject(originResourcePath);
180            Assert.fail("An exception was expected but it didn't happened!");
181        } catch (FedoraException e) {
182            Assert.assertTrue(e.getMessage().contains("410 Gone"));
183        }
184    }
185
186    @Test
187    public void testForceMoveResource() throws FedoraException {
188        final String originResourcePath = getRandomUniqueId();
189        final String destinyResourcePath = getRandomUniqueId();
190
191        // create origin resource
192        FedoraObject originResource = repo.createObject(originResourcePath);
193        Assert.assertNotNull(originResource);
194        Assert.assertEquals(originResourcePath, originResource.getPath());
195
196        // move resource to another location and remove tombstone
197        originResource.forceMove(destinyResourcePath);
198        final FedoraObject destinyResource = repo.getObject(destinyResourcePath);
199        Assert.assertNotNull(destinyResource);
200
201        // try to obtain, from origin, the object that was moved and doesn't have a tombstone because it was removed
202        try {
203            originResource = repo.getObject(originResourcePath);
204            Assert.fail("An exception was expected but it didn't happened!");
205        } catch (FedoraException e) {
206            Assert.assertTrue(e.getClass() == NotFoundException.class);
207        }
208    }
209
210    @Test
211    public void testCopyResource() throws FedoraException {
212        final String originResourcePath = getRandomUniqueId();
213        final String originChildResourcePath = originResourcePath + "/" + getRandomUniqueId();
214        final String destinyResourcePath = getRandomUniqueId();
215
216        // create origin resource
217        FedoraObject originResource = repo.createObject(originResourcePath);
218        Assert.assertNotNull(originResource);
219        Assert.assertEquals(originResourcePath, originResource.getPath());
220
221        // create child origin resource
222        final FedoraObject originChildResource = repo.createObject(originChildResourcePath);
223        Assert.assertNotNull(originChildResource);
224        Assert.assertEquals(originChildResourcePath, originChildResource.getPath());
225
226        // copy resource to another location
227        originResource.copy(destinyResourcePath);
228        final FedoraObject destinyResource = repo.getObject(destinyResourcePath);
229        Assert.assertNotNull(destinyResource);
230        Assert.assertEquals(destinyResourcePath, destinyResource.getPath());
231
232        // ensure that copied resource has the same number of child resources
233        originResource = repo.getObject(originResourcePath);
234        final Collection<FedoraResource> originChildren = originResource.getChildren(null);
235        final Collection<FedoraResource> destinyChildren = destinyResource.getChildren(null);
236        Assert.assertEquals(originChildren.size(),destinyChildren.size());
237    }
238
239    @Test
240    public void testDeleteResource() throws FedoraException {
241        final String resourcePath = getRandomUniqueId();
242        // create resource
243        FedoraObject resource = repo.createObject(resourcePath);
244        Assert.assertNotNull(resource);
245        Assert.assertEquals(resourcePath, resource.getPath());
246
247        // delete resource
248        resource.delete();
249
250        try {
251            resource = repo.getObject(resourcePath);
252        } catch (FedoraException e) {
253            Assert.assertTrue(e.getMessage().contains("410 Gone"));
254        }
255    }
256
257    @Test
258    public void testForceDeleteResource() throws FedoraException {
259        final String resourcePath = getRandomUniqueId();
260        // create resource
261        FedoraObject resource = repo.createObject(resourcePath);
262        Assert.assertNotNull(resource);
263        Assert.assertEquals(resourcePath, resource.getPath());
264
265        // delete resource and remove tombstone
266        resource.forceDelete();
267
268        try {
269            resource = repo.getObject(resourcePath);
270        } catch (FedoraException e) {
271            Assert.assertTrue(e.getClass() == NotFoundException.class);
272        }
273    }
274
275    private FedoraContent getStringTextContent(final String value) throws UnsupportedEncodingException {
276        return new FedoraContent().setContent(new ByteArrayInputStream(value.getBytes("UTF-8")))
277                .setContentType("text/plain");
278    }
279
280    private String getRandomUniqueId() {
281        return UUID.randomUUID().toString();
282    }
283}