Skip to content

Commit

Permalink
Merge pull request #59 from carlos-schmidt/main
Browse files Browse the repository at this point in the history
Update postman, fix minor bugs
  • Loading branch information
carlos-schmidt committed Nov 25, 2023
2 parents 99970d5 + 500b332 commit 6c3d0e4
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public Response deleteModel(URL aasServiceUrl, String element) {
*
* @param aasServiceUrl AAS service to be updated
* @return AAS model enriched with each elements access URL as string in assetId
* field.
* field.
*/
public CustomAssetAdministrationShellEnvironment getAasEnvWithUrls(URL aasServiceUrl)
throws IOException, DeserializationException {
Expand All @@ -139,10 +139,15 @@ public CustomAssetAdministrationShellEnvironment getAasEnvWithUrls(URL aasServic
Encoder.encodeBase64(submodel.getIdentification().getId())));
submodel.getSubmodelElements()
.forEach(elem -> putUrlRec(
format("%s/submodels/%s/submodel/submodel-elements", aasServiceUrlString,
Encoder.encodeBase64(submodel.getIdentification().getId())),
elem));
format("%s/submodels/%s/submodel/submodel-elements", aasServiceUrlString,
Encoder.encodeBase64(submodel.getIdentification().getId())),
elem));
});
model.getSubmodels().forEach(submodel -> AASUtil.getAllSubmodelElements(submodel)
.forEach(element -> element.setSourceUrl(
element.getSourceUrl()
.replaceFirst("\\.", "/"))));

