-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: started DOIP v2.0 over HTTP implementation
- Loading branch information
Showing
6 changed files
with
468 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
src/main/java/edu/kit/datamanager/pit/web/doip/DoipOperationId.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Adapted from https://git.rwth-aachen.de/nfdi4ing/s-3/s-3-3/metadatahub/-/blob/main/src/main/java/edu/kit/metadatahub/doip/rest/Operations.java | ||
* | ||
* License: Apache 2.0 | ||
*/ | ||
|
||
package edu.kit.datamanager.pit.web.doip; | ||
|
||
import net.dona.doip.DoipConstants; | ||
|
||
/** | ||
* Define valid operations for REST interface of DOIP. | ||
*/ | ||
public enum DoipOperationId { | ||
// Basic operations | ||
OP_HELLO(DoipConstants.OP_HELLO), | ||
OP_CREATE(DoipConstants.OP_CREATE), | ||
OP_RETRIEVE(DoipConstants.OP_RETRIEVE), | ||
OP_UPDATE(DoipConstants.OP_UPDATE), | ||
OP_DELETE(DoipConstants.OP_DELETE), | ||
OP_SEARCH(DoipConstants.OP_SEARCH), | ||
OP_LIST(DoipConstants.OP_LIST_OPERATIONS), | ||
// Extended operations | ||
OP_VALIDATE("dev/Validation"); | ||
|
||
private final String value; | ||
|
||
DoipOperationId(String v) { | ||
value = v; | ||
} | ||
|
||
public String value() { | ||
return value; | ||
} | ||
|
||
public static DoipOperationId fromValue(String v) { | ||
for (DoipOperationId c : DoipOperationId.values()) { | ||
if (c.value.equals(v)) { | ||
return c; | ||
} | ||
} | ||
throw new IllegalArgumentException(v); | ||
} | ||
|
||
} |
179 changes: 179 additions & 0 deletions
179
src/main/java/edu/kit/datamanager/pit/web/doip/DoipOverHttp.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
/** | ||
* A lot of code re-used from metadataHub, Apache 2.0 License. | ||
* | ||
* Original Code: https://git.rwth-aachen.de/nfdi4ing/s-3/s-3-3/metadatahub/-/blob/main/src/main/java/edu/kit/metadatahub/rest/controller/Rest4DoipController.java | ||
*/ | ||
|
||
package edu.kit.datamanager.pit.web.doip; | ||
|
||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.Objects; | ||
|
||
import org.apache.commons.lang3.NotImplementedException; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.CrossOrigin; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.ResponseBody; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import com.fasterxml.jackson.databind.JsonNode; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
|
||
import edu.kit.datamanager.pit.pitservice.ITypingService; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.Parameter; | ||
import io.swagger.v3.oas.annotations.parameters.RequestBody; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
|
||
/** | ||
* REST controller for DOIP over HTTP. | ||
*/ | ||
@RestController | ||
@CrossOrigin(origins = "*", allowedHeaders = "*") | ||
@ApiResponses(value = { | ||
@ApiResponse(responseCode = "200", description = "The request was processed successfully."), | ||
@ApiResponse(responseCode = "400", description = "There was something wrong with the structure or content of the request"), | ||
@ApiResponse(responseCode = "401", description = "The client must authenticate to perform the attempted operation"), | ||
@ApiResponse(responseCode = "403", description = "The client was not permitted to perform the attempted operation"), | ||
@ApiResponse(responseCode = "404", description = "The requested digital object could not be found"), | ||
@ApiResponse(responseCode = "409", description = "There was a conflict preventing the request from being executed"), | ||
@ApiResponse(responseCode = "500", description = "There was an internal server error") }) | ||
public class DoipOverHttp { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(DoipOverHttp.class); | ||
|
||
private final String SELF_IDENTIFIER_FALLBACK = "self"; | ||
private final Collection<DoipOperationId> SERVICE_OPERATIONS = List.of( | ||
//DoipOperationId.OP_HELLO, | ||
//DoipOperationId.OP_CREATE, | ||
//DoipOperationId.OP_RETRIEVE, | ||
//DoipOperationId.OP_SEARCH, | ||
DoipOperationId.OP_LIST | ||
); | ||
private final Collection<DoipOperationId> FAIRDO_OPERATIONS = List.of( | ||
//DoipOperationId.OP_UPDATE, | ||
//DoipOperationId.OP_DELETE, | ||
DoipOperationId.OP_LIST | ||
//DoipOperationId.OP_VALIDATE | ||
); | ||
|
||
@Autowired | ||
ITypingService pit; | ||
|
||
public DoipResponse op_server_create( | ||
final DoipOperationId operationId, | ||
final String targetId, | ||
final String clientId, | ||
final JsonNode attributes, | ||
final DoipRequest body | ||
) { | ||
throw new NotImplementedException(); | ||
} | ||
|
||
/** | ||
* DOIP Entpoint. Basically executes targetId.operationId(attributes, body, clientId). | ||
*/ | ||
@Operation(summary = "DOIPv2 over HTTP.", description = "DOIPv2 via HTTP as defined by Cordra, as far as applicable.") | ||
@PostMapping(value = { "/doip" }, consumes = { MediaType.ALL_VALUE }) | ||
@ResponseBody | ||
public ResponseEntity<DoipResponse> postDoipOperation( | ||
@Parameter(description = "The operationId.", required = true) | ||
@RequestParam(value = "operationId") | ||
final DoipOperationId operationId, | ||
|
||
@Parameter(description = "The targetId.", required = true) | ||
@RequestParam(value = "targetId") | ||
final String targetId, | ||
|
||
@Parameter(description = "the identifier of the caller", required = true) | ||
@RequestParam(value = "clientId") | ||
final String clientId, | ||
|
||
@Parameter(description = "arbitrary JSON to inform the operation", required = true) | ||
@RequestParam(value = "attributes") | ||
final JsonNode attributes, | ||
|
||
@Parameter(description = "Json representation of the Digital Object.", required = false) | ||
@RequestBody(required = false) | ||
final DoipRequest body | ||
) { | ||
// Authentication: is done by security layer (keycloak / JWT) | ||
|
||
boolean isServiceTarget = Objects.equals(targetId, SELF_IDENTIFIER_FALLBACK) /* TODO or a real identifier configured for this service? */; | ||
|
||
if (isServiceTarget) { | ||
switch (operationId) { | ||
case OP_LIST: | ||
return operation_service_list(targetId, operationId, body, attributes, clientId); | ||
//case OP_HELLO: | ||
// break; | ||
//case OP_CREATE: | ||
// break; | ||
//case OP_RETRIEVE: | ||
// break; | ||
//case OP_SEARCH: | ||
// break; | ||
default: | ||
DoipResponse r = new DoipResponse(DoipStatus.REQUEST_INVALID); | ||
return new ResponseEntity<>(r, r.getDoipStatus().getHttpStatus()); | ||
} | ||
} else { | ||
// check if identifier is registered | ||
if (pit.isIdentifierRegistered(targetId)) { | ||
switch (operationId) { | ||
case OP_LIST: | ||
return operation_fairdo_list(targetId, operationId, body, attributes, clientId); | ||
//case OP_UPDATE: | ||
// break; | ||
//case OP_DELETE: | ||
// break; | ||
//case OP_VALIDATE: | ||
// break; | ||
default: | ||
DoipResponse r = new DoipResponse(DoipStatus.REQUEST_INVALID); | ||
return new ResponseEntity<>(r, r.getDoipStatus().getHttpStatus()); | ||
} | ||
} else { | ||
DoipResponse r = new DoipResponse(DoipStatus.DIGITAL_OBJECT_NOT_FOUND); | ||
return new ResponseEntity<>(r, r.getDoipStatus().getHttpStatus()); | ||
} | ||
// if not, return error | ||
} | ||
} | ||
|
||
private ResponseEntity<DoipResponse> operation_fairdo_list( | ||
String targetId, | ||
DoipOperationId operationId, | ||
DoipRequest body, | ||
JsonNode attributes, | ||
String clientId | ||
){ | ||
ObjectMapper mapper = new ObjectMapper(); | ||
DoipResponse r = new DoipResponse(DoipStatus.OPERATION_SUCCESS); | ||
// TODO add other known operations | ||
r.setOutput(mapper.valueToTree(FAIRDO_OPERATIONS)); | ||
return new ResponseEntity<>(r, r.getDoipStatus().getHttpStatus()); | ||
} | ||
|
||
private ResponseEntity<DoipResponse> operation_service_list( | ||
String targetId, | ||
DoipOperationId operationId, | ||
DoipRequest body, | ||
JsonNode attributes, | ||
String clientId | ||
) { | ||
ObjectMapper mapper = new ObjectMapper(); | ||
DoipResponse r = new DoipResponse(DoipStatus.OPERATION_SUCCESS); | ||
r.setOutput(mapper.valueToTree(SERVICE_OPERATIONS)); | ||
return new ResponseEntity<>(r, r.getDoipStatus().getHttpStatus()); | ||
} | ||
|
||
} |
84 changes: 84 additions & 0 deletions
84
src/main/java/edu/kit/datamanager/pit/web/doip/DoipRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
* Adapted from: https://git.rwth-aachen.de/nfdi4ing/s-3/s-3-3/metadatahub/-/blob/main/src/main/java/edu/kit/metadatahub/doip/rest/RestDoip.java#L39 | ||
* | ||
* License: Apache 2.0 | ||
*/ | ||
package edu.kit.datamanager.pit.web.doip; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import com.fasterxml.jackson.annotation.JsonInclude; | ||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import com.fasterxml.jackson.annotation.JsonPropertyOrder; | ||
|
||
import edu.kit.datamanager.pit.domain.SimplePair; | ||
|
||
@JsonInclude(JsonInclude.Include.NON_NULL) | ||
@JsonPropertyOrder({ | ||
"id", | ||
"clientId", | ||
"attributes" | ||
}) | ||
public class DoipRequest { | ||
|
||
@JsonProperty("id") | ||
private String id; | ||
@JsonProperty("clientId") | ||
private String clientId; | ||
@JsonProperty("targetId") | ||
private String targetId; | ||
@JsonProperty("token") | ||
private String token; | ||
@JsonProperty("attributes") | ||
private List<SimplePair> attributes = new ArrayList<>(); | ||
|
||
@JsonProperty("id") | ||
public String getId() { | ||
return id; | ||
} | ||
|
||
@JsonProperty("id") | ||
public void setId(String id) { | ||
this.id = id; | ||
} | ||
|
||
@JsonProperty("clientId") | ||
public String getClientId() { | ||
return clientId; | ||
} | ||
|
||
@JsonProperty("clientId") | ||
public void setClientId(String clientId) { | ||
this.clientId = clientId; | ||
} | ||
|
||
@JsonProperty("targetId") | ||
public String getTargetId() { | ||
return targetId; | ||
} | ||
|
||
@JsonProperty("targetId") | ||
public void setTargetId(String targetId) { | ||
this.targetId = targetId; | ||
} | ||
|
||
@JsonProperty("token") | ||
public String getToken() { | ||
return token; | ||
} | ||
|
||
@JsonProperty("token") | ||
public void setToken(String token) { | ||
this.token = token; | ||
} | ||
|
||
@JsonProperty("attributes") | ||
public List<SimplePair> getAttributes() { | ||
return attributes; | ||
} | ||
|
||
@JsonProperty("attributes") | ||
public void setAttributes(List<SimplePair> attributes) { | ||
this.attributes = attributes; | ||
} | ||
} |
Oops, something went wrong.