001/*
002 * Licensed to DuraSpace under one or more contributor license agreements.
003 * See the NOTICE file distributed with this work for additional information
004 * regarding copyright ownership.
005 *
006 * DuraSpace licenses this file to you under the Apache License,
007 * Version 2.0 (the "License"); you may not use this file except in
008 * compliance with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.fcrepo.integration.http.api;
019
020import static org.apache.http.HttpStatus.SC_CONFLICT;
021import static org.junit.Assert.assertEquals;
022
023import java.io.IOException;
024import java.nio.file.Files;
025import java.nio.file.Paths;
026
027import org.fcrepo.kernel.api.identifiers.FedoraId;
028
029import org.apache.http.HttpStatus;
030import org.junit.Before;
031import org.junit.Test;
032import org.slf4j.Logger;
033import org.slf4j.LoggerFactory;
034import org.springframework.test.context.TestExecutionListeners;
035
036import edu.wisc.library.ocfl.api.OcflOption;
037import edu.wisc.library.ocfl.api.OcflRepository;
038import edu.wisc.library.ocfl.api.model.ObjectVersionId;
039import edu.wisc.library.ocfl.api.model.VersionNum;
040
041/**
042 * @author dbernstein
043 * @since 12/01/20
044 */
045@TestExecutionListeners(
046        listeners = {TestIsolationExecutionListener.class},
047        mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
048public class FedoraReindexIT extends AbstractResourceIT {
049
050    private static final Logger LOGGER = LoggerFactory.getLogger(FedoraReindexIT.class);
051
052    private OcflRepository ocflRepository;
053
054    @Before
055    public void setUp() {
056        ocflRepository = getBean(OcflRepository.class);
057    }
058
059    private void prepareContentForSideLoading(final String objectId, final String name) {
060        final var id = FedoraId.create(objectId).getFullId();
061        final var dir = Paths.get("src/test/resources", name);
062        var currentVersion = VersionNum.fromInt(1);
063        var currentDir = dir.resolve(currentVersion.toString());
064
065        ocflRepository.purgeObject(id);
066
067        while (Files.exists(currentDir)) {
068            ocflRepository.putObject(ObjectVersionId.head(id), currentDir,
069                    null, OcflOption.OVERWRITE);
070            currentVersion = currentVersion.nextVersionNum();
071            currentDir = dir.resolve(currentVersion.toString());
072        }
073    }
074
075    @Test
076    public void testReindexNewObjects() throws Exception {
077        final var fedoraId = "container1";
078        //validate that the fedora resource is not found (404)
079        assertNotFound(fedoraId);
080
081        prepareContentForSideLoading(fedoraId, "reindex-test");
082        doReindex(fedoraId, HttpStatus.SC_NO_CONTENT);
083
084        //validate the the fedora resource is found (200)
085        assertNotDeleted(fedoraId);
086
087        //verify that attempting to index an already existing resource returns a CONFLICT.
088        doReindex(fedoraId, SC_CONFLICT);
089    }
090
091    @Test
092    public void reindexFailsWhenObjectInvalid() throws Exception {
093        final var fedoraId = "container1";
094
095        assertNotFound(fedoraId);
096
097        prepareContentForSideLoading(fedoraId, "reindex-test-invalid");
098        doReindex(fedoraId, HttpStatus.SC_BAD_REQUEST);
099
100        assertNotFound(fedoraId);
101    }
102
103    @Test
104    public void testReindexNonExistentObject() throws Exception {
105        final var fedoraId = "container1";
106        //validate that the fedora resource is not found (404)
107        assertNotFound(fedoraId);
108        doReindex(fedoraId, HttpStatus.SC_BAD_REQUEST);
109    }
110
111    @Test
112    public void testReindexChildWithinArchivalGroup() throws Exception {
113        final var parentId = "archival-group";
114        final var fedoraId = parentId + "/child1";
115
116        prepareContentForSideLoading(fedoraId, "reindex-test-ag");
117
118        //validate that the fedora resource is not found (404)
119        assertNotFound(fedoraId);
120        assertNotFound(parentId);
121
122        doReindex(fedoraId, HttpStatus.SC_BAD_REQUEST);
123
124        //ensure the resource is still not found
125        assertNotFound(fedoraId);
126        assertNotFound(parentId);
127    }
128
129    private void doReindex(final String fedoraId, final int expectedStatus) throws IOException {
130        //invoke reindex command
131        final var httpPost = postObjMethod(getReindexEndpoint(fedoraId));
132
133        assertEquals(expectedStatus, getStatus(httpPost));
134    }
135
136    private String getReindexEndpoint(final String fedoraId) {
137        return fedoraId + "/fcr:reindex";
138    }
139
140    @Test
141    public void testMethodNotAllowed() throws Exception {
142
143        //test get
144        try (final var response = execute(getObjMethod(getReindexEndpoint("fedoraId")))) {
145            assertEquals("expected 405", HttpStatus.SC_METHOD_NOT_ALLOWED, response.getStatusLine().getStatusCode());
146        }
147
148        //test put
149        try (final var response = execute(putObjMethod(getReindexEndpoint("fedoraId")))) {
150            assertEquals("expected 405", HttpStatus.SC_METHOD_NOT_ALLOWED, response.getStatusLine().getStatusCode());
151        }
152
153        //test delete
154        try (final var response = execute(deleteObjMethod(getReindexEndpoint("fedoraId")))) {
155            assertEquals("expected 405", HttpStatus.SC_METHOD_NOT_ALLOWED, response.getStatusLine().getStatusCode());
156        }
157    }
158
159}