// Add urls to all concept descriptions
model.getConceptDescriptions().forEach(
conceptDesc -> conceptDesc.setSourceUrl(format("%s/concept-descriptions/%s", aasServiceUrlString,
Expand All @@ -160,12 +165,12 @@ private CustomAssetAdministrationShellEnvironment readModel(URL aasServiceUrl)
String conceptResponse;
String submodelResponse;
try {
shellResponse =
shellResponse =
Objects.requireNonNull(httpRestClient.get(aasServiceUrl.toURI().resolve("/shells").toURL()).body()).string();
submodelResponse =
submodelResponse =
Objects.requireNonNull(httpRestClient.get(aasServiceUrl.toURI().resolve("/submodels").toURL()).body()).string();
conceptResponse = Objects.requireNonNull(httpRestClient.get(aasServiceUrl.toURI().resolve("/concept" +
"-descriptions").toURL()).body())
"-descriptions").toURL()).body())
.string();
} catch (URISyntaxException e) {
throw new EdcException(e.getMessage());
Expand Down Expand Up @@ -219,11 +224,11 @@ private CustomSubmodelElement putUrlRec(String url, CustomSubmodelElement elemen
if (element instanceof CustomSubmodelElementCollection) {
Collection<CustomSubmodelElement> newCollectionElements = new ArrayList<>();
for (var collectionElement : ((CustomSubmodelElementCollection) element).getValue()) {
newCollectionElements.add(putUrlRec(format("%s/%s", url, element.getIdShort()), collectionElement));
newCollectionElements.add(putUrlRec(format("%s.%s", url, element.getIdShort()), collectionElement));
}
((CustomSubmodelElementCollection) element).setValues(newCollectionElements);
}
element.setSourceUrl(format("%s/%s", url, element.getIdShort()));
element.setSourceUrl(format("%s.%s", url, element.getIdShort()));
return element;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,12 @@ public Response getDataset(@QueryParam("providerUrl") URL providerUrl,
@POST
@Path(NEGOTIATE_CONTRACT_PATH)
public Response negotiateContract(ContractRequest contractRequest) {
Objects.requireNonNull(contractRequest, "ContractOffer must not be null");
Objects.requireNonNull(contractRequest, "ContractRequest must not be null");
try {
var agreement = negotiator.negotiate(contractRequest);
return Response.ok(agreement).build(); // TODO contract request instead of contractoffer: do whole change
return Response.ok(agreement).build();
} catch (InterruptedException | ExecutionException negotiationException) {
LOGGER.error(format("Negotiation failed for provider %s and contractOffer %s", contractRequest.getProviderId(),
LOGGER.error(format("Negotiation failed for provider %s and contractRequest %s", contractRequest.getProviderId(),
contractRequest.getContractOffer().getId()), negotiationException);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(negotiationException.getMessage())
.build();
Expand Down Expand Up @@ -269,7 +269,7 @@ public Response deleteAcceptedPolicyDefinition(@QueryParam("policyDefinitionId")
var removed = policyService.removeAccepted(policyDefinitionId);

if (removed.isPresent()) {
return Response.ok(removed).build();
return Response.ok(policyDefinitionId).build();
}
return Response.status(Response.Status.NOT_FOUND).entity("Unknown policyDefinitionId.").build();
}
Expand All @@ -290,7 +290,7 @@ public Response updateAcceptedPolicyDefinition(PolicyDefinition policyDefinition

var updated = policyService.updateAccepted(policyDefinition.getId(), policyDefinition);
if (updated.isPresent()) {
return Response.ok(updated).build();
return Response.ok(policyDefinition.getId()).build();
}
return Response.status(Response.Status.NOT_FOUND).entity("Unknown policyDefinitionId.").build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package de.fraunhofer.iosb.app.client.contract;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import de.fraunhofer.iosb.app.Logger;
import de.fraunhofer.iosb.app.model.configuration.Configuration;
import org.eclipse.edc.connector.policy.spi.PolicyDefinition;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public PolicyService(CatalogService catalogService, TypeTransformerRegistry tran
* @param providerUrl Provider of the asset.
* @param assetId Asset ID of the asset whose contract should be fetched.
* @return A list of dataset offered by the provider for the given
* assetId.
* assetId.
* @throws InterruptedException Thread for agreementId was waiting, sleeping, or
* otherwise occupied, and was interrupted.
*/
Expand Down Expand Up @@ -140,18 +140,22 @@ public Dataset getDatasetForAssetId(URL providerUrl, String assetId) throws Inte
}

/**
* Return policyDefinition for assetId that match any policyDefinitions' policy of
* the services' policyDefinitionStore instance containing user added policyDefinitions.
* Return policyDefinition for assetId that match any policyDefinitions' policy
* of
* the services' policyDefinitionStore instance containing user added
* policyDefinitions.
* If more than one policyDefinitions are provided by the provider
* connector, an AmbiguousOrNullException will be thrown.
*
* @param providerUrl Provider of the asset.
* @param assetId Asset ID of the asset whose contract should be fetched.
* @return One policyDefinition offered by the provider for the given assetId.
* @throws InterruptedException Thread for agreementId was waiting, sleeping, or otherwise occupied, and was
* @throws InterruptedException Thread for agreementId was waiting, sleeping, or
* otherwise occupied, and was
* interrupted.
*/
public Pair<String, Policy> getAcceptablePolicyForAssetId(URL providerUrl, String assetId) throws InterruptedException {
public Pair<String, Policy> getAcceptablePolicyForAssetId(URL providerUrl, String assetId)
throws InterruptedException {
var dataset = getDatasetForAssetId(providerUrl, assetId);

Map.Entry<String, Policy> acceptablePolicy;
Expand All @@ -175,12 +179,12 @@ public Pair<String, Policy> getAcceptablePolicyForAssetId(URL providerUrl, Strin
.first(acceptablePolicy.getKey()).second(acceptablePolicy.getValue()).build();
}


/**
* Adds an accepted contractOffer to match when checking a provider
* contractOffer. Only the policies' rules are relevant.
*
* @param policyDefinitions policies' rules that are acceptable for an automated contract negotiation
* @param policyDefinitions policies' rules that are acceptable for an automated
* contract negotiation
*/
public void addAccepted(PolicyDefinition[] policyDefinitions) {
policyDefinitionStore.putPolicyDefinitions(policyDefinitions);
Expand All @@ -198,7 +202,8 @@ public List<PolicyDefinition> getAccepted() {
/**
* Removes an accepted policyDefinitions.
*
* @param policyDefinitions policyDefinition id of policyDefinition to be removed
* @param policyDefinitions policyDefinition id of policyDefinition to be
* removed
* @return Optional containing removed policy definition or null
*/
public Optional<PolicyDefinition> removeAccepted(String policyDefinitions) {
Expand All @@ -208,47 +213,47 @@ public Optional<PolicyDefinition> removeAccepted(String policyDefinitions) {
/**
* Updates an accepted policyDefinition.
*
* @param policyDefinitionId PolicyDefinition id of policyDefinition to be updated
* @param policyDefinitionId PolicyDefinition id of policyDefinition to be
* updated
* @param policyDefinition Updated PolicyDefinition
*/
public Optional<PolicyDefinition> updateAccepted(String policyDefinitionId, PolicyDefinition policyDefinition) {
return policyDefinitionStore.updatePolicyDefinitions(policyDefinitionId, policyDefinition);
}


private boolean matchesOwnPolicyDefinitions(Policy policy) {
return policyDefinitionStore.getPolicyDefinitions().stream().anyMatch(acceptedPolicyDefinition -> policyDefinitionRulesEquality(acceptedPolicyDefinition.getPolicy(), policy));
return policyDefinitionStore.getPolicyDefinitions().stream().anyMatch(
acceptedPolicyDefinition -> policyDefinitionRulesEquality(acceptedPolicyDefinition.getPolicy(),
policy));
}

private boolean policyDefinitionRulesEquality(Policy first, Policy second) {
List<Rule> firstRules = Stream.of(
first.getPermissions(),
first.getProhibitions(),
first.getObligations()
)
first.getPermissions(),
first.getProhibitions(),
first.getObligations())
.flatMap(Collection::stream)
.collect(Collectors.toList());

List<Rule> secondRules = Stream.of(
second.getPermissions(),
second.getProhibitions(),
second.getObligations()
)
second.getPermissions(),
second.getProhibitions(),
second.getObligations())
.flatMap(Collection::stream)
.collect(Collectors.toList());


return firstRules.stream().anyMatch(firstRule -> secondRules.stream().anyMatch(secondRule -> !ruleEquality(firstRule, secondRule)));
return firstRules.stream().anyMatch(
firstRule -> secondRules.stream().anyMatch(secondRule -> !ruleEquality(firstRule, secondRule)));
}

private <T extends Rule> boolean ruleEquality(T first, T second) {
return Objects.equals(first.getAction(), second.getAction()) && Objects.equals(first.getConstraints(),
second.getConstraints());
}


/*
* Since EDC api does not return Catalog object directly, resort to a hacky solution for now.
* Since EDC api does not return Catalog object directly, resort to another
* solution for now.
*/
private JsonObject modifyCatalogJson(byte[] catalogBytes) throws IOException {

Expand All @@ -260,7 +265,6 @@ private JsonObject modifyCatalogJson(byte[] catalogBytes) throws IOException {
.replace(DSPACE_PREFIX + ":", DSPACE_SCHEMA)
.getBytes();

// Alarming... looking into it though
Distribution distribution = Distribution.Builder.newInstance()
.format("JSON")
.dataService(DataService.Builder.newInstance().build())
Expand All @@ -275,11 +279,16 @@ private JsonObject modifyCatalogJson(byte[] catalogBytes) throws IOException {
.replace("dataService", DCAT_ACCESS_SERVICE_ATTRIBUTE));

jsonNode = om.readTree(catalogBytes);

if (!jsonNode.has(DCAT_SCHEMA + "dataset") || jsonNode.get(DCAT_SCHEMA + "dataset") == null
|| jsonNode.get(DCAT_SCHEMA + "dataset").isEmpty()) {
throw new EdcException("No dataset provided in catalog.");
}

((ArrayNode) jsonNode
.get(DCAT_SCHEMA + "dataset")
.get(DCAT_SCHEMA + "distribution"))
.add(distributionNode);

catalogBytes = om.writeValueAsBytes(jsonNode);

var jsonReader = Json.createReader(new ByteArrayInputStream(catalogBytes));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import static java.lang.String.format;

/**
* Send contract offer, negotiation status watch
* Send contractrequest, negotiation status watch
*/
public class Negotiator {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.json.JsonMapper;

import de.fraunhofer.iosb.app.Logger;
import de.fraunhofer.iosb.app.RequestType;
import de.fraunhofer.iosb.app.model.configuration.Configuration;
Expand All @@ -39,9 +41,7 @@ public class ConfigurationController implements Controllable {
public ConfigurationController() {
logger = Logger.getInstance();
configuration = Configuration.getInstance();
objectMapper = new ObjectMapper();
// TODO case insensitive object mapper without deprecated configuration?
objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
objectMapper = JsonMapper.builder().configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true).build();
objectReader = objectMapper.readerForUpdating(configuration);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

@JsonIgnoreProperties(ignoreUnknown = true)
Expand Down Expand Up @@ -75,11 +74,7 @@ public boolean equals(Object obj) {
return false;
}

if ((this.getSubmodelElements() == null) ? (other.getSubmodelElements() != null)
: this.getSubmodelElements().size() != other.getSubmodelElements().size()) {
return false;
}

return new HashSet<>(other.getSubmodelElements()).containsAll(this.getSubmodelElements());
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public class Synchronizer implements SelfDescriptionChangeListener {
private final ResourceController resourceController;

public Synchronizer(SelfDescriptionRepository selfDescriptionRepository,
AasController aasController, ResourceController resourceController) {
AasController aasController, ResourceController resourceController) {
this.selfDescriptionRepository = selfDescriptionRepository;
this.aasController = aasController;
this.resourceController = resourceController;
Expand Down Expand Up @@ -105,22 +105,22 @@ private CustomAssetAdministrationShellEnvironment fetchCurrentAasModel(URL aasSe

private void addNewElements(CustomAssetAdministrationShellEnvironment newEnvironment) {
var envElements = AASUtil.getAllElements(newEnvironment);
addAssetsContracts(envElements.stream().filter(element -> Objects.isNull(element.getIdsContractId()))
addAssetsContracts(envElements.stream().filter(element -> Objects.isNull(element.getIdsAssetId()) || Objects.isNull(element.getIdsContractId()))
.toList());
}

/*
* Removes elements that were deleted on AAS service
*/
private void removeOldElements(CustomAssetAdministrationShellEnvironment newEnvironment,
CustomAssetAdministrationShellEnvironment oldEnvironment) {
CustomAssetAdministrationShellEnvironment oldEnvironment) {
var elementsToRemove = AASUtil.getAllElements(oldEnvironment);
elementsToRemove.removeAll(AASUtil.getAllElements(newEnvironment));
removeAssetsContracts(elementsToRemove);
}

private void syncShell(CustomAssetAdministrationShellEnvironment newEnvironment,
CustomAssetAdministrationShellEnvironment oldEnvironment) {
CustomAssetAdministrationShellEnvironment oldEnvironment) {
var oldShells = oldEnvironment.getAssetAdministrationShells();
newEnvironment.getAssetAdministrationShells().replaceAll(
shell -> oldShells.contains(shell)
Expand All @@ -129,7 +129,7 @@ private void syncShell(CustomAssetAdministrationShellEnvironment newEnvironment,
}

private void syncConceptDescription(CustomAssetAdministrationShellEnvironment newEnvironment,
CustomAssetAdministrationShellEnvironment oldEnvironment) {
CustomAssetAdministrationShellEnvironment oldEnvironment) {
var oldConceptDescriptions = oldEnvironment.getConceptDescriptions();
newEnvironment.getConceptDescriptions().replaceAll(
conceptDescription -> oldConceptDescriptions.contains(conceptDescription)
Expand All @@ -138,17 +138,15 @@ private void syncConceptDescription(CustomAssetAdministrationShellEnvironment ne
}

private void syncSubmodel(CustomAssetAdministrationShellEnvironment newEnvironment,
CustomAssetAdministrationShellEnvironment oldEnvironment) {
CustomAssetAdministrationShellEnvironment oldEnvironment) {
var oldSubmodels = oldEnvironment.getSubmodels();
newEnvironment.getSubmodels().forEach(submodel -> {
CustomSubmodel oldSubmodel;
if (oldSubmodels.contains(submodel)) {
oldSubmodel = oldSubmodels
.get(oldSubmodels.indexOf(submodel));
oldSubmodel = oldSubmodels.get(oldSubmodels.indexOf(submodel));
} else {
oldSubmodel = oldSubmodels.stream().filter(
oldSubmodelTest -> oldSubmodelTest.getIdentification().equals(submodel.getIdentification())
&& oldSubmodelTest.getIdShort().equals(submodel.getIdShort()))
oldSubmodelTest -> submodel.equals(oldSubmodelTest))
.findFirst().orElse(null);
if (Objects.isNull(oldSubmodel)) {
return;
Expand All @@ -164,7 +162,7 @@ private void syncSubmodel(CustomAssetAdministrationShellEnvironment newEnvironme
}

private void syncSubmodelElements(Collection<CustomSubmodelElement> allElements,
Collection<CustomSubmodelElement> allOldElements) {
Collection<CustomSubmodelElement> allOldElements) {
allElements.stream()
.filter(allOldElements::contains)
.forEach(element -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,7 @@ public void negotiateContractTest() {
}

@Test
@Disabled("Until catalog fetching works again")
public void negotiateContractAndTransferTest() {
// TODO repair after fixing ContractOfferService.class
try (var ignored = clientEndpoint.negotiateContract(url, "test-id", "test-asset-id", null)) {
fail();
} catch (EdcException expected) {
Expand Down
Loading

0 comments on commit 6c3d0e4

Please sign in to comment.