Skip to content

Commit

Permalink
API Wrapper: filter expressions on catalog fetch (sovity#923)
Browse files Browse the repository at this point in the history
* feat: implemented use case catalog fetch with filterExpressions
  • Loading branch information
kamilczaja authored May 16, 2024
1 parent 80d298e commit ec338b4
Show file tree
Hide file tree
Showing 23 changed files with 993 additions and 58 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ please see [changelog_updates.md](docs/dev/changelog_updates.md).

#### Minor Changes

- API Wrapper Use Case API: Catalog endpoint

#### Patch Changes

Security updates
Expand Down
87 changes: 87 additions & 0 deletions docs/api/sovity-edc-api-wrapper.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,27 @@ paths:
type: array
items:
type: string
/wrapper/use-case-api/catalog:
post:
tags:
- Use Case
description: Fetch a connector's data offers
operationId: queryCatalog
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CatalogQuery'
required: true
responses:
default:
description: default response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/UiDataOffer'
components:
schemas:
ConnectorLimits:
Expand Down Expand Up @@ -1575,3 +1596,69 @@ components:
format: int64
description: States and counts of outgoing transferprocess counts
description: Counts of incoming and outgoing TransferProcesses and status
CatalogFilterExpression:
required:
- operandLeft
- operandRight
- operator
type: object
properties:
operandLeft:
type: string
description: Asset property name
example: https://w3id.org/edc/v0.0.1/ns/assetId
operator:
$ref: '#/components/schemas/CatalogFilterExpressionOperator'
operandRight:
$ref: '#/components/schemas/CatalogFilterExpressionLiteral'
description: Generic expression for filtering the data offers in the catalog
CatalogFilterExpressionLiteral:
type: object
properties:
type:
$ref: '#/components/schemas/CatalogFilterExpressionLiteralType'
value:
type: string
description: Only for type VALUE. The single value representation.
valueList:
type: array
description: "Only for type VALUE_LIST. List of values, e.g. for the IN-Operator."
items:
type: string
description: "Only for type VALUE_LIST. List of values, e.g. for the IN-Operator."
description: FilterExpression Criterion Literal
CatalogFilterExpressionLiteralType:
type: string
description: Value type of a filter expression criterion
enum:
- VALUE
- VALUE_LIST
CatalogFilterExpressionOperator:
type: string
description: Operator for filter expressions
enum:
- LIKE
- EQ
- IN
CatalogQuery:
required:
- connectorEndpoint
type: object
properties:
connectorEndpoint:
type: string
description: Target EDC DSP endpoint URL
limit:
type: integer
description: Limit the number of results
format: int32
offset:
type: integer
description: "Offset for returned results, e.g. start at result 2"
format: int32
filterExpressions:
type: array
description: Filter expressions for catalog filtering
items:
$ref: '#/components/schemas/CatalogFilterExpression'
description: Catalog query parameters
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,16 @@

package de.sovity.edc.ext.wrapper.api.usecase;

import de.sovity.edc.ext.wrapper.api.ui.model.UiDataOffer;
import de.sovity.edc.ext.wrapper.api.usecase.model.CatalogQuery;
import de.sovity.edc.ext.wrapper.api.usecase.model.KpiResult;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
Expand All @@ -43,4 +49,14 @@ public interface UseCaseResource {
@Produces(MediaType.APPLICATION_JSON)
@Operation(description = "List available functions in policies, prohibitions and obligations.")
List<String> getSupportedFunctions();

@POST
@Path("catalog")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Operation(description = "Fetch a connector's data offers")
List<UiDataOffer> queryCatalog(
@Valid @NotNull
CatalogQuery catalogQuery
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2024 sovity GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* sovity GmbH - initial API and implementation
*
*/

package de.sovity.edc.ext.wrapper.api.usecase.model;

import de.sovity.edc.utils.jsonld.vocab.Prop;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;

@Data
@AllArgsConstructor
@RequiredArgsConstructor
@Schema(description = "Generic expression for filtering the data offers in the catalog", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
public class CatalogFilterExpression {
@Schema(description = "Asset property name", requiredMode = Schema.RequiredMode.REQUIRED, example = Prop.Edc.ASSET_ID)
private String operandLeft;

@Schema(description = "Operator", requiredMode = Schema.RequiredMode.REQUIRED)
private CatalogFilterExpressionOperator operator;

@Schema(description = "Right Operand", requiredMode = Schema.RequiredMode.REQUIRED)
private CatalogFilterExpressionLiteral operandRight;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2024 sovity GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* sovity GmbH - initial API and implementation
*
*/

package de.sovity.edc.ext.wrapper.api.usecase.model;

import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.ToString;

import java.util.List;

@Getter
@ToString
@Schema(description = "FilterExpression Criterion Literal")
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CatalogFilterExpressionLiteral {

private CatalogFilterExpressionLiteralType type;

@Schema(description = "Only for type VALUE. The single value representation.")
private String value;

@Schema(description = "Only for type VALUE_LIST. List of values, e.g. for the IN-Operator.")
private List<String> valueList;

public static CatalogFilterExpressionLiteral ofValue(@NonNull String value) {
return new CatalogFilterExpressionLiteral(CatalogFilterExpressionLiteralType.VALUE, value, null);
}

public static CatalogFilterExpressionLiteral ofValueList(@NonNull List<String> valueList) {
return new CatalogFilterExpressionLiteral(CatalogFilterExpressionLiteralType.VALUE_LIST, null, valueList);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2024 sovity GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* sovity GmbH - initial API and implementation
*
*/

package de.sovity.edc.ext.wrapper.api.usecase.model;

import io.swagger.v3.oas.annotations.media.Schema;

@Schema(description = "Value type of a filter expression criterion", enumAsRef = true)
public enum CatalogFilterExpressionLiteralType {
VALUE, VALUE_LIST
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2024 sovity GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* sovity GmbH - initial API and implementation
*
*/

package de.sovity.edc.ext.wrapper.api.usecase.model;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
@Schema(description = "Operator for filter expressions", enumAsRef = true)
public enum CatalogFilterExpressionOperator {
LIKE, EQ, IN
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2024 sovity GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* sovity GmbH - initial API and implementation
*
*/

package de.sovity.edc.ext.wrapper.api.usecase.model;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;

import java.util.List;

@Data
@AllArgsConstructor
@RequiredArgsConstructor
@Schema(description = "Catalog query parameters")
public class CatalogQuery {
@Schema(description = "Target EDC DSP endpoint URL", requiredMode = Schema.RequiredMode.REQUIRED)
private String connectorEndpoint;

@Schema(description = "Limit the number of results", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private Integer limit;

@Schema(description = "Offset for returned results, e.g. start at result 2", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private Integer offset;

@Schema(description = "Filter expressions for catalog filtering", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
private List<CatalogFilterExpression> filterExpressions;
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import de.sovity.edc.ext.wrapper.api.ui.pages.asset.AssetBuilder;
import de.sovity.edc.ext.wrapper.api.ui.pages.asset.AssetIdValidator;
import de.sovity.edc.ext.wrapper.api.ui.pages.catalog.CatalogApiService;
import de.sovity.edc.ext.wrapper.api.ui.pages.catalog.UiDataOfferBuilder;
import de.sovity.edc.ext.wrapper.api.ui.pages.contract_agreements.ContractAgreementPageApiService;
import de.sovity.edc.ext.wrapper.api.ui.pages.contract_agreements.ContractAgreementTransferApiService;
import de.sovity.edc.ext.wrapper.api.ui.pages.contract_agreements.services.ContractAgreementDataFetcher;
Expand Down Expand Up @@ -60,6 +61,10 @@
import de.sovity.edc.ext.wrapper.api.ui.pages.transferhistory.TransferHistoryPageAssetFetcherService;
import de.sovity.edc.ext.wrapper.api.ui.pages.transferhistory.TransferProcessStateService;
import de.sovity.edc.ext.wrapper.api.usecase.UseCaseResourceImpl;
import de.sovity.edc.ext.wrapper.api.usecase.pages.catalog.FilterExpressionLiteralMapper;
import de.sovity.edc.ext.wrapper.api.usecase.pages.catalog.FilterExpressionMapper;
import de.sovity.edc.ext.wrapper.api.usecase.pages.catalog.FilterExpressionOperatorMapper;
import de.sovity.edc.ext.wrapper.api.usecase.pages.catalog.UseCaseCatalogApiService;
import de.sovity.edc.ext.wrapper.api.usecase.services.KpiApiService;
import de.sovity.edc.ext.wrapper.api.usecase.services.SupportedPolicyApiService;
import de.sovity.edc.utils.catalog.DspCatalogService;
Expand Down Expand Up @@ -137,7 +142,13 @@ public static WrapperExtensionContext buildContext(
var textUtils = new TextUtils();
var selfDescriptionService = new SelfDescriptionService(config, monitor);
var ownConnectorEndpointService = new OwnConnectorEndpointServiceImpl(selfDescriptionService);
var uiAssetMapper = new UiAssetMapper(edcPropertyUtils, assetJsonLdUtils, markdownToTextConverter, textUtils, ownConnectorEndpointService);
var uiAssetMapper = new UiAssetMapper(
edcPropertyUtils,
assetJsonLdUtils,
markdownToTextConverter,
textUtils,
ownConnectorEndpointService
);
var assetMapper = new AssetMapper(typeTransformerRegistry, uiAssetMapper, jsonLd);
var transferProcessStateService = new TransferProcessStateService();
var contractNegotiationUtils = new ContractNegotiationUtils(
Expand Down Expand Up @@ -210,10 +221,10 @@ public static WrapperExtensionContext buildContext(
policyMapper
);
var dataOfferBuilder = new DspDataOfferBuilder(jsonLd);
var uiDataOfferBuilder = new UiDataOfferBuilder(assetMapper, policyMapper);
var dspCatalogService = new DspCatalogService(catalogService, dataOfferBuilder);
var catalogApiService = new CatalogApiService(
assetMapper,
policyMapper,
uiDataOfferBuilder,
dspCatalogService
);
var contractOfferMapper = new ContractOfferMapper(policyMapper);
Expand Down Expand Up @@ -254,6 +265,13 @@ public static WrapperExtensionContext buildContext(
);

// Use Case API
var filterExpressionOperatorMapper = new FilterExpressionOperatorMapper();
var filterExpressionLiteralMapper = new FilterExpressionLiteralMapper();
var filterExpressionMapper = new FilterExpressionMapper(
filterExpressionOperatorMapper,
filterExpressionLiteralMapper
);

var kpiApiService = new KpiApiService(
assetIndex,
policyDefinitionStore,
Expand All @@ -263,9 +281,15 @@ public static WrapperExtensionContext buildContext(
transferProcessStateService
);
var supportedPolicyApiService = new SupportedPolicyApiService(policyEngine);
var useCaseCatalogApiService = new UseCaseCatalogApiService(
uiDataOfferBuilder,
dspCatalogService,
filterExpressionMapper
);
var useCaseResource = new UseCaseResourceImpl(
kpiApiService,
supportedPolicyApiService
supportedPolicyApiService,
useCaseCatalogApiService
);

// Collect all JAX-RS resources
Expand Down
Loading

0 comments on commit ec338b4

Please sign in to comment.