diff --git a/checkstyle.xml b/checkstyle.xml index 23332dd05..16e58d296 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -311,7 +311,7 @@ - + rdf4j-sail-nativerdf ${rdf4j.version} + + org.eclipse.rdf4j + rdf4j-tools-federation + ${rdf4j.version} + io.jsonwebtoken jjwt-api diff --git a/src/main/java/nl/dtls/fairdatapoint/api/controller/metadata/GenericController.java b/src/main/java/nl/dtls/fairdatapoint/api/controller/metadata/GenericController.java index 5cb966964..8a7e865ab 100644 --- a/src/main/java/nl/dtls/fairdatapoint/api/controller/metadata/GenericController.java +++ b/src/main/java/nl/dtls/fairdatapoint/api/controller/metadata/GenericController.java @@ -24,12 +24,11 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import nl.dtls.fairdatapoint.database.rdf.repository.generic.GenericMetadataRepository; import nl.dtls.fairdatapoint.entity.exception.ForbiddenException; import nl.dtls.fairdatapoint.entity.exception.ValidationException; -import nl.dtls.fairdatapoint.entity.metadata.Metadata; -import nl.dtls.fairdatapoint.entity.metadata.MetadataState; import nl.dtls.fairdatapoint.entity.resource.ResourceDefinition; import nl.dtls.fairdatapoint.entity.resource.ResourceDefinitionChild; import nl.dtls.fairdatapoint.entity.user.User; @@ -73,9 +72,6 @@ @RequestMapping("/") public class GenericController { - private static final String MSG_ERROR_DRAFT_FORBIDDEN = - "You are not allow to view this record in state DRAFT"; - @Autowired @Qualifier("persistentUrl") private String persistentUrl; @@ -89,9 +85,6 @@ public class GenericController { @Autowired private MetadataSchemaService metadataSchemaService; - @Autowired - private MetadataStateService metadataStateService; - @Autowired private MetadataEnhancer metadataEnhancer; @@ -101,6 +94,9 @@ public class GenericController { @Autowired private GenericMetadataRepository metadataRepository; + @Autowired + private MetadataStateService metadataStateService; + @Autowired private SearchFilterCache searchFilterCache; @@ -130,28 +126,23 @@ public Model getMetaDataExpanded( final MetadataService metadataService = metadataServiceFactory.getMetadataServiceByUrlPrefix(urlPrefix); final ResourceDefinition rd = resourceDefinitionService.getByUrlPrefix(urlPrefix); - // 2. Get entity + // 2. Get entity (from repository based on permissions) + final Optional oCurrentUser = currentUserService.getCurrentUser(); IRI entityUri = getMetadataIRI(persistentUrl, urlPrefix, recordId); - Model entity = metadataService.retrieve(entityUri); + final RepositoryMode mode = oCurrentUser.isEmpty() ? RepositoryMode.MAIN : RepositoryMode.COMBINED; + Model entity = metadataService.retrieve(entityUri, mode); resultRdf.addAll(entity); - // 3. Check if it is DRAFT - final Metadata state = metadataStateService.get(entityUri); - final Optional oCurrentUser = currentUserService.getCurrentUser(); - if (state.getState().equals(MetadataState.DRAFT) && oCurrentUser.isEmpty()) { - throw new ForbiddenException(MSG_ERROR_DRAFT_FORBIDDEN); - } - - // 4. Enhance + // 3. Enhance metadataEnhancer.enhanceWithResourceDefinition(entityUri, rd, resultRdf); - // 5. Get parent + // 4. Get parent while (true) { final IRI parentUri = i(getStringObjectBy(entity, entityUri, DCTERMS.IS_PART_OF)); if (parentUri == null) { break; } - final Model parent = metadataService.retrieve(parentUri); + final Model parent = metadataService.retrieve(parentUri, mode); resultRdf.addAll(parent); entity = parent; entityUri = parentUri; @@ -179,34 +170,30 @@ public Model getMetaData( // 2. Get resource definition final ResourceDefinition rd = resourceDefinitionService.getByUrlPrefix(urlPrefix); - // 3. Get entity + // 3. Get entity (from repository based on permissions) + final Optional oCurrentUser = currentUserService.getCurrentUser(); final IRI entityUri = getMetadataIRI(persistentUrl, urlPrefix, recordId); - final Model entity = metadataService.retrieve(entityUri); + final RepositoryMode mode = oCurrentUser.isEmpty() ? RepositoryMode.MAIN : RepositoryMode.COMBINED; + final Model entity = metadataService.retrieve(entityUri, mode); resultRdf.addAll(entity); - // 4. Check if it is DRAFT - final Metadata state = metadataStateService.get(entityUri); - final Optional oCurrentUser = currentUserService.getCurrentUser(); - if (state.getState().equals(MetadataState.DRAFT) && oCurrentUser.isEmpty()) { - throw new ForbiddenException(MSG_ERROR_DRAFT_FORBIDDEN); - } - - // 5. Filter children - for (ResourceDefinitionChild rdChild : rd.getChildren()) { - final IRI relationUri = i(rdChild.getRelationUri()); - for (org.eclipse.rdf4j.model.Value childUri : getObjectsBy(entity, entityUri, relationUri)) { - final Metadata childState = metadataStateService.get(i(childUri.stringValue())); - if (!(childState.getState().equals(MetadataState.PUBLISHED) || oCurrentUser.isPresent())) { - resultRdf.remove(entityUri, relationUri, childUri); - } - } - } - - // 6. Add links + // 4. Filter children + // TODO: get drafts only if permissions + // for (ResourceDefinitionChild rdChild : rd.getChildren()) { + // final IRI relationUri = i(rdChild.getRelationUri()); + // for (org.eclipse.rdf4j.model.Value childUri : getObjectsBy(entity, entityUri, relationUri)) { + // final Metadata childState = metadataStateService.get(i(childUri.stringValue())); + // if (!(childState.getState().equals(MetadataState.PUBLISHED) || oCurrentUser.isPresent())) { + // resultRdf.remove(entityUri, relationUri, childUri); + // } + // } + // } + + // 5. Add links metadataEnhancer.enhanceWithLinks(entityUri, entity, rd, persistentUrl, resultRdf); metadataEnhancer.enhanceWithResourceDefinition(entityUri, rd, resultRdf); - // 7. Create response + // 6. Create response return resultRdf; } @@ -225,7 +212,6 @@ public ResponseEntity storeMetaData( } // 2. Init - // String urlPrefix = getResourceNameForList(getRequestURL(request, persistentUrl)); final MetadataService metadataService = metadataServiceFactory.getMetadataServiceByUrlPrefix(urlPrefix); final ResourceDefinition rd = resourceDefinitionService.getByUrlPrefix(urlPrefix); @@ -341,18 +327,14 @@ public ResponseEntity getMetaDataChildren( final String recordId = oRecordId.orElse(""); final MetadataService metadataService = metadataServiceFactory.getMetadataServiceByUrlPrefix(urlPrefix); - // 2. Get entity - final IRI entityUri = getMetadataIRI(persistentUrl, urlPrefix, recordId); - final Model entity = metadataService.retrieve(entityUri); - - // 3. Check if it is draft - final Metadata state = metadataStateService.get(entityUri); + // 2. Get entity (from repository based on permissions) final Optional oCurrentUser = currentUserService.getCurrentUser(); - if (state.getState().equals(MetadataState.DRAFT) && oCurrentUser.isEmpty()) { - throw new ForbiddenException(MSG_ERROR_DRAFT_FORBIDDEN); - } + final IRI entityUri = getMetadataIRI(persistentUrl, urlPrefix, recordId); + final RepositoryMode mode = oCurrentUser.isEmpty() ? RepositoryMode.MAIN : RepositoryMode.COMBINED; + final Model entity = metadataService.retrieve(entityUri, mode); + resultRdf.addAll(entity); - // 4. Get Children + // 3. Get Children final ResourceDefinition rd = resourceDefinitionService.getByUrlPrefix(urlPrefix); final ResourceDefinition currentChildRd = resourceDefinitionService.getByUrlPrefix(childPrefix); final MetadataService childMetadataService = metadataServiceFactory.getMetadataServiceByUrlPrefix(childPrefix); @@ -361,19 +343,21 @@ public ResponseEntity getMetaDataChildren( if (rdChild.getResourceDefinitionUuid().equals(currentChildRd.getUuid())) { final IRI relationUri = i(rdChild.getRelationUri()); - // 4.1 Get all titles for sort - final Map titles = metadataRepository.findChildTitles(entityUri, relationUri); + // 3.1 Get all titles for sort + final Map titles = metadataRepository.findChildTitles(entityUri, relationUri, mode); - // 4.2 Get all children sorted + // 3.2 Get all children sorted final List children = getObjectsBy(entity, entityUri, relationUri) .stream() .filter(childUri -> getResourceNameForChild(childUri.toString()).equals(childPrefix)) .filter(childUri -> { - if (oCurrentUser.isPresent()) { - return true; + try { + return oCurrentUser.isPresent() + || metadataStateService.isPublished(i(childUri.stringValue())); + } + catch (MetadataServiceException exc) { + return false; } - final Metadata childState = metadataStateService.get(i(childUri.stringValue())); - return childState.getState().equals(MetadataState.PUBLISHED); }) .sorted((value1, value2) -> { final String title1 = titles.get(value1.toString()); @@ -382,14 +366,14 @@ public ResponseEntity getMetaDataChildren( }) .toList(); - // 4.3 Retrieve children metadata only for requested page + // 3.3 Retrieve children metadata only for requested page final int childrenCount = children.size(); children.stream().skip((long) page * size).limit(size) .map(childUri -> retrieveChildModel(childMetadataService, childUri)) .flatMap(Optional::stream) .forEach(resultRdf::addAll); - // 4.4 Set Link headers and send response + // 3.4 Set Link headers and send response final HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.set( "Link", diff --git a/src/main/java/nl/dtls/fairdatapoint/api/controller/metadata/GenericMetaController.java b/src/main/java/nl/dtls/fairdatapoint/api/controller/metadata/GenericMetaController.java index 9aebcb985..3ef1deff5 100644 --- a/src/main/java/nl/dtls/fairdatapoint/api/controller/metadata/GenericMetaController.java +++ b/src/main/java/nl/dtls/fairdatapoint/api/controller/metadata/GenericMetaController.java @@ -94,6 +94,7 @@ public MetaDTO getMeta( // 3. Get and check existence entity IRI entityUri = getMetadataIRI(persistentUrl, urlPrefix, recordId); + // TODO COMBINED/DRAFT Model entity = metadataService.retrieve(entityUri); // 4. Get member @@ -103,7 +104,7 @@ public MetaDTO getMeta( final MemberDTO member = oMember.orElse(new MemberDTO(null, null)); // 5. Get state - final MetaStateDTO state = metadataStateService.getState(entityUri, entity, definition); + final MetaStateDTO state = metadataStateService.getStateDTO(entityUri, entity, definition); // 6. Make path map final Map pathMap = new HashMap<>(); diff --git a/src/main/java/nl/dtls/fairdatapoint/api/controller/sparql/QueryResponder.java b/src/main/java/nl/dtls/fairdatapoint/api/controller/sparql/QueryResponder.java new file mode 100644 index 000000000..8a1302e6e --- /dev/null +++ b/src/main/java/nl/dtls/fairdatapoint/api/controller/sparql/QueryResponder.java @@ -0,0 +1,248 @@ +/** + * The MIT License + * Copyright © 2017 DTL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +// Adapted from: https://github.com/eclipse/rdf4j/tree/main/spring-components/spring-boot-sparql-web +package nl.dtls.fairdatapoint.api.controller.sparql; + +import static org.springframework.http.HttpHeaders.ACCEPT; +import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE; + +import java.io.IOException; +import java.util.Optional; +import java.util.function.Predicate; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.eclipse.rdf4j.common.annotation.Experimental; +import org.eclipse.rdf4j.common.lang.FileFormat; +import org.eclipse.rdf4j.model.IRI; +import org.eclipse.rdf4j.query.BooleanQuery; +import org.eclipse.rdf4j.query.GraphQuery; +import org.eclipse.rdf4j.query.MalformedQueryException; +import org.eclipse.rdf4j.query.Query; +import org.eclipse.rdf4j.query.QueryEvaluationException; +import org.eclipse.rdf4j.query.QueryLanguage; +import org.eclipse.rdf4j.query.TupleQuery; +import org.eclipse.rdf4j.query.impl.SimpleDataset; +import org.eclipse.rdf4j.query.resultio.BooleanQueryResultFormat; +import org.eclipse.rdf4j.query.resultio.BooleanQueryResultWriter; +import org.eclipse.rdf4j.query.resultio.BooleanQueryResultWriterFactory; +import org.eclipse.rdf4j.query.resultio.BooleanQueryResultWriterRegistry; +import org.eclipse.rdf4j.query.resultio.QueryResultFormat; +import org.eclipse.rdf4j.query.resultio.QueryResultIO; +import org.eclipse.rdf4j.query.resultio.TupleQueryResultFormat; +import org.eclipse.rdf4j.repository.Repository; +import org.eclipse.rdf4j.repository.RepositoryConnection; +import org.eclipse.rdf4j.rio.RDFFormat; +import org.eclipse.rdf4j.rio.RDFHandlerException; +import org.eclipse.rdf4j.rio.Rio; +import org.eclipse.rdf4j.rio.UnsupportedRDFormatException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Experimental +@RestController +@RequiredArgsConstructor +public class QueryResponder { + + @Autowired + private final Repository mainRepository; + + @RequestMapping(value = "/sparql", method = RequestMethod.POST, consumes = APPLICATION_FORM_URLENCODED_VALUE) + public void sparqlPostURLencoded( + @RequestParam(value = "default-graph-uri", required = false) String defaultGraphUri, + @RequestParam(value = "named-graph-uri", required = false) String namedGraphUri, + @RequestParam(value = "query") String query, @RequestHeader(ACCEPT) String acceptHeader, + HttpServletRequest request, HttpServletResponse response) throws IOException { + doSparql(request, query, acceptHeader, defaultGraphUri, namedGraphUri, response); + } + + @RequestMapping(value = "/sparql", method = RequestMethod.GET) + public void sparqlGet(@RequestParam(value = "default-graph-uri", required = false) String defaultGraphUri, + @RequestParam(value = "named-graph-uri", required = false) String namedGraphUri, + @RequestParam(value = "query") String query, @RequestHeader(ACCEPT) String acceptHeader, + HttpServletRequest request, HttpServletResponse response) throws IOException { + doSparql(request, query, acceptHeader, defaultGraphUri, namedGraphUri, response); + } + + private void doSparql(HttpServletRequest request, String query, String acceptHeader, String defaultGraphUri, + String namedGraphUri, HttpServletResponse response) throws IOException { + + try (RepositoryConnection connection = mainRepository.getConnection()) { + final Query preparedQuery = connection.prepareQuery(QueryLanguage.SPARQL, query); + setQueryDataSet(preparedQuery, defaultGraphUri, namedGraphUri, connection); + for (QueryTypes qts : QueryTypes.values()) { + if (qts.accepts(preparedQuery, acceptHeader)) { + qts.evaluate(preparedQuery, acceptHeader, response, defaultGraphUri, namedGraphUri); + } + } + } + catch (MalformedQueryException | MismatchingAcceptHeaderException mqe) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST); + } + catch (IllegalArgumentException exc) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Bad IRI for default or namedGraphIri"); + } + } + + /** + * @see protocol dataset + * @param query the query + * @param defaultGraphUri + * @param namedGraphUri + * @param connection + */ + private void setQueryDataSet(Query query, String defaultGraphUri, String namedGraphUri, + RepositoryConnection connection) { + if (defaultGraphUri != null || namedGraphUri != null) { + final SimpleDataset dataset = new SimpleDataset(); + + if (defaultGraphUri != null) { + final IRI defaultIri = connection.getValueFactory().createIRI(defaultGraphUri); + dataset.addDefaultGraph(defaultIri); + } + + if (namedGraphUri != null) { + final IRI namedIri = connection.getValueFactory().createIRI(namedGraphUri); + dataset.addNamedGraph(namedIri); + } + query.setDataset(dataset); + } + } + + private enum QueryTypes { + CONSTRUCT_OR_DESCRIBE(query -> query instanceof GraphQuery, RDFFormat.TURTLE, RDFFormat.NTRIPLES, + RDFFormat.JSONLD, RDFFormat.RDFXML) { + @Override + protected void evaluate(Query q, String acceptHeader, HttpServletResponse response, String defaultGraphUri, + String namedGraphUri) + throws QueryEvaluationException, RDFHandlerException, UnsupportedRDFormatException, IOException { + final GraphQuery gq = (GraphQuery) q; + final RDFFormat format = (RDFFormat) bestFormat(acceptHeader); + response.setContentType(format.getDefaultMIMEType()); + gq.evaluate(Rio.createWriter(format, response.getOutputStream())); + } + }, + SELECT(query -> query instanceof TupleQuery, TupleQueryResultFormat.JSON, TupleQueryResultFormat.SPARQL, + TupleQueryResultFormat.CSV, TupleQueryResultFormat.TSV) { + @Override + protected void evaluate(Query q, String acceptHeader, HttpServletResponse response, String defaultGraphUri, + String namedGraphUri) + throws QueryEvaluationException, RDFHandlerException, UnsupportedRDFormatException, IOException { + final TupleQuery tq = (TupleQuery) q; + final QueryResultFormat format = (QueryResultFormat) bestFormat(acceptHeader); + response.setContentType(format.getDefaultMIMEType()); + tq.evaluate(QueryResultIO.createTupleWriter(format, response.getOutputStream())); + } + }, + + ASK(query -> query instanceof BooleanQuery, BooleanQueryResultFormat.TEXT, BooleanQueryResultFormat.JSON, + BooleanQueryResultFormat.SPARQL) { + @Override + protected void evaluate(Query q, String acceptHeader, HttpServletResponse response, String defaultGraphUri, + String namedGraphUri) + throws QueryEvaluationException, RDFHandlerException, UnsupportedRDFormatException, IOException { + final BooleanQuery bq = (BooleanQuery) q; + final QueryResultFormat format = (QueryResultFormat) bestFormat(acceptHeader); + response.setContentType(format.getDefaultMIMEType()); + final Optional optional = BooleanQueryResultWriterRegistry + .getInstance() + .get(format); + if (optional.isPresent()) { + final BooleanQueryResultWriter writer = optional.get().getWriter(response.getOutputStream()); + writer.handleBoolean(bq.evaluate()); + } + + } + }; + + private final FileFormat[] formats; + private final Predicate typeChecker; + + QueryTypes(Predicate typeChecker, FileFormat... formats) { + this.typeChecker = typeChecker; + this.formats = formats; + } + + /** + * Test if the query is of a type that can be answered. And that the accept headers allow for the response to be + * send. + * + * @param preparedQuery + * @param acceptHeader + * @return true if the query is of the right type and acceptHeaders are acceptable. + * @throws MismatchingAcceptHeaderException + */ + protected boolean accepts(Query preparedQuery, String acceptHeader) throws MismatchingAcceptHeaderException { + if (accepts(preparedQuery)) { + if (acceptHeader == null || acceptHeader.isEmpty()) { + return true; + } + else { + for (FileFormat format : formats) { + for (String mimeType : format.getMIMETypes()) { + if (acceptHeader.contains(mimeType)) { + return true; + } + } + } + } + throw new MismatchingAcceptHeaderException(); + } + return false; + } + + protected boolean accepts(Query query) { + return typeChecker.test(query); + } + + protected abstract void evaluate(Query query, String acceptHeader, HttpServletResponse response, + String defaultGraphUri, String namedGraphUri) + throws QueryEvaluationException, RDFHandlerException, UnsupportedRDFormatException, IOException; + + protected FileFormat bestFormat(String acceptHeader) { + if (acceptHeader == null || acceptHeader.isEmpty()) { + return formats[0]; + } + else { + for (FileFormat format : formats) { + for (String mimeType : format.getMIMETypes()) { + if (acceptHeader.contains(mimeType)) { + return format; + } + } + } + } + return formats[0]; + } + } + + private static final class MismatchingAcceptHeaderException extends Exception { + private static final long serialVersionUID = 1L; + + } +} diff --git a/src/main/java/nl/dtls/fairdatapoint/api/dto/settings/SettingsDTO.java b/src/main/java/nl/dtls/fairdatapoint/api/dto/settings/SettingsDTO.java index c32691e27..cdba5d5d4 100644 --- a/src/main/java/nl/dtls/fairdatapoint/api/dto/settings/SettingsDTO.java +++ b/src/main/java/nl/dtls/fairdatapoint/api/dto/settings/SettingsDTO.java @@ -53,7 +53,9 @@ public class SettingsDTO { private SettingsPingDTO ping; - private SettingsRepositoryDTO repository; + private SettingsRepositoryDTO mainRepository; + + private SettingsRepositoryDTO draftsRepository; private SettingsSearchDTO search; diff --git a/src/main/java/nl/dtls/fairdatapoint/config/RepositoryConfig.java b/src/main/java/nl/dtls/fairdatapoint/config/RepositoryConfig.java index 09faef725..831643aa0 100644 --- a/src/main/java/nl/dtls/fairdatapoint/config/RepositoryConfig.java +++ b/src/main/java/nl/dtls/fairdatapoint/config/RepositoryConfig.java @@ -23,6 +23,7 @@ package nl.dtls.fairdatapoint.config; import lombok.extern.slf4j.Slf4j; +import nl.dtls.fairdatapoint.config.properties.RepositoryConnectionProperties; import nl.dtls.fairdatapoint.config.properties.RepositoryProperties; import org.eclipse.rdf4j.repository.Repository; import org.eclipse.rdf4j.repository.RepositoryException; @@ -51,16 +52,25 @@ public class RepositoryConfig { @Autowired private RepositoryProperties repositoryProperties; - @Bean(initMethod = "init", destroyMethod = "shutDown") - public Repository repository(ApplicationContext context) + @Bean(initMethod = "init", destroyMethod = "shutDown", name = "mainRepository") + public Repository mainRepository(ApplicationContext context) throws RepositoryException { + return prepareRepository(context, repositoryProperties.getMain()); + } + + @Bean(initMethod = "init", destroyMethod = "shutDown", name = "draftsRepository") + public Repository draftsRepository(ApplicationContext context) throws RepositoryException { + return prepareRepository(context, repositoryProperties.getMain()); + } + + public Repository prepareRepository(ApplicationContext context, RepositoryConnectionProperties properties) throws RepositoryException { - final Repository repository = switch (repositoryProperties.getType()) { - case RepositoryProperties.TYPE_IN_MEMORY -> getInMemoryStore(); - case RepositoryProperties.TYPE_NATIVE -> getNativeStore(); - case RepositoryProperties.TYPE_ALLEGRO -> getAgraphRepository(); - case RepositoryProperties.TYPE_GRAPHDB -> getGraphDBRepository(); - case RepositoryProperties.TYPE_BLAZEGRAPH -> getBlazeGraphRepository(); + final Repository repository = switch (properties.getType()) { + case RepositoryConnectionProperties.TYPE_IN_MEMORY -> getInMemoryStore(); + case RepositoryConnectionProperties.TYPE_NATIVE -> getNativeStore(properties); + case RepositoryConnectionProperties.TYPE_ALLEGRO -> getAgraphRepository(properties); + case RepositoryConnectionProperties.TYPE_GRAPHDB -> getGraphDBRepository(properties); + case RepositoryConnectionProperties.TYPE_BLAZEGRAPH -> getBlazeGraphRepository(properties); default -> null; }; @@ -81,26 +91,26 @@ private Repository getInMemoryStore() { return new SailRepository(store); } - private Repository getNativeStore() { + private Repository getNativeStore(RepositoryConnectionProperties properties) { log.info("Setting up Native Store"); - if (!repositoryProperties.getNativeRepo().getDir().isEmpty()) { - final File dataDir = new File(repositoryProperties.getNativeRepo().getDir()); + if (!properties.getNativeRepo().getDir().isEmpty()) { + final File dataDir = new File(properties.getNativeRepo().getDir()); return new SailRepository(new NativeStore(dataDir)); } log.warn("'repository.native.dir' is empty"); return null; } - private Repository getAgraphRepository() { + private Repository getAgraphRepository(RepositoryConnectionProperties properties) { log.info("Setting up Allegro Graph Store"); - if (!repositoryProperties.getAgraph().getUrl().isEmpty()) { + if (!properties.getAgraph().getUrl().isEmpty()) { final SPARQLRepository repository = - new SPARQLRepository(repositoryProperties.getAgraph().getUrl()); - if (!repositoryProperties.getAgraph().getUsername().isEmpty() - && !repositoryProperties.getAgraph().getPassword().isEmpty()) { + new SPARQLRepository(properties.getAgraph().getUrl()); + if (!properties.getAgraph().getUsername().isEmpty() + && !properties.getAgraph().getPassword().isEmpty()) { repository.setUsernameAndPassword( - repositoryProperties.getAgraph().getUsername(), - repositoryProperties.getAgraph().getPassword() + properties.getAgraph().getUsername(), + properties.getAgraph().getPassword() ); } return repository; @@ -109,17 +119,17 @@ private Repository getAgraphRepository() { return null; } - private Repository getBlazeGraphRepository() { + private Repository getBlazeGraphRepository(RepositoryConnectionProperties properties) { log.info("Setting up Blaze Graph Store"); - String blazegraphUrl = repositoryProperties.getBlazegraph().getUrl(); + String blazegraphUrl = properties.getBlazegraph().getUrl(); if (!blazegraphUrl.isEmpty()) { blazegraphUrl = removeLastSlash(blazegraphUrl); // Build url for blazegraph (Eg: http://localhost:8079/bigdata/namespace/test1/sparql) final StringBuilder urlBuilder = new StringBuilder(); urlBuilder.append(blazegraphUrl); urlBuilder.append("/namespace/"); - if (!repositoryProperties.getBlazegraph().getRepository().isEmpty()) { - urlBuilder.append(repositoryProperties.getBlazegraph().getRepository()); + if (!properties.getBlazegraph().getRepository().isEmpty()) { + urlBuilder.append(properties.getBlazegraph().getRepository()); } else { urlBuilder.append("kb"); @@ -131,28 +141,28 @@ private Repository getBlazeGraphRepository() { return null; } - private Repository getGraphDBRepository() { + private Repository getGraphDBRepository(RepositoryConnectionProperties properties) { log.info("Setting up GraphDB Store"); try { System.setProperty("org.eclipse.rdf4j.rio.binary.format_version", "1"); - if (!repositoryProperties.getGraphDb().getUrl().isEmpty() - && !repositoryProperties.getGraphDb().getRepository().isEmpty()) { + if (!properties.getGraphDb().getUrl().isEmpty() + && !properties.getGraphDb().getRepository().isEmpty()) { final RepositoryManager repositoryManager; - if (!repositoryProperties.getGraphDb().getUsername().isEmpty() - && !repositoryProperties.getGraphDb().getPassword().isEmpty()) { + if (!properties.getGraphDb().getUsername().isEmpty() + && !properties.getGraphDb().getPassword().isEmpty()) { repositoryManager = RemoteRepositoryManager.getInstance( - repositoryProperties.getGraphDb().getUrl(), - repositoryProperties.getGraphDb().getUsername(), - repositoryProperties.getGraphDb().getPassword() + properties.getGraphDb().getUrl(), + properties.getGraphDb().getUsername(), + properties.getGraphDb().getPassword() ); } else { repositoryManager = RemoteRepositoryManager.getInstance( - repositoryProperties.getGraphDb().getUrl() + properties.getGraphDb().getUrl() ); } return repositoryManager.getRepository( - repositoryProperties.getGraphDb().getRepository() + properties.getGraphDb().getRepository() ); } log.warn("'repository.graphDb.url' or 'repository.graphDb.repository' is empty"); diff --git a/src/main/java/nl/dtls/fairdatapoint/config/properties/RepositoryConnectionProperties.java b/src/main/java/nl/dtls/fairdatapoint/config/properties/RepositoryConnectionProperties.java new file mode 100644 index 000000000..46700ee86 --- /dev/null +++ b/src/main/java/nl/dtls/fairdatapoint/config/properties/RepositoryConnectionProperties.java @@ -0,0 +1,108 @@ +/** + * The MIT License + * Copyright © 2017 DTL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package nl.dtls.fairdatapoint.config.properties; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class RepositoryConnectionProperties { + // TODO: use polymorphism for types of repository + + public static final int TYPE_IN_MEMORY = 1; + + public static final int TYPE_NATIVE = 2; + + public static final int TYPE_ALLEGRO = 3; + + public static final int TYPE_GRAPHDB = 4; + + public static final int TYPE_BLAZEGRAPH = 5; + + private int type; + private RepositoryNativeProperties nativeRepo; + private RepositoryBasicProperties agraph; + private RepositoryBasicProperties graphDb; + private RepositoryBasicProperties blazegraph; + + public void setNative(RepositoryNativeProperties repositoryNativeProperties) { + this.nativeRepo = repositoryNativeProperties; + } + + public String getStringType() { + return switch (type) { + case TYPE_IN_MEMORY -> "InMemory"; + case TYPE_NATIVE -> "Native"; + case TYPE_ALLEGRO -> "AllegroGraph"; + case TYPE_GRAPHDB -> "GraphDB"; + case TYPE_BLAZEGRAPH -> "Blazegraph"; + default -> "Invalid"; + }; + } + + public String getDir() { + if (type == TYPE_NATIVE) { + return nativeRepo.getDir(); + } + return null; + } + + public String getUrl() { + return switch (type) { + case TYPE_ALLEGRO -> agraph.getUrl(); + case TYPE_GRAPHDB -> graphDb.getUrl(); + case TYPE_BLAZEGRAPH -> blazegraph.getUrl(); + default -> null; + }; + } + + public String getRepository() { + return switch (type) { + case TYPE_ALLEGRO -> agraph.getRepository(); + case TYPE_GRAPHDB -> graphDb.getRepository(); + case TYPE_BLAZEGRAPH -> blazegraph.getRepository(); + default -> null; + }; + } + + public String getUsername() { + return switch (type) { + case TYPE_ALLEGRO -> agraph.getUsername(); + case TYPE_GRAPHDB -> graphDb.getUsername(); + default -> null; + }; + } + + public String getPassword() { + return switch (type) { + case TYPE_ALLEGRO -> agraph.getPassword(); + case TYPE_GRAPHDB -> graphDb.getPassword(); + default -> null; + }; + } +} diff --git a/src/main/java/nl/dtls/fairdatapoint/config/properties/RepositoryProperties.java b/src/main/java/nl/dtls/fairdatapoint/config/properties/RepositoryProperties.java index f6b610256..5256f0a6b 100644 --- a/src/main/java/nl/dtls/fairdatapoint/config/properties/RepositoryProperties.java +++ b/src/main/java/nl/dtls/fairdatapoint/config/properties/RepositoryProperties.java @@ -34,77 +34,8 @@ @Setter @ConfigurationProperties(prefix = "repository") public class RepositoryProperties { - // TODO: use polymorphism for types of repository - public static final int TYPE_IN_MEMORY = 1; + private RepositoryConnectionProperties main; - public static final int TYPE_NATIVE = 2; - - public static final int TYPE_ALLEGRO = 3; - - public static final int TYPE_GRAPHDB = 4; - - public static final int TYPE_BLAZEGRAPH = 5; - - private int type; - private RepositoryNativeProperties nativeRepo; - private RepositoryBasicProperties agraph; - private RepositoryBasicProperties graphDb; - private RepositoryBasicProperties blazegraph; - - public void setNative(RepositoryNativeProperties repositoryNativeProperties) { - this.nativeRepo = repositoryNativeProperties; - } - - public String getStringType() { - return switch (type) { - case TYPE_IN_MEMORY -> "InMemory"; - case TYPE_NATIVE -> "Native"; - case TYPE_ALLEGRO -> "AllegroGraph"; - case TYPE_GRAPHDB -> "GraphDB"; - case TYPE_BLAZEGRAPH -> "Blazegraph"; - default -> "Invalid"; - }; - } - - public String getDir() { - if (type == TYPE_NATIVE) { - return nativeRepo.getDir(); - } - return null; - } - - public String getUrl() { - return switch (type) { - case TYPE_ALLEGRO -> agraph.getUrl(); - case TYPE_GRAPHDB -> graphDb.getUrl(); - case TYPE_BLAZEGRAPH -> blazegraph.getUrl(); - default -> null; - }; - } - - public String getRepository() { - return switch (type) { - case TYPE_ALLEGRO -> agraph.getRepository(); - case TYPE_GRAPHDB -> graphDb.getRepository(); - case TYPE_BLAZEGRAPH -> blazegraph.getRepository(); - default -> null; - }; - } - - public String getUsername() { - return switch (type) { - case TYPE_ALLEGRO -> agraph.getUsername(); - case TYPE_GRAPHDB -> graphDb.getUsername(); - default -> null; - }; - } - - public String getPassword() { - return switch (type) { - case TYPE_ALLEGRO -> agraph.getPassword(); - case TYPE_GRAPHDB -> graphDb.getPassword(); - default -> null; - }; - } + private RepositoryConnectionProperties drafts; } diff --git a/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/development/MigrationRunner.java b/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/development/MigrationRunner.java index 9720b32ff..e86177378 100644 --- a/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/development/MigrationRunner.java +++ b/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/development/MigrationRunner.java @@ -29,7 +29,6 @@ import nl.dtls.fairdatapoint.database.mongo.migration.development.index.entry.IndexEntryMigration; import nl.dtls.fairdatapoint.database.mongo.migration.development.index.event.EventMigration; import nl.dtls.fairdatapoint.database.mongo.migration.development.membership.MembershipMigration; -import nl.dtls.fairdatapoint.database.mongo.migration.development.metadata.MetadataMigration; import nl.dtls.fairdatapoint.database.mongo.migration.development.resource.ResourceDefinitionMigration; import nl.dtls.fairdatapoint.database.mongo.migration.development.schema.MetadataSchemaMigration; import nl.dtls.fairdatapoint.database.mongo.migration.development.settings.SettingsMigration; @@ -64,9 +63,6 @@ public class MigrationRunner { @Autowired private ApiKeyMigration apiKeyMigration; - @Autowired - private MetadataMigration metadataMigration; - @Autowired private IndexEntryMigration indexEntryMigration; @@ -98,7 +94,6 @@ public void run() { resourceDefinitionMigration.runMigration(); metadataSchemaMigration.runMigration(); apiKeyMigration.runMigration(); - metadataMigration.runMigration(); indexEntryMigration.runMigration(); eventMigration.runMigration(); resourceDefinitionTargetClassesCache.computeCache(); diff --git a/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/development/metadata/MetadataMigration.java b/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/development/metadata/MetadataMigration.java deleted file mode 100644 index 695fca295..000000000 --- a/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/development/metadata/MetadataMigration.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * The MIT License - * Copyright © 2017 DTL - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package nl.dtls.fairdatapoint.database.mongo.migration.development.metadata; - -import nl.dtls.fairdatapoint.database.common.migration.Migration; -import nl.dtls.fairdatapoint.database.mongo.repository.MetadataRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class MetadataMigration implements Migration { - - @Autowired - private MetadataRepository metadataRepository; - - public void runMigration() { - metadataRepository.deleteAll(); - } - -} diff --git a/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/development/metadata/data/MetadataFixtures.java b/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/development/metadata/data/MetadataFixtures.java deleted file mode 100644 index dff6f4e15..000000000 --- a/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/development/metadata/data/MetadataFixtures.java +++ /dev/null @@ -1,101 +0,0 @@ -/** - * The MIT License - * Copyright © 2017 DTL - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package nl.dtls.fairdatapoint.database.mongo.migration.development.metadata.data; - -import nl.dtls.fairdatapoint.entity.metadata.Metadata; -import nl.dtls.fairdatapoint.entity.metadata.MetadataState; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Service; - -@Service -public class MetadataFixtures { - - @Autowired - @Qualifier("persistentUrl") - private String persistentUrl; - - public Metadata fdpMetadata() { - return - new Metadata( - null, - persistentUrl, - MetadataState.PUBLISHED - ); - } - - public Metadata catalog1() { - return - new Metadata( - null, - persistentUrl + "/catalog/catalog-1", - MetadataState.PUBLISHED - ); - } - - public Metadata catalog2() { - return - new Metadata( - null, - persistentUrl + "/catalog/catalog-2", - MetadataState.DRAFT - ); - } - - public Metadata dataset1() { - return - new Metadata( - null, - persistentUrl + "/dataset/dataset-1", - MetadataState.PUBLISHED - ); - } - - public Metadata dataset2() { - return - new Metadata( - null, - persistentUrl + "/dataset/dataset-2", - MetadataState.DRAFT - ); - } - - public Metadata distribution1() { - return - new Metadata( - null, - persistentUrl + "/distribution/distribution-1", - MetadataState.PUBLISHED - ); - } - - public Metadata distribution2() { - return - new Metadata( - null, - persistentUrl + "/distribution/distribution-2", - MetadataState.DRAFT - ); - } - -} diff --git a/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/development/metadata/RdfMetadataMigration.java b/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/development/metadata/RdfMetadataMigration.java index 67e3def0b..20479da3a 100644 --- a/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/development/metadata/RdfMetadataMigration.java +++ b/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/development/metadata/RdfMetadataMigration.java @@ -27,6 +27,7 @@ import nl.dtls.fairdatapoint.database.mongo.migration.development.resource.data.ResourceDefinitionFixtures; import nl.dtls.fairdatapoint.database.mongo.migration.development.user.data.UserFixtures; import nl.dtls.fairdatapoint.database.rdf.migration.development.metadata.data.RdfMetadataFixtures; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import nl.dtls.fairdatapoint.database.rdf.repository.generic.GenericMetadataRepository; import nl.dtls.fairdatapoint.entity.metadata.MetadataState; @@ -82,7 +83,7 @@ public class RdfMetadataMigration implements Migration { public void runMigration() { try { // 1. Remove all previous metadata - metadataRepository.removeAll(); + metadataRepository.removeAll(RepositoryMode.COMBINED); // 2. Auth user final String adminUuid = userFixtures.admin().getUuid(); diff --git a/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0001_Init.java b/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0001_Init.java index 38cfb083a..fbd985c74 100644 --- a/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0001_Init.java +++ b/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0001_Init.java @@ -48,9 +48,10 @@ @Slf4j @Service public class Rdf_Migration_0001_Init implements RdfProductionMigration { + // TODO: squash RDF migrations @Autowired - private Repository repository; + private Repository mainRepository; @Autowired @Qualifier("persistentUrl") @@ -74,7 +75,7 @@ public void runMigration() { } private void createRepositoryInTripleStore() { - try (RepositoryConnection conn = repository.getConnection()) { + try (RepositoryConnection conn = mainRepository.getConnection()) { final List statements = FactoryDefaults.repositoryStatements( persistentUrl, license, diff --git a/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0002_Metadata_Draft.java b/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0002_Metadata_Draft.java index 82c14cc6c..36bd2b9a4 100644 --- a/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0002_Metadata_Draft.java +++ b/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0002_Metadata_Draft.java @@ -23,9 +23,6 @@ package nl.dtls.fairdatapoint.database.rdf.migration.production; import lombok.extern.slf4j.Slf4j; -import nl.dtls.fairdatapoint.database.mongo.repository.MetadataRepository; -import nl.dtls.fairdatapoint.entity.metadata.Metadata; -import nl.dtls.fairdatapoint.entity.metadata.MetadataState; import nl.dtls.rdf.migration.entity.RdfMigrationAnnotation; import nl.dtls.rdf.migration.runner.RdfProductionMigration; import org.eclipse.rdf4j.model.Resource; @@ -42,19 +39,20 @@ @Slf4j @Service public class Rdf_Migration_0002_Metadata_Draft implements RdfProductionMigration { + // TODO: squash RDF migrations @Autowired - private Repository repository; + private Repository mainRepository; - @Autowired - private MetadataRepository metadataRepository; + // @Autowired + // private MetadataRepository metadataRepository; public void runMigration() { createRepositoryInTripleStore(); } private void createRepositoryInTripleStore() { - try (RepositoryConnection conn = repository.getConnection()) { + try (RepositoryConnection conn = mainRepository.getConnection()) { conn.getContextIDs() .stream() .forEach(this::saveMetadataForResource); @@ -65,7 +63,7 @@ private void createRepositoryInTripleStore() { } private void saveMetadataForResource(Resource resource) { - metadataRepository.save(new Metadata(null, resource.stringValue(), MetadataState.PUBLISHED)); + // metadataRepository.save(new Metadata(null, resource.stringValue(), MetadataState.PUBLISHED)); } } diff --git a/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0003_FDPO.java b/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0003_FDPO.java index 0dcbae49d..95f5aeacf 100644 --- a/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0003_FDPO.java +++ b/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0003_FDPO.java @@ -51,6 +51,7 @@ @Slf4j @Service public class Rdf_Migration_0003_FDPO implements RdfProductionMigration { + // TODO: squash RDF migrations private static final String LEGACY_CONFORMS_TO = "https://www.purl.org/fairtools/fdp/schema/0.1/fdpMetadata"; @@ -65,7 +66,7 @@ public class Rdf_Migration_0003_FDPO implements RdfProductionMigration { private static final String MSG_REMOVE = "Removing: {} {} {}"; @Autowired - private Repository repository; + private Repository mainRepository; public void runMigration() { removeOldConformsTo(); @@ -76,7 +77,7 @@ public void runMigration() { private void removeOldConformsTo() { // remove conformsTo for repository if present (https://www.purl.org/fairtools/fdp/schema/0.1/fdpMetadata) - try (RepositoryConnection conn = repository.getConnection()) { + try (RepositoryConnection conn = mainRepository.getConnection()) { final RepositoryResult queryResult = conn.getStatements(null, DCTERMS.CONFORMS_TO, i(LEGACY_CONFORMS_TO)); while (queryResult.hasNext()) { @@ -93,7 +94,7 @@ private void removeOldConformsTo() { private void updateRepositoryStatements() { // change r3d:Repository -> fdp-o:FAIRDataPoint (and dcat:DataService + fdp-o:MetadataService?) final List newTypes = List.of(DCAT.DATA_SERVICE, FDP.METADATASERVICE, FDP.FAIRDATAPOINT); - try (RepositoryConnection conn = repository.getConnection()) { + try (RepositoryConnection conn = mainRepository.getConnection()) { final RepositoryResult queryResult = conn.getStatements(null, RDF.TYPE, R3D.REPOSITORY); while (queryResult.hasNext()) { final Statement st = queryResult.next(); @@ -112,7 +113,7 @@ private void updateRepositoryStatements() { private void updateOldFdpoStatements() { // update old FDP-O generated metadata - try (RepositoryConnection conn = repository.getConnection()) { + try (RepositoryConnection conn = mainRepository.getConnection()) { RepositoryResult queryResult = conn.getStatements(null, OLD_METADATA_IDENTIFIER, null); while (queryResult.hasNext()) { final Statement st = queryResult.next(); @@ -145,7 +146,7 @@ private void updateOldFdpoStatements() { private void updateRepositoryCatalogLinks() { // change r3d:dataCatalog to fdp-o:metadataCatalog property (between Repository/FDP and Catalogs) - try (RepositoryConnection conn = repository.getConnection()) { + try (RepositoryConnection conn = mainRepository.getConnection()) { final RepositoryResult queryResult = conn.getStatements(null, R3D.DATACATALOG, null); while (queryResult.hasNext()) { final Statement st = queryResult.next(); diff --git a/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0004_Cleanup_Index.java b/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0004_Cleanup_Index.java index 4e81633d2..63314a6fd 100644 --- a/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0004_Cleanup_Index.java +++ b/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0004_Cleanup_Index.java @@ -25,6 +25,7 @@ import lombok.extern.slf4j.Slf4j; import nl.dtls.fairdatapoint.config.properties.InstanceProperties; import nl.dtls.fairdatapoint.database.mongo.repository.IndexEntryRepository; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import nl.dtls.fairdatapoint.database.rdf.repository.generic.GenericMetadataRepository; import nl.dtls.fairdatapoint.entity.index.entry.IndexEntry; @@ -46,9 +47,10 @@ @Slf4j @Service public class Rdf_Migration_0004_Cleanup_Index implements RdfProductionMigration { + // TODO: squash RDF migrations @Autowired - private Repository repository; + private Repository mainRepository; @Autowired private GenericMetadataRepository genericMetadataRepository; @@ -89,7 +91,7 @@ public void cleanupHarvestedRecordsFrom(IndexEntry entry) { return; } - try (RepositoryConnection conn = repository.getConnection()) { + try (RepositoryConnection conn = mainRepository.getConnection()) { conn.getContextIDs() .stream() .filter(Value::isIRI) @@ -98,7 +100,7 @@ public void cleanupHarvestedRecordsFrom(IndexEntry entry) { .forEach(contextId -> { log.info("Deleting harvested records for '{}': {}", entry.getClientUrl(), contextId); try { - genericMetadataRepository.remove(i(contextId)); + genericMetadataRepository.remove(i(contextId), RepositoryMode.COMBINED); } catch (MetadataRepositoryException exception) { throw new RuntimeException(exception); diff --git a/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0005_FixMetadataVersion.java b/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0005_FixMetadataVersion.java index 78281e1de..ac920322e 100644 --- a/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0005_FixMetadataVersion.java +++ b/src/main/java/nl/dtls/fairdatapoint/database/rdf/migration/production/Rdf_Migration_0005_FixMetadataVersion.java @@ -49,7 +49,7 @@ public class Rdf_Migration_0005_FixMetadataVersion implements RdfProductionMigra private static final String MSG_REMOVE = "Removing: {} {} {}"; @Autowired - private Repository repository; + private Repository mainRepository; public void runMigration() { updateVersionStatements(); @@ -57,7 +57,7 @@ public void runMigration() { private void updateVersionStatements() { // change dcterms:hasVersion to dcat:version property (if object is literal) - try (RepositoryConnection conn = repository.getConnection()) { + try (RepositoryConnection conn = mainRepository.getConnection()) { final RepositoryResult queryResult = conn.getStatements(null, DCTERMS.HAS_VERSION, null); while (queryResult.hasNext()) { final Statement st = queryResult.next(); diff --git a/src/main/java/nl/dtls/fairdatapoint/database/mongo/repository/MetadataRepository.java b/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/RepositoryMode.java similarity index 73% rename from src/main/java/nl/dtls/fairdatapoint/database/mongo/repository/MetadataRepository.java rename to src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/RepositoryMode.java index effc67963..9eb82a2d6 100644 --- a/src/main/java/nl/dtls/fairdatapoint/database/mongo/repository/MetadataRepository.java +++ b/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/RepositoryMode.java @@ -20,18 +20,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package nl.dtls.fairdatapoint.database.mongo.repository; - -import nl.dtls.fairdatapoint.entity.metadata.Metadata; -import org.springframework.data.mongodb.repository.MongoRepository; - -import java.util.List; -import java.util.Optional; - -public interface MetadataRepository extends MongoRepository { - - Optional findByUri(String uri); - - List findByUriIn(List uris); +package nl.dtls.fairdatapoint.database.rdf.repository; +public enum RepositoryMode { + MAIN, + DRAFTS, + COMBINED } diff --git a/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/catalog/CatalogMetadataRepository.java b/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/catalog/CatalogMetadataRepository.java index 6fbe9f957..5d0dfcf28 100644 --- a/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/catalog/CatalogMetadataRepository.java +++ b/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/catalog/CatalogMetadataRepository.java @@ -22,6 +22,7 @@ */ package nl.dtls.fairdatapoint.database.rdf.repository.catalog; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.common.MetadataRepository; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import org.eclipse.rdf4j.model.IRI; @@ -30,6 +31,6 @@ public interface CatalogMetadataRepository extends MetadataRepository { - List getDatasetThemesForCatalog(IRI uri) throws MetadataRepositoryException; + List getDatasetThemesForCatalog(IRI uri, RepositoryMode mode) throws MetadataRepositoryException; } diff --git a/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/catalog/CatalogMetadataRepositoryImpl.java b/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/catalog/CatalogMetadataRepositoryImpl.java index 97c5391f6..0ad831ef0 100644 --- a/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/catalog/CatalogMetadataRepositoryImpl.java +++ b/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/catalog/CatalogMetadataRepositoryImpl.java @@ -23,17 +23,17 @@ package nl.dtls.fairdatapoint.database.rdf.repository.catalog; import jakarta.annotation.PostConstruct; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.common.AbstractMetadataRepository; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import org.eclipse.rdf4j.model.IRI; -import org.springframework.beans.factory.annotation.Autowired; +import org.eclipse.rdf4j.repository.Repository; import org.springframework.cache.Cache; import org.springframework.cache.concurrent.ConcurrentMapCacheManager; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import static nl.dtls.fairdatapoint.config.CacheConfig.CATALOG_THEMES_CACHE; import static nl.dtls.fairdatapoint.util.ValueFactoryHelper.i; @@ -43,24 +43,33 @@ public class CatalogMetadataRepositoryImpl extends AbstractMetadataRepository im private static final String GET_DATASET_THEMES_FOR_CATALOG = "getDatasetThemesForCatalog.sparql"; - @Autowired - private ConcurrentMapCacheManager cacheManager; + private final ConcurrentMapCacheManager cacheManager; + + public CatalogMetadataRepositoryImpl(ConcurrentMapCacheManager cacheManager, + Repository mainRepository, Repository draftsRepository) { + super(mainRepository, draftsRepository); + this.cacheManager = cacheManager; + } @PostConstruct public void init() { cacheManager.setCacheNames(List.of(CATALOG_THEMES_CACHE)); } - public List getDatasetThemesForCatalog(IRI uri) throws MetadataRepositoryException { + public List getDatasetThemesForCatalog(IRI uri, RepositoryMode mode) throws MetadataRepositoryException { List result = cache().get(uri.toString(), List.class); if (result != null) { return result; } - result = runSparqlQuery(GET_DATASET_THEMES_FOR_CATALOG, CatalogMetadataRepository.class, Map.of( - "catalog", uri)) + result = runSparqlQuery( + GET_DATASET_THEMES_FOR_CATALOG, + CatalogMetadataRepository.class, + Map.of("catalog", uri), + mode + ) .stream() .map(item -> i(item.getValue("theme").stringValue())) - .collect(Collectors.toList()); + .toList(); cache().put(uri.toString(), result); return result; } diff --git a/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/common/AbstractMetadataRepository.java b/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/common/AbstractMetadataRepository.java index 457ef88ce..aa6a21eef 100644 --- a/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/common/AbstractMetadataRepository.java +++ b/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/common/AbstractMetadataRepository.java @@ -22,14 +22,15 @@ */ package nl.dtls.fairdatapoint.database.rdf.repository.common; -import com.google.common.base.Charsets; import com.google.common.io.Resources; import lombok.extern.slf4j.Slf4j; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import nl.dtls.fairdatapoint.entity.search.SearchFilterValue; import nl.dtls.fairdatapoint.entity.search.SearchResult; import nl.dtls.fairdatapoint.entity.search.SearchResultRelation; -import org.eclipse.rdf4j.common.iteration.Iterations; +import org.eclipse.rdf4j.federated.FedXFactory; +import org.eclipse.rdf4j.federated.endpoint.EndpointFactory; import org.eclipse.rdf4j.model.*; import org.eclipse.rdf4j.query.BindingSet; import org.eclipse.rdf4j.query.QueryResults; @@ -37,10 +38,10 @@ import org.eclipse.rdf4j.repository.Repository; import org.eclipse.rdf4j.repository.RepositoryConnection; import org.eclipse.rdf4j.repository.RepositoryException; -import org.springframework.beans.factory.annotation.Autowired; import java.io.IOException; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -74,49 +75,77 @@ public abstract class AbstractMetadataRepository { private static final String FIELD_REL_PRED = "relationPredicate"; private static final String FIELD_REL_OBJ = "relationObject"; - @Autowired - private Repository repository; + private final Repository mainRepository; - protected Repository getRepository() { - return repository; + private final Repository draftsRepository; + + private final Repository combinedRepository; + + public AbstractMetadataRepository(Repository mainRepository, Repository draftsRepository) { + this.mainRepository = mainRepository; + this.draftsRepository = draftsRepository; + this.combinedRepository = FedXFactory.createFederation( + List.of( + EndpointFactory.loadEndpoint("main", mainRepository), + EndpointFactory.loadEndpoint("drafts", draftsRepository) + ) + ); } - public List findResources() throws MetadataRepositoryException { - try (RepositoryConnection conn = repository.getConnection()) { + protected Repository getMainRepository() { + return mainRepository; + } - return Iterations.asList( - conn.getContextIDs() - ); + protected Repository getDraftsRepository() { + return draftsRepository; + } + + protected Repository getCombinedRepository() { + return combinedRepository; + } + + protected Repository getRepository(RepositoryMode mode) { + if (mode == RepositoryMode.DRAFTS) { + return getDraftsRepository(); + } + if (mode == RepositoryMode.COMBINED) { + return getCombinedRepository(); + } + return getMainRepository(); + } + + public List findResources(RepositoryMode mode) throws MetadataRepositoryException { + try (RepositoryConnection conn = getRepository(mode).getConnection()) { + return conn.getContextIDs().stream().toList(); } catch (RepositoryException exception) { throw new MetadataRepositoryException(MSG_ERROR_RESOURCE + exception.getMessage()); } } - public List find(IRI context) throws MetadataRepositoryException { - try (RepositoryConnection conn = repository.getConnection()) { - return Iterations.asList( - conn.getStatements(null, null, null, context) - ); + public List find(IRI context, RepositoryMode mode) throws MetadataRepositoryException { + try (RepositoryConnection conn = getRepository(mode).getConnection()) { + return conn.getStatements(null, null, null, context).stream().toList(); } catch (RepositoryException exception) { throw new MetadataRepositoryException(MSG_ERROR_RESOURCE + exception.getMessage()); } } - public List findByLiteral(Literal query) throws MetadataRepositoryException { + public List findByLiteral(Literal query, RepositoryMode mode) throws MetadataRepositoryException { return runSparqlQuery( FIND_ENTITY_BY_LITERAL, AbstractMetadataRepository.class, - Map.of("query", query) + Map.of("query", query), + mode ) .stream() .map(item -> toSearchResult(item, true)) .toList(); } - public List findBySparqlQuery(String query) throws MetadataRepositoryException { - return runSparqlQuery(query) + public List findBySparqlQuery(String query, RepositoryMode mode) throws MetadataRepositoryException { + return runSparqlQuery(query, mode) .stream() .map(item -> toSearchResult(item, false)) .toList(); @@ -139,13 +168,14 @@ private SearchResult toSearchResult(BindingSet item, boolean withRelation) { ); } - public List findByFilterPredicate(IRI predicateUri) + public List findByFilterPredicate(IRI predicateUri, RepositoryMode mode) throws MetadataRepositoryException { final Map values = new HashMap<>(); runSparqlQuery( FIND_OBJECT_FOR_PREDICATE, AbstractMetadataRepository.class, - Map.of("predicate", predicateUri) + Map.of("predicate", predicateUri), + mode ).forEach(entry -> { values.put( entry.getValue(FIELD_VALUE).stringValue(), @@ -161,7 +191,7 @@ public List findByFilterPredicate(IRI predicateUri) .toList(); } - public Map findChildTitles(IRI parent, IRI relation) + public Map findChildTitles(IRI parent, IRI relation, RepositoryMode mode) throws MetadataRepositoryException { final Map titles = new HashMap<>(); @@ -171,7 +201,9 @@ public Map findChildTitles(IRI parent, IRI relation) Map.of( "parent", parent, "relation", relation - )); + ), + mode + ); for (var result : results) { final String childUri = result.getValue(FIELD_CHILD).stringValue(); @@ -182,9 +214,9 @@ public Map findChildTitles(IRI parent, IRI relation) return titles; } - public boolean checkExistence(Resource subject, IRI predicate, Value object) + public boolean checkExistence(Resource subject, IRI predicate, Value object, RepositoryMode mode) throws MetadataRepositoryException { - try (RepositoryConnection conn = repository.getConnection()) { + try (RepositoryConnection conn = getRepository(mode).getConnection()) { return conn.hasStatement(subject, predicate, object, false); } catch (RepositoryException exception) { @@ -192,8 +224,8 @@ public boolean checkExistence(Resource subject, IRI predicate, Value object) } } - public void save(List statements, IRI context) throws MetadataRepositoryException { - try (RepositoryConnection conn = repository.getConnection()) { + public void save(List statements, IRI context, RepositoryMode mode) throws MetadataRepositoryException { + try (RepositoryConnection conn = getRepository(mode).getConnection()) { conn.add(statements, context); } catch (RepositoryException exception) { @@ -201,8 +233,13 @@ public void save(List statements, IRI context) throws MetadataReposit } } - public void removeAll() throws MetadataRepositoryException { - try (RepositoryConnection conn = repository.getConnection()) { + public void removeAll(RepositoryMode mode) throws MetadataRepositoryException { + if (mode.equals(RepositoryMode.COMBINED)) { + removeAll(RepositoryMode.MAIN); + removeAll(RepositoryMode.DRAFTS); + return; + } + try (RepositoryConnection conn = getRepository(mode).getConnection()) { conn.clear(); } catch (RepositoryException exception) { @@ -210,13 +247,13 @@ public void removeAll() throws MetadataRepositoryException { } } - public void remove(IRI uri) throws MetadataRepositoryException { - removeStatement(null, null, null, uri); + public void remove(IRI uri, RepositoryMode mode) throws MetadataRepositoryException { + removeStatement(null, null, null, uri, mode); } - public void removeStatement(Resource subject, IRI predicate, Value object, IRI context) + public void removeStatement(Resource subject, IRI predicate, Value object, IRI context, RepositoryMode mode) throws MetadataRepositoryException { - try (RepositoryConnection conn = repository.getConnection()) { + try (RepositoryConnection conn = getRepository(mode).getConnection()) { conn.remove(subject, predicate, object, context); } catch (RepositoryException exception) { @@ -225,9 +262,9 @@ public void removeStatement(Resource subject, IRI predicate, Value object, IRI c } public List runSparqlQuery(String queryName, Class repositoryType, - Map bindings) + Map bindings, RepositoryMode mode) throws MetadataRepositoryException { - try (RepositoryConnection conn = repository.getConnection()) { + try (RepositoryConnection conn = getRepository(mode).getConnection()) { final String queryString = loadSparqlQuery(queryName, repositoryType); final TupleQuery query = conn.prepareTupleQuery(queryString); bindings.forEach(query::setBinding); @@ -242,8 +279,8 @@ public List runSparqlQuery(String queryName, Class repositoryType, } } - public List runSparqlQuery(String queryString) throws MetadataRepositoryException { - try (RepositoryConnection conn = repository.getConnection()) { + public List runSparqlQuery(String queryString, RepositoryMode mode) throws MetadataRepositoryException { + try (RepositoryConnection conn = getRepository(mode).getConnection()) { final TupleQuery query = conn.prepareTupleQuery(queryString); return query.evaluate().stream().toList(); } @@ -254,6 +291,18 @@ public List runSparqlQuery(String queryString) throws MetadataReposi protected String loadSparqlQuery(String queryName, Class repositoryType) throws IOException { final URL fileURL = repositoryType.getResource(queryName); - return Resources.toString(fileURL, Charsets.UTF_8); + return Resources.toString(fileURL, StandardCharsets.UTF_8); + } + + public void moveToMain(IRI context) throws MetadataRepositoryException { + final List statements = find(context, RepositoryMode.DRAFTS); + save(statements, context, RepositoryMode.MAIN); + remove(context, RepositoryMode.DRAFTS); + } + + public void moveToDrafts(IRI context) throws MetadataRepositoryException { + final List statements = find(context, RepositoryMode.MAIN); + save(statements, context, RepositoryMode.DRAFTS); + remove(context, RepositoryMode.MAIN); } } diff --git a/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/common/MetadataRepository.java b/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/common/MetadataRepository.java index 8af2a5ca0..ba9af294b 100644 --- a/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/common/MetadataRepository.java +++ b/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/common/MetadataRepository.java @@ -27,6 +27,7 @@ */ package nl.dtls.fairdatapoint.database.rdf.repository.common; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import nl.dtls.fairdatapoint.entity.search.SearchFilterValue; import nl.dtls.fairdatapoint.entity.search.SearchResult; @@ -38,33 +39,37 @@ public interface MetadataRepository { - List findResources() throws MetadataRepositoryException; + List findResources(RepositoryMode mode) throws MetadataRepositoryException; - List find(IRI context) throws MetadataRepositoryException; + List find(IRI context, RepositoryMode mode) throws MetadataRepositoryException; - List findByLiteral(Literal query) throws MetadataRepositoryException; + List findByLiteral(Literal query, RepositoryMode mode) throws MetadataRepositoryException; - List findBySparqlQuery(String query) throws MetadataRepositoryException; + List findBySparqlQuery(String query, RepositoryMode mode) throws MetadataRepositoryException; - List findByFilterPredicate(IRI predicateUri) + List findByFilterPredicate(IRI predicateUri, RepositoryMode mode) throws MetadataRepositoryException; - Map findChildTitles(IRI parent, IRI relation) + Map findChildTitles(IRI parent, IRI relation, RepositoryMode mode) throws MetadataRepositoryException; - boolean checkExistence(Resource subject, IRI predicate, Value object) + boolean checkExistence(Resource subject, IRI predicate, Value object, RepositoryMode mode) throws MetadataRepositoryException; - void save(List statements, IRI context) throws MetadataRepositoryException; + void save(List statements, IRI context, RepositoryMode mode) throws MetadataRepositoryException; - void removeAll() throws MetadataRepositoryException; + void removeAll(RepositoryMode mode) throws MetadataRepositoryException; - void remove(IRI uri) throws MetadataRepositoryException; + void remove(IRI uri, RepositoryMode mode) throws MetadataRepositoryException; - void removeStatement(Resource subject, IRI predicate, Value object, IRI context) + void removeStatement(Resource subject, IRI predicate, Value object, IRI context, RepositoryMode mode) throws MetadataRepositoryException; List runSparqlQuery(String queryName, Class repositoryType, - Map bindings) + Map bindings, RepositoryMode mode) throws MetadataRepositoryException; + + void moveToDrafts(IRI context) throws MetadataRepositoryException; + + void moveToMain(IRI context) throws MetadataRepositoryException; } diff --git a/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/generic/GenericMetadataRepositoryImpl.java b/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/generic/GenericMetadataRepositoryImpl.java index dee590abc..3684f7e2c 100644 --- a/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/generic/GenericMetadataRepositoryImpl.java +++ b/src/main/java/nl/dtls/fairdatapoint/database/rdf/repository/generic/GenericMetadataRepositoryImpl.java @@ -27,10 +27,12 @@ */ package nl.dtls.fairdatapoint.database.rdf.repository.generic; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.common.AbstractMetadataRepository; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import org.eclipse.rdf4j.model.*; import org.eclipse.rdf4j.model.impl.LinkedHashModel; +import org.eclipse.rdf4j.repository.Repository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.concurrent.ConcurrentMapCacheManager; import org.springframework.stereotype.Service; @@ -46,28 +48,32 @@ public class GenericMetadataRepositoryImpl extends AbstractMetadataRepository im @Autowired private ConcurrentMapCacheManager cacheManager; + public GenericMetadataRepositoryImpl(Repository mainRepository, Repository draftsRepository) { + super(mainRepository, draftsRepository); + } + @Override - public void save(List statements, IRI context) throws MetadataRepositoryException { - super.save(statements, context); - clearCatalogCache(context); + public void save(List statements, IRI context, RepositoryMode mode) throws MetadataRepositoryException { + super.save(statements, context, mode); + clearCatalogCache(context, mode); } @Override - public void remove(IRI uri) throws MetadataRepositoryException { - clearCatalogCache(uri); - super.remove(uri); + public void remove(IRI uri, RepositoryMode mode) throws MetadataRepositoryException { + clearCatalogCache(uri, mode); + super.remove(uri, mode); } @Override - public void removeStatement(Resource subject, IRI predicate, Value object, IRI context) + public void removeStatement(Resource subject, IRI predicate, Value object, IRI context, RepositoryMode mode) throws MetadataRepositoryException { - clearCatalogCache(context); - super.removeStatement(subject, predicate, object, context); + clearCatalogCache(context, mode); + super.removeStatement(subject, predicate, object, context, mode); } - private void clearCatalogCache(IRI uri) throws MetadataRepositoryException { + private void clearCatalogCache(IRI uri, RepositoryMode mode) throws MetadataRepositoryException { final Model metadata = new LinkedHashModel(); - metadata.addAll(find(uri)); + metadata.addAll(find(uri, mode)); final IRI parent = getParent(metadata); if (parent != null) { cacheManager.getCache(CATALOG_THEMES_CACHE).evict(parent.stringValue()); diff --git a/src/main/java/nl/dtls/fairdatapoint/entity/metadata/Metadata.java b/src/main/java/nl/dtls/fairdatapoint/entity/metadata/Metadata.java index 2fd5ca9e1..1169d4b0e 100644 --- a/src/main/java/nl/dtls/fairdatapoint/entity/metadata/Metadata.java +++ b/src/main/java/nl/dtls/fairdatapoint/entity/metadata/Metadata.java @@ -23,11 +23,7 @@ package nl.dtls.fairdatapoint.entity.metadata; import lombok.*; -import org.bson.types.ObjectId; -import org.springframework.data.annotation.Id; -import org.springframework.data.mongodb.core.mapping.Document; -@Document @NoArgsConstructor @AllArgsConstructor @Getter @@ -35,9 +31,6 @@ @Builder(toBuilder = true) public class Metadata { - @Id - private ObjectId id; - private String uri; private MetadataState state; diff --git a/src/main/java/nl/dtls/fairdatapoint/service/dashboard/DashboardService.java b/src/main/java/nl/dtls/fairdatapoint/service/dashboard/DashboardService.java index a8cab6d0c..0d4a6a07b 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/dashboard/DashboardService.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/dashboard/DashboardService.java @@ -26,6 +26,7 @@ import nl.dtls.fairdatapoint.api.dto.member.MemberDTO; import nl.dtls.fairdatapoint.api.dto.membership.MembershipDTO; import nl.dtls.fairdatapoint.entity.metadata.Metadata; +import nl.dtls.fairdatapoint.entity.metadata.MetadataState; import nl.dtls.fairdatapoint.entity.resource.ResourceDefinition; import nl.dtls.fairdatapoint.entity.resource.ResourceDefinitionChild; import nl.dtls.fairdatapoint.service.member.MemberService; @@ -94,7 +95,7 @@ private DashboardItemDTO getDashboardItem( final Optional member = memberService.getMemberForCurrentUser(metadataUri.stringValue(), Metadata.class); final Optional membership = member.map(MemberDTO::getMembership); - final Metadata state = metadataStateService.get(metadataUri); + final MetadataState state = metadataStateService.getState(metadataUri); return new DashboardItemDTO( metadataUri.toString(), getTitle(model).getLabel(), @@ -103,7 +104,7 @@ private DashboardItemDTO getDashboardItem( .filter(this::childOnDashboard) .toList(), membership, - state.getState() + state ); } diff --git a/src/main/java/nl/dtls/fairdatapoint/service/index/entry/IndexEntryService.java b/src/main/java/nl/dtls/fairdatapoint/service/index/entry/IndexEntryService.java index 0b0d61046..34a5cd9b5 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/index/entry/IndexEntryService.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/index/entry/IndexEntryService.java @@ -27,6 +27,7 @@ import nl.dtls.fairdatapoint.api.dto.index.entry.*; import nl.dtls.fairdatapoint.api.dto.index.ping.PingDTO; import nl.dtls.fairdatapoint.database.mongo.repository.IndexEntryRepository; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import nl.dtls.fairdatapoint.database.rdf.repository.generic.GenericMetadataRepository; import nl.dtls.fairdatapoint.entity.exception.ResourceNotFoundException; @@ -282,7 +283,7 @@ public Model getEntryHarvestedData(String uuid) throws MetadataRepositoryExcepti .findByUuid(uuid) .orElseThrow(() -> new ResourceNotFoundException(MSG_NOT_FOUND)); final Model model = new TreeModel(); - model.addAll(genericMetadataRepository.find(i(entry.getClientUrl()))); + model.addAll(genericMetadataRepository.find(i(entry.getClientUrl()), RepositoryMode.MAIN)); return model; } diff --git a/src/main/java/nl/dtls/fairdatapoint/service/index/harvester/HarvesterService.java b/src/main/java/nl/dtls/fairdatapoint/service/index/harvester/HarvesterService.java index a18d5138d..7460d4fcd 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/index/harvester/HarvesterService.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/index/harvester/HarvesterService.java @@ -23,6 +23,7 @@ package nl.dtls.fairdatapoint.service.index.harvester; import lombok.extern.slf4j.Slf4j; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import nl.dtls.fairdatapoint.database.rdf.repository.generic.GenericMetadataRepository; import org.eclipse.rdf4j.model.IRI; @@ -64,7 +65,7 @@ public class HarvesterService { private RestTemplate restTemplate; public void deleteHarvestedData(String clientUrl) throws MetadataRepositoryException { - genericMetadataRepository.remove(i(clientUrl)); + genericMetadataRepository.remove(i(clientUrl), RepositoryMode.MAIN); } @Async @@ -83,7 +84,7 @@ public void harvest(String clientUrl) throws MetadataRepositoryException { // 3. Store data for (Map.Entry item : result.entrySet()) { - genericMetadataRepository.save(new ArrayList<>(item.getValue()), i(clientUrl)); + genericMetadataRepository.save(new ArrayList<>(item.getValue()), i(clientUrl), RepositoryMode.MAIN); } log.info("Harvesting for '{}' completed", clientUrl); @@ -106,7 +107,7 @@ private void visitNode( nodes.put(uri, model); final List containers = getSubjectsBy(model, RDF.TYPE, LDP.DIRECT_CONTAINER); - if (containers.size() > 0) { + if (!containers.isEmpty()) { // Get children through LDP links for (Value container : containers) { for (Value child : getObjectsBy( diff --git a/src/main/java/nl/dtls/fairdatapoint/service/metadata/catalog/CatalogMetadataService.java b/src/main/java/nl/dtls/fairdatapoint/service/metadata/catalog/CatalogMetadataService.java index 2b22923f4..dbb562f52 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/metadata/catalog/CatalogMetadataService.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/metadata/catalog/CatalogMetadataService.java @@ -23,6 +23,7 @@ package nl.dtls.fairdatapoint.service.metadata.catalog; import lombok.extern.slf4j.Slf4j; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.catalog.CatalogMetadataRepository; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import nl.dtls.fairdatapoint.entity.resource.ResourceDefinition; @@ -48,10 +49,10 @@ public class CatalogMetadataService extends AbstractMetadataService { private CatalogMetadataRepository metadataRepository; @Override - public Model retrieve(@Nonnull IRI uri) throws MetadataServiceException { - final Model catalog = super.retrieve(uri); + public Model retrieve(@Nonnull IRI uri, RepositoryMode mode) throws MetadataServiceException { + final Model catalog = super.retrieve(uri, mode); try { - final List themes = metadataRepository.getDatasetThemesForCatalog(uri); + final List themes = metadataRepository.getDatasetThemesForCatalog(uri, mode); setThemeTaxonomies(catalog, uri, themes); } catch (MetadataRepositoryException exception) { diff --git a/src/main/java/nl/dtls/fairdatapoint/service/metadata/common/AbstractMetadataService.java b/src/main/java/nl/dtls/fairdatapoint/service/metadata/common/AbstractMetadataService.java index 8ea4b3bdf..87099062c 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/metadata/common/AbstractMetadataService.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/metadata/common/AbstractMetadataService.java @@ -23,8 +23,10 @@ package nl.dtls.fairdatapoint.service.metadata.common; import lombok.extern.slf4j.Slf4j; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.common.MetadataRepository; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; +import nl.dtls.fairdatapoint.entity.exception.ForbiddenException; import nl.dtls.fairdatapoint.entity.exception.ResourceNotFoundException; import nl.dtls.fairdatapoint.entity.metadata.Metadata; import nl.dtls.fairdatapoint.entity.metadata.MetadataGetter; @@ -34,7 +36,6 @@ import nl.dtls.fairdatapoint.service.member.MemberService; import nl.dtls.fairdatapoint.service.metadata.enhance.MetadataEnhancer; import nl.dtls.fairdatapoint.service.metadata.exception.MetadataServiceException; -import nl.dtls.fairdatapoint.service.metadata.state.MetadataStateService; import nl.dtls.fairdatapoint.service.metadata.validator.MetadataValidator; import nl.dtls.fairdatapoint.service.resource.ResourceDefinitionCache; import nl.dtls.fairdatapoint.service.resource.ResourceDefinitionService; @@ -50,7 +51,6 @@ import java.time.OffsetDateTime; import java.util.*; -import java.util.stream.Collectors; import static java.lang.String.format; import static nl.dtls.fairdatapoint.entity.metadata.MetadataGetter.getChildren; @@ -61,6 +61,9 @@ @Slf4j public abstract class AbstractMetadataService implements MetadataService { + private static final String MSG_ERROR_DRAFT_FORBIDDEN = + "You are not allow to view this record in state DRAFT"; + @Autowired @Qualifier("genericMetadataRepository") private MetadataRepository metadataRepository; @@ -80,18 +83,24 @@ public abstract class AbstractMetadataService implements MetadataService { @Autowired private ResourceDefinitionCache resourceDefinitionCache; - @Autowired - private MetadataStateService metadataStateService; - @Autowired private ResourceDefinitionService resourceDefinitionService; @Override public Model retrieve(IRI uri) throws MetadataServiceException, ResourceNotFoundException { + return retrieve(uri, RepositoryMode.COMBINED); + } + + @Override + public Model retrieve(IRI uri, RepositoryMode mode) throws MetadataServiceException, ResourceNotFoundException { try { // 1. Get metadata - final List statements = metadataRepository.find(uri); + final List statements = metadataRepository.find(uri, mode); if (statements.isEmpty()) { + if (mode.equals(RepositoryMode.MAIN) + && !metadataRepository.find(uri, RepositoryMode.DRAFTS).isEmpty()) { + throw new ForbiddenException(MSG_ERROR_DRAFT_FORBIDDEN); + } throw new ResourceNotFoundException( format("No metadata found for the uri '%s'", uri) ); @@ -109,11 +118,16 @@ public Model retrieve(IRI uri) throws MetadataServiceException, ResourceNotFound @Override public List retrieve(List uris) { + return retrieve(uris, RepositoryMode.MAIN); + } + + @Override + public List retrieve(List uris, RepositoryMode mode) { return uris .stream() - .map(suppress(this::retrieve)) + .map(suppress(uri -> retrieve(uri, mode))) .filter(Objects::nonNull) - .collect(Collectors.toList()); + .toList(); } @Override @@ -123,10 +137,9 @@ public Model store( try { metadataValidator.validate(metadata, uri, resourceDefinition); metadataEnhancer.enhance(metadata, uri, resourceDefinition); - metadataRepository.save(new ArrayList<>(metadata), uri); + metadataRepository.save(new ArrayList<>(metadata), uri, RepositoryMode.DRAFTS); updateParent(metadata, uri, resourceDefinition); addPermissions(uri); - addState(uri); return metadata; } catch (MetadataRepositoryException exception) { @@ -147,11 +160,18 @@ public Model update( if (validate) { metadataValidator.validate(metadata, uri, resourceDefinition); } - final Model oldMetadata = retrieve(uri); - metadataEnhancer.enhance(metadata, uri, resourceDefinition, oldMetadata); - metadataRepository.remove(uri); - metadataRepository.save(new ArrayList<>(metadata), uri); - updateParent(metadata, uri, resourceDefinition); + final Model oldMainMetadata = retrieve(uri, RepositoryMode.MAIN); + if (oldMainMetadata.isEmpty()) { + final Model oldDraftMetadata = retrieve(uri, RepositoryMode.DRAFTS); + metadataEnhancer.enhance(metadata, uri, resourceDefinition, oldDraftMetadata); + metadataRepository.remove(uri, RepositoryMode.DRAFTS); + metadataRepository.save(new ArrayList<>(metadata), uri, RepositoryMode.DRAFTS); + } + else { + metadataEnhancer.enhance(metadata, uri, resourceDefinition, oldMainMetadata); + metadataRepository.remove(uri, RepositoryMode.MAIN); + metadataRepository.save(new ArrayList<>(metadata), uri, RepositoryMode.MAIN); + } return metadata; } catch (MetadataRepositoryException | MetadataServiceException exception) { @@ -193,7 +213,8 @@ public void delete(IRI uri, ResourceDefinition rd) throws MetadataServiceExcepti } // Delete itself - metadataRepository.remove(uri); + metadataRepository.remove(uri, RepositoryMode.MAIN); + metadataRepository.remove(uri, RepositoryMode.DRAFTS); } catch (MetadataRepositoryException | MetadataServiceException exception) { throw new MetadataServiceException(exception.getMessage()); @@ -203,6 +224,7 @@ public void delete(IRI uri, ResourceDefinition rd) throws MetadataServiceExcepti protected void updateParent( Model metadata, IRI uri, ResourceDefinition resourceDefinition ) throws MetadataServiceException { + // TODO REPO: first check if in DRAFTS or MAIN and then update final IRI parent = MetadataGetter.getParent(metadata); if (parent != null) { final ResourceDefinition rdParent = @@ -216,9 +238,21 @@ protected void updateParent( statements.add(s(parent, i(rdChild.getRelationUri()), uri)); } } - metadataRepository.removeStatement(parent, FDP.METADATAMODIFIED, null, parent); - statements.add(s(parent, FDP.METADATAMODIFIED, l(OffsetDateTime.now()))); - metadataRepository.save(statements, parent); + final List parentMetadata = metadataRepository.find(parent, RepositoryMode.MAIN); + if (parentMetadata.isEmpty()) { + metadataRepository.removeStatement( + parent, FDP.METADATAMODIFIED, null, parent, RepositoryMode.DRAFTS + ); + statements.add(s(parent, FDP.METADATAMODIFIED, l(OffsetDateTime.now()))); + metadataRepository.save(statements, parent, RepositoryMode.DRAFTS); + } + else { + metadataRepository.removeStatement( + parent, FDP.METADATAMODIFIED, null, parent, RepositoryMode.MAIN + ); + statements.add(s(parent, FDP.METADATAMODIFIED, l(OffsetDateTime.now()))); + metadataRepository.save(statements, parent, RepositoryMode.MAIN); + } } catch (MetadataRepositoryException exception) { throw new MetadataServiceException("Problem with updating parent timestamp"); @@ -237,10 +271,6 @@ private void addPermissions(IRI uri) { memberService.createOwner(uri.stringValue(), Metadata.class, user.get().getUuid()); } - private void addState(IRI uri) { - metadataStateService.initState(uri); - } - protected MemberService getMemberService() { return memberService; } diff --git a/src/main/java/nl/dtls/fairdatapoint/service/metadata/common/MetadataService.java b/src/main/java/nl/dtls/fairdatapoint/service/metadata/common/MetadataService.java index 7e106561a..3b79801c5 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/metadata/common/MetadataService.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/metadata/common/MetadataService.java @@ -22,6 +22,7 @@ */ package nl.dtls.fairdatapoint.service.metadata.common; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.entity.exception.ResourceNotFoundException; import nl.dtls.fairdatapoint.entity.resource.ResourceDefinition; import nl.dtls.fairdatapoint.service.metadata.exception.MetadataServiceException; @@ -36,6 +37,10 @@ public interface MetadataService { List retrieve(List uri) throws MetadataServiceException, ResourceNotFoundException; + Model retrieve(IRI uri, RepositoryMode mode) throws MetadataServiceException, ResourceNotFoundException; + + List retrieve(List uri, RepositoryMode mode) throws MetadataServiceException, ResourceNotFoundException; + Model store( Model metadata, IRI uri, ResourceDefinition resourceDefinition ) throws MetadataServiceException; diff --git a/src/main/java/nl/dtls/fairdatapoint/service/metadata/state/MetadataStateService.java b/src/main/java/nl/dtls/fairdatapoint/service/metadata/state/MetadataStateService.java index aa3cf62f1..47835349d 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/metadata/state/MetadataStateService.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/metadata/state/MetadataStateService.java @@ -22,106 +22,130 @@ */ package nl.dtls.fairdatapoint.service.metadata.state; +import lombok.extern.slf4j.Slf4j; import nl.dtls.fairdatapoint.api.dto.metadata.MetaStateChangeDTO; import nl.dtls.fairdatapoint.api.dto.metadata.MetaStateDTO; -import nl.dtls.fairdatapoint.database.mongo.repository.MetadataRepository; -import nl.dtls.fairdatapoint.entity.exception.ResourceNotFoundException; -import nl.dtls.fairdatapoint.entity.metadata.Metadata; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; +import nl.dtls.fairdatapoint.database.rdf.repository.common.MetadataRepository; +import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; +import nl.dtls.fairdatapoint.entity.exception.ValidationException; import nl.dtls.fairdatapoint.entity.metadata.MetadataState; import nl.dtls.fairdatapoint.entity.resource.ResourceDefinition; import nl.dtls.fairdatapoint.entity.resource.ResourceDefinitionChild; -import nl.dtls.fairdatapoint.service.metadata.validator.MetadataStateValidator; +import nl.dtls.fairdatapoint.service.metadata.common.MetadataService; +import nl.dtls.fairdatapoint.service.metadata.exception.MetadataServiceException; import nl.dtls.fairdatapoint.service.user.CurrentUserService; import org.eclipse.rdf4j.model.IRI; import org.eclipse.rdf4j.model.Model; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; -import static java.lang.String.format; -import static nl.dtls.fairdatapoint.entity.metadata.MetadataGetter.getUri; import static nl.dtls.fairdatapoint.util.RdfUtil.getObjectsBy; import static nl.dtls.fairdatapoint.util.ValueFactoryHelper.i; +@Slf4j @Service public class MetadataStateService { - private static final String MSG_NOT_FOUND = "Metadata info '%s' was not found"; - @Autowired - private MetadataRepository metadataRepository; + @Qualifier("genericMetadataService") + private MetadataService metadataService; @Autowired - private MetadataStateValidator metadataStateValidator; + @Qualifier("genericMetadataRepository") + private MetadataRepository metadataRepository; @Autowired private CurrentUserService currentUserService; - public Metadata get(IRI metadataUri) { - final Optional oMetadata = metadataRepository.findByUri(metadataUri.stringValue()); - if (oMetadata.isEmpty()) { - throw new ResourceNotFoundException(format(MSG_NOT_FOUND, metadataUri)); + public boolean isDraft(IRI uri) throws MetadataServiceException { + try { + return !metadataRepository.find(uri, RepositoryMode.DRAFTS).isEmpty(); + } + catch (MetadataRepositoryException exc) { + throw new MetadataServiceException(exc.getMessage()); + } + } + + public boolean isPublished(IRI uri) throws MetadataServiceException { + try { + return !metadataRepository.find(uri, RepositoryMode.MAIN).isEmpty(); + } + catch (MetadataRepositoryException exc) { + throw new MetadataServiceException(exc.getMessage()); + } + } + + public MetadataState getState(IRI entityUri) throws MetadataServiceException { + if (isDraft(entityUri)) { + return MetadataState.DRAFT; } - return oMetadata.get(); + return MetadataState.PUBLISHED; } - public MetaStateDTO getState(IRI metadataUri, Model model, ResourceDefinition definition) { - // 1. Return null if user is not log in + public MetaStateDTO getStateDTO( + IRI entityUri, Model entity, ResourceDefinition definition + ) throws MetadataServiceException { + // 1. Return null if user is not logged in if (currentUserService.getCurrentUser().isEmpty()) { return null; } + final Model model = metadataService.retrieve(entityUri, RepositoryMode.COMBINED); // 2. Get metadata info for current - final Optional oMetadata = metadataRepository.findByUri(metadataUri.stringValue()); - if (oMetadata.isEmpty()) { - throw new ResourceNotFoundException(format(MSG_NOT_FOUND, metadataUri)); - } - final Metadata metadata = oMetadata.get(); + final MetaStateDTO result = new MetaStateDTO(); + result.setCurrent(getState(entityUri)); // 3. Get metadata info for children + // TODO: make querying more efficient (query published and drafts, in 2 queries) final List childrenUris = new ArrayList<>(); for (ResourceDefinitionChild rdChild : definition.getChildren()) { final IRI relationUri = i(rdChild.getRelationUri()); - for (org.eclipse.rdf4j.model.Value childUri : getObjectsBy(model, metadataUri, relationUri)) { + for (org.eclipse.rdf4j.model.Value childUri : getObjectsBy(model, entityUri, relationUri)) { childrenUris.add(childUri.stringValue()); } } - final Map children = - metadataRepository.findByUriIn(childrenUris) - .stream() - .collect(Collectors.toMap(Metadata::getUri, Metadata::getState)); - - // 4. Build response - return new MetaStateDTO( - metadata.getState(), - children - ); - } - - public void initState(IRI metadataUri) { - final Metadata metadata = new Metadata(null, metadataUri.stringValue(), MetadataState.DRAFT); - metadataRepository.save(metadata); + final Map children = new HashMap<>(); + childrenUris.forEach(childUri -> { + try { + children.put(childUri, getState(i(childUri))); + } + catch (MetadataServiceException exc) { + log.warn("Failed to metadata check state: {} ({})", childUri, exc.getMessage()); + } + }); + result.setChildren(children); + return result; } - public void modifyState(IRI metadataUri, MetaStateChangeDTO reqDto) { - // 1. Get metadata info for current - final Optional oMetadata = metadataRepository.findByUri(metadataUri.stringValue()); - if (oMetadata.isEmpty()) { - throw new ResourceNotFoundException(format(MSG_NOT_FOUND, metadataUri)); + public void modifyState(IRI entityUri, MetaStateChangeDTO reqDto) + throws MetadataServiceException, ValidationException { + try { + if (isDraft(entityUri)) { + if (reqDto.getCurrent().equals(MetadataState.PUBLISHED)) { + metadataRepository.moveToMain(entityUri); + } + else { + throw new ValidationException("You can not change state to DRAFT"); + } + } + else { + if (reqDto.getCurrent().equals(MetadataState.DRAFT)) { + metadataRepository.moveToDrafts(entityUri); + } + else { + throw new ValidationException("Metadata is already published"); + } + } + } + catch (MetadataRepositoryException exc) { + throw new MetadataServiceException(exc.getMessage()); } - final Metadata metadata = oMetadata.get(); - - // 2. Validate - metadataStateValidator.validate(reqDto, metadata); - - // 3. Update - metadata.setState(reqDto.getCurrent()); - metadataRepository.save(metadata); } - } diff --git a/src/main/java/nl/dtls/fairdatapoint/service/metadata/validator/MetadataValidator.java b/src/main/java/nl/dtls/fairdatapoint/service/metadata/validator/MetadataValidator.java index 6832d482c..5fbd9b854 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/metadata/validator/MetadataValidator.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/metadata/validator/MetadataValidator.java @@ -22,6 +22,7 @@ */ package nl.dtls.fairdatapoint.service.metadata.validator; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.common.MetadataRepository; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import nl.dtls.fairdatapoint.entity.exception.ValidationException; @@ -90,7 +91,7 @@ private void validateParent(Model metadata, ResourceDefinition definition) throw try { // select parent based on URI prefix for (String rdfType : resourceDefinitionService.getTargetClassUris(rdParent)) { - if (!metadataRepository.checkExistence(parent, RDF.TYPE, i(rdfType))) { + if (!metadataRepository.checkExistence(parent, RDF.TYPE, i(rdfType), RepositoryMode.COMBINED)) { throw new ValidationException(format("Parent is not of type (missing type: %s)", rdfType)); } } diff --git a/src/main/java/nl/dtls/fairdatapoint/service/reset/FactoryDefaults.java b/src/main/java/nl/dtls/fairdatapoint/service/reset/FactoryDefaults.java index a44b39791..7c085d106 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/reset/FactoryDefaults.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/reset/FactoryDefaults.java @@ -24,8 +24,6 @@ import nl.dtls.fairdatapoint.entity.membership.Membership; import nl.dtls.fairdatapoint.entity.membership.MembershipPermission; -import nl.dtls.fairdatapoint.entity.metadata.Metadata; -import nl.dtls.fairdatapoint.entity.metadata.MetadataState; import nl.dtls.fairdatapoint.entity.resource.*; import nl.dtls.fairdatapoint.entity.schema.MetadataSchema; import nl.dtls.fairdatapoint.entity.schema.MetadataSchemaType; @@ -513,13 +511,6 @@ public static List fdpStatements(String persistentUrl, IRI license, return s; } - public static Metadata metadataRepository(String persistentUrl) { - return Metadata.builder() - .uri(persistentUrl) - .state(MetadataState.PUBLISHED) - .build(); - } - private static void add(List statements, IRI predicate, org.eclipse.rdf4j.model.Value object, IRI base) { statements.add(s(base, predicate, object, base)); diff --git a/src/main/java/nl/dtls/fairdatapoint/service/reset/ResetService.java b/src/main/java/nl/dtls/fairdatapoint/service/reset/ResetService.java index 0879a829b..f5b3381db 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/reset/ResetService.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/reset/ResetService.java @@ -70,7 +70,10 @@ public class ResetService { private IRI language; @Autowired - private Repository repository; + private Repository mainRepository; + + @Autowired + private Repository draftsRepository; @Autowired private ApiKeyRepository apiKeyRepository; @@ -99,9 +102,6 @@ public class ResetService { @Autowired private ResourceDefinitionTargetClassesCache resourceDefinitionTargetClassesCache; - @Autowired - private MetadataRepository metadataRepository; - @Autowired private GenericMetadataService genericMetadataService; @@ -169,12 +169,12 @@ private void clearResourceDefinitions() { } private void clearMetadata() throws MetadataServiceException { + // TODO REPO: clear DRAFTS repository log.debug("Clearing metadata"); final Optional resourceDefinition = resourceDefinitionRepository.findByUrlPrefix(""); if (resourceDefinition.isPresent()) { genericMetadataService.delete(i(persistentUrl), resourceDefinition.get()); - metadataRepository.deleteAll(); } } @@ -196,7 +196,7 @@ private void restoreDefaultMemberships() { private void restoreDefaultMetadata() { log.debug("Creating default metadata"); - try (RepositoryConnection conn = repository.getConnection()) { + try (RepositoryConnection conn = mainRepository.getConnection()) { final List statements = FactoryDefaults.fdpStatements( persistentUrl, license, @@ -204,7 +204,6 @@ private void restoreDefaultMetadata() { accessRightsDescription ); conn.add(statements); - metadataRepository.save(FactoryDefaults.metadataRepository(persistentUrl)); } catch (RepositoryException exception) { log.error(exception.getMessage(), exception); diff --git a/src/main/java/nl/dtls/fairdatapoint/service/search/SearchService.java b/src/main/java/nl/dtls/fairdatapoint/service/search/SearchService.java index 3ecd0808b..daa094fe1 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/search/SearchService.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/search/SearchService.java @@ -22,13 +22,11 @@ */ package nl.dtls.fairdatapoint.service.search; -import com.google.common.base.Charsets; import com.google.common.io.Resources; import nl.dtls.fairdatapoint.api.dto.search.*; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import nl.dtls.fairdatapoint.database.rdf.repository.generic.GenericMetadataRepository; -import nl.dtls.fairdatapoint.entity.exception.ResourceNotFoundException; -import nl.dtls.fairdatapoint.entity.metadata.MetadataState; import nl.dtls.fairdatapoint.entity.search.SearchFilterCacheContainer; import nl.dtls.fairdatapoint.entity.search.SearchFilterType; import nl.dtls.fairdatapoint.entity.search.SearchFilterValue; @@ -37,7 +35,6 @@ import nl.dtls.fairdatapoint.service.metadata.state.MetadataStateService; import nl.dtls.fairdatapoint.service.settings.SettingsService; import org.apache.commons.lang.text.StrSubstitutor; -import org.eclipse.rdf4j.model.IRI; import org.eclipse.rdf4j.query.MalformedQueryException; import org.eclipse.rdf4j.query.parser.sparql.SPARQLParser; import org.springframework.beans.factory.annotation.Autowired; @@ -46,6 +43,7 @@ import java.io.IOException; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -88,7 +86,7 @@ public List search( } public List search(SearchQueryDTO reqDto) throws MetadataRepositoryException { - final List results = metadataRepository.findByLiteral(l(reqDto.getQuery())); + final List results = metadataRepository.findByLiteral(l(reqDto.getQuery()), RepositoryMode.MAIN); return processSearchResults(results); } @@ -101,7 +99,7 @@ public List search( final SPARQLParser parser = new SPARQLParser(); parser.parseQuery(query, persistentUrl); // Get and process results for query - final List results = metadataRepository.findBySparqlQuery(query); + final List results = metadataRepository.findBySparqlQuery(query, RepositoryMode.MAIN); return processSearchResults(results); } @@ -150,7 +148,6 @@ private SearchFilterDTO enrichItems(SettingsSearchFilter filter) { } private List queryFilterItems(String predicate) { - // TODO: filter related to DRAFT records final SearchFilterCacheContainer cacheContainer = searchFilterCache.getFilter(predicate); if (cacheContainer != null) { @@ -158,7 +155,7 @@ private List queryFilterItems(String predicate) { } try { final List result = - metadataRepository.findByFilterPredicate(i(predicate)); + metadataRepository.findByFilterPredicate(i(predicate), RepositoryMode.MAIN); searchFilterCache.setFilter(predicate, new SearchFilterCacheContainer(result)); return result; } @@ -178,7 +175,6 @@ private List processSearchResults(List results) { ) .entrySet() .parallelStream() - .filter(entry -> isUsableForFilter(i(entry.getKey()))) .map(entry -> searchMapper.toResultDTO(entry.getKey(), entry.getValue())) .collect(Collectors.toMap(SearchResultDTO::getUri, Function.identity())); return results @@ -190,18 +186,6 @@ private List processSearchResults(List results) { .toList(); } - private boolean isUsableForFilter(IRI iri) { - try { - return !metadataStateService - .get(iri) - .getState() - .equals(MetadataState.DRAFT); - } - catch (ResourceNotFoundException exception) { - return true; - } - } - private String composeQuery(SearchQueryVariablesDTO reqDto) { final StrSubstitutor substitutor = new StrSubstitutor(searchMapper.toSubstitutions(reqDto), "{{", "}}"); @@ -211,7 +195,7 @@ private String composeQuery(SearchQueryVariablesDTO reqDto) { private static String loadSparqlQueryTemplate() { try { final URL fileURL = SearchService.class.getResource(QUERY_TEMPLATE_NAME); - return Resources.toString(fileURL, Charsets.UTF_8); + return Resources.toString(fileURL, StandardCharsets.UTF_8); } catch (IOException exception) { throw new RuntimeException( diff --git a/src/main/java/nl/dtls/fairdatapoint/service/settings/SettingsMapper.java b/src/main/java/nl/dtls/fairdatapoint/service/settings/SettingsMapper.java index 6ed192250..2e4ea7777 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/settings/SettingsMapper.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/settings/SettingsMapper.java @@ -59,7 +59,8 @@ public SettingsDTO toDTO(Settings settings) { .persistentUrl(instanceProperties.getPersistentUrl()) .metadataMetrics(settings.getMetadataMetrics()) .ping(toDTO(settings.getPing())) - .repository(getRepositoryDTO()) + .mainRepository(getMainRepositoryDTO()) + .draftsRepository(getDraftsRepositoryDTO()) .search( SettingsSearchDTO .builder() @@ -129,15 +130,27 @@ public SettingsPingDTO toDTO(SettingsPing settingsPing) { .build(); } - public SettingsRepositoryDTO getRepositoryDTO() { + public SettingsRepositoryDTO getMainRepositoryDTO() { return SettingsRepositoryDTO .builder() - .type(repositoryProperties.getStringType()) - .dir(repositoryProperties.getDir()) - .url(repositoryProperties.getUrl()) - .repository(repositoryProperties.getRepository()) - .username(repositoryProperties.getUsername()) - .password(repositoryProperties.getPassword() != null ? "" : null) + .type(repositoryProperties.getMain().getStringType()) + .dir(repositoryProperties.getMain().getDir()) + .url(repositoryProperties.getMain().getUrl()) + .repository(repositoryProperties.getMain().getRepository()) + .username(repositoryProperties.getMain().getUsername()) + .password(redact(repositoryProperties.getMain().getPassword())) + .build(); + } + + public SettingsRepositoryDTO getDraftsRepositoryDTO() { + return SettingsRepositoryDTO + .builder() + .type(repositoryProperties.getDrafts().getStringType()) + .dir(repositoryProperties.getDrafts().getDir()) + .url(repositoryProperties.getDrafts().getUrl()) + .repository(repositoryProperties.getDrafts().getRepository()) + .username(repositoryProperties.getDrafts().getUsername()) + .password(redact(repositoryProperties.getDrafts().getPassword())) .build(); } @@ -243,4 +256,8 @@ public SettingsPingUpdateDTO toUpdateDTO(SettingsPing settingsPing) { .endpoints(settingsPing.getEndpoints()) .build(); } + + private String redact(String secret) { + return secret != null ? "" : null; + } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index f09eaeec7..7aa149cbd 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -42,21 +42,38 @@ security: # valid repository type options {1 = inMemoryStore, 2 = NativeStore, 3 = AllegroGraph, 4 = graphDB, 5 = blazegraph} repository: - type: ${FDP_TRIPLE_STORE_TYPE:1} - native: - dir: ${FDP_TRIPLE_STORE_DIR:/tmp/fdp-store/} - agraph: - url: ${FDP_TRIPLE_STORE_URL:http://localhost:10035/repositories/fdp} - username: ${FDP_TRIPLE_STORE_USERNAME:user} - password: ${FDP_TRIPLE_STORE_PASSWORD:password} - graphDb: - url: ${FDP_TRIPLE_STORE_URL:http://localhost:7200} - repository: ${FDP_TRIPLE_STORE_REPOSITORY:test} - username: ${FDP_TRIPLE_STORE_USERNAME:user} - password: ${FDP_TRIPLE_STORE_PASSWORD:password} - blazegraph: - url: ${FDP_TRIPLE_STORE_URL:http://localhost:8888/blazegraph} - repository: ${FDP_TRIPLE_STORE_REPOSITORY:test} + main: + type: ${FDP_TRIPLE_STORE_TYPE:1} + native: + dir: ${FDP_TRIPLE_STORE_DIR:/tmp/fdp-store/} + agraph: + url: ${FDP_TRIPLE_STORE_URL:http://localhost:10035/repositories/fdp} + username: ${FDP_TRIPLE_STORE_USERNAME:user} + password: ${FDP_TRIPLE_STORE_PASSWORD:password} + graphDb: + url: ${FDP_TRIPLE_STORE_URL:http://localhost:7200} + repository: ${FDP_TRIPLE_STORE_REPOSITORY:test} + username: ${FDP_TRIPLE_STORE_USERNAME:user} + password: ${FDP_TRIPLE_STORE_PASSWORD:password} + blazegraph: + url: ${FDP_TRIPLE_STORE_URL:http://localhost:8888/blazegraph} + repository: ${FDP_TRIPLE_STORE_REPOSITORY:test} + drafts: + type: ${FDP_DRAFT_TRIPLE_STORE_TYPE:1} + native: + dir: ${FDP_DRAFT_TRIPLE_STORE_DIR:/tmp/fdp-store/} + agraph: + url: ${FDP_DRAFT_TRIPLE_STORE_URL:http://localhost:10035/repositories/fdp} + username: ${FDP_DRAFT_TRIPLE_STORE_USERNAME:user} + password: ${FDP_DRAFT_TRIPLE_STORE_PASSWORD:password} + graphDb: + url: ${FDP_DRAFT_TRIPLE_STORE_URL:http://localhost:7200} + repository: ${FDP_DRAFT_TRIPLE_STORE_REPOSITORY:test} + username: ${FDP_DRAFT_TRIPLE_STORE_USERNAME:user} + password: ${FDP_DRAFT_TRIPLE_STORE_PASSWORD:password} + blazegraph: + url: ${FDP_DRAFT_TRIPLE_STORE_URL:http://localhost:8888/blazegraph} + repository: ${FDP_DRAFT_TRIPLE_STORE_REPOSITORY:test} metadataProperties: language: ${FDP_METADATA_LANGUAGE:http://id.loc.gov/vocabulary/iso639-1/en} diff --git a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/catalog/meta/List_GET.java b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/catalog/meta/List_GET.java index 7e6bf8f4c..427c0f21f 100644 --- a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/catalog/meta/List_GET.java +++ b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/catalog/meta/List_GET.java @@ -27,12 +27,13 @@ import nl.dtls.fairdatapoint.api.dto.metadata.MetaDTO; import nl.dtls.fairdatapoint.api.dto.metadata.MetaStateDTO; import nl.dtls.fairdatapoint.database.mongo.migration.development.membership.data.MembershipFixtures; -import nl.dtls.fairdatapoint.database.mongo.migration.development.metadata.data.MetadataFixtures; import nl.dtls.fairdatapoint.database.mongo.migration.development.user.data.UserFixtures; +import nl.dtls.fairdatapoint.entity.metadata.MetadataState; import nl.dtls.fairdatapoint.service.member.MemberMapper; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -63,7 +64,8 @@ public class List_GET extends WebIntegrationTest { private MemberMapper memberMapper; @Autowired - private MetadataFixtures metadataFixtures; + @Qualifier("persistentUrl") + private String persistentUrl; private URI url(String id) { return URI.create(format("/catalog/%s/meta", id)); @@ -91,10 +93,10 @@ public void res200() { assertThat(result.getStatusCode(), is(equalTo(HttpStatus.OK))); assertThat(result.getBody().getMember(), is(equalTo(expMember))); assertThat(result.getBody().getState(), is(equalTo(new MetaStateDTO( - metadataFixtures.catalog1().getState(), + MetadataState.PUBLISHED, Map.of( - metadataFixtures.dataset1().getUri(), metadataFixtures.dataset1().getState(), - metadataFixtures.dataset2().getUri(), metadataFixtures.dataset2().getState() + persistentUrl + "/dataset/dataset-1", MetadataState.PUBLISHED, + persistentUrl + "/dataset/dataset-2", MetadataState.DRAFT ) )))); } diff --git a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/catalog/meta/List_State_PUT.java b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/catalog/meta/List_State_PUT.java index 7d58754b0..725d3457e 100644 --- a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/catalog/meta/List_State_PUT.java +++ b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/catalog/meta/List_State_PUT.java @@ -24,13 +24,13 @@ import nl.dtls.fairdatapoint.WebIntegrationTest; import nl.dtls.fairdatapoint.api.dto.metadata.MetaStateChangeDTO; -import nl.dtls.fairdatapoint.database.mongo.migration.development.metadata.data.MetadataFixtures; -import nl.dtls.fairdatapoint.database.mongo.repository.MetadataRepository; -import nl.dtls.fairdatapoint.entity.metadata.Metadata; +import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; +import nl.dtls.fairdatapoint.database.rdf.repository.generic.GenericMetadataRepository; import nl.dtls.fairdatapoint.entity.metadata.MetadataState; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -43,6 +43,7 @@ import static nl.dtls.fairdatapoint.acceptance.common.ForbiddenTest.createNoUserForbiddenTestPut; import static nl.dtls.fairdatapoint.acceptance.metadata.Common.createMetadataStateAlreadyPublished; import static nl.dtls.fairdatapoint.acceptance.metadata.Common.createMetadataStateChangeToDraft; +import static nl.dtls.fairdatapoint.util.ValueFactoryHelper.i; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsEqual.equalTo; @@ -51,10 +52,11 @@ public class List_State_PUT extends WebIntegrationTest { @Autowired - private MetadataFixtures metadataFixtures; + @Qualifier("persistentUrl") + private String persistentUrl; @Autowired - private MetadataRepository metadataRepository; + private GenericMetadataRepository repository; private URI url(String id) { return URI.create(format("/catalog/%s/meta/state", id)); @@ -66,7 +68,7 @@ private MetaStateChangeDTO reqDto() { @Test @DisplayName("HTTP 200") - public void res200() { + public void res200() throws MetadataRepositoryException { // GIVEN: RequestEntity request = RequestEntity .put(url("catalog-1")) @@ -76,10 +78,8 @@ public void res200() { ParameterizedTypeReference responseType = new ParameterizedTypeReference<>() { }; - // AND: Prepare database - Metadata metadata = metadataRepository.findByUri(metadataFixtures.catalog1().getUri()).get(); - metadata.setState(MetadataState.DRAFT); - metadataRepository.save(metadata); + // AND: Prepare database (make it a draft) + repository.moveToDrafts(i(persistentUrl + "/catalog/catalog-1")); // WHEN: ResponseEntity result = client.exchange(request, responseType); @@ -91,13 +91,15 @@ public void res200() { @Test @DisplayName("HTTP 400: Metadata is already published") - public void res400_already_published() { + public void res400_already_published() throws MetadataRepositoryException { + repository.moveToMain(i(persistentUrl + "/catalog/catalog-1")); createMetadataStateAlreadyPublished(client, url("catalog-1")); } @Test @DisplayName("HTTP 400: You can not change state to DRAFT") - public void res400_change_to_draft() { + public void res400_change_to_draft() throws MetadataRepositoryException { + repository.moveToDrafts(i(persistentUrl + "/catalog/catalog-1")); createMetadataStateChangeToDraft(client, url("catalog-1")); } diff --git a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/dataset/meta/List_GET.java b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/dataset/meta/List_GET.java index e79d05da0..a9c5c1117 100644 --- a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/dataset/meta/List_GET.java +++ b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/dataset/meta/List_GET.java @@ -27,13 +27,15 @@ import nl.dtls.fairdatapoint.api.dto.metadata.MetaDTO; import nl.dtls.fairdatapoint.api.dto.metadata.MetaStateDTO; import nl.dtls.fairdatapoint.database.mongo.migration.development.membership.data.MembershipFixtures; -import nl.dtls.fairdatapoint.database.mongo.migration.development.metadata.data.MetadataFixtures; import nl.dtls.fairdatapoint.database.mongo.migration.development.user.data.UserFixtures; +import nl.dtls.fairdatapoint.entity.metadata.MetadataState; import nl.dtls.fairdatapoint.service.member.MemberMapper; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.data.mongodb.core.query.Meta; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.RequestEntity; @@ -63,7 +65,8 @@ public class List_GET extends WebIntegrationTest { private MemberMapper memberMapper; @Autowired - private MetadataFixtures metadataFixtures; + @Qualifier("persistentUrl") + private String persistentUrl; private URI url(String id) { return URI.create(format("/dataset/%s/meta", id)); @@ -91,10 +94,10 @@ public void res200() { assertThat(result.getStatusCode(), is(equalTo(HttpStatus.OK))); assertThat(result.getBody().getMember(), is(equalTo(expMember))); assertThat(result.getBody().getState(), is(equalTo(new MetaStateDTO( - metadataFixtures.dataset1().getState(), + MetadataState.PUBLISHED, Map.of( - metadataFixtures.distribution1().getUri(), metadataFixtures.distribution1().getState(), - metadataFixtures.distribution2().getUri(), metadataFixtures.distribution2().getState() + persistentUrl + "/distribution/distribution-1", MetadataState.PUBLISHED, + persistentUrl + "/distribution/distribution-2", MetadataState.DRAFT ) )))); } diff --git a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/dataset/meta/List_State_PUT.java b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/dataset/meta/List_State_PUT.java index 9a958a4bb..447d52434 100644 --- a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/dataset/meta/List_State_PUT.java +++ b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/dataset/meta/List_State_PUT.java @@ -24,13 +24,13 @@ import nl.dtls.fairdatapoint.WebIntegrationTest; import nl.dtls.fairdatapoint.api.dto.metadata.MetaStateChangeDTO; -import nl.dtls.fairdatapoint.database.mongo.migration.development.metadata.data.MetadataFixtures; -import nl.dtls.fairdatapoint.database.mongo.repository.MetadataRepository; -import nl.dtls.fairdatapoint.entity.metadata.Metadata; +import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; +import nl.dtls.fairdatapoint.database.rdf.repository.generic.GenericMetadataRepository; import nl.dtls.fairdatapoint.entity.metadata.MetadataState; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -43,6 +43,7 @@ import static nl.dtls.fairdatapoint.acceptance.common.ForbiddenTest.createNoUserForbiddenTestPut; import static nl.dtls.fairdatapoint.acceptance.metadata.Common.createMetadataStateAlreadyPublished; import static nl.dtls.fairdatapoint.acceptance.metadata.Common.createMetadataStateChangeToDraft; +import static nl.dtls.fairdatapoint.util.ValueFactoryHelper.i; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsEqual.equalTo; @@ -51,10 +52,11 @@ public class List_State_PUT extends WebIntegrationTest { @Autowired - private MetadataFixtures metadataFixtures; + @Qualifier("persistentUrl") + private String persistentUrl; @Autowired - private MetadataRepository metadataRepository; + private GenericMetadataRepository repository; private URI url(String id) { return URI.create(format("/dataset/%s/meta/state", id)); @@ -66,7 +68,7 @@ private MetaStateChangeDTO reqDto() { @Test @DisplayName("HTTP 200") - public void res200() { + public void res200() throws MetadataRepositoryException { // GIVEN: RequestEntity request = RequestEntity .put(url("dataset-1")) @@ -76,10 +78,8 @@ public void res200() { ParameterizedTypeReference responseType = new ParameterizedTypeReference<>() { }; - // AND: Prepare database - Metadata metadata = metadataRepository.findByUri(metadataFixtures.dataset1().getUri()).get(); - metadata.setState(MetadataState.DRAFT); - metadataRepository.save(metadata); + // AND: Prepare database (make it a draft) + repository.moveToDrafts(i(persistentUrl + "/dataset/dataset-1")); // WHEN: ResponseEntity result = client.exchange(request, responseType); @@ -91,13 +91,15 @@ public void res200() { @Test @DisplayName("HTTP 400: Metadata is already published") - public void res400_already_published() { + public void res400_already_published() throws MetadataRepositoryException { + repository.moveToMain(i(persistentUrl + "/dataset/dataset-1")); createMetadataStateAlreadyPublished(client, url("dataset-1")); } @Test @DisplayName("HTTP 400: You can not change state to DRAFT") - public void res400_change_to_draft() { + public void res400_change_to_draft() throws MetadataRepositoryException { + repository.moveToDrafts(i(persistentUrl + "/dataset/dataset-1")); createMetadataStateChangeToDraft(client, url("dataset-1")); } diff --git a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/distribution/meta/List_GET.java b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/distribution/meta/List_GET.java index 1186c91ac..3b62953be 100644 --- a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/distribution/meta/List_GET.java +++ b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/distribution/meta/List_GET.java @@ -27,8 +27,8 @@ import nl.dtls.fairdatapoint.api.dto.metadata.MetaDTO; import nl.dtls.fairdatapoint.api.dto.metadata.MetaStateDTO; import nl.dtls.fairdatapoint.database.mongo.migration.development.membership.data.MembershipFixtures; -import nl.dtls.fairdatapoint.database.mongo.migration.development.metadata.data.MetadataFixtures; import nl.dtls.fairdatapoint.database.mongo.migration.development.user.data.UserFixtures; +import nl.dtls.fairdatapoint.entity.metadata.MetadataState; import nl.dtls.fairdatapoint.service.member.MemberMapper; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -62,9 +62,6 @@ public class List_GET extends WebIntegrationTest { @Autowired private MemberMapper memberMapper; - @Autowired - private MetadataFixtures metadataFixtures; - private URI url(String id) { return URI.create(format("/distribution/%s/meta", id)); } @@ -91,7 +88,7 @@ public void res200() { assertThat(result.getStatusCode(), is(equalTo(HttpStatus.OK))); assertThat(result.getBody().getMember(), is(equalTo(expMember))); assertThat(result.getBody().getState(), is(equalTo(new MetaStateDTO( - metadataFixtures.distribution1().getState(), + MetadataState.PUBLISHED, Map.of() )))); } diff --git a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/distribution/meta/List_State_PUT.java b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/distribution/meta/List_State_PUT.java index 6bd2748a2..dea84b493 100644 --- a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/distribution/meta/List_State_PUT.java +++ b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/distribution/meta/List_State_PUT.java @@ -24,13 +24,13 @@ import nl.dtls.fairdatapoint.WebIntegrationTest; import nl.dtls.fairdatapoint.api.dto.metadata.MetaStateChangeDTO; -import nl.dtls.fairdatapoint.database.mongo.migration.development.metadata.data.MetadataFixtures; -import nl.dtls.fairdatapoint.database.mongo.repository.MetadataRepository; -import nl.dtls.fairdatapoint.entity.metadata.Metadata; +import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; +import nl.dtls.fairdatapoint.database.rdf.repository.generic.GenericMetadataRepository; import nl.dtls.fairdatapoint.entity.metadata.MetadataState; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -43,6 +43,7 @@ import static nl.dtls.fairdatapoint.acceptance.common.ForbiddenTest.createNoUserForbiddenTestPut; import static nl.dtls.fairdatapoint.acceptance.metadata.Common.createMetadataStateAlreadyPublished; import static nl.dtls.fairdatapoint.acceptance.metadata.Common.createMetadataStateChangeToDraft; +import static nl.dtls.fairdatapoint.util.ValueFactoryHelper.i; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsEqual.equalTo; @@ -51,10 +52,11 @@ public class List_State_PUT extends WebIntegrationTest { @Autowired - private MetadataFixtures metadataFixtures; + @Qualifier("persistentUrl") + private String persistentUrl; @Autowired - private MetadataRepository metadataRepository; + private GenericMetadataRepository repository; private URI url(String id) { return URI.create(format("/distribution/%s/meta/state", id)); @@ -66,7 +68,7 @@ private MetaStateChangeDTO reqDto() { @Test @DisplayName("HTTP 200") - public void res200() { + public void res200() throws MetadataRepositoryException { // GIVEN: RequestEntity request = RequestEntity .put(url("distribution-1")) @@ -76,10 +78,8 @@ public void res200() { ParameterizedTypeReference responseType = new ParameterizedTypeReference<>() { }; - // AND: Prepare database - Metadata metadata = metadataRepository.findByUri(metadataFixtures.distribution1().getUri()).get(); - metadata.setState(MetadataState.DRAFT); - metadataRepository.save(metadata); + // AND: Prepare database (make it a draft) + repository.moveToDrafts(i(persistentUrl + "/distribution/distribution-1")); // WHEN: ResponseEntity result = client.exchange(request, responseType); @@ -91,13 +91,15 @@ public void res200() { @Test @DisplayName("HTTP 400: Metadata is already published") - public void res400_already_published() { + public void res400_already_published() throws MetadataRepositoryException { + repository.moveToMain(i(persistentUrl + "/distribution/distribution-1")); createMetadataStateAlreadyPublished(client, url("distribution-1")); } @Test @DisplayName("HTTP 400: You can not change state to DRAFT") - public void res400_change_to_draft() { + public void res400_change_to_draft() throws MetadataRepositoryException { + repository.moveToDrafts(i(persistentUrl + "/distribution/distribution-1")); createMetadataStateChangeToDraft(client, url("distribution-1")); } diff --git a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/repository/meta/List_GET.java b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/repository/meta/List_GET.java index 3fc55f76b..c2c394cdb 100644 --- a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/repository/meta/List_GET.java +++ b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/repository/meta/List_GET.java @@ -25,10 +25,11 @@ import nl.dtls.fairdatapoint.WebIntegrationTest; import nl.dtls.fairdatapoint.api.dto.metadata.MetaDTO; import nl.dtls.fairdatapoint.api.dto.metadata.MetaStateDTO; -import nl.dtls.fairdatapoint.database.mongo.migration.development.metadata.data.MetadataFixtures; +import nl.dtls.fairdatapoint.entity.metadata.MetadataState; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -48,7 +49,8 @@ public class List_GET extends WebIntegrationTest { @Autowired - private MetadataFixtures metadataFixtures; + @Qualifier("persistentUrl") + private String persistentUrl; private URI url() { return URI.create("/meta"); @@ -73,10 +75,10 @@ public void res200() { assertThat(result.getStatusCode(), is(equalTo(HttpStatus.OK))); assertEmptyMember(result.getBody().getMember()); assertThat(result.getBody().getState(), is(equalTo(new MetaStateDTO( - metadataFixtures.fdpMetadata().getState(), + MetadataState.PUBLISHED, Map.of( - metadataFixtures.catalog1().getUri(), metadataFixtures.catalog1().getState(), - metadataFixtures.catalog2().getUri(), metadataFixtures.catalog2().getState() + persistentUrl + "/catalog/catalog-1", MetadataState.PUBLISHED, + persistentUrl + "/catalog/catalog-2", MetadataState.DRAFT ) )))); } diff --git a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/repository/meta/List_State_PUT.java b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/repository/meta/List_State_PUT.java index 0c7d01985..509aa86c1 100644 --- a/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/repository/meta/List_State_PUT.java +++ b/src/test/java/nl/dtls/fairdatapoint/acceptance/metadata/repository/meta/List_State_PUT.java @@ -24,13 +24,13 @@ import nl.dtls.fairdatapoint.WebIntegrationTest; import nl.dtls.fairdatapoint.api.dto.metadata.MetaStateChangeDTO; -import nl.dtls.fairdatapoint.database.mongo.migration.development.metadata.data.MetadataFixtures; -import nl.dtls.fairdatapoint.database.mongo.repository.MetadataRepository; -import nl.dtls.fairdatapoint.entity.metadata.Metadata; +import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; +import nl.dtls.fairdatapoint.database.rdf.repository.generic.GenericMetadataRepository; import nl.dtls.fairdatapoint.entity.metadata.MetadataState; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -42,6 +42,7 @@ import static nl.dtls.fairdatapoint.acceptance.common.ForbiddenTest.createNoUserForbiddenTestPut; import static nl.dtls.fairdatapoint.acceptance.metadata.Common.createMetadataStateAlreadyPublished; import static nl.dtls.fairdatapoint.acceptance.metadata.Common.createMetadataStateChangeToDraft; +import static nl.dtls.fairdatapoint.util.ValueFactoryHelper.i; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsEqual.equalTo; @@ -50,10 +51,11 @@ public class List_State_PUT extends WebIntegrationTest { @Autowired - private MetadataFixtures metadataFixtures; + @Qualifier("persistentUrl") + private String persistentUrl; @Autowired - private MetadataRepository metadataRepository; + private GenericMetadataRepository repository; private URI url() { return URI.create("/meta/state"); @@ -65,7 +67,7 @@ private MetaStateChangeDTO reqDto() { @Test @DisplayName("HTTP 200") - public void res200() { + public void res200() throws MetadataRepositoryException { // GIVEN: RequestEntity request = RequestEntity .put(url()) @@ -75,10 +77,8 @@ public void res200() { ParameterizedTypeReference responseType = new ParameterizedTypeReference<>() { }; - // AND: Prepare database - Metadata metadata = metadataRepository.findByUri(metadataFixtures.fdpMetadata().getUri()).get(); - metadata.setState(MetadataState.DRAFT); - metadataRepository.save(metadata); + // AND: Prepare database (make it a draft) + repository.moveToDrafts(i(persistentUrl)); // WHEN: ResponseEntity result = client.exchange(request, responseType); @@ -90,13 +90,15 @@ public void res200() { @Test @DisplayName("HTTP 400: Metadata is already published") - public void res400_already_published() { + public void res400_already_published() throws MetadataRepositoryException { + repository.moveToMain(i(persistentUrl)); createMetadataStateAlreadyPublished(client, url()); } @Test @DisplayName("HTTP 400: You can not change state to DRAFT") - public void res400_change_to_draft() { + public void res400_change_to_draft() throws MetadataRepositoryException { + repository.moveToDrafts(i(persistentUrl)); createMetadataStateChangeToDraft(client, url()); } diff --git a/src/test/java/nl/dtls/fairdatapoint/config/RepositoryTestConfig.java b/src/test/java/nl/dtls/fairdatapoint/config/RepositoryTestConfig.java index c51c969c0..931432c0f 100644 --- a/src/test/java/nl/dtls/fairdatapoint/config/RepositoryTestConfig.java +++ b/src/test/java/nl/dtls/fairdatapoint/config/RepositoryTestConfig.java @@ -38,7 +38,7 @@ @TestConfiguration public class RepositoryTestConfig { - @Bean(initMethod = "initialize", destroyMethod = "shutDown") + @Bean(initMethod = "init", destroyMethod = "shutDown") public Repository repository() throws RepositoryException, RDFParseException { return new SailRepository(new MemoryStore()); } diff --git a/src/test/java/nl/dtls/fairdatapoint/database/rdf/repository/catalog/CatalogMetadataRepositoryTest.java b/src/test/java/nl/dtls/fairdatapoint/database/rdf/repository/catalog/CatalogMetadataRepositoryTest.java index a67e2b694..6dd0c6788 100644 --- a/src/test/java/nl/dtls/fairdatapoint/database/rdf/repository/catalog/CatalogMetadataRepositoryTest.java +++ b/src/test/java/nl/dtls/fairdatapoint/database/rdf/repository/catalog/CatalogMetadataRepositoryTest.java @@ -22,6 +22,7 @@ */ package nl.dtls.fairdatapoint.database.rdf.repository.catalog; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import org.eclipse.rdf4j.model.IRI; import org.eclipse.rdf4j.query.TupleQuery; @@ -80,10 +81,10 @@ public void themesInCache() throws MetadataRepositoryException { when(cache.get(catalogUri.toString(), List.class)).thenReturn(Collections.emptyList()); // WHEN: - catalogMetadataRepository.getDatasetThemesForCatalog(catalogUri); + catalogMetadataRepository.getDatasetThemesForCatalog(catalogUri, RepositoryMode.MAIN); // THEN: - verify(catalogMetadataRepository, never()).runSparqlQuery(any(), any(), any()); + verify(catalogMetadataRepository, never()).runSparqlQuery(any(), any(), any(), eq(RepositoryMode.MAIN)); } @Test @@ -96,10 +97,10 @@ public void themesNotInCache() throws MetadataRepositoryException { when(tupleQuery.evaluate()).thenReturn(tupleQueryResult); // WHEN: - catalogMetadataRepository.getDatasetThemesForCatalog(catalogUri); + catalogMetadataRepository.getDatasetThemesForCatalog(catalogUri, RepositoryMode.MAIN); // THEN: - verify(catalogMetadataRepository, times(1)).runSparqlQuery(any(), any(), any()); + verify(catalogMetadataRepository, times(1)).runSparqlQuery(any(), any(), any(), eq(RepositoryMode.MAIN)); } } diff --git a/src/test/java/nl/dtls/fairdatapoint/database/rdf/repository/common/MetadataRepositoryTest.java b/src/test/java/nl/dtls/fairdatapoint/database/rdf/repository/common/MetadataRepositoryTest.java index 751910bd4..36634c833 100644 --- a/src/test/java/nl/dtls/fairdatapoint/database/rdf/repository/common/MetadataRepositoryTest.java +++ b/src/test/java/nl/dtls/fairdatapoint/database/rdf/repository/common/MetadataRepositoryTest.java @@ -28,6 +28,7 @@ package nl.dtls.fairdatapoint.database.rdf.repository.common; import nl.dtls.fairdatapoint.WebIntegrationTest; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.generic.GenericMetadataRepository; import nl.dtls.fairdatapoint.utils.TestRdfMetadataFixtures; import org.eclipse.rdf4j.model.IRI; @@ -62,7 +63,7 @@ public void findWorks() throws Exception { IRI context = getUri(testMetadataFixtures.catalog1()); // WHEN: - List result = metadataRepository.find(context); + List result = metadataRepository.find(context, RepositoryMode.MAIN); // THEN: assertThat(result.size(), is(equalTo(metadata.size()))); @@ -74,7 +75,7 @@ public void findNonExistingResource() throws Exception { IRI context = i("http://localhost/non-existing"); // WHEN: - List result = metadataRepository.find(context); + List result = metadataRepository.find(context, RepositoryMode.MAIN); // THEN: assertThat(result.size(), is(equalTo(0))); @@ -86,7 +87,7 @@ public void checkExistenceWorks() throws Exception { Model metadata = testMetadataFixtures.catalog1(); // WHEN: - boolean result = metadataRepository.checkExistence(getUri(metadata), DCTERMS.LANGUAGE, getLanguage(metadata)); + boolean result = metadataRepository.checkExistence(getUri(metadata), DCTERMS.LANGUAGE, getLanguage(metadata), RepositoryMode.MAIN); // THEN: assertThat(result, is(equalTo(true))); @@ -100,10 +101,10 @@ public void saveWorks() throws Exception { ArrayList statements = new ArrayList<>(metadata); // WHEN: - metadataRepository.save(statements, context); + metadataRepository.save(statements, context, RepositoryMode.MAIN); // THEN: - assertThat(metadataRepository.find(context).size(), is(equalTo(28))); + assertThat(metadataRepository.find(context, RepositoryMode.MAIN).size(), is(equalTo(28))); } @Test @@ -113,13 +114,13 @@ public void removeWorks() throws Exception { IRI context = getUri(metadata); // AND: Check existence before delete - assertThat(metadataRepository.find(context).size(), is(equalTo(metadata.size()))); + assertThat(metadataRepository.find(context, RepositoryMode.MAIN).size(), is(equalTo(metadata.size()))); // WHEN: - metadataRepository.remove(context); + metadataRepository.remove(context, RepositoryMode.MAIN); // THEN: - assertThat(metadataRepository.find(context).size(), is(equalTo(0))); + assertThat(metadataRepository.find(context, RepositoryMode.MAIN).size(), is(equalTo(0))); } @Test @@ -129,13 +130,13 @@ public void removeStatementWorks() throws Exception { IRI context = getUri(metadata); // AND: Check existence before delete - assertThat(metadataRepository.find(context).size(), is(equalTo(metadata.size()))); + assertThat(metadataRepository.find(context, RepositoryMode.MAIN).size(), is(equalTo(metadata.size()))); // WHEN: - metadataRepository.removeStatement(getUri(metadata), DCTERMS.LANGUAGE, getLanguage(metadata), context); + metadataRepository.removeStatement(getUri(metadata), DCTERMS.LANGUAGE, getLanguage(metadata), context, RepositoryMode.MAIN); // THEN: - assertThat(metadataRepository.find(context).size(), is(equalTo(metadata.size() - 1))); + assertThat(metadataRepository.find(context, RepositoryMode.MAIN).size(), is(equalTo(metadata.size() - 1))); } } diff --git a/src/test/java/nl/dtls/fairdatapoint/database/rdf/repository/generic/GenericMetadataRepositoryTest.java b/src/test/java/nl/dtls/fairdatapoint/database/rdf/repository/generic/GenericMetadataRepositoryTest.java index 4e54801dd..10e52b761 100644 --- a/src/test/java/nl/dtls/fairdatapoint/database/rdf/repository/generic/GenericMetadataRepositoryTest.java +++ b/src/test/java/nl/dtls/fairdatapoint/database/rdf/repository/generic/GenericMetadataRepositoryTest.java @@ -23,6 +23,7 @@ package nl.dtls.fairdatapoint.database.rdf.repository.generic; import nl.dtls.fairdatapoint.WebIntegrationTest; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.catalog.CatalogMetadataRepository; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import nl.dtls.fairdatapoint.utils.TestRdfMetadataFixtures; @@ -68,13 +69,13 @@ public void saveEvictsCache() throws MetadataRepositoryException { Model dataset = testMetadataFixtures.c1_dataset1(); // AND: Compute cache - catalogMetadataRepository.getDatasetThemesForCatalog(catalogUri); + catalogMetadataRepository.getDatasetThemesForCatalog(catalogUri, RepositoryMode.MAIN); // AND: Check if cache is full assertThat(getCache().get(catalogUri.stringValue()), is(notNullValue())); // WHEN: - metadataRepository.save(new ArrayList<>(dataset), getUri(dataset)); + metadataRepository.save(new ArrayList<>(dataset), getUri(dataset), RepositoryMode.MAIN); // THEN: assertThat(getCache().get(catalogUri.stringValue()), is(nullValue())); @@ -89,13 +90,13 @@ public void removeStatementEvictsCache() throws MetadataRepositoryException { Model dataset = testMetadataFixtures.c1_dataset1(); // AND: Compute cache - catalogMetadataRepository.getDatasetThemesForCatalog(catalogUri); + catalogMetadataRepository.getDatasetThemesForCatalog(catalogUri, RepositoryMode.MAIN); // AND: Check if cache is full assertThat(getCache().get(catalogUri.stringValue()), is(notNullValue())); // WHEN: - metadataRepository.removeStatement(getUri(dataset), DCTERMS.LANGUAGE, getLanguage(dataset), getUri(dataset)); + metadataRepository.removeStatement(getUri(dataset), DCTERMS.LANGUAGE, getLanguage(dataset), getUri(dataset), RepositoryMode.MAIN); // THEN: assertThat(getCache().get(catalogUri.stringValue()), is(nullValue())); @@ -110,13 +111,13 @@ public void removeEvictsCache() throws MetadataRepositoryException { Model dataset = testMetadataFixtures.c1_dataset1(); // AND: Compute cache - catalogMetadataRepository.getDatasetThemesForCatalog(catalogUri); + catalogMetadataRepository.getDatasetThemesForCatalog(catalogUri, RepositoryMode.MAIN); // AND: Check if cache is full assertThat(getCache().get(catalogUri.stringValue()), is(notNullValue())); // WHEN: - metadataRepository.remove(getUri(dataset)); + metadataRepository.remove(getUri(dataset), RepositoryMode.MAIN); // THEN: assertThat(getCache().get(catalogUri.stringValue()), is(nullValue())); diff --git a/src/test/java/nl/dtls/fairdatapoint/service/index/harvester/HarvesterServiceTest.java b/src/test/java/nl/dtls/fairdatapoint/service/index/harvester/HarvesterServiceTest.java index 8eed328e2..385068032 100644 --- a/src/test/java/nl/dtls/fairdatapoint/service/index/harvester/HarvesterServiceTest.java +++ b/src/test/java/nl/dtls/fairdatapoint/service/index/harvester/HarvesterServiceTest.java @@ -25,6 +25,7 @@ import nl.dtls.fairdatapoint.database.mongo.migration.development.resource.data.ResourceDefinitionFixtures; import nl.dtls.fairdatapoint.database.rdf.migration.development.metadata.data.RdfMetadataFixtures; import nl.dtls.fairdatapoint.database.rdf.migration.development.metadata.factory.MetadataFactoryImpl; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import nl.dtls.fairdatapoint.database.rdf.repository.generic.GenericMetadataRepository; import nl.dtls.fairdatapoint.entity.resource.ResourceDefinition; @@ -109,7 +110,7 @@ public void harvestSucceed() throws MetadataRepositoryException { harvesterService.harvest(repositoryUrl); // THEN: - verify(genericMetadataRepository, times(2)).save(anyList(), eq(i(repositoryUrl))); + verify(genericMetadataRepository, times(2)).save(anyList(), eq(i(repositoryUrl)), eq(RepositoryMode.MAIN)); } @Test @@ -122,7 +123,7 @@ public void harvestFailedForLinkedChildren() throws MetadataRepositoryException harvesterService.harvest(repositoryUrl); // THEN: - verify(genericMetadataRepository, times(1)).save(anyList(), eq(i(repositoryUrl))); + verify(genericMetadataRepository, times(1)).save(anyList(), eq(i(repositoryUrl)), eq(RepositoryMode.MAIN)); } private void mockEndpoint(String url, Model body) { diff --git a/src/test/java/nl/dtls/fairdatapoint/service/metadata/catalog/CatalogMetadataServiceMockTest.java b/src/test/java/nl/dtls/fairdatapoint/service/metadata/catalog/CatalogMetadataServiceMockTest.java index a06188026..ee9f5a271 100644 --- a/src/test/java/nl/dtls/fairdatapoint/service/metadata/catalog/CatalogMetadataServiceMockTest.java +++ b/src/test/java/nl/dtls/fairdatapoint/service/metadata/catalog/CatalogMetadataServiceMockTest.java @@ -23,6 +23,7 @@ package nl.dtls.fairdatapoint.service.metadata.catalog; import nl.dtls.fairdatapoint.BaseIntegrationTest; +import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode; import nl.dtls.fairdatapoint.database.rdf.repository.catalog.CatalogMetadataRepository; import nl.dtls.fairdatapoint.database.rdf.repository.generic.GenericMetadataRepositoryImpl; import nl.dtls.fairdatapoint.utils.TestRdfMetadataFixtures; @@ -74,13 +75,13 @@ public void retrieve() throws Exception { // GIVEN: Retrieve catalog from Repository Model catalog = testMetadataFixtures.catalog1(); List catalogStatements = new ArrayList<>(catalog); - when(metadataRepository.find(getUri(catalog))).thenReturn(catalogStatements); + when(metadataRepository.find(getUri(catalog), RepositoryMode.COMBINED)).thenReturn(catalogStatements); // AND: Retrieve themes from datasets IRI theme1 = i("http://localhost/my_theme_1"); IRI theme2_duplicated = i("http://localhost/my_theme_2_duplicated"); List themes = List.of(theme1, theme2_duplicated, theme2_duplicated); - when(catalogMetadataRepository.getDatasetThemesForCatalog(getUri(catalog))).thenReturn(themes); + when(catalogMetadataRepository.getDatasetThemesForCatalog(getUri(catalog), RepositoryMode.COMBINED)).thenReturn(themes); // WHEN: Model catalogMetadata = catalogMetadataService.retrieve(getUri(catalog));