import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.servers.Server;
-import io.swagger.v3.oas.annotations.servers.Servers;
import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.tags.Tags;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Comparator;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic;
-import org.openecomp.sdc.be.components.impl.ComponentBusinessLogicProvider;
import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
import org.openecomp.sdc.be.components.impl.ElementBusinessLogic;
import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
import org.openecomp.sdc.be.ecomp.converters.AssetMetadataConverter;
import org.openecomp.sdc.be.externalapi.servlet.representation.AssetMetadata;
+import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceAssetMetadata;
import org.openecomp.sdc.be.impl.ComponentsUtils;
import org.openecomp.sdc.be.impl.ServletUtils;
import org.openecomp.sdc.be.model.Component;
*/
@Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
@Path("/v1/catalog")
-@Tags({@Tag(name = "SDCE-7 APIs")})
-@Servers({@Server(url = "/sdc")})
+@Tag(name = "SDCE-7 APIs")
+@Server(url = "/sdc")
@Controller
public class AssetsDataServlet extends AbstractValidationsServlet {
private static final Logger log = Logger.getLogger(AssetsDataServlet.class);
- private final ElementBusinessLogic elementBusinessLogic;
+ private final ElementBusinessLogic elementBL;
private final AssetMetadataConverter assetMetadataConverter;
- private final ServiceBusinessLogic serviceBusinessLogic;
- private final ResourceBusinessLogic resourceBusinessLogic;
- private final ComponentBusinessLogicProvider componentBusinessLogicProvider;
+ private final ServiceBusinessLogic serviceBL;
+ private final ResourceBusinessLogic resourceBL;
@Context
private HttpServletRequest request;
@Inject
- public AssetsDataServlet(ComponentInstanceBusinessLogic componentInstanceBL, ComponentsUtils componentsUtils,
- ServletUtils servletUtils, ResourceImportManager resourceImportManager, ElementBusinessLogic elementBusinessLogic,
- AssetMetadataConverter assetMetadataConverter, ComponentBusinessLogicProvider componentBusinessLogicProvider,
- ServiceBusinessLogic serviceBusinessLogic, ResourceBusinessLogic resourceBusinessLogic) {
+ public AssetsDataServlet(ComponentInstanceBusinessLogic componentInstanceBL, ComponentsUtils componentsUtils, ServletUtils servletUtils,
+ ResourceImportManager resourceImportManager, ElementBusinessLogic elementBL,
+ AssetMetadataConverter assetMetadataConverter, ServiceBusinessLogic serviceBL,
+ ResourceBusinessLogic resourceBL) {
super(componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
- this.elementBusinessLogic = elementBusinessLogic;
+ this.elementBL = elementBL;
this.assetMetadataConverter = assetMetadataConverter;
- this.serviceBusinessLogic = serviceBusinessLogic;
- this.resourceBusinessLogic = resourceBusinessLogic;
- this.componentBusinessLogicProvider = componentBusinessLogicProvider;
+ this.serviceBL = serviceBL;
+ this.resourceBL = resourceBL;
}
@GET
@ApiResponse(responseCode = "500", description = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000")})
@PermissionAllowed(AafPermission.PermNames.READ_VALUE)
public Response getAssetListExternal(
- @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
+ @Parameter(description = "X-ECOMP-RequestID header") @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
@Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
- @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
+ @Parameter(description = "Determines the format of the body of the response") @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
@Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
@Parameter(description = "The requested asset type", schema = @Schema(allowableValues = {"resources",
"services"}), required = true) @PathParam("assetType") final String assetType,
- @Parameter(description = "The filter key (resourceType only for resources)", required = false) @QueryParam("category") String category,
- @Parameter(description = "The filter key (resourceType only for resources)", required = false) @QueryParam("subCategory") String subCategory,
- @Parameter(description = "The filter key (resourceType only for resources)", required = false) @QueryParam("distributionStatus") String distributionStatus,
- @Parameter(description = "The filter key (resourceType only for resources)", required = false) @QueryParam("resourceType") String resourceType)
- throws IOException {
- ResponseFormat responseFormat = null;
- String query = request.getQueryString();
- String requestURI = request.getRequestURI().endsWith("/") ? removeDuplicateSlashSeparator(request.getRequestURI()) : request.getRequestURI();
- String url = request.getMethod() + " " + requestURI;
+
+ @Parameter(description = "The category to filter the result set on") @QueryParam("category") String category,
+ @Parameter(description = "The sub category to filter the result set on. Only applicable when assetType = resources") @QueryParam("subCategory") String subCategory,
+ @Parameter(description = "The distribution status to filter the result set on") @QueryParam("distributionStatus") String distributionStatus,
+ @Parameter(description = "The resource type to filter the result set on. Only applicable when assetType = resources") @QueryParam("resourceType") String resourceType,
+ @Parameter(description = "Additional metadata keys to include in the response, not all keys are supported.\nSupported keys: lastUpdateDate, creationDate, description, uniqueId and category specific metadata keys")
+ @QueryParam("include") List<String> additionalMetadataKeysToInclude,
+ @Parameter(description = "The version(s) to filter the result set on\n" +
+ "Syntax: /services?version=(highestMatchingVersionOnly|lessThan|greaterThan|equals)(:=)(value)",
+ examples = {
+ @ExampleObject(
+ name = "An example request to get each service with highest version",
+ value = "highestMatchingVersionOnly:true"),
+ @ExampleObject(
+ name = "An example request to get all services with version less than 2.1",
+ value = "lessThan:2.1"),
+ @ExampleObject(
+ name = "An example request to get all services with version equal 2.0",
+ value = "equals:2.0"),
+ @ExampleObject(
+ name = "An example request to get all services with version greater than 1.1",
+ value = "greaterThan:1.1")})
+ @QueryParam("version") String version,
+ @Parameter(description = "The keys of the metadata to include in the entries in the result set. Only applicable when assetType = services\n" +
+ "Only category specific metadata keys are supported\n" +
+ "Syntax: /services?metadata=<KEY1>(:=)<VALUE1>&metadata=<KEY2>(:=)<VALUE2> ...",
+ examples = {
+ @ExampleObject(
+ name = "An example request to get all services matching following Category Specific Metadata condition 'ETSI Version=3.3.1'",
+ value = "ETSI Version:3.3.1")})
+ @QueryParam("metadata") List<String> metadata) throws IOException {
+ ResponseFormat responseFormat;
+ final String query = request.getQueryString();
+ final String requestURI =
+ request.getRequestURI().endsWith("/") ? removeDuplicateSlashSeparator(request.getRequestURI()) : request.getRequestURI();
+ final String url = request.getMethod() + " " + requestURI;
log.debug("Start handle request of {}", url);
- AuditingActionEnum auditingActionEnum = query == null ? AuditingActionEnum.GET_ASSET_LIST : AuditingActionEnum.GET_FILTERED_ASSET_LIST;
- String resourceUrl = query == null ? requestURI : requestURI + "?" + query;
- DistributionData distributionData = new DistributionData(instanceIdHeader, resourceUrl);
+ final AuditingActionEnum auditingActionEnum = query == null ? AuditingActionEnum.GET_ASSET_LIST : AuditingActionEnum.GET_FILTERED_ASSET_LIST;
+ final String resourceUrl = query == null ? requestURI : requestURI + "?" + query;
+ final DistributionData distributionData = new DistributionData(instanceIdHeader, resourceUrl);
// Mandatory
if (instanceIdHeader == null || instanceIdHeader.isEmpty()) {
log.debug("getAssetList: Missing X-ECOMP-InstanceID header");
return buildErrorResponse(responseFormat);
}
try {
- Map<FilterKeyEnum, String> filters = new EnumMap<>(FilterKeyEnum.class);
+ final Map<FilterKeyEnum, Object> filters = new EnumMap<>(FilterKeyEnum.class);
if (category != null) {
filters.put(FilterKeyEnum.CATEGORY, category);
}
if (distributionStatus != null) {
filters.put(FilterKeyEnum.DISTRIBUTION_STATUS, distributionStatus);
}
+ if (version != null) {
+ filters.put(FilterKeyEnum.VERSION, version);
+ }
+ if (CollectionUtils.isNotEmpty(metadata)) {
+ filters.put(FilterKeyEnum.METADATA, metadata);
+ }
if (resourceType != null) {
ResourceTypeEnum resourceTypeEnum = ResourceTypeEnum.getTypeIgnoreCase(resourceType);
if (resourceTypeEnum == null) {
}
filters.put(FilterKeyEnum.RESOURCE_TYPE, resourceTypeEnum.name());
}
- Either<List<? extends Component>, ResponseFormat> assetTypeData = elementBusinessLogic
- .getFilteredCatalogComponents(assetType, filters, query);
- if (assetTypeData.isRight()) {
+ final Either<List<? extends Component>, ResponseFormat> componentList = elementBL.getFilteredCatalogComponents(assetType, filters, query);
+ if (componentList.isRight()) {
log.debug("getAssetList: Asset Fetching Failed");
- responseFormat = assetTypeData.right().value();
+ responseFormat = componentList.right().value();
getComponentsUtils().auditExternalGetAssetList(responseFormat, auditingActionEnum, distributionData, requestId);
return buildErrorResponse(responseFormat);
} else {
log.debug("getAssetList: Asset Fetching Success");
- Either<List<? extends AssetMetadata>, ResponseFormat> resMetadata = assetMetadataConverter
- .convertToAssetMetadata(assetTypeData.left().value(), requestURI, false);
+ final Either<List<? extends AssetMetadata>, ResponseFormat> resMetadata = assetMetadataConverter
+ .convertToAssetMetadata(componentList.left().value(), requestURI, false, additionalMetadataKeysToInclude);
if (resMetadata.isRight()) {
log.debug("getAssetList: Asset conversion Failed");
responseFormat = resMetadata.right().value();
getComponentsUtils().auditExternalGetAssetList(responseFormat, auditingActionEnum, distributionData, requestId);
return buildErrorResponse(responseFormat);
}
- Object result = RepresentationUtils.toRepresentation(resMetadata.left().value());
+ final Object result = RepresentationUtils.toRepresentation(sortIfNeed(resMetadata.left().value(), additionalMetadataKeysToInclude));
responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
getComponentsUtils().auditExternalGetAssetList(responseFormat, auditingActionEnum, distributionData, requestId);
return buildOkResponse(responseFormat, result);
@ApiResponse(responseCode = "500", description = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000")})
@PermissionAllowed(AafPermission.PermNames.READ_VALUE)
public Response getAssetSpecificMetadataByUuidExternal(
- @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
+ @Parameter(description = "X-ECOMP-RequestID header") @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
@Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
- @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
+ @Parameter(description = "Determines the format of the body of the response") @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
@Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
@Parameter(description = "The requested asset type", schema = @Schema(allowableValues = {"resources",
"services"}), required = true) @PathParam("assetType") final String assetType,
return buildErrorResponse(responseFormat);
}
try {
- Either<List<? extends Component>, ResponseFormat> assetTypeData = elementBusinessLogic
- .getCatalogComponentsByUuidAndAssetType(assetType, uuid);
+ final Either<List<? extends Component>, ResponseFormat> assetTypeData = elementBL.getCatalogComponentsByUuidAndAssetType(assetType, uuid);
if (assetTypeData.isRight()) {
log.debug("getAssetList: Asset Fetching Failed");
responseFormat = assetTypeData.right().value();
resourceCommonInfo.setResourceName(assetTypeData.left().value().iterator().next().getName());
log.debug("getAssetList: Asset Fetching Success");
Either<List<? extends AssetMetadata>, ResponseFormat> resMetadata = assetMetadataConverter
- .convertToAssetMetadata(assetTypeData.left().value(), requestURI, true);
+ .convertToAssetMetadata(assetTypeData.left().value(), requestURI, true, null);
if (resMetadata.isRight()) {
log.debug("getAssetList: Asset conversion Failed");
responseFormat = resMetadata.right().value();
private ComponentBusinessLogic getComponentBLByType(ComponentTypeEnum componentTypeEnum) {
if (componentTypeEnum.equals(RESOURCE)) {
- return resourceBusinessLogic;
+ return resourceBL;
} else {
// Implementation is the same for any ComponentBusinessLogic
- return serviceBusinessLogic;
+ return serviceBL;
}
}
@ApiResponse(responseCode = "500", description = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000")})
@PermissionAllowed(AafPermission.PermNames.READ_VALUE)
public Response getToscaModelExternal(
- @Parameter(description = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
+ @Parameter(description = "X-ECOMP-RequestID header") @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
@Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
- @Parameter(description = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
+ @Parameter(description = "Determines the format of the body of the response") @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
@Parameter(description = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
@Parameter(description = "The requested asset type", schema = @Schema(allowableValues = {"resources",
"services"}), required = true) @PathParam("assetType") final String assetType,
private String removeDuplicateSlashSeparator(String requestUri) {
return requestUri.substring(0, requestUri.length() - 1);
}
+
+ private List<? extends AssetMetadata> sortIfNeed(final List<? extends AssetMetadata> assetMetadataList,
+ final List<String> additionalMetadataKeysToInclude) {
+ if (additionalMetadataKeysToInclude.contains("creationDate")) {
+ assetMetadataList.sort(
+ Comparator.comparing((AssetMetadata am) -> ((ServiceAssetMetadata) am).getAdditionalRequestedMetadata().get("creationDate")));
+ }
+ return assetMetadataList;
+ }
+
}