Skip to content

Commit

Permalink
WIP: Use dedicated repository for drafts
Browse files Browse the repository at this point in the history
  • Loading branch information
MarekSuchanek committed Sep 5, 2023
1 parent 21e1a3f commit b8dadad
Show file tree
Hide file tree
Showing 30 changed files with 497 additions and 418 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@
<artifactId>rdf4j-sail-nativerdf</artifactId>
<version>${rdf4j.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.rdf4j</groupId>
<artifactId>rdf4j-tools-federation</artifactId>
<version>${rdf4j.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

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;
Expand Down Expand Up @@ -89,9 +90,6 @@ public class GenericController {
@Autowired
private MetadataSchemaService metadataSchemaService;

@Autowired
private MetadataStateService metadataStateService;

@Autowired
private MetadataEnhancer metadataEnhancer;

Expand All @@ -101,6 +99,9 @@ public class GenericController {
@Autowired
private GenericMetadataRepository metadataRepository;

@Autowired
private MetadataStateService metadataStateService;

@Autowired
private SearchFilterCache searchFilterCache;

Expand Down Expand Up @@ -130,28 +131,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<User> oCurrentUser = currentUserService.getCurrentUser();
IRI entityUri = getMetadataIRI(persistentUrl, urlPrefix, recordId);
Model entity = metadataService.retrieve(entityUri);
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<User> 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;
Expand Down Expand Up @@ -179,34 +175,30 @@ public Model getMetaData(
// 2. Get resource definition
final ResourceDefinition rd = resourceDefinitionService.getByUrlPrefix(urlPrefix);

// 3. Get entity
final IRI entityUri = getMetadataIRI(persistentUrl, urlPrefix, recordId);
final Model entity = metadataService.retrieve(entityUri);
resultRdf.addAll(entity);

// 4. Check if it is DRAFT
final Metadata state = metadataStateService.get(entityUri);
// 3. Get entity (from repository based on permissions)
final Optional<User> 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);
}
}
}
IRI entityUri = getMetadataIRI(persistentUrl, urlPrefix, recordId);
RepositoryMode mode = oCurrentUser.isEmpty() ? RepositoryMode.MAIN : RepositoryMode.COMBINED;
Model entity = metadataService.retrieve(entityUri, mode);
resultRdf.addAll(entity);

// 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;
}

Expand All @@ -225,7 +217,6 @@ public ResponseEntity<Model> storeMetaData(
}

// 2. Init
// String urlPrefix = getResourceNameForList(getRequestURL(request, persistentUrl));
final MetadataService metadataService = metadataServiceFactory.getMetadataServiceByUrlPrefix(urlPrefix);
final ResourceDefinition rd = resourceDefinitionService.getByUrlPrefix(urlPrefix);

Expand Down Expand Up @@ -283,6 +274,7 @@ public ResponseEntity<Model> updateMetaData(
}

// 4. Store metadata
// TODO: make sure that updating draft works as well
final Model metadata = metadataService.update(reqDto, uri, rd, true);

// 5. Invalidate search filters cache
Expand Down Expand Up @@ -314,6 +306,7 @@ public ResponseEntity<Void> deleteMetadata(
final IRI uri = getMetadataIRI(persistentUrl, urlPrefix, recordId);

// 4. Store metadata
// TODO: make sure that updating draft works as well
metadataService.delete(uri, rd);

// 5. Invalidate search filters cache
Expand Down Expand Up @@ -341,18 +334,14 @@ public ResponseEntity<Model> 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<User> oCurrentUser = currentUserService.getCurrentUser();
if (state.getState().equals(MetadataState.DRAFT) && oCurrentUser.isEmpty()) {
throw new ForbiddenException(MSG_ERROR_DRAFT_FORBIDDEN);
}
IRI entityUri = getMetadataIRI(persistentUrl, urlPrefix, recordId);
RepositoryMode mode = oCurrentUser.isEmpty() ? RepositoryMode.MAIN : RepositoryMode.COMBINED;
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);
Expand All @@ -361,19 +350,19 @@ public ResponseEntity<Model> getMetaDataChildren(
if (rdChild.getResourceDefinitionUuid().equals(currentChildRd.getUuid())) {
final IRI relationUri = i(rdChild.getRelationUri());

// 4.1 Get all titles for sort
final Map<String, String> titles = metadataRepository.findChildTitles(entityUri, relationUri);
// 3.1 Get all titles for sort
final Map<String, String> titles = metadataRepository.findChildTitles(entityUri, relationUri, mode);

// 4.2 Get all children sorted
// 3.2 Get all children sorted
final List<Value> 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 e) {
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());
Expand All @@ -382,14 +371,14 @@ public ResponseEntity<Model> 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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,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<String, MetaPathDTO> pathMap = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ public class SettingsDTO {

private SettingsPingDTO ping;

private SettingsRepositoryDTO repository;
private SettingsRepositoryDTO mainRepository;

private SettingsRepositoryDTO draftsRepository;

private SettingsSearchDTO search;

Expand Down
74 changes: 42 additions & 32 deletions src/main/java/nl/dtls/fairdatapoint/config/RepositoryConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
};

Expand All @@ -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;
Expand All @@ -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");
Expand All @@ -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");
Expand Down
Loading

0 comments on commit b8dadad

Please sign in to comment.