Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • fit-connect/sdk-java
1 result
Show changes
Commits on Source (26)
Showing
with 384 additions and 20 deletions
......@@ -4,7 +4,7 @@ include:
file: 'reuse.gitlab-ci.yml'
variables:
MAVEN_CLI_OPTS: "-s .m2/release.xml --batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"
MAVEN_CLI_OPTS: "-s .m2/release.xml --batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true -Dlocal-version-suffix="
MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
ENCRYPTED_GPG_SECRET_KEY: "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"
......
......@@ -95,7 +95,7 @@ _The following steps show how to get the SDK running_
```sh
./mvnw clean install -DskipTests
```
5. Configure your `config.yml`
5. Configure your `config.yml` (see [template](/config.yml))
- add Sender OAuth credentials from the self-service portal to *SENDER* section
- add Subscriber OAuth credentials from the self-service portal to *SUBSCRIBER* section
- add reference to private decryption key (JWK) to *SUBSCRIBER* section
......@@ -110,6 +110,59 @@ _The following steps show how to get the SDK running_
<p align="right">(<a href="#top">back to top</a>)</p>
## API Usage for Routing
The Routing-Client allows to retrieve data about areas and services as well as their service destination.
A typical workflow using the `RoutingClient` and `SenderClient` would be:
1) Find the `areaId` for an area via routing
2) Find the destination for a `leikaKey` and an `areaId` via routing
3) Submit a new submission to the destination using the `SenderClient`
### Finding Areas
Areas can be searched with one or more search criteria:
```java
final RoutingClient routingClient = ClientFactory.routingClient(config);
final var citySearchCriterion = "Leip*";
final var zipCodeSearchCriterion = "04229";
// get first 5 area results
final List<Area> areas = routingClient.findAreas(List.of(citySearchCriterion, zipCodeSearchCriterion), 0, 5);
LOGGER.info("Found {} areas", areas.size());
for (final Area area : areas){
LOGGER.info("Area {} with id {} found", area.getName(), area.getId());
}
```
### Finding Destinations by service identifier and region
For searching a destination the `DestinationSearch.Builder` is used pass a search request to the routing client.
The leikaKey is mandatory, as well as (max.) one other search criterion for the area/region, like one of:
- ars amtlicher regionalschlüssel
- ags amtlicher gemeindeschlüssel
- areaId identifier of an area that can be retrieved via [finding areas](#finding-areas)
```java
final RoutingClient routingClient = ClientFactory.routingClient(config);
final DestinationSearch search = DestinationSearch.Builder()
.withLeikaKey("99123456760610")
.withArs("064350014014")
.withLimit(5)
.build();
// get first 5 route results
final List<Route> routes = routingClient.findDestinations(search);
LOGGER.info("Found {} routes for service identifier {}", routes.size(), leikaKey);
for (final Route route : routes){
LOGGER.info("Route {} with destinationId {} found", route.getName(), route.getDestinationId());
}
```
## API Usage for Sender
For sending submission and already encrypted submissions builder are provided to construct the necessary payload to be sent.
......@@ -373,9 +426,29 @@ if(validationResult.hasError()){
}
```
## Integration Tests
Integration tests in `dev.fitko.fitconnect.client.ClientIntegrationTest` run only on the CI-Server and are ignored by default locally.
To run them on a local machine the following environment variables have to be set in the run-configuration of the IDE:
* SENDER_CLIENT_ID
* SENDER_CLIENT_SECRET
* SUBSCRIBER_CLIENT_ID
* SUBSCRIBER_CLIENT_SECRET
* TEST_DESTINATION_ID
Submit submissions are cleaned on every test run, please be aware that this might affect the present submissions on the destination that is configured.
Currently, the tests are set up for the test-environment with:
```
var authBaseUrl = "https://auth-testing.fit-connect.fitko.dev";
var routingBaseUrl = "https://routing-api-testing.fit-connect.fitko.dev";
var selfServicePortalUrl = "https://portal.auth-testing.fit-connect.fitko.dev";
var submissionBaseUrl = "https://submission-api-testing.fit-connect.fitko.dev";
```
## Roadmap
- [ ] Add Routing features
- [ ] Add Callback validation
- [ ] Add auto-reject on technical errors
- [ ] Maven central release of 1.0.0
......
## API Module
The API-module contains interfaces and domain model value classes that provide the basic functionality to build an
sdk-client.
The API-module contains interfaces and domain model value classes that provide the basic functionality to build a sdk-client.
### Structure
......@@ -10,7 +9,7 @@ sdk-client.
- **api.exceptions** - all use case specific the services throw
- **api.services** - all services to authenticate, encrypt, validate and perform REST-requests
There are two service facade interfaces that provide a client centric wrapper around the underlying services,
There are two service facade interfaces that provide a client centric wrapper around the underlying services:
- **Sender** - create a submission, announce attachments, encrypt and send the submission including metadata
- **Subscriber** - poll, receive and decrypt submissions and confirm their valid transmission
......
......@@ -30,6 +30,9 @@ public class ApplicationConfig {
@Builder.Default
private URI metadataSchemaWriteVersion = SchemaConfig.METADATA_V_1_0_0.getSchemaUri();
@Builder.Default
private URI destinationSchemaVersion = SchemaConfig.XZUFI_DESTINATION_SCHEMA.getSchemaUri();
private SenderConfig senderConfig;
private SubscriberConfig subscriberConfig;
......
......@@ -6,14 +6,19 @@ final class ResourcePaths {
}
static final String AUTH_TOKEN_PATH = "/token";
static final String DESTINATIONS_PATH = "/v1/destinations/{destinationId}";
static final String DESTINATIONS_KEY_PATH = "/v1/destinations/{destinationId}/keys/{kid}";
static final String EVENTS_PATH = "/v1/cases/{caseId}/events";
static final String SUBMISSION_PATH = "/v1/submissions/{submissionId}";
static final String SUBMISSIONS_PATH = "/v1/submissions";
static final String SUBMISSION_ATTACHMENT_PATH = "/v1/submissions/{submissionId}/attachments/{attachmentId}";
static final String ROUTING_AREA_PATH = "/v1/areas";
static final String ROUTING_ROUTE_PATH = "/v1/routes";
static final String WELL_KNOWN_KEYS_PATH = "/.well-known/jwks.json";
}
......@@ -14,7 +14,9 @@ public enum SchemaConfig {
EVENTS_SCHEMA_PATH(SCHEMA_BASE_URL.schemaUri.resolve("events/")),
SET_V_1_0_1(SCHEMA_BASE_URL.schemaUri.resolve("set-payload/1.0.1/set-payload.schema.json"), "set_schema_1.0.1.json"),
SET_V_1_0_0(SCHEMA_BASE_URL.schemaUri.resolve("set-payload/1.0.0/set-payload.schema.json"), "set_schema_1.0.0.json"),
METADATA_V_1_0_0(SCHEMA_BASE_URL.schemaUri.resolve("metadata/1.0.0/metadata.schema.json"), "metadata_schema_1.0.0.json");
METADATA_V_1_0_0(SCHEMA_BASE_URL.schemaUri.resolve("metadata/1.0.0/metadata.schema.json"), "metadata_schema_1.0.0.json"),
XZUFI_DESTINATION_SCHEMA(SCHEMA_BASE_URL.schemaUri.resolve("xzufi/destination.schema.json"), "destination_schema.json");
private final URI schemaUri;
......@@ -42,6 +44,12 @@ public enum SchemaConfig {
.collect(Collectors.toList());
}
public static List<String> getDestinationSchemaPaths(final String destinationSchemaBaseDir) {
return Stream.of(XZUFI_DESTINATION_SCHEMA.fileName)
.map(fileName -> destinationSchemaBaseDir + "/" + fileName)
.collect(Collectors.toList());
}
@Override
public String toString() {
return schemaUri.toString();
......
package dev.fitko.fitconnect.api.domain.model.destination;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@JsonTypeName("ReplyChannel_eMail")
@NoArgsConstructor
public class ReplyChannelEMail {
class ReplyChannelEMail {
@JsonProperty("usePgp")
private Boolean usePgp;
......
......@@ -3,34 +3,45 @@ package dev.fitko.fitconnect.api.domain.model.metadata.attachment;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public enum Purpose {
FORM("form"),
ATTACHMENT("attachment"),
REPORT("report");
private final String value;
private static final Map<String, Purpose> CONSTANTS = new HashMap<>();
static {
for (final Purpose p : values()) {
CONSTANTS.put(p.value, p);
}
}
Purpose(final String value) {
this.value = value;
}
@Override
public String toString() {
return this.value;
return value;
}
@JsonValue
public String value() {
return this.value;
return value;
}
@JsonCreator
public static Purpose fromValue(final String value) {
return Arrays.stream(Purpose.values())
.filter(enumValue -> enumValue.value.equals(value))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("Unexpected value '" + value + "'"));
final Purpose constant = CONSTANTS.get(value);
if (constant == null) {
throw new IllegalArgumentException("Unexpected value '" + value + "'");
}
return constant;
}
}
package dev.fitko.fitconnect.api.domain.model.route;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Area {
@JsonProperty("id")
private String id;
@JsonProperty("name")
private String name;
@JsonProperty("type")
private String type;
}
package dev.fitko.fitconnect.api.domain.model.route;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AreaResult {
@JsonProperty("count")
private Integer count;
@JsonProperty("offset")
private Integer offset;
@JsonProperty("totalCount")
private Integer totalCount;
@JsonProperty("areas")
private List<Area> areas = new ArrayList<>();
}
package dev.fitko.fitconnect.api.domain.model.route;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.UUID;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Route {
@JsonProperty("destinationId")
private UUID destinationId;
@JsonProperty("destinationSignature")
private String destinationSignature;
@JsonProperty("destinationParameters")
private RouteDestination destinationParameters;
@JsonProperty("destinationParametersSignature")
private String destinationParametersSignature;
@JsonProperty("destinationName")
private String destinationName;
@JsonProperty("destinationLogo")
private String destinationLogo;
}
package dev.fitko.fitconnect.api.domain.model.route;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import dev.fitko.fitconnect.api.domain.model.destination.ReplyChannel;
import dev.fitko.fitconnect.api.domain.model.destination.StatusEnum;
import dev.fitko.fitconnect.api.domain.model.jwk.ApiJwkSet;
import dev.fitko.fitconnect.api.domain.model.metadata.data.SubmissionSchema;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class RouteDestination {
@JsonProperty("encryptionKid")
private String encryptionKid = null;
@JsonProperty("metadataVersions")
private List<String> metadataVersions = new ArrayList<>();
@JsonProperty("publicKeys")
private ApiJwkSet publicKeys = null;
@JsonProperty("replyChannels")
private ReplyChannel replyChannels = null;
@JsonProperty("status")
private StatusEnum status = null;
@JsonProperty("submissionSchemas")
private List<SubmissionSchema> submissionSchemas = new ArrayList<>();
@JsonProperty("submissionUrl")
private String submissionUrl = null;
}
package dev.fitko.fitconnect.api.domain.model.route;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class RouteResult {
@JsonProperty("count")
private Integer count;
@JsonProperty("offset")
private Integer offset;
@JsonProperty("totalCount")
private Integer totalCount;
@JsonProperty("routes")
private List<Route> routes = new ArrayList<>();
}
package dev.fitko.fitconnect.api.domain.schema;
import lombok.Value;
import java.util.List;
@Value
public class SchemaResources {
List<String> setSchemaPaths;
List<String> metadataSchemaPaths;
List<String> destinationSchemaPaths;
}
package dev.fitko.fitconnect.api.exceptions;
public class RoutingException extends RuntimeException {
public RoutingException(final String errorMessage) {
super(errorMessage);
}
public RoutingException(final String errorMessage, final Throwable error) {
super(errorMessage, error);
}
}
......@@ -38,7 +38,7 @@ public interface KeyService {
* @param keyId unique identifier of the {@link RSAKey}
* @return validated {@link RSAKey} (@see {@link ValidationService#validateEncryptionPublicKey(RSAKey)})
*/
RSAKey getPortalSignatureKey(String keyId);
RSAKey getPortalPublicKey(String keyId);
/**
* Get a public signature key for a given key-id from the submission service well-known keys.
......@@ -46,6 +46,15 @@ public interface KeyService {
* @param keyId unique identifier of the {@link RSAKey}
* @return validated {@link RSAKey} (@see {@link ValidationService#validateEncryptionPublicKey(RSAKey)})
*/
RSAKey getSubmissionServiceSignatureKey(String keyId);
RSAKey getSubmissionServicePublicKey(String keyId);
/**
* Get a public signature key for a given key-id from a submission service instance url well known keys.
* The <b>'/well-known/jkws.json'</b> is added to the given url.
*
* @param url custom url to load the well known keys from
* @param keyId unique identifier of the {@link RSAKey} the well known keys are filtered by
* @return validated {@link RSAKey} (@see {@link ValidationService#validateEncryptionPublicKey(RSAKey)})
*/
RSAKey getWellKnownKeysForSubmissionUrl(String url, String keyId);
}
package dev.fitko.fitconnect.api.services.routing;
import dev.fitko.fitconnect.api.domain.model.route.Area;
import dev.fitko.fitconnect.api.domain.model.route.AreaResult;
import dev.fitko.fitconnect.api.domain.model.route.Route;
import dev.fitko.fitconnect.api.domain.model.route.RouteResult;
import dev.fitko.fitconnect.api.exceptions.RestApiException;
import java.util.List;
/**
* Routing API Service that retrieves data form FIT-Connect Routing API REST-Endpoints
*/
public interface RoutingService {
/**
* Finds an {@link AreaResult} based on a list of multiple filter criteria include a zip code or e.g. city as in List.of("04229", "Leip*").
*
* @param searchExpressions list of string filters
* @param offset offset to start from
* @param limit max entries
*
* @return list of {@link Area}
* @throws RestApiException if a technical error occurred
*/
AreaResult getAreas(List<String> searchExpressions, int offset, int limit) throws RestApiException;
/**
* Finds a {@link RouteResult} by a given service identifier and AT LEAST ONE OTHER search criterion (ars | ags | areaId).
*
* @param leikaKey leikaKey
* @param ars amtlicher regionalschlüssel
* @param ags amtlicher gemeindeschlüssel
* @param areaId areaId
* @param offset offset to start from
* @param limit max entries
*
* @return list of found {@link Route}s matching the search criteria
* @throws RestApiException if a technical error occurred
*/
RouteResult getRoutes(String leikaKey, String ars, String ags, String areaId, int offset, int limit) throws RestApiException;
}
package dev.fitko.fitconnect.api.services.routing;
import dev.fitko.fitconnect.api.domain.model.route.Route;
import dev.fitko.fitconnect.api.domain.validation.ValidationResult;
import java.util.List;
/**
* Service to verify the validity of routing-related data.
*/
public interface RoutingVerificationService {
/**
* Verifies host url, self-service portal signature and DVDV signature of the provided {@link Route}.
*
* @param routes list of routes to be verified
* @param requestedServiceIdentifier requested service identifier to be checked if the route supports it
* @param requestedRegion requested service region to be checked if the routes supports it
* @return {@link ValidationResult}, is ok if validation passes, has an error including an exception if the validation failed
*/
ValidationResult validateRouteDestinations(List<Route> routes, String requestedServiceIdentifier, String requestedRegion);
}
......@@ -50,4 +50,14 @@ public interface SchemaProvider {
* @throws SchemaNotFoundException if the schema is not existing
*/
String loadMetadataSchema(URI schemaUri) throws SchemaNotFoundException;
/**
* Load the schema for payload of signed destination.
*
* @param schemaUri uri of the destination schema that should be loaded
* @return the schema as string
*
* @throws SchemaNotFoundException if the schema is not existing
*/
String loadDestinationSchema(URI schemaUri) throws SchemaNotFoundException;
}
\ No newline at end of file
......@@ -4,6 +4,8 @@ import com.nimbusds.jose.jwk.RSAKey;
import dev.fitko.fitconnect.api.domain.model.metadata.Metadata;
import dev.fitko.fitconnect.api.domain.validation.ValidationResult;
import java.util.Map;
/**
* Validator for publicKeys and metadata.
*
......@@ -53,6 +55,15 @@ public interface ValidationService {
*/
ValidationResult validateSetEventSchema(String setEventPayload);
/**
* Validates signature payload claims against a given schema.
*
* @param destinationPayload the payload to be validated
*
* @return a {@link ValidationResult} with an optional error
*/
ValidationResult validateDestinationSchema(Map<String, Object> destinationPayload);
/**
* Compares a given byte[] to its original hash value.
*
......