Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 148 add DOIP interface / add support for operation handling #158

Draft
wants to merge 7 commits into
base: dev-v2
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ plugins {
// https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/htmlsingle/
id 'org.springframework.boot' version '2.7.13'
// https://docs.spring.io/dependency-management-plugin/docs/current-SNAPSHOT/reference/html/
id "io.spring.dependency-management" version "1.1.2"
id "io.spring.dependency-management" version "1.1.3"
// Lombok generates getter and setter and more. https://projectlombok.org/
// check for new versions here: https://plugins.gradle.org/plugin/io.freefair.lombok
id "io.freefair.lombok" version "8.1.0"
id "io.freefair.lombok" version "8.3"
// Release tagging with `./gradlew release`
// Check for new versions here: https://plugins.gradle.org/plugin/net.researchgate.release
// Usage: https://github.com/researchgate/gradle-release
Expand All @@ -20,7 +20,7 @@ plugins {
// Adds coveralls task for CI to send results to the coveralls service.
id "com.github.kt3k.coveralls" version "2.12.2"
//id "com.github.kt3k.coveralls" version "2.12.0"
id "org.owasp.dependencycheck" version "8.3.1"
id "org.owasp.dependencycheck" version "8.4.0"
id 'org.asciidoctor.jvm.convert' version '3.3.2'
// include build and git information via Spring Actuator
id "com.gorylenko.gradle-git-properties" version "2.4.1"
Expand Down Expand Up @@ -60,7 +60,7 @@ dependencies {
implementation("edu.kit.datamanager:service-base:1.1.1")
implementation("edu.kit.datamanager:repo-core:1.1.2")
// com.google.common, LoadingCache
implementation("com.google.guava:guava:32.1.1-jre")
implementation("com.google.guava:guava:32.1.2-jre")
// Required by Spring/Javers at runtime
implementation 'com.google.code.gson:gson:2.10.1'

Expand Down Expand Up @@ -93,6 +93,7 @@ dependencies {
implementation('org.apache.httpcomponents:httpclient-cache:4.5.14')

implementation("net.handle:handle-client:9.3.1")
implementation("net.dona.doip:doip-sdk:2.1.0")

testImplementation(platform('org.junit:junit-bom:5.10.0'))
testImplementation('org.junit.jupiter:junit-jupiter')
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@

systemProp.jdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2"

version=2.0.0
version=1.1.2
91 changes: 91 additions & 0 deletions src/main/java/edu/kit/datamanager/pit/domain/Operations.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
Expand All @@ -31,12 +33,101 @@ public class Operations {
"21.T11148/397d831aa3a9d18eb52c"
};

private static final List<String> KNOWN_DIGITAL_OBJECT_TYPE_ATTRIBUTES = List.of(
"21.T11148/1c699a5d1b4ad3ba4956"
);

private static final List<String> KNOWN_SUPPORTED_TYPES = List.of(
"21.T11148/2694e4a7a5a00d44e62b"
);

private static final List<String> KNOWN_SUPPORTED_LOCATIONS = List.of();

private ITypingService typingService;

public Operations(ITypingService typingService) {
this.typingService = typingService;
}

public Set<String> findDigitalObjectTypes(PIDRecord pidRecord) throws IOException {
Set<String> doTypes = KNOWN_DIGITAL_OBJECT_TYPE_ATTRIBUTES
.stream()
.map(pidRecord::getPropertyValues)
.map(Arrays::asList)
.flatMap(List<String>::stream)
.collect(Collectors.toSet());
if (!doTypes.isEmpty()) {
return doTypes;
}

/* TODO try to find types extending or relating otherwise to known types
* (currently not supported by our TypeDefinition) */
// we need to resolve types without streams to forward possible exceptions
Collection<TypeDefinition> resolvedAttributeDescriptions = new ArrayList<>();
for (String attributePid : pidRecord.getPropertyIdentifiers()) {
if (this.typingService.isIdentifierRegistered(attributePid)) {
TypeDefinition type = this.typingService.describeType(attributePid);
resolvedAttributeDescriptions.add(type);
}
}

/*
* as a last fallback, try find types with human readable names containing
* "digitalObjectType".
*
* This can be removed as soon as we have some default FAIR DO types new type
* definitions can refer to (e.g. "extend" them or declare the same meaning as
* our known types, see above)
*/
return resolvedAttributeDescriptions
.stream()
.filter(type -> type.getName().equals("digitalObjectType"))
.map(type -> pidRecord.getPropertyValues(type.getIdentifier()))
.map(Arrays::asList)
.flatMap(List<String>::stream)
.collect(Collectors.toSet());
}

/**
* Tries to get supported types. Usually, this property only exists for FAIR DOs
* representing operations.
*
* Strategy: - try to get it from known "dateModified" types
*
* Semantic reasoning in some sense is planned but not yet supported.
*
* @param pidRecord the record to extract the information from.
* @return the extracted "supported types", if any.
*/
public Set<String> findSupportedTypes(PIDRecord pidRecord) {
return KNOWN_SUPPORTED_TYPES
.stream()
.map(pidRecord::getPropertyValues)
.map(Arrays::asList)
.flatMap(List<String>::stream)
.collect(Collectors.toSet());
}

/**
* Tries to get supported types. Usually, this property only exists for FAIR DOs
* representing operations.
*
* Strategy: - try to get it from known "dateModified" types
*
* Semantic reasoning in some sense is planned but not yet supported.
*
* @param pidRecord the record to extract the information from.
* @return the extracted "supported locations", if any.
*/
public Set<String> findSupportedLocations(PIDRecord pidRecord) {
return KNOWN_SUPPORTED_LOCATIONS
.stream()
.map(pidRecord::getPropertyValues)
.map(Arrays::asList)
.flatMap(List<String>::stream)
.collect(Collectors.toSet());
}

/**
* Tries to get the date when a FAIR DO was created from a PID record.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
*/
package edu.kit.datamanager.pit.elasticsearch;

import java.util.Collection;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

/**
Expand All @@ -28,4 +31,10 @@ public interface PidRecordElasticRepository extends ElasticsearchRepository<PidR

Page<PidRecordElasticWrapper> findByPid(String pid, Pageable pageable);

@Query("{\"match\": {\"supportedLocations\": \"?0\"}}")
Collection<PidRecordElasticWrapper> findBySupportedLocationsContain(String location);

@Query("{\"match\": {\"supportedTypes\": \"?0\"}}")
Collection<PidRecordElasticWrapper> findBySupportedTypesContain(String type);

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.ElementCollection;
import javax.persistence.FetchType;
Expand Down Expand Up @@ -54,21 +56,101 @@ public class PidRecordElasticWrapper {
@Field(type = FieldType.Date, format = DateFormat.basic_date_time)
private Date lastUpdate;

@ElementCollection(fetch = FetchType.EAGER)
private Set<String> supportedTypes = new HashSet<>();

@ElementCollection(fetch = FetchType.EAGER)
private Set<String> supportedLocations = new HashSet<>();

@Field(type = FieldType.Text)
private List<String> read = new ArrayList<>();

public PidRecordElasticWrapper(PIDRecord pidRecord, Operations dateOperations) {
protected PidRecordElasticWrapper() {
// for PidRecordElasticRepository
}

public PidRecordElasticWrapper(PIDRecord pidRecord, Operations recordOperations) {
pid = pidRecord.getPid();
PidDatabaseObject simple = new PidDatabaseObject(pidRecord);
this.attributes = simple.getEntries();
this.read.add("anonymousUser");

this.supportedTypes = recordOperations.findSupportedTypes(pidRecord);
this.supportedLocations = recordOperations.findSupportedLocations(pidRecord);

try {
this.created = dateOperations.findDateCreated(pidRecord).orElse(null);
this.lastUpdate = dateOperations.findDateModified(pidRecord).orElse(null);
this.created = recordOperations.findDateCreated(pidRecord).orElse(null);
this.lastUpdate = recordOperations.findDateModified(pidRecord).orElse(null);
} catch (IOException e) {
LOG.error("Could not retrieve date from record (pid: " + pidRecord.getPid() + ").", e);
e.printStackTrace();
}
}

/**
* Generated with Lombok
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((pid == null) ? 0 : pid.hashCode());
result = prime * result + ((attributes == null) ? 0 : attributes.hashCode());
result = prime * result + ((created == null) ? 0 : created.hashCode());
result = prime * result + ((lastUpdate == null) ? 0 : lastUpdate.hashCode());
result = prime * result + ((supportedTypes == null) ? 0 : supportedTypes.hashCode());
result = prime * result + ((supportedLocations == null) ? 0 : supportedLocations.hashCode());
result = prime * result + ((read == null) ? 0 : read.hashCode());
return result;
}

/**
* Generated with Lombok
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PidRecordElasticWrapper other = (PidRecordElasticWrapper) obj;
if (pid == null) {
if (other.pid != null)
return false;
} else if (!pid.equals(other.pid))
return false;
if (attributes == null) {
if (other.attributes != null)
return false;
} else if (!attributes.equals(other.attributes))
return false;
if (created == null) {
if (other.created != null)
return false;
} else if (!created.equals(other.created))
return false;
if (lastUpdate == null) {
if (other.lastUpdate != null)
return false;
} else if (!lastUpdate.equals(other.lastUpdate))
return false;
if (supportedTypes == null) {
if (other.supportedTypes != null)
return false;
} else if (!supportedTypes.equals(other.supportedTypes))
return false;
if (supportedLocations == null) {
if (other.supportedLocations != null)
return false;
} else if (!supportedLocations.equals(other.supportedLocations))
return false;
if (read == null) {
if (other.read != null)
return false;
} else if (!read.equals(other.read))
return false;
return true;
}
}
Loading