summaryrefslogtreecommitdiffstats
path: root/dcaedt_catalog/asdc/src/main/java/org/onap/sdc
diff options
context:
space:
mode:
Diffstat (limited to 'dcaedt_catalog/asdc/src/main/java/org/onap/sdc')
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDC.java1101
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCController.java0
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCEngine.java25
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCException.java18
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtils.java448
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtilsController.java76
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/Blueprinter.java76
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/Cloudify.java249
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/ISdcClient.java47
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/SdcRestClient.java221
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/ArtifactGroupType.java5
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/ArtifactType.java16
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/AssetType.java5
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/LifecycleOperationType.java16
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/SdcConsumerInfo.java5
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/AbstractSdncException.java97
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/BaseException.java61
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/OkResponseInfo.java8
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/PolicyException.java11
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/RequestError.java65
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/ResponseFormat.java75
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/ServiceException.java12
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/utils/Normalizers.java34
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/utils/SDCResponseErrorHandler.java43
-rw-r--r--dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/utils/SdcRestClientUtils.java85
25 files changed, 2799 insertions, 0 deletions
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDC.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDC.java
new file mode 100644
index 0000000..66afab1
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDC.java
@@ -0,0 +1,1101 @@
+package org.onap.sdc.dcae.catalog.asdc;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.Collections;
+
+import java.util.function.UnaryOperator;
+
+import javax.annotation.PostConstruct;
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.enums.ArtifactGroupType;
+import org.onap.sdc.dcae.enums.ArtifactType;
+import org.onap.sdc.dcae.composition.restmodels.sdc.ResourceDetailed;
+import org.springframework.http.MediaType;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpRequest;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.RequestEntity;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.client.AsyncClientHttpRequestExecution;
+import org.springframework.http.client.AsyncClientHttpRequestInterceptor;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.web.client.AsyncRestTemplate;
+import org.springframework.web.client.RestClientException;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.http.converter.HttpMessageConverter;
+
+import org.springframework.util.Base64Utils;
+//import org.springframework.util.DigestUtils;
+import org.apache.commons.codec.digest.DigestUtils;
+
+import org.springframework.stereotype.Component;
+import org.springframework.context.annotation.Scope;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import org.springframework.util.concurrent.ListenableFuture;
+import org.springframework.util.concurrent.ListenableFutureCallback;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import org.json.JSONObject;
+import org.onap.sdc.dcae.catalog.commons.Action;
+import org.onap.sdc.dcae.catalog.commons.Future;
+import org.onap.sdc.dcae.catalog.commons.Futures;
+import org.onap.sdc.dcae.catalog.commons.JSONHttpMessageConverter;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.onap.sdc.dcae.composition.util.SystemProperties;
+import org.json.JSONArray;
+
+import org.apache.commons.cli.BasicParser;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+
+
+@Component("asdc")
+@Scope("singleton")
+//@ConfigurationProperties(prefix="asdc")
+public class ASDC {
+
+ public static enum AssetType {
+ resource,
+ service,
+ product
+ }
+
+// public static enum ArtifactType {
+// DCAE_TOSCA,
+// DCAE_JSON,
+// DCAE_POLICY,
+// DCAE_DOC,
+// DCAE_EVENT,
+// DCAE_INVENTORY_TOSCA,
+// DCAE_INVENTORY_JSON,
+// DCAE_INVENTORY_POLICY,
+// DCAE_INVENTORY_DOC,
+// DCAE_INVENTORY_BLUEPRINT,
+// DCAE_INVENTORY_EVENT,
+// HEAT,
+// HEAT_VOL,
+// HEAT_NET,
+// HEAT_NESTED,
+// HEAT_ARTIFACT,
+// HEAT_ENV,
+// OTHER
+// }
+
+// public static enum ArtifactGroupType {
+// DEPLOYMENT,
+// INFORMATIONAL
+// }
+
+ public static enum LifecycleState {
+ Checkin,
+ Checkout,
+ Certify,
+ undocheckout
+ }
+
+
+// @Retention(RetentionPolicy.RUNTIME)
+// @Target(ElementType.METHOD)
+// public @interface Mandatory {
+// }
+
+ protected static OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ protected static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ @Autowired
+ private SystemProperties systemProperties;
+
+ private URI rootUri;
+ private String rootPath = "/sdc/v1/catalog/";
+ private String user,
+ passwd;
+ private String instanceId;
+
+
+ public void setUri(URI theUri) {
+ //theUri = URI.create(systemProperties.getProperties().getProperty(SystemProperties.ASDC_CATALOG_URL));
+ String userInfo = theUri.getUserInfo();
+ if (userInfo != null) {
+ String[] userInfoParts = userInfo.split(":");
+ setUser(userInfoParts[0]);
+ if (userInfoParts.length > 1)
+ setPassword(userInfoParts[1]);
+ }
+ String fragment = theUri.getFragment();
+ if (fragment == null)
+ throw new IllegalArgumentException("The URI must contain a fragment specification, to be used as ASDC instance id");
+ setInstanceId(fragment);
+
+ try {
+ this.rootUri = new URI(theUri.getScheme(), null, theUri.getHost(), theUri.getPort(), theUri.getPath(), theUri.getQuery(), null);
+ }
+ catch (URISyntaxException urix) {
+ throw new IllegalArgumentException("Invalid uri", urix);
+ }
+ }
+
+ public URI getUri() {
+ return this.rootUri;
+ }
+
+ public void setUser(String theUser) {
+ this.user = theUser;
+ }
+
+ public String getUser() {
+ return this.user;
+ }
+
+ public void setPassword(String thePassword) {
+ this.passwd = thePassword;
+ }
+
+ public String getPassword() {
+ return this.passwd;
+ }
+
+ public void setInstanceId(String theId) {
+ this.instanceId = theId;
+ }
+
+ public String getInstanceId() {
+ return this.instanceId;
+ }
+
+ public void setRootPath(String thePath) {
+ this.rootPath = systemProperties.getProperties().getProperty(DcaeBeConstants.Config.ASDC_ROOTPATH);
+ }
+
+ public String getRootPath() {
+ return systemProperties.getProperties().getProperty(DcaeBeConstants.Config.ASDC_ROOTPATH);
+ }
+
+ @Scheduled(fixedRateString = "${beans.context.scripts.updateCheckFrequency?:60000}")
+ public void checkForUpdates() {
+ }
+
+ @PostConstruct
+ public void initASDC() {
+ }
+
+ public <T> Future<T> getResources(Class<T> theType) {
+ return getAssets(AssetType.resource, theType);
+ }
+
+ public Future<JSONArray> getResources() {
+ return getAssets(AssetType.resource, JSONArray.class);
+ }
+
+ public <T> Future<T> getResources(Class<T> theType, String theCategory, String theSubCategory) {
+ return getAssets(AssetType.resource, theType, theCategory, theSubCategory);
+ }
+
+ public Future<JSONArray> getResources(String category, String subCategory, String resourceType) {
+ return getAssets(AssetType.resource, JSONArray.class, category, subCategory, resourceType);
+ }
+
+ public <T> Future<T> getServices(Class<T> theType) {
+ return getAssets(AssetType.service, theType);
+ }
+
+ public Future<JSONArray> getServices() {
+ return getAssets(AssetType.service, JSONArray.class);
+ }
+
+ public <T> Future<T> getServices(Class<T> theType, String theCategory, String theSubCategory) {
+ return getAssets(AssetType.service, theType, theCategory, theSubCategory);
+ }
+
+ public Future<JSONArray> getServices(String theCategory, String theSubCategory) {
+ return getAssets(AssetType.service, JSONArray.class, theCategory, theSubCategory);
+ }
+
+ public <T> Future<T> getAssets(AssetType theAssetType, Class<T> theType) {
+ return fetch(refAssets(theAssetType), theType);
+ }
+
+ public <T> Action<T> getAssetsAction(AssetType theAssetType, Class<T> theType) {
+ return (() -> fetch(refAssets(theAssetType), theType));
+ }
+
+ public <T> Future<T> getAssets(AssetType theAssetType, Class<T> theType,
+ String theCategory, String theSubCategory) {
+ return getAssets(theAssetType, theType, theCategory, theSubCategory, null);
+ }
+
+ public <T> Future<T> getAssets(AssetType theAssetType, Class<T> theType,
+ String theCategory, String theSubCategory, String theResourceType) {
+ return fetch(refAssets(theAssetType) + filter(theCategory, theSubCategory, theResourceType), theType);
+ }
+
+ public <T> Action<T> getAssetsAction(AssetType theAssetType, Class<T> theType,
+ String theCategory, String theSubCategory, String theResourceType) {
+ return (() -> fetch(refAssets(theAssetType) + filter(theCategory, theSubCategory, theResourceType), theType));
+ }
+
+ protected String refAssets(AssetType theAssetType) {
+ return this.rootPath + theAssetType + "s/";
+ }
+
+ private String filter(String theCategory, String theSubCategory, String theResourceType) {
+ StringBuilder filter = null;
+ if (theCategory != null) {
+ filter = new StringBuilder();
+ filter.append("?category=")
+ .append(theCategory);
+ if (theSubCategory != null) {
+ filter.append("&subCategory=")
+ .append(theSubCategory);
+ if (theResourceType != null) {
+ filter.append("&resourceType=")
+ .append(theResourceType);
+ }
+ }
+ }
+ return filter == null ? "" : filter.toString();
+ }
+
+ protected String refAsset(AssetType theAssetType, UUID theId) {
+ return this.rootPath + theAssetType + "s/" + theId;
+ }
+
+ public <T> Future<T> getResource(UUID theId, Class<T> theType) {
+ return getAsset(AssetType.resource, theId, theType);
+ }
+
+ public Future<JSONObject> getResource(UUID theId) {
+ return getAsset(AssetType.resource, theId, JSONObject.class);
+ }
+
+ public Future<ResourceDetailed> getSDCResource(UUID theId) {
+ return getAsset(AssetType.resource, theId, ResourceDetailed.class);
+ }
+
+
+ public <T> Future<T> getService(UUID theId, Class<T> theType) {
+ return getAsset(AssetType.service, theId, theType);
+ }
+
+ public Future<JSONObject> getService(UUID theId) {
+ return getAsset(AssetType.service, theId, JSONObject.class);
+ }
+
+ public <T> Future<T> getAsset(AssetType theAssetType, UUID theId, Class<T> theType) {
+ return fetch(refAsset(theAssetType, theId) + "/metadata", theType);
+ }
+
+ public <T> Action<T> getAssetAction(AssetType theAssetType, UUID theId, Class<T> theType) {
+ return (() -> fetch(refAsset(theAssetType, theId) + "/metadata", theType));
+ }
+
+ public Future<byte[]> getResourceArchive(UUID theId) {
+ return getAssetArchive(AssetType.resource, theId);
+ }
+
+ public Future<byte[]> getServiceArchive(UUID theId) {
+ return getAssetArchive(AssetType.service, theId);
+ }
+
+ public Future<byte[]> getAssetArchive(AssetType theAssetType, UUID theId) {
+ return fetch(refAsset(theAssetType, theId) + "/toscaModel", byte[].class);
+ }
+
+ public Action<byte[]> getAssetArchiveAction(AssetType theAssetType, UUID theId) {
+ return (() -> fetch(refAsset(theAssetType, theId) + "/toscaModel", byte[].class));
+ }
+
+ public Future<JSONObject> checkinResource(UUID theId, String theUser, String theMessage) {
+ return cycleAsset(AssetType.resource, theId, LifecycleState.Checkin, theUser, theMessage);
+ }
+
+ public Future<JSONObject> checkinService(UUID theId, String theUser, String theMessage) {
+ return cycleAsset(AssetType.service, theId, LifecycleState.Checkin, theUser, theMessage);
+ }
+
+ public Future<JSONObject> checkoutResource(UUID theId, String theUser, String theMessage) {
+ return cycleAsset(AssetType.resource, theId, LifecycleState.Checkout, theUser, theMessage);
+ }
+
+ public Future<JSONObject> checkoutService(UUID theId, String theUser, String theMessage) {
+ return cycleAsset(AssetType.service, theId, LifecycleState.Checkout, theUser, theMessage);
+ }
+
+ public Future<JSONObject> certifyResource(UUID theId, String theUser, String theMessage) {
+ return cycleAsset(AssetType.resource, theId, LifecycleState.Certify, theUser, theMessage);
+ }
+
+ public Future<JSONObject> certifyService(UUID theId, String theUser, String theMessage) {
+ return cycleAsset(AssetType.service, theId, LifecycleState.Certify, theUser, theMessage);
+ }
+
+ /* Normally theMessage is mandatory (and we'd use put instead of putOpt) but .. not so for undocheckout ..
+ */
+ public Future<JSONObject> cycleAsset(AssetType theAssetType, UUID theId, LifecycleState theState,
+ String theUser, String theMessage) {
+ return post(refAsset(theAssetType, theId) + "/lifecycleState/" + theState,
+ (headers) -> prepareHeaders(headers)
+ .header("USER_ID", theUser),
+ new JSONObject().putOpt("userRemarks", theMessage));
+ }
+
+ protected String refAssetInstanceArtifact(AssetType theAssetType, UUID theAssetId, String theAssetInstance, UUID theArtifactId) {
+ return refAsset(theAssetType, theAssetId) + "/resourceInstances/" + theAssetInstance + "/artifacts" + (theArtifactId == null ? "" : ("/" + theArtifactId));
+ }
+
+ protected String refAssetArtifact(AssetType theAssetType, UUID theAssetId, UUID theArtifactId) {
+ return refAsset(theAssetType, theAssetId) + "/artifacts" + (theArtifactId == null ? "" : ("/" + theArtifactId));
+ }
+
+ public <T> Future<T> getResourceArtifact(UUID theAssetId, UUID theArtifactId, Class<T> theType) {
+ return getAssetArtifact(AssetType.resource, theAssetId, theArtifactId, theType);
+ }
+
+ public <T> Future<T> getServiceArtifact(UUID theAssetId, UUID theArtifactId, Class<T> theType) {
+ return getAssetArtifact(AssetType.service, theAssetId, theArtifactId, theType);
+ }
+
+ public <T> Future<T> getResourceInstanceArtifact(UUID theAssetId, UUID theArtifactId, String theInstance, Class<T> theType) {
+ return getAssetInstanceArtifact(AssetType.resource, theAssetId, theInstance, theArtifactId, theType);
+ }
+
+ public <T> Future<T> getServiceInstanceArtifact(UUID theAssetId, UUID theArtifactId, String theInstance, Class<T> theType) {
+ return getAssetInstanceArtifact(AssetType.service, theAssetId, theInstance, theArtifactId, theType);
+ }
+
+ public <T> Future<T> getAssetArtifact(AssetType theAssetType, UUID theAssetId, UUID theArtifactId, Class<T> theType) {
+ return fetch(refAssetArtifact(theAssetType, theAssetId, theArtifactId), theType);
+ }
+
+ public <T> Action<T> getAssetArtifactAction(AssetType theAssetType, UUID theAssetId, UUID theArtifactId, Class<T> theType) {
+ return (() -> fetch(refAssetArtifact(theAssetType, theAssetId, theArtifactId), theType));
+ }
+
+ public <T> Future<T> getAssetInstanceArtifact(AssetType theAssetType, UUID theAssetId, String theInstance, UUID theArtifactId, Class<T> theType) {
+ return fetch(refAssetInstanceArtifact(theAssetType, theAssetId, theInstance, theArtifactId), theType);
+ }
+
+ public <T> Action<T> getAssetInstanceArtifactAction(AssetType theAssetType, UUID theAssetId, String theInstance, UUID theArtifactId, Class<T> theType) {
+ return (() -> fetch(refAssetInstanceArtifact(theAssetType, theAssetId, theInstance, theArtifactId), theType));
+ }
+
+ public ArtifactUploadAction createResourceArtifact(UUID theAssetId) {
+ return createAssetArtifact(AssetType.resource, theAssetId);
+ }
+
+ public ArtifactUploadAction createServiceArtifact(UUID theAssetId) {
+ return createAssetArtifact(AssetType.service, theAssetId);
+ }
+
+ public ArtifactUploadAction createResourceInstanceArtifact(UUID theAssetId, String theInstance) {
+ return createAssetInstanceArtifact(AssetType.resource, theAssetId, theInstance);
+ }
+
+ public ArtifactUploadAction createServiceInstanceArtifact(UUID theAssetId, String theInstance) {
+ return createAssetInstanceArtifact(AssetType.service, theAssetId, theInstance);
+ }
+
+ public ArtifactUploadAction createAssetArtifact(AssetType theAssetType, UUID theAssetId) {
+ return new ArtifactUploadAction()
+ .ofAsset(theAssetType, theAssetId);
+ }
+
+ public ArtifactUploadAction createAssetInstanceArtifact(AssetType theAssetType, UUID theAssetId, String theInstance) {
+ return new ArtifactUploadAction()
+ .ofAssetInstance(theAssetType, theAssetId, theInstance);
+ }
+
+ public ArtifactUpdateAction updateResourceArtifact(UUID theAssetId, JSONObject theArtifactInfo) {
+ return updateAssetArtifact(AssetType.resource, theAssetId, theArtifactInfo);
+ }
+
+ public ArtifactUpdateAction updateResourceInstanceArtifact(UUID theAssetId, String theInstance, JSONObject theArtifactInfo) {
+ return updateAssetInstanceArtifact(AssetType.resource, theAssetId, theInstance, theArtifactInfo);
+ }
+
+ public ArtifactUpdateAction updateServiceArtifact(UUID theAssetId, JSONObject theArtifactInfo) {
+ return updateAssetArtifact(AssetType.service, theAssetId, theArtifactInfo);
+ }
+
+ public ArtifactUpdateAction updateServiceInstanceArtifact(UUID theAssetId, String theInstance, JSONObject theArtifactInfo) {
+ return updateAssetInstanceArtifact(AssetType.service, theAssetId, theInstance, theArtifactInfo);
+ }
+
+ public ArtifactUpdateAction updateAssetArtifact(AssetType theAssetType, UUID theAssetId, JSONObject theArtifactInfo) {
+ return new ArtifactUpdateAction(theArtifactInfo)
+ .ofAsset(theAssetType, theAssetId);
+ }
+
+ public ArtifactUpdateAction updateAssetInstanceArtifact(AssetType theAssetType, UUID theAssetId, String theInstance, JSONObject theArtifactInfo) {
+ return new ArtifactUpdateAction(theArtifactInfo)
+ .ofAssetInstance(theAssetType, theAssetId, theInstance);
+ }
+
+ public ArtifactDeleteAction deleteResourceArtifact(UUID theAssetId, UUID theArtifactId) {
+ return deleteAssetArtifact(AssetType.resource, theAssetId, theArtifactId);
+ }
+
+ public ArtifactDeleteAction deleteResourceInstanceArtifact(UUID theAssetId, String theInstance, UUID theArtifactId) {
+ return deleteAssetInstanceArtifact(AssetType.resource, theAssetId, theInstance, theArtifactId);
+ }
+
+ public ArtifactDeleteAction deleteServiceArtifact(UUID theAssetId, UUID theArtifactId) {
+ return deleteAssetArtifact(AssetType.service, theAssetId, theArtifactId);
+ }
+
+ public ArtifactDeleteAction deleteServiceInstanceArtifact(UUID theAssetId, String theInstance, UUID theArtifactId) {
+ return deleteAssetInstanceArtifact(AssetType.service, theAssetId, theInstance, theArtifactId);
+ }
+
+ public ArtifactDeleteAction deleteAssetArtifact(AssetType theAssetType, UUID theAssetId, UUID theArtifactId) {
+ return new ArtifactDeleteAction(theArtifactId)
+ .ofAsset(theAssetType, theAssetId);
+ }
+
+ public ArtifactDeleteAction deleteAssetInstanceArtifact(AssetType theAssetType, UUID theAssetId, String theInstance, UUID theArtifactId) {
+ return new ArtifactDeleteAction(theArtifactId)
+ .ofAssetInstance(theAssetType, theAssetId, theInstance);
+ }
+
+
+ public abstract class ASDCAction<A extends ASDCAction<A, T>, T> implements Action<T> {
+
+ protected JSONObject info; //info passed to asdc as request body
+ protected String operatorId; //id of the SDC user performing the action
+
+ protected ASDCAction(JSONObject theInfo) {
+ this.info = theInfo;
+ }
+
+ protected abstract A self();
+
+ protected ASDC asdc() {
+ return ASDC.this;
+ }
+
+ protected A withInfo(JSONObject theInfo) {
+ merge(this.info, theInfo);
+ return self();
+ }
+
+ public A with(String theProperty, Object theValue) {
+ info.put(theProperty, theValue);
+ return self();
+ }
+
+ public A withOperator(String theOperator) {
+ this.operatorId = theOperator;
+ return self();
+ }
+
+ protected abstract String[] mandatoryInfoEntries();
+
+ protected void checkOperatorId() {
+ if (this.operatorId == null) {
+ throw new IllegalStateException("No operator id was provided");
+ }
+ }
+
+ protected void checkMandatoryInfo() {
+ for (String field: mandatoryInfoEntries()) {
+ if (!info.has(field))
+ throw new IllegalStateException("No '" + field + "' was provided");
+ }
+ }
+
+ protected void checkMandatory() {
+ checkOperatorId();
+ checkMandatoryInfo();
+ }
+ }
+
+ protected static final String[] artifactMandatoryEntries = new String[] {};
+
+ /**
+ * We use teh same API to operate on artifacts attached to assets or to their instances
+ */
+ public abstract class ASDCArtifactAction<A extends ASDCArtifactAction<A>> extends ASDCAction<A, JSONObject> {
+
+ protected AssetType assetType;
+ protected UUID assetId;
+ protected String assetInstance;
+
+ protected ASDCArtifactAction(JSONObject theInfo) {
+ super(theInfo);
+ }
+
+ protected A ofAsset(AssetType theAssetType, UUID theAssetId) {
+ this.assetType = theAssetType;
+ this.assetId = theAssetId;
+ return self();
+ }
+
+ protected A ofAssetInstance(AssetType theAssetType, UUID theAssetId, String theInstance) {
+ this.assetType = theAssetType;
+ this.assetId = theAssetId;
+ this.assetInstance = theInstance;
+ return self();
+ }
+
+ protected String normalizeInstanceName(String theName) {
+ return StringUtils.removePattern(theName, "[ \\.\\-]+").toLowerCase();
+ }
+
+ protected String[] mandatoryInfoEntries() {
+ return ASDC.this.artifactMandatoryEntries;
+ }
+
+ protected String ref(UUID theArtifactId) {
+ return (this.assetInstance == null) ?
+ refAssetArtifact(this.assetType, this.assetId, theArtifactId) :
+ refAssetInstanceArtifact(this.assetType, this.assetId, normalizeInstanceName(this.assetInstance), theArtifactId);
+ }
+ }
+
+ protected static final String[] uploadMandatoryEntries = new String[] { "artifactName",
+ "artifactType",
+ "artifactGroupType",
+ "artifactLabel",
+ "description",
+ "payloadData" };
+
+ public class ArtifactUploadAction extends ASDCArtifactAction<ArtifactUploadAction> {
+
+ protected ArtifactUploadAction() {
+ super(new JSONObject());
+ }
+
+ protected ArtifactUploadAction self() {
+ return this;
+ }
+
+ public ArtifactUploadAction withContent(byte[] theContent) {
+ return with("payloadData", Base64Utils.encodeToString(theContent));
+ }
+
+ public ArtifactUploadAction withContent(File theFile) throws IOException {
+ return withContent(FileUtils.readFileToByteArray(theFile));
+ }
+
+ public ArtifactUploadAction withLabel(String theLabel) {
+ return with("artifactLabel", theLabel);
+ }
+
+ public ArtifactUploadAction withName(String theName) {
+ return with("artifactName", theName);
+ }
+
+ public ArtifactUploadAction withDisplayName(String theName) {
+ return with("artifactDisplayName", theName);
+ }
+
+ public ArtifactUploadAction withType(ArtifactType theType) {
+ return with("artifactType", theType.toString());
+ }
+
+ public ArtifactUploadAction withGroupType(ArtifactGroupType theGroupType) {
+ return with("artifactGroupType", theGroupType.toString());
+ }
+
+ public ArtifactUploadAction withDescription(String theDescription) {
+ return with("description", theDescription);
+ }
+
+ protected String[] mandatoryInfoEntries() {
+ return ASDC.this.uploadMandatoryEntries;
+ }
+
+ public Future<JSONObject> execute() {
+ checkMandatory();
+ return ASDC.this.post(ref(null),
+ (headers) -> prepareHeaders(headers)
+ .header("USER_ID", this.operatorId),
+ this.info);
+ }
+ }
+
+ protected static final String[] updateMandatoryEntries = new String[] { "artifactName",
+ "artifactType",
+ "artifactGroupType",
+ "artifactLabel",
+ "description",
+ "payloadData" };
+
+ /**
+ * In its current form the update relies on a previous artifact retrieval. One cannot build an update from scratch.
+ * The label, tye and group type must be submitted but cannot be updated
+ */
+ public class ArtifactUpdateAction extends ASDCArtifactAction<ArtifactUpdateAction> {
+
+
+ protected ArtifactUpdateAction(JSONObject theInfo) {
+ super(theInfo);
+ }
+
+ protected ArtifactUpdateAction self() {
+ return this;
+ }
+
+ public ArtifactUpdateAction withContent(byte[] theContent) {
+ return with("payloadData", Base64Utils.encodeToString(theContent));
+ }
+
+ public ArtifactUpdateAction withContent(File theFile) throws IOException {
+ return withContent(FileUtils.readFileToByteArray(theFile));
+ }
+
+ public ArtifactUpdateAction withDescription(String theDescription) {
+ return with("description", theDescription);
+ }
+
+ public ArtifactUpdateAction withName(String theName) {
+ return with("artifactName", theName);
+ }
+
+ protected String[] mandatoryInfoEntries() {
+ return ASDC.this.updateMandatoryEntries;
+ }
+
+ /* The json object originates (normally) from a get so it will have entries we need to cleanup */
+ protected void cleanupInfoEntries() {
+ this.info.remove("artifactChecksum");
+ this.info.remove("artifactUUID");
+ this.info.remove("artifactVersion");
+ this.info.remove("artifactURL");
+ this.info.remove("artifactDescription");
+ }
+
+ public Future<JSONObject> execute() {
+ UUID artifactUUID = UUID.fromString(this.info.getString("artifactUUID"));
+ checkMandatory();
+ cleanupInfoEntries();
+ return ASDC.this.post(ref(artifactUUID),
+ (headers) -> prepareHeaders(headers)
+ .header("USER_ID", this.operatorId),
+ this.info);
+ }
+ }
+
+ public class ArtifactDeleteAction extends ASDCArtifactAction<ArtifactDeleteAction> {
+
+ private UUID artifactId;
+
+ protected ArtifactDeleteAction(UUID theArtifactId) {
+ super(null);
+ this.artifactId = theArtifactId;
+ }
+
+ protected ArtifactDeleteAction self() {
+ return this;
+ }
+
+ public Future<JSONObject> execute() {
+ checkMandatory();
+ return ASDC.this.delete(ref(this.artifactId),
+ (headers) -> prepareHeaders(headers)
+ .header("USER_ID", this.operatorId));
+ }
+ }
+
+
+
+
+ public VFCMTCreateAction createVFCMT() {
+ return new VFCMTCreateAction();
+ }
+
+ protected static final String[] vfcmtMandatoryEntries = new String[] { "name",
+ "vendorName",
+ "vendorRelease",
+ "contactId" };
+
+
+ public class VFCMTCreateAction extends ASDCAction<VFCMTCreateAction, JSONObject> {
+
+ protected VFCMTCreateAction() {
+
+ super(new JSONObject());
+ this
+ .with("resourceType", "VFCMT")
+ .with("category", "Template")
+ .with("subcategory", "Monitoring Template")
+ .with("icon", "defaulticon");
+ }
+
+ protected VFCMTCreateAction self() {
+ return this;
+ }
+
+ public VFCMTCreateAction withName(String theName) {
+ return with("name", theName);
+ }
+
+ public VFCMTCreateAction withDescription(String theDescription) {
+ return with("description", theDescription);
+ }
+
+ public VFCMTCreateAction withVendorName(String theVendorName) {
+ return with("vendorName", theVendorName);
+ }
+
+ public VFCMTCreateAction withVendorRelease(String theVendorRelease) {
+ return with("vendorRelease", theVendorRelease);
+ }
+
+ public VFCMTCreateAction withTags(String... theTags) {
+ for (String tag: theTags)
+ this.info.append("tags", tag);
+ return this;
+ }
+
+ public VFCMTCreateAction withIcon(String theIcon) {
+ return with("icon", theIcon);
+ }
+
+ protected String[] mandatoryInfoEntries() {
+ return ASDC.this.vfcmtMandatoryEntries;
+ }
+
+ public VFCMTCreateAction withContact(String theContact) {
+ return with("contactId", theContact);
+ }
+
+ public Future<JSONObject> execute() {
+
+ this.info.putOnce("contactId", this.operatorId);
+ this.info.append("tags", info.optString("name"));
+ checkMandatory();
+ return ASDC.this.post(refAssets(AssetType.resource),
+ (headers) -> prepareHeaders(headers)
+ .header("USER_ID", this.operatorId),
+ this.info);
+ }
+
+ }
+
+ public static JSONObject merge(JSONObject theOriginal, JSONObject thePatch) {
+ for (String key: (Set<String>)thePatch.keySet()) {
+ if (!theOriginal.has(key))
+ theOriginal.put(key, thePatch.get(key));
+ }
+ return theOriginal;
+ }
+
+ protected URI refUri(String theRef) {
+ try {
+ return new URI(this.rootUri + theRef);
+ }
+ catch(URISyntaxException urisx) {
+ throw new UncheckedIOException(new IOException(urisx));
+ }
+ }
+
+ private HttpHeaders prepareHeaders() {
+ HttpHeaders headers = new HttpHeaders();
+ headers.add(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString((this.user + ":" + this.passwd).getBytes()));
+ headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
+ headers.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_OCTET_STREAM_VALUE);
+ headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
+ headers.add("X-ECOMP-InstanceID", this.instanceId);
+
+ return headers;
+ }
+
+ private RequestEntity.HeadersBuilder prepareHeaders(RequestEntity.HeadersBuilder theBuilder) {
+ return theBuilder
+ .header(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils.encodeToString((this.user + ":" + this.passwd).getBytes()))
+ .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
+ .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_OCTET_STREAM_VALUE)
+ .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
+ .header("X-ECOMP-InstanceID", this.instanceId);
+ }
+
+ public <T> Future<T> fetch(String theRef, Class<T> theContentType) {
+ return exchange(theRef, HttpMethod.GET, new HttpEntity(prepareHeaders()), theContentType);
+ }
+
+ public Future<JSONObject> post(String theRef, JSONObject thePost) {
+ return exchange(theRef, HttpMethod.POST, new HttpEntity<JSONObject>(thePost, prepareHeaders()), JSONObject.class);
+ }
+
+ public Future<JSONObject> post(String theRef, UnaryOperator<RequestEntity.HeadersBuilder> theHeadersBuilder, JSONObject thePost) {
+ RequestEntity.BodyBuilder builder = RequestEntity.post(refUri(theRef));
+ theHeadersBuilder.apply(builder);
+
+ return exchange(theRef, HttpMethod.POST, builder.body(thePost), JSONObject.class);
+ }
+
+ public Future<JSONObject> delete(String theRef, UnaryOperator<RequestEntity.HeadersBuilder> theHeadersBuilder) {
+
+ RequestEntity.HeadersBuilder builder = RequestEntity.delete(refUri(theRef));
+ theHeadersBuilder.apply(builder);
+
+ return exchange(theRef, HttpMethod.DELETE, builder.build(), JSONObject.class);
+ }
+
+ public <T> Future<T> exchange(String theRef, HttpMethod theMethod, HttpEntity theRequest, Class<T> theResponseType) {
+
+ AsyncRestTemplate restTemplate = new AsyncRestTemplate();
+
+ List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();
+ converters.add(0, new JSONHttpMessageConverter());
+ restTemplate.setMessageConverters(converters);
+
+ restTemplate.setInterceptors(Collections.singletonList(new ContentMD5Interceptor()));
+ ASDCFuture<T> result = new ASDCFuture<T>();
+ String uri = this.rootUri + theRef;
+ try {
+ restTemplate
+ .exchange(uri, theMethod, theRequest, theResponseType)
+ .addCallback(result.callback);
+ }
+ catch (RestClientException rcx) {
+ errLogger.log(LogLevel.WARN, this.getClass().getName(), "Failed to fetch {} {}", uri, rcx);
+ return Futures.failedFuture(rcx);
+ }
+ catch (Exception x) {
+ errLogger.log(LogLevel.WARN, this.getClass().getName(), "Failed to fetch {} {}", uri, x);
+ return Futures.failedFuture(x);
+ }
+
+ return result;
+ }
+
+
+
+ public class ASDCFuture<T>
+ extends Futures.BasicFuture<T> {
+
+ private boolean http404toEmpty = false;
+
+ ASDCFuture() {
+ }
+
+ public ASDCFuture setHttp404ToEmpty(boolean doEmpty) {
+ this.http404toEmpty = doEmpty;
+ return this;
+ }
+
+ ListenableFutureCallback<ResponseEntity<T>> callback = new ListenableFutureCallback<ResponseEntity<T>>() {
+
+ public void onSuccess(ResponseEntity<T> theResult) {
+ ASDCFuture.this.result(theResult.getBody());
+ }
+
+ public void onFailure(Throwable theError) {
+ if (theError instanceof HttpClientErrorException) {
+ // if (theError.getRawStatusCode() == 404 && this.http404toEmpty)
+ // ASDCFuture.this.result(); //th eresult is of type T ...
+ // else
+ ASDCFuture.this.cause(new ASDCException((HttpClientErrorException)theError));
+ }
+ else {
+ ASDCFuture.this.cause(theError);
+ }
+ }
+ };
+
+ }
+
+ public class ContentMD5Interceptor implements AsyncClientHttpRequestInterceptor {
+
+ @Override
+ public ListenableFuture<ClientHttpResponse> intercept(
+ HttpRequest theRequest, byte[] theBody, AsyncClientHttpRequestExecution theExecution)
+ throws IOException {
+ if (HttpMethod.POST == theRequest.getMethod()) {
+ HttpHeaders headers = theRequest.getHeaders();
+ headers.add("Content-MD5", Base64Utils.encodeToString(
+ //DigestUtils.md5Digest(theBody)));
+ DigestUtils.md5Hex(theBody).getBytes()));
+
+ }
+ return theExecution.executeAsync(theRequest, theBody);
+ }
+ }
+
+ public static void main(String[] theArgs) throws Exception {
+
+ CommandLineParser parser = new BasicParser();
+
+ String user_id = "jh0003";
+
+ Options options = new Options();
+ options.addOption(OptionBuilder
+ .withArgName("target")
+ .withLongOpt("target")
+ .withDescription("target asdc system")
+ .hasArg()
+ .isRequired()
+ .create('t') );
+
+ options.addOption(OptionBuilder
+ .withArgName("action")
+ .withLongOpt("action")
+ .withDescription("one of: list, get, getartifact, checkin, checkout")
+ .hasArg()
+ .isRequired()
+ .create('a') );
+
+ options.addOption(OptionBuilder
+ .withArgName("assetType")
+ .withLongOpt("assetType")
+ .withDescription("one of resource, service, product")
+ .hasArg()
+ .isRequired()
+ .create('k') ); //k for 'kind' ..
+
+ options.addOption(OptionBuilder
+ .withArgName("assetId")
+ .withLongOpt("assetId")
+ .withDescription("asset uuid")
+ .hasArg()
+ .create('u') ); //u for 'uuid'
+
+ options.addOption(OptionBuilder
+ .withArgName("artifactId")
+ .withLongOpt("artifactId")
+ .withDescription("artifact uuid")
+ .hasArg()
+ .create('s') ); //s for 'stuff'
+
+ options.addOption(OptionBuilder
+ .withArgName("listFilter")
+ .withLongOpt("listFilter")
+ .withDescription("filter for list operations")
+ .hasArg()
+ .create('f') ); //u for 'uuid'
+
+ CommandLine line = null;
+ try {
+ line = parser.parse(options, theArgs);
+ }
+ catch(ParseException exp) {
+ errLogger.log(LogLevel.ERROR, ASDC.class.getName(), exp.getMessage());
+ new HelpFormatter().printHelp("asdc", options);
+ return;
+ }
+
+ ASDC asdc = new ASDC();
+ asdc.setUri(new URI(line.getOptionValue("target")));
+
+ String action = line.getOptionValue("action");
+ if (action.equals("list")) {
+ JSONObject filterInfo = new JSONObject(
+ line.hasOption("listFilter") ?
+ line.getOptionValue("listFilter") : "{}");
+ JSONArray assets =
+ asdc.getAssets(ASDC.AssetType.valueOf(line.getOptionValue("assetType")), JSONArray.class,
+ filterInfo.optString("category", null), filterInfo.optString("subCategory", null))
+ .waitForResult();
+ for (int i = 0; i < assets.length(); i++) {
+ debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),"> {}", assets.getJSONObject(i).toString(2));
+ }
+ }
+ else if (action.equals("get")) {
+ debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),
+ asdc.getAsset(ASDC.AssetType.valueOf(line.getOptionValue("assetType")),
+ UUID.fromString(line.getOptionValue("assetId")),
+ JSONObject.class)
+ .waitForResult()
+ .toString(2)
+ );
+ }
+ else if (action.equals("getartifact")) {
+ debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),
+ asdc.getAssetArtifact(ASDC.AssetType.valueOf(line.getOptionValue("assetType")),
+ UUID.fromString(line.getOptionValue("assetId")),
+ UUID.fromString(line.getOptionValue("artifactId")),
+ String.class)
+ .waitForResult()
+ );
+ }
+ else if (action.equals("checkin")) {
+ debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),
+ asdc.cycleAsset(ASDC.AssetType.valueOf(line.getOptionValue("assetType")),
+ UUID.fromString(line.getOptionValue("assetId")),
+ ASDC.LifecycleState.Checkin,
+ user_id,
+ "cli op")
+ .waitForResult()
+ .toString()
+ );
+ }
+ else if (action.equals("checkout")) {
+ debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),
+ asdc.cycleAsset(ASDC.AssetType.valueOf(line.getOptionValue("assetType")),
+ UUID.fromString(line.getOptionValue("assetId")),
+ ASDC.LifecycleState.Checkout,
+ user_id,
+ "cli op")
+ .waitForResult()
+ .toString()
+ );
+ }
+ else if (action.equals("cleanup")) {
+ JSONArray resources = asdc.getResources()
+ .waitForResult();
+ debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),"Got {} resources", resources.length());
+
+ // vfcmt cleanup
+ for (int i = 0; i < resources.length(); i++) {
+
+ JSONObject resource = resources.getJSONObject(i);
+
+ if (resource.getString("resourceType").equals("VFCMT") &&
+ resource.getString("name").contains("test")) {
+
+ debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),"undocheckout for {}", resource.getString("uuid"));
+
+ try {
+ asdc.cycleAsset(AssetType.resource, UUID.fromString(resource.getString("uuid")), LifecycleState.undocheckout, user_id, null)
+ .waitForResult();
+ }
+ catch (Exception x) {
+ debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),"** {}", x);
+ }
+ }
+ }
+
+ }
+ else {
+ try {
+ debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),
+ asdc.createVFCMT()
+ .withName("Clonator")
+ .withDescription("Clone operation target 06192017")
+ .withVendorName("CloneInc")
+ .withVendorRelease("1.0")
+ .withTags("clone")
+ .withOperator(user_id)
+ .execute()
+ .waitForResult()
+ .toString()
+ );
+ }
+ catch(Exception x) {
+ debugLogger.log(LogLevel.DEBUG, ASDC.class.getName(),"Failed to create VFCMT: {}", x);
+ }
+ }
+ }
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCController.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCController.java
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCController.java
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCEngine.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCEngine.java
new file mode 100644
index 0000000..73c7601
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCEngine.java
@@ -0,0 +1,25 @@
+package org.onap.sdc.dcae.catalog.asdc;
+
+import org.onap.sdc.dcae.composition.util.SystemProperties;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+
+@SpringBootApplication
+public class ASDCEngine {
+
+ /**
+ * Creates and returns a new instance of a {@link SystemProperties} class.
+ *
+ * @return New instance of {@link SystemProperties}.
+ */
+ @Bean
+ public SystemProperties systemProperties() {
+ return new SystemProperties();
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(ASDCEngine.class, args);
+ }
+
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCException.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCException.java
new file mode 100644
index 0000000..659653d
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCException.java
@@ -0,0 +1,18 @@
+package org.onap.sdc.dcae.catalog.asdc;
+
+import org.onap.sdc.dcae.errormng.BaseException;
+import org.onap.sdc.dcae.errormng.RequestError;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.client.HttpClientErrorException;
+
+public class ASDCException extends BaseException {
+
+ ASDCException(HttpClientErrorException error) {
+ super(error);
+ }
+
+ public ASDCException(HttpStatus status, RequestError re){
+ super(status, re);
+ }
+
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtils.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtils.java
new file mode 100644
index 0000000..1d70627
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtils.java
@@ -0,0 +1,448 @@
+package org.onap.sdc.dcae.catalog.asdc;
+
+import org.apache.commons.jxpath.JXPathContext;
+import org.apache.commons.lang3.StringUtils;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.catalog.commons.Actions;
+import org.onap.sdc.dcae.catalog.commons.Future;
+import org.onap.sdc.dcae.catalog.commons.Futures;
+import org.onap.sdc.dcae.catalog.commons.Recycler;
+import org.onap.sdc.dcae.checker.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Base64Utils;
+
+import java.io.*;
+import java.net.URI;
+import java.util.*;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+
+@Component("asdcutils")
+@Scope("singleton")
+@ConfigurationProperties(prefix="asdcutils")
+public class ASDCUtils {
+
+ private static OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ @Autowired
+ private ASDC asdc;
+
+ @Autowired
+ private Blueprinter blueprint;
+
+ public ASDCUtils() {
+ // Making sonar happy
+ }
+
+ public ASDCUtils(URI theASDCURI) {
+ this(theASDCURI, null);
+ }
+
+ public ASDCUtils(URI theASDCURI, URI theBlueprinterURI) {
+ this.asdc = new ASDC();
+ this.asdc.setUri(theASDCURI);
+ if (theBlueprinterURI != null) {
+ this.blueprint = new Blueprinter();
+ this.blueprint.setUri(theBlueprinterURI);
+ }
+ }
+
+ public ASDCUtils(ASDC theASDC) {
+ this(theASDC, null);
+ }
+
+ public ASDCUtils(ASDC theASDC, Blueprinter theBlueprinter) {
+ this.asdc = theASDC;
+ this.blueprint = theBlueprinter;
+ }
+
+ public CloneAssetArtifactsAction cloneAssetArtifacts(ASDC.AssetType theAssetType, UUID theSourceId, UUID theTargetId) {
+ return new CloneAssetArtifactsAction(this.asdc, theAssetType, theSourceId, theTargetId);
+ }
+
+ public static class CloneAssetArtifactsAction extends ASDC.ASDCAction<CloneAssetArtifactsAction, List<JSONObject>> {
+
+ private ASDC.AssetType assetType;
+ private UUID sourceId, targetId;
+
+ protected CloneAssetArtifactsAction(ASDC theASDC, ASDC.AssetType theAssetType, UUID theSourceId, UUID theTargetId) {
+ theASDC.super(new JSONObject());
+ this.assetType = theAssetType;
+ this.sourceId = theSourceId;
+ this.targetId = theTargetId;
+ }
+
+ protected CloneAssetArtifactsAction self() {
+ return this;
+ }
+
+ public CloneAssetArtifactsAction withLabel(String theLabel) {
+ return with("artifactLabel", theLabel);
+ }
+
+ protected String[] mandatoryInfoEntries() {
+ return new String[] {};
+ }
+
+ public Future<List<JSONObject>> execute() {
+ checkMandatory();
+
+ final Actions.Sequence<JSONObject> sequencer = new Actions.Sequence<JSONObject>();
+
+ new Actions.Sequence().add(super.asdc().getAssetArchiveAction(this.assetType, this.sourceId)).add(super.asdc().getAssetAction(this.assetType, this.sourceId, JSONObject.class)).execute().setHandler(assetFuture -> {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "*** {}", assetFuture.result());
+ processArtifacts((List) assetFuture.result(), (JSONObject theInfo, byte[] theData) -> {
+ theInfo.remove("artifactChecksum");
+ theInfo.remove("artifactUUID");
+ theInfo.remove("artifactVersion");
+ theInfo.remove("artifactURL");
+ theInfo.put("description", theInfo.remove("artifactDescription"));
+ theInfo.put("payloadData", Base64Utils.encodeToString(theData));
+ return theInfo;
+ }, null).forEach(artifactInfo -> sequencer.add(super.asdc().createAssetArtifact(this.assetType, this.targetId).withInfo(ASDC.merge(artifactInfo, this.info)).withOperator(this.operatorId)));
+ sequencer.execute();
+ });
+
+ return sequencer.future();
+ }
+ } //the Action class
+
+ /* */
+ private static JSONObject lookupArtifactInfo(JSONArray theArtifacts, String theName) {
+
+ for (int i = 0; theArtifacts != null && i < theArtifacts.length(); i++) {
+ JSONObject artifactInfo = theArtifacts.getJSONObject(i);
+ if (theName.equals(artifactInfo.getString("artifactName"))) {
+ debugLogger.log(LogLevel.DEBUG, ASDCUtils.class.getName(), "Found artifact info {}", artifactInfo);
+ return artifactInfo;
+ }
+ }
+
+ return null;
+ }
+
+ private static byte[] extractArtifactData(InputStream theEntryStream) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try {
+ byte[] buff = new byte[4096];
+ int cnt = 0;
+ while ((cnt = theEntryStream.read(buff)) != -1) {
+ baos.write(buff, 0, cnt);
+ }
+ } finally {
+ baos.close();
+ }
+ return baos.toByteArray();
+ }
+
+ /**
+ * Recycle a cdump, fetch all relevant ASDC artifacts, interact with Shu's toscalib service in order to generate
+ * a blueprint. No 'Action' object here as there is nothig to set up.
+ */
+ public Future<Future<String>> buildBlueprint(Reader theCdump) {
+
+ final Recycler recycler = new Recycler();
+ Object template = null;
+
+ try {
+ template = recycler.recycle(theCdump);
+
+ } catch (Exception x) {
+ return Futures.failedFuture(x);
+ }
+
+ JXPathContext jxroot = JXPathContext.newContext(template);
+ jxroot.setLenient(true);
+
+ //based on the output of ASDCCatalog the node description will contain the UUID of the resource declaring it
+ List uuids = (List) StreamSupport.stream(Spliterators.spliteratorUnknownSize(jxroot.iterate("topology_template/node_templates/*/description"), 16), false).distinct().filter(desc -> desc != null)
+ //the desc contains the full URI and the resource uuid is the 5th path element
+ .map(desc -> desc.toString().split("/")[5]).collect(Collectors.toList());
+
+ //prepare fetching all archives/resource details
+ final Futures.Accumulator accumulator = new Futures.Accumulator();
+ uuids.stream().forEach(uuid -> {
+ UUID rid = UUID.fromString((String) uuid);
+ accumulator.add(this.asdc.getAssetArchive(ASDC.AssetType.resource, rid));
+ accumulator.add(this.asdc.getAsset(ASDC.AssetType.resource, rid, JSONObject.class));
+ });
+
+ final byte[] templateData = recycler.toString(template).getBytes(/*"UTF-8"*/);
+ //retrieve all resource archive+details, prepare blueprint service request and send its request
+ return Futures.advance(accumulator.accumulate(), (List theArchives) -> {
+ Blueprinter.BlueprintAction action = blueprint.generateBlueprint();
+ processArtifacts(theArchives, (JSONObject theInfo, byte[] theData) -> new JSONObject().put(theInfo.getString("artifactName").split("\\.")[0], Base64Utils.encodeToString(theData)),
+ (Stream<JSONObject> theAssetArtifacts) -> theAssetArtifacts.reduce(new JSONObject(), ASDC::merge)).forEach(artifactInfo -> action.withModelInfo(artifactInfo));
+
+ return action.withTemplateData(templateData).execute();
+ });
+ }
+
+ public Future<Future<String>> buildBlueprintViaToscaLab(Reader theCdump) {
+ return processCdump(theCdump, (theTemplate, theArchives) -> {
+ Blueprinter.BlueprintAction action = blueprint.generateBlueprint();
+ processArtifacts(theArchives, (JSONObject theInfo, byte[] theData) -> new JSONObject().put(theInfo.getString("artifactName").split("\\.")[0], Base64Utils.encodeToString(theData)),
+ (Stream<JSONObject> theAssetArtifacts) -> theAssetArtifacts.reduce(new JSONObject(), ASDC::merge)).forEach(artifactInfo -> action.withModelInfo(artifactInfo));
+
+ return action.withTemplateData(Recycler.toString(theTemplate).getBytes()).execute();
+
+ });
+ }
+
+ private static class Tracker implements TargetLocator {
+
+ private static enum Position {
+ SCHEMA, TEMPLATE, TRANSLATE;
+ }
+
+ private static final int Positions = Position.values().length;
+
+ private List<Target> tgts = new ArrayList<Target>(3);
+
+ public Tracker() {
+ clear();
+ }
+
+ public boolean addSearchPath(URI theURI) {
+ return false;
+ }
+
+ public boolean addSearchPath(String thePath) {
+ return false;
+ }
+
+ public Iterable<URI> searchPaths() {
+ return Collections.emptyList();
+ }
+
+ protected int position(String... theKeys) {
+ for (String key : theKeys) {
+ if ("schema".equals(key)) {
+ return Position.SCHEMA.ordinal();
+ }
+ if ("template".equals(key)) {
+ return Position.TEMPLATE.ordinal();
+ }
+ if ("translate".equals(key)) {
+ return Position.TRANSLATE.ordinal();
+ }
+ }
+ return -1;
+ }
+
+ public Target resolve(String theName) {
+ for (Target tgt : tgts) {
+ if (tgt != null && tgt.getName().equals(theName)) {
+ return tgt;
+ }
+ }
+ return null;
+ }
+
+ public void track(JSONObject theInfo, final byte[] theData) {
+ String uri = theInfo.getString("artifactURL").split("/")[5];
+ String name = theInfo.getString("artifactName"), desc = theInfo.getString("artifactDescription"), label = theInfo.getString("artifactLabel");
+ int pos = position(desc, label);
+
+ debugLogger.log(LogLevel.DEBUG, ASDCUtils.class.getName(), "Tracking {} at {}, {}", name, pos, theInfo.optString("artifactURL"));
+
+ if (pos > -1) {
+ tgts.set(pos, new Target(name, URI.create("asdc:" + uri + "/" + name)) {
+ @Override
+ public Reader open(){
+ return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(theData)));
+ }
+ });
+ }
+ }
+
+ public boolean hasSchema() {
+ return tgts.get(Position.SCHEMA.ordinal()) != null;
+ }
+
+ public Target schema() {
+ return tgts.get(Position.SCHEMA.ordinal());
+ }
+
+ public boolean hasTemplate() {
+ return tgts.get(Position.TEMPLATE.ordinal()) != null;
+ }
+
+ public Target template() {
+ return tgts.get(Position.TEMPLATE.ordinal());
+ }
+
+ public boolean hasTranslation() {
+ return tgts.get(Position.TRANSLATE.ordinal()) != null;
+ }
+
+ public Target translation() {
+ return tgts.get(Position.TRANSLATE.ordinal());
+ }
+
+ public void clear() {
+ if (tgts.isEmpty()) {
+ for (int i = 0; i < Positions; i++) {
+ tgts.add(null);
+ }
+ } else {
+ Collections.fill(tgts, null);
+ }
+ }
+ }
+
+ private Checker buildChecker() {
+ try {
+ return new Checker();
+ } catch (CheckerException cx) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "CheckerException while creating Checker {}", cx);
+ return null;
+ }
+ }
+
+ public Future<Catalog> buildCatalog(Reader theCdump) {
+
+ //
+ //the purpose of the tracking is to be able to resolve import references within the 'space' of an
+ //asset's artifacts
+ //processing order is important too so we 'order the targets: schema, template, translation
+ //
+ final Tracker tracker = new Tracker();
+ final Catalog catalog = Checker.buildCatalog();
+
+ return processCdump(theCdump, (theTemplate, theArchives) -> {
+
+ final Checker checker = buildChecker();
+ if (checker == null) {
+ return null;
+ }
+ checker.setTargetLocator(tracker);
+
+ processArtifacts(theArchives, (JSONObject theInfo, byte[] theData) -> {
+ tracker.track(theInfo, theData);
+ return (Catalog) null;
+ },
+ // aggregation: this is where the actual processing takes place now that
+ // we have all the targets
+ (Stream<Catalog> theAssetArtifacts) -> {
+ //the stream is full of nulls, ignore it, work with the tracker
+
+ try {
+ if (tracker.hasSchema()) {
+ checker.check(tracker.schema(), catalog);
+ }
+ if (tracker.hasTemplate()) {
+ checker.check(tracker.template(), catalog);
+ }
+ if (tracker.hasTranslation()) {
+ checker.check(tracker.translation(), catalog);
+ }
+ } catch (CheckerException cx) {
+ //got to do better than this
+ errLogger.log(LogLevel.ERROR, ASDC.class.getName(),"CheckerException while checking catalog:{}", cx);
+ } finally {
+ tracker.clear();
+ }
+ return checker.catalog();
+ });
+
+ Target cdump = new Target("cdump", URI.create("asdc:cdump"));
+ cdump.setTarget(theTemplate);
+
+ validateCatalog(catalog, checker, cdump);
+
+ return catalog;
+ });
+ }
+
+ private void validateCatalog(Catalog catalog, Checker checker, Target cdump) {
+ try {
+ checker.validate(cdump, catalog);
+ } catch (CheckerException cx) {
+ errLogger.log(LogLevel.ERROR, ASDC.class.getName(),"CheckerException while building catalog:{}", cx);
+ }
+ }
+
+ /* The common process of recycling, retrieving all related artifacts and then doing 'something' */
+ private <T> Future<T> processCdump(Reader theCdump, BiFunction<Object, List, T> theProcessor) {
+
+ final Recycler recycler = new Recycler();
+ Object template = null;
+ try {
+ template = recycler.recycle(theCdump);
+
+ } catch (Exception x) {
+ return Futures.failedFuture(x);
+ }
+
+ JXPathContext jxroot = JXPathContext.newContext(template);
+ jxroot.setLenient(true);
+
+ //based on the output of ASDCCatalog the node description will contain the UUID of the resource declaring it
+ //the desc contains the full URI and the resource uuid is the 5th path element
+ List uuids = (List) StreamSupport.stream(Spliterators.spliteratorUnknownSize(jxroot.iterate("topology_template/node_templates/*/description"), 16), false).distinct().filter(desc -> desc != null)
+ .map(desc -> desc.toString().split("/")[5]).collect(Collectors.toList());
+
+ //serialized fetch version
+ final Actions.Sequence sequencer = new Actions.Sequence();
+ uuids.stream().forEach(uuid -> {
+ UUID rid = UUID.fromString((String) uuid);
+ sequencer.add(this.asdc.getAssetArchiveAction(ASDC.AssetType.resource, rid));
+ sequencer.add(this.asdc.getAssetAction(ASDC.AssetType.resource, rid, JSONObject.class));
+ });
+
+ final Object tmpl = template;
+ return Futures.advance(sequencer.execute(), (List theArchives) -> theProcessor.apply(tmpl, theArchives));
+ }
+
+ private static <T> Stream<T> processArtifacts(List theArtifactData, BiFunction<JSONObject, byte[], T> theProcessor, Function<Stream<T>, T> theAggregator) {
+
+ Stream.Builder<T> assetBuilder = Stream.builder();
+
+ for (int i = 0; i < theArtifactData.size(); i = i + 2) { //cute old style loop
+
+ JSONObject assetInfo = (JSONObject) theArtifactData.get(i + 1);
+ byte[] assetData = (byte[]) theArtifactData.get(i + 0);
+
+ JSONArray artifacts = assetInfo.optJSONArray("artifacts");
+
+ Stream.Builder<T> artifactBuilder = Stream.builder();
+
+ try (ZipInputStream zipper = new ZipInputStream(new ByteArrayInputStream(assetData))){
+ //we process the artifacts in the order they are stored in the archive .. fugly
+ for (ZipEntry zipped = zipper.getNextEntry(); zipped != null; zipped = zipper.getNextEntry()) {
+ JSONObject artifactInfo = lookupArtifactInfo(artifacts, StringUtils.substringAfterLast(zipped.getName(), "/"));
+ if (artifactInfo != null) {
+ artifactBuilder.add(theProcessor.apply(artifactInfo, extractArtifactData(zipper)));
+ }
+ zipper.closeEntry();
+ }
+ } catch (IOException iox) {
+ errLogger.log(LogLevel.ERROR, ASDC.class.getName(), "IOException: {}", iox);
+ return null;
+ }
+
+ if (theAggregator != null) {
+ assetBuilder.add(theAggregator.apply(artifactBuilder.build()));
+ } else {
+ artifactBuilder.build().forEach(entry -> assetBuilder.add(entry));
+ }
+ }
+
+ return assetBuilder.build();
+ }
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtilsController.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtilsController.java
new file mode 100644
index 0000000..4432712
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/ASDCUtilsController.java
@@ -0,0 +1,76 @@
+package org.onap.sdc.dcae.catalog.asdc;
+
+import java.io.StringReader;
+
+import java.util.UUID;
+import java.util.Map;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.springframework.beans.BeansException;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import org.onap.sdc.dcae.catalog.asdc.ASDC;
+import org.onap.sdc.dcae.catalog.asdc.ASDCUtils;
+import org.onap.sdc.dcae.catalog.asdc.ASDCUtilsController;
+
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.ResponseEntity;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+import org.json.JSONObject;
+
+
+@RestController
+@ConfigurationProperties(prefix="asdcUtilsController")
+public class ASDCUtilsController implements ApplicationContextAware {
+
+ private ApplicationContext appCtx;
+ private OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ //Constants//
+ private static String NOT_CERTIFIED_CHECKOUT = "NOT_CERTIFIED_CHECKOUT";
+ private static String NOT_CERTIFIED_CHECKIN = "NOT_CERTIFIED_CHECKIN";
+ private static String CERTIFICATION_IN_PROGRESS = "CERTIFICATION_IN_PROGRESS";
+ private static String CERTIFIED = "CERTIFIED";
+
+
+ public void setApplicationContext(ApplicationContext theCtx) throws BeansException {
+ this.appCtx = theCtx;
+ }
+
+ @PostConstruct
+ public void initController() {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"initASDCUtilsController");
+
+ //Done
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"ASDCUtilsController started");
+ }
+
+ @PreDestroy
+ public void cleanupController() {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(),"cleanupASDCUtilsController");
+ }
+
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/Blueprinter.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/Blueprinter.java
new file mode 100644
index 0000000..3e78d38
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/Blueprinter.java
@@ -0,0 +1,76 @@
+package org.onap.sdc.dcae.catalog.asdc;
+
+import java.net.URI;
+
+import java.util.Collections;
+
+import org.json.JSONObject;
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.catalog.commons.Action;
+import org.onap.sdc.dcae.catalog.commons.Future;
+import org.onap.sdc.dcae.catalog.commons.Http;
+import org.json.JSONArray;
+
+import org.springframework.util.Base64Utils;
+
+import org.springframework.http.MediaType;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.context.annotation.Scope;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@Component("blueprinter")
+@Scope("singleton")
+@ConfigurationProperties(prefix="blueprinter")
+public class Blueprinter {
+
+
+ private URI serviceUri;
+ private OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+
+ public Blueprinter() {
+ }
+
+ public void setUri(URI theUri) {
+ this.serviceUri = theUri;
+ }
+
+ public BlueprintAction generateBlueprint() {
+ return new BlueprintAction();
+ }
+
+ public class BlueprintAction implements Action<String> {
+
+ private JSONObject body = new JSONObject();
+
+
+ protected BlueprintAction() {
+ }
+
+ public BlueprintAction withModelData(byte[] theSchema, byte[] theTemplate, byte[] theTranslation) {
+ return this;
+ }
+
+ public BlueprintAction withModelInfo(JSONObject theModelInfo) {
+ body.append("models", theModelInfo);
+ return this;
+ }
+
+ public BlueprintAction withTemplateData(byte[] theData) {
+ body.put("template", Base64Utils.encodeToString(theData));
+ return this;
+ }
+
+ public Future<String> execute() {
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Blueprinter::execute() | PAYLOAD to TOSCA_LAB={}", body.toString());
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
+ return Http.exchange(serviceUri.toString(), HttpMethod.POST, new HttpEntity<String>(body.toString(), headers), String.class);
+ }
+ }
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/Cloudify.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/Cloudify.java
new file mode 100644
index 0000000..3208bd2
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/catalog/asdc/Cloudify.java
@@ -0,0 +1,249 @@
+package org.onap.sdc.dcae.catalog.asdc;
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.stream.Stream;
+
+import org.apache.commons.jxpath.JXPathContext;
+import org.apache.commons.jxpath.Pointer;
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.onap.sdc.dcae.catalog.commons.ListBuilder;
+import org.onap.sdc.dcae.catalog.commons.MapBuilder;
+import org.onap.sdc.dcae.checker.Catalog;
+import org.onap.sdc.dcae.checker.Construct;
+import org.onap.sdc.dcae.checker.Target;
+
+import com.google.common.collect.Lists;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.Yaml;
+
+
+public class Cloudify {
+
+ private static OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ Catalog catalog;
+
+ public Cloudify(Catalog c)
+ {
+ catalog = c;
+ }
+ public class ModelTemplate {
+ public Map<String, Map> template;
+ public JXPathContext jx;
+ public String node;
+ public ModelTemplate(Map<String, Map> t, JXPathContext j, String node_name)
+ {
+ template = t;
+ jx = j;
+ node = node_name;
+ }
+
+ public Object getPropValue(JXPathContext jx_src, String name)
+ {
+ try{
+ Object ret = jx_src.getValue("properties/"+name+"/get_input");
+ if (ret==null)
+ return jx_src.getValue("properties/"+name);
+ return getDefaultPropValue((String)ret);
+ }
+ catch (RuntimeException e) {
+
+ }
+ try{
+ return jx_src.getValue("properties/"+name+"");
+ }
+ catch (RuntimeException e) {
+ return null;
+ }
+ }
+
+ public Object getDefaultPropValue(String name) {
+ try {
+ return jx.getValue("//"+name+"/default");
+ }
+ catch (RuntimeException e) {
+ return null;
+ }
+
+ }
+ }
+
+ public class ModelTranslate {
+ public Map<String, Map> template;
+ public JXPathContext jx;
+ public String node;
+
+ public ModelTranslate(Map<String, Map> t, JXPathContext j, String node_name)
+ {
+ template = t;
+ jx = j;
+ node = node_name;
+ }
+
+ public String getTranslateName()
+ {
+ Map<String, Object> node_temp = (Map<String, Object>)jx.getValue("//node_templates");
+ Iterator it = node_temp.keySet().iterator();
+ if (it.hasNext())
+ return node + "_"+ it.next();
+ else
+ return null;
+ }
+
+ public Map<String, Object> translate(JXPathContext jx_src, Map<String, Map> model_lib, String node_name)
+ {
+ for (Iterator prop_iter = jx.iteratePointers("//*[@get_input]"); prop_iter.hasNext();) {
+
+ Pointer p = (Pointer)prop_iter.next();
+ JXPathContext prop_path = jx.getRelativeContext(p);
+
+ ModelTemplate src_model =(ModelTemplate) model_lib.get(node_name).get("model");
+
+ Object temp_o = src_model.getPropValue(jx_src, (String) prop_path.getValue("get_input"));
+ //prop_path.setValue(".", temp_o);
+ jx.setValue(p.asPath(), temp_o);
+ }
+
+// JXPathContext jx_src = JXPathContext.newContext(src);
+ for (Iterator req_iter = jx_src.iteratePointers("//*/node"); req_iter.hasNext();) {
+ Pointer p = (Pointer)req_iter.next();
+ String req_node_name = (String)jx_src.getValue(p.asPath());
+
+ for (Iterator it = model_lib.keySet().iterator(); it.hasNext();) {
+ String key = (String) it.next();
+ if (key.indexOf(req_node_name) <0 )
+ continue;
+ ModelTranslate tt = (ModelTranslate) model_lib.get(key).get("translate");
+ if (tt == null)
+ req_node_name = null;
+ else
+ {
+ req_node_name = tt.getTranslateName();
+ }
+ break;
+ }
+
+ }
+
+ String tn_name = getTranslateName();
+
+ if (tn_name == null)
+ return (Map<String, Object>)jx.getValue("//node_templates");
+ else
+ return (new MapBuilder<String, Object>().put(tn_name, jx.getValue("//node_templates/*")).build());
+ }
+
+ }
+
+ public ModelTranslate findTranslateTemplate(String ty, String node) {
+ for (Target t: catalog.targets()) {
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "findTranslateTemplate: target {}", t.getName());
+ if (t.getName().startsWith("translat") == false) {
+ continue;
+ }
+
+ Map<String, Map>temp = (Map<String, Map>)t.getTarget();
+
+ JXPathContext jxroot = JXPathContext.newContext(temp);
+ try{
+ String sub_type = (String)jxroot.getValue("topology_template/substitution_mappings/node_type");
+ if (sub_type != null && sub_type.equals(ty)) {
+ return new ModelTranslate(temp, jxroot, node);
+ }
+ }
+ catch (RuntimeException e) {
+ errLogger.log(LogLevel.ERROR, this.getClass().getName(), "translate template {} does not have substitution mapping section", t.getName());
+ }
+ }
+ return null;
+ }
+
+ public ModelTemplate findModelTemplate(String ty, String node) {
+ for (Target t: catalog.targets()) {
+
+ if (t.getName().startsWith("templat") == false)
+ continue;
+ Map<String, Map>temp = (Map<String, Map>)t.getTarget();
+
+ JXPathContext jxroot = JXPathContext.newContext(temp);
+ for (Iterator it = jxroot.iterate("topology_template/node_templates/*/type"); it.hasNext();) {
+ String node_type = (String)it.next();
+ if (node_type != null && node_type.equals(ty)) {
+ return new ModelTemplate(temp, jxroot, node);
+ }
+ }
+ }
+ return null;
+ }
+
+ public Map<String, Object> createBlueprint() {
+
+ Map<String, Map> target_temp = null;
+ for (Target t: catalog.targets()) {
+
+ if (t.getName().equals("cdump")) {
+ target_temp = catalog.getTargetTemplates(t, Construct.Node);
+ }
+ }
+
+ JXPathContext jxroot = JXPathContext.newContext(target_temp);
+
+ Map<String, Object> output_temp = new HashMap<String, Object>();
+ Map<String, Map> model_lib = new HashMap<String, Map>();
+
+ for (Iterator iter = target_temp.keySet().iterator(); iter.hasNext();)
+ {
+ String node_key = (String)iter.next();
+ //jxroot.getVariables().declareVariable("name", target_temp.get(node_key));
+ //String node_type = (String)jxroot.getValue("$name/type");
+ String node_type = (String)jxroot.getValue(node_key+"/type");
+
+ ModelTranslate t_temp = findTranslateTemplate(node_type, node_key);
+ ModelTemplate t_model = findModelTemplate(node_type, node_key);
+
+ model_lib.put(node_key, new MapBuilder()
+ .put("model", t_model)
+ .put("translate", t_temp)
+ .build());
+ }
+
+ for (Iterator iter = model_lib.keySet().iterator(); iter.hasNext();) {
+ String node_key = (String) iter.next();
+ ModelTranslate t = (ModelTranslate) model_lib.get(node_key).get("translate");
+ JXPathContext jxnode = jxroot.getRelativeContext(jxroot.getPointer(node_key));
+ if (t != null) {
+ Map<String, Object> t_output =t.translate(jxnode, model_lib, node_key);
+ if (t_output != null)
+ output_temp.putAll(t_output);
+ }
+
+ }
+
+ return new MapBuilder<String, Object>()
+ .put("tosca_definitions_version", new String("cloudify_dsl_1_3"))
+ .put("imports", new ListBuilder()
+ .add(new MapBuilder()
+ .put("cloudify",
+ "http://www.getcloudify.org/spec/cloudify/3.4/types.yaml")
+ .build())
+ .build())
+ .put("node_templates", output_temp)
+ .build();
+
+ }
+
+ public String createBlueprintDocument() {
+ DumperOptions options = new DumperOptions();
+ options.setWidth(1000000);
+ Yaml yaml = new Yaml(options);
+ return yaml.dump(createBlueprint());
+ }
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/ISdcClient.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/ISdcClient.java
new file mode 100644
index 0000000..554991a
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/ISdcClient.java
@@ -0,0 +1,47 @@
+package org.onap.sdc.dcae.client;
+
+import org.onap.sdc.dcae.composition.restmodels.CreateVFCMTRequest;
+import org.onap.sdc.dcae.composition.restmodels.sdc.*;
+import org.onap.sdc.dcae.composition.restmodels.ReferenceUUID;
+import org.onap.sdc.dcae.enums.AssetType;
+
+import java.util.List;
+
+public interface ISdcClient {
+
+ ResourceDetailed getResource(String uuid, String requestId) throws Exception;
+
+ ServiceDetailed getService(String uuid, String requestId) throws Exception;
+
+ List<Resource> getResources(String resourceType, String category, String subcategory, String requestId) throws Exception;
+
+ List<Service> getServices(String requestId) throws Exception;
+
+ String addExternalMonitoringReference(String userId, CreateVFCMTRequest resource, ReferenceUUID vfiUuid, String requestId);
+
+ void deleteExternalMonitoringReference(String userId, String context, String uuid, String vfiName, String vfcmtUuid, String requestId);
+
+ ResourceDetailed createResource(String userId, CreateVFCMTRequest resource, String requestId) throws Exception;
+
+ ResourceDetailed changeResourceLifecycleState(String userId, String uuid, String lifecycleOperation, String userRemarks, String requestId) throws Exception;
+
+ ServiceDetailed changeServiceLifecycleState(String userId, String uuid, String lifecycleOperation, String userRemarks, String requestId) throws Exception;
+
+ Asset changeAssetLifecycleState(String userId, String uuid, String lifecycleOperation, String userRemarks, AssetType assetType, String requestId) throws Exception;
+
+ String getResourceArtifact(String resourceUuid, String artifactUuid, String requestId) throws Exception;
+
+ Artifact createResourceArtifact(String userId, String resourceUuid, Artifact artifact, String requestId) throws Exception;
+
+ Artifact updateResourceArtifact(String userId, String resourceUuid, Artifact artifact, String requestId) throws Exception;
+
+ void deleteResourceArtifact(String userId, String resourceUuid, String artifactId, String requestId) throws Exception;
+
+ Artifact createVfInstanceArtifact(String userId, String serviceUuid, String normalizedInstanceName, Artifact artifact, String requestId) throws Exception;
+
+ Artifact updateVfInstanceArtifact(String userId, String serviceUuid, String normalizedInstanceName, Artifact artifact, String requestId) throws Exception;
+
+ ExternalReferencesMap getMonitoringReferences(String context, String uuid, String version, String requestId);
+
+ void deleteInstanceResourceArtifact(String userId, String context, String serviceUuid, String normalizedVfiName, String artifactUuid, String requestId);
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/SdcRestClient.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/SdcRestClient.java
new file mode 100644
index 0000000..058d9c7
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/client/SdcRestClient.java
@@ -0,0 +1,221 @@
+package org.onap.sdc.dcae.client;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.message.BasicHeader;
+import org.onap.sdc.dcae.composition.restmodels.CreateVFCMTRequest;
+import org.onap.sdc.dcae.composition.restmodels.ReferenceUUID;
+import org.onap.sdc.dcae.composition.restmodels.sdc.*;
+import org.onap.sdc.dcae.composition.util.DcaeBeConstants;
+import org.onap.sdc.dcae.composition.util.SystemProperties;
+import org.onap.sdc.dcae.enums.AssetType;
+import org.onap.sdc.dcae.enums.SdcConsumerInfo;
+import org.onap.sdc.dcae.utils.Normalizers;
+import org.onap.sdc.dcae.utils.SDCResponseErrorHandler;
+import org.onap.sdc.dcae.utils.SdcRestClientUtils;
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.*;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Base64Utils;
+import org.springframework.web.client.*;
+
+import javax.annotation.PostConstruct;
+import java.net.URI;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@Component("sdcrestclient")
+public class SdcRestClient implements ISdcClient {
+
+ @Autowired
+ private SystemProperties systemProperties;
+
+ private static final String SLASH = "/";
+ private static final String ECOMP_INSTANCE_ID_HEADER = "X-ECOMP-InstanceID";
+ private static final String ECOMP_REQUEST_ID_HEADER = "X-ECOMP-RequestID";
+ private static final String USER_ID_HEADER = "USER_ID";
+ private static final String RESOURCES_PATH = "resources";
+ private static final String SERVICES_PATH = "services";
+ private static final String ARTIFACTS_PATH = "artifacts";
+ private static final String CONTENT_MD5_HEADER = "Content-MD5";
+ private static final String RESOURCE_INSTANCES_PATH = "resourceInstances";
+ private static final String LIFECYCLE_STATE_PATH = "lifecycleState/{lifecycleOperation}";
+ private static final String METADATA_PATH = "metadata";
+ private static final String VERSION_PATH = "version";
+ private static final String MONITORING_REFERENCES_PATH = "externalReferences/monitoring";
+
+ private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ private String uri;
+
+ private RestTemplate client;
+
+ @PostConstruct
+ private void init() {
+ URI configUri = URI.create(systemProperties.getProperties().getProperty(DcaeBeConstants.Config.URI));
+ EnumMap<SdcConsumerInfo, String> userInfo = SdcRestClientUtils.extractConsumerInfoFromUri(configUri);
+ CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultHeaders(defaultHeaders(userInfo)).build();
+ HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
+ requestFactory.setHttpClient(httpClient);
+ client = new RestTemplate(requestFactory);
+ client.setErrorHandler(new SDCResponseErrorHandler());
+ uri = userInfo.get(SdcConsumerInfo.CATALOG_URL);
+ }
+
+ private List<BasicHeader> defaultHeaders(EnumMap<SdcConsumerInfo, String> userInfo) {
+ List<BasicHeader> headers = new ArrayList<>();
+ headers.add(new BasicHeader(HttpHeaders.AUTHORIZATION, userInfo.get(SdcConsumerInfo.AUTH)));
+ headers.add(new BasicHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE));
+ headers.add(new BasicHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_OCTET_STREAM_VALUE));
+ headers.add(new BasicHeader(ECOMP_INSTANCE_ID_HEADER, userInfo.get(SdcConsumerInfo.INSTANCE_ID)));
+ return headers;
+ }
+
+ public ResourceDetailed getResource(String uuid, String requestId) {
+ String url = buildRequestPath(RESOURCES_PATH, uuid, METADATA_PATH);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Get resource from SDC. URL={}", url);
+ return getObject(url, requestId, ResourceDetailed.class);
+ }
+
+ public ServiceDetailed getService(String uuid, String requestId) {
+ String url = buildRequestPath(SERVICES_PATH, uuid, METADATA_PATH);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Get service from SDC. URL={}", url);
+ return getObject(url, requestId, ServiceDetailed.class);
+ }
+
+ public List<Resource> getResources(String resourceType, String category, String subcategory, String requestId) {
+ String url = buildRequestPath(RESOURCES_PATH, SdcRestClientUtils.buildResourceFilterQuery(resourceType, category, subcategory));
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Get resources from SDC. URL={}", url);
+ return Arrays.asList(getObject(url, requestId, Resource[].class));
+ }
+
+ public List<Service> getServices(String requestId) {
+ String url = buildRequestPath(SERVICES_PATH);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Get services from SDC. URL={}", url);
+ return Arrays.asList(getObject(url, requestId, Service[].class));
+ }
+
+ public String addExternalMonitoringReference(String userId, CreateVFCMTRequest resource, ReferenceUUID vfcmtUuid, String requestId) {
+ String url = buildRequestPath(resource.getContextType(), resource.getServiceUuid(), RESOURCE_INSTANCES_PATH,
+ Normalizers.normalizeComponentInstanceName(resource.getVfiName()), MONITORING_REFERENCES_PATH);
+
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Connecting service id {} name {} to vfcmt {} URL={}",
+ resource.getServiceUuid(), resource.getVfiName(), vfcmtUuid.getReferenceUUID(), url);
+
+ return client.postForObject(url, new HttpEntity<>(vfcmtUuid, postResourceHeaders(userId, requestId)),
+ String.class);
+ }
+
+ public void deleteExternalMonitoringReference(String userId, String context, String uuid, String normalizeVfiName, String vfcmtUuid, String requestId) {
+ String url = buildRequestPath(context, uuid, RESOURCE_INSTANCES_PATH,
+ normalizeVfiName, MONITORING_REFERENCES_PATH, vfcmtUuid);
+ client.exchange(url, HttpMethod.DELETE, new HttpEntity(postResourceHeaders(userId, requestId)), String.class);
+ }
+
+ public ResourceDetailed createResource(String userId, CreateVFCMTRequest resource, String requestId) {
+ String url = buildRequestPath(RESOURCES_PATH);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Create SDC resource with name {} URL={}", resource.getName(), url);
+ return client.postForObject(url, new HttpEntity<>(resource, postResourceHeaders(userId, requestId)), ResourceDetailed.class);
+ }
+
+ public ResourceDetailed changeResourceLifecycleState(String userId, String uuid, String lifecycleOperation, String userRemarks, String requestId) {
+ String url = buildRequestPath(RESOURCES_PATH, uuid, LIFECYCLE_STATE_PATH);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Change SDC resource lifecycle state ({}). URL={}", lifecycleOperation, url);
+ return client.postForObject(url, new HttpEntity<>(SdcRestClientUtils.buildUserRemarksObject(userRemarks), postResourceHeaders(userId, requestId)), ResourceDetailed.class, lifecycleOperation);
+ }
+
+ public ServiceDetailed changeServiceLifecycleState(String userId, String uuid, String lifecycleOperation, String userRemarks, String requestId) {
+ String url = buildRequestPath(SERVICES_PATH, uuid, LIFECYCLE_STATE_PATH);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Change SDC service lifecycle state ({}). URL={}", lifecycleOperation, url);
+ return client.postForObject(url, new HttpEntity<>(SdcRestClientUtils.buildUserRemarksObject(userRemarks), postResourceHeaders(userId, requestId)), ServiceDetailed.class, lifecycleOperation);
+ }
+
+ public Asset changeAssetLifecycleState(String userId, String uuid, String lifecycleOperation, String userRemarks, AssetType assetType, String requestId) {
+ return AssetType.RESOURCE == assetType ? changeResourceLifecycleState(userId, uuid, lifecycleOperation, userRemarks, requestId) : changeServiceLifecycleState(userId, uuid, lifecycleOperation, userRemarks, requestId);
+ }
+
+ public String getResourceArtifact(String resourceUuid, String artifactUuid, String requestId) {
+ String url = buildRequestPath(RESOURCES_PATH, resourceUuid, ARTIFACTS_PATH, artifactUuid);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Get resource artifact from SDC. URL={}", url);
+ return getObject(url, requestId, String.class);
+ }
+
+ public Artifact createResourceArtifact(String userId, String resourceUuid, Artifact artifact, String requestId) throws Exception {
+ String url = buildRequestPath(RESOURCES_PATH, resourceUuid, ARTIFACTS_PATH);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Create SDC resource artifact. URL={}", url);
+ String artifactData = SdcRestClientUtils.artifactToString(artifact);
+ return client.postForObject(url, new HttpEntity<>(artifactData, postArtifactHeaders(userId, artifactData, requestId)), Artifact.class);
+ }
+
+ public Artifact updateResourceArtifact(String userId, String resourceUuid, Artifact artifact, String requestId) throws Exception {
+ String url = buildRequestPath(RESOURCES_PATH, resourceUuid, ARTIFACTS_PATH, artifact.getArtifactUUID());
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Update SDC resource artifact. URL={}", url);
+ String artifactData = SdcRestClientUtils.artifactToString(artifact);
+ return client.postForObject(url, new HttpEntity<>(artifactData, postArtifactHeaders(userId, artifactData, requestId)), Artifact.class);
+ }
+
+ public void deleteResourceArtifact(String userId, String resourceUuid, String artifactId, String requestId) {
+ String url = buildRequestPath(RESOURCES_PATH, resourceUuid, ARTIFACTS_PATH, artifactId);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Delete SDC resource artifact. URL={}", url);
+ client.exchange(url, HttpMethod.DELETE, new HttpEntity(postResourceHeaders(userId, requestId)), Artifact.class);
+ }
+
+ public Artifact createVfInstanceArtifact(String userId, String serviceUuid, String normalizedInstanceName, Artifact artifact, String requestId) throws Exception {
+ String url = buildRequestPath(SERVICES_PATH, serviceUuid, RESOURCE_INSTANCES_PATH, normalizedInstanceName, ARTIFACTS_PATH);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Create SDC resource instance artifact. URL={}", url);
+ String artifactData = SdcRestClientUtils.artifactToString(artifact);
+ return client.postForObject(url, new HttpEntity<>(artifactData, postArtifactHeaders(userId, artifactData, requestId)), Artifact.class);
+ }
+
+ public Artifact updateVfInstanceArtifact(String userId, String serviceUuid, String normalizedInstanceName, Artifact artifact, String requestId) throws Exception {
+ String url = buildRequestPath(SERVICES_PATH, serviceUuid, RESOURCE_INSTANCES_PATH, normalizedInstanceName, ARTIFACTS_PATH, artifact.getArtifactUUID());
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Update SDC resource instance artifact. URL={}", url);
+ String artifactData = SdcRestClientUtils.artifactToString(artifact);
+ return client.postForObject(url, new HttpEntity<>(artifactData, postArtifactHeaders(userId, artifactData, requestId)), Artifact.class);
+ }
+
+ public ExternalReferencesMap getMonitoringReferences(String context, String uuid, String version, String requestId) {
+ String url = buildRequestPath(context, uuid, VERSION_PATH, version, MONITORING_REFERENCES_PATH);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Get SDC service monitoring references. URL={}", url);
+ return getObject(url, requestId, ExternalReferencesMap.class);
+ }
+
+ public void deleteInstanceResourceArtifact(String userId, String context, String serviceUuid, String normalizedVfiName, String artifactUuid, String requestId) {
+ String url = buildRequestPath(context, serviceUuid, RESOURCE_INSTANCES_PATH, normalizedVfiName, ARTIFACTS_PATH, artifactUuid);
+ debugLogger.log(LogLevel.DEBUG, this.getClass().getName(), "Delete SDC instance resource artifact. URL={}", url);
+ client.exchange(url, HttpMethod.DELETE, new HttpEntity(postResourceHeaders(userId, requestId)), Artifact.class);
+ }
+
+ private HttpHeaders postResourceHeaders(String userId, String requestId) {
+ HttpHeaders headers = requestHeader(requestId);
+ headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
+ headers.add(USER_ID_HEADER, userId);
+ return headers;
+ }
+
+ private HttpHeaders postArtifactHeaders(String userId, String artifact, String requestId) {
+ HttpHeaders headers = postResourceHeaders(userId, requestId);
+ String md5 = Base64Utils.encodeToString(DigestUtils.md5Hex(artifact).getBytes());
+ headers.add(CONTENT_MD5_HEADER, md5);
+ return headers;
+ }
+
+ private HttpHeaders requestHeader(String requestId){
+ HttpHeaders headers = new HttpHeaders();
+ headers.add(ECOMP_REQUEST_ID_HEADER, requestId);
+ return headers;
+ }
+
+ private <T> T getObject(String url, String requestId, Class<T> clazz) {
+ return client.exchange(url, HttpMethod.GET, new HttpEntity<>(requestHeader(requestId)), clazz).getBody();
+ }
+
+ private String buildRequestPath(String... args){
+ return uri + Stream.of(args).collect(Collectors.joining(SLASH));
+ }
+} \ No newline at end of file
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/ArtifactGroupType.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/ArtifactGroupType.java
new file mode 100644
index 0000000..98e78c6
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/ArtifactGroupType.java
@@ -0,0 +1,5 @@
+package org.onap.sdc.dcae.enums;
+
+public enum ArtifactGroupType {
+ DEPLOYMENT
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/ArtifactType.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/ArtifactType.java
new file mode 100644
index 0000000..2da4cc7
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/ArtifactType.java
@@ -0,0 +1,16 @@
+package org.onap.sdc.dcae.enums;
+
+public enum ArtifactType {
+ DCAE_TOSCA,
+ DCAE_JSON,
+ DCAE_POLICY,
+ DCAE_DOC,
+ DCAE_EVENT,
+ DCAE_INVENTORY_TOSCA,
+ DCAE_INVENTORY_JSON,
+ DCAE_INVENTORY_POLICY,
+ DCAE_INVENTORY_DOC,
+ DCAE_INVENTORY_BLUEPRINT,
+ DCAE_INVENTORY_EVENT,
+ OTHER
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/AssetType.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/AssetType.java
new file mode 100644
index 0000000..576643f
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/AssetType.java
@@ -0,0 +1,5 @@
+package org.onap.sdc.dcae.enums;
+
+public enum AssetType {
+ RESOURCE, SERVICE
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/LifecycleOperationType.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/LifecycleOperationType.java
new file mode 100644
index 0000000..80e01df
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/LifecycleOperationType.java
@@ -0,0 +1,16 @@
+package org.onap.sdc.dcae.enums;
+
+
+public enum LifecycleOperationType {
+ CHECKIN("checkin"), CHECKOUT("checkout"), CERTIFY("certify"), UNDO_CHECKOUT("undoCheckout");
+
+ private String value;
+
+ LifecycleOperationType(String value){
+ this.value = value;
+ }
+
+ public String getValue(){
+ return value;
+ }
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/SdcConsumerInfo.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/SdcConsumerInfo.java
new file mode 100644
index 0000000..aecb61d
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/enums/SdcConsumerInfo.java
@@ -0,0 +1,5 @@
+package org.onap.sdc.dcae.enums;
+
+public enum SdcConsumerInfo {
+ AUTH, INSTANCE_ID, CATALOG_URL
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/AbstractSdncException.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/AbstractSdncException.java
new file mode 100644
index 0000000..360e28b
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/AbstractSdncException.java
@@ -0,0 +1,97 @@
+package org.onap.sdc.dcae.errormng;
+
+
+import org.onap.sdc.common.onaplog.OnapLoggerDebug;
+import org.onap.sdc.common.onaplog.OnapLoggerError;
+import org.onap.sdc.common.onaplog.Enums.LogLevel;
+
+import java.util.Arrays;
+import java.util.Formatter;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class AbstractSdncException {
+ private String messageId;
+
+ private String text;
+
+ private String[] variables;
+
+ private static OnapLoggerError errLogger = OnapLoggerError.getInstance();
+ private static OnapLoggerDebug debugLogger = OnapLoggerDebug.getInstance();
+
+ private final static Pattern ERROR_PARAM_PATTERN = Pattern.compile("%\\d");
+
+ public AbstractSdncException() {
+ }
+
+ public AbstractSdncException(String messageId, String text, String[] variables) {
+ super();
+ this.messageId = messageId;
+ this.text = text;
+ this.variables = validateParameters(messageId, text, variables);
+ }
+
+ private String[] validateParameters(String messageId, String text, String[] variables) {
+ String[] res = null;
+ Matcher m = ERROR_PARAM_PATTERN.matcher(text);
+ int expectedParamsNum = 0;
+ while (m.find()) {
+ expectedParamsNum += 1;
+ }
+ int actualParamsNum = (variables != null) ? variables.length : 0;
+ if (actualParamsNum < expectedParamsNum) {
+ errLogger.log(LogLevel.WARN, this.getClass().getName(),
+ "Received less parameters than expected for error with messageId {}, expected: {}, actual: {}. Missing parameters are padded with null values.",
+ messageId, expectedParamsNum, actualParamsNum);
+ } else if (actualParamsNum > expectedParamsNum) {
+ errLogger.log(LogLevel.WARN, this.getClass().getName(),
+ "Received more parameters than expected for error with messageId {}, expected: {}, actual: {}. Extra parameters are ignored.",
+ messageId, expectedParamsNum, actualParamsNum);
+ }
+ if (variables != null) {
+ res = Arrays.copyOf(variables, expectedParamsNum);
+ }
+
+ return res;
+ }
+
+ public String getMessageId() {
+ return this.messageId;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public String[] getVariables() {
+ return variables;
+ }
+
+ public void setMessageId(String messageId) {
+ this.messageId = messageId;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ public void setVariables(String[] variables) {
+ this.variables = variables;
+ }
+
+ public String getFormattedErrorMessage() {
+ String res;
+ if (variables != null && variables.length > 0) {
+ Formatter formatter = new Formatter();
+ try {
+ res = formatter.format(this.text.replaceAll("%\\d", "%s"), (Object[]) this.variables).toString();
+ } finally {
+ formatter.close();
+ }
+ } else {
+ res = this.text;
+ }
+ return res;
+ }
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/BaseException.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/BaseException.java
new file mode 100644
index 0000000..b559634
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/BaseException.java
@@ -0,0 +1,61 @@
+package org.onap.sdc.dcae.errormng;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.gson.Gson;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.client.HttpClientErrorException;
+
+public class BaseException extends HttpClientErrorException {
+
+ private static Gson gson = new Gson();
+
+ protected RequestError requestError;
+
+ public RequestError getRequestError() {
+ return requestError;
+ }
+
+ public void setRequestError(RequestError requestError) {
+ this.requestError = requestError;
+ }
+
+ public BaseException(HttpClientErrorException theError) {
+ super(theError.getStatusCode());
+ String body = theError.getResponseBodyAsString();
+ if (body != null) {
+ requestError = extractRequestError(body);
+ }
+ }
+
+ public BaseException(HttpStatus status, RequestError re){
+ super(status);
+ requestError = re;
+ }
+
+ private RequestError extractRequestError(String error) {
+ ResponseFormat responseFormat = gson.fromJson(error, ResponseFormat.class);
+ return responseFormat.getRequestError();
+ }
+
+ @JsonIgnore
+ public String getMessageId() {
+ return requestError.getMessageId();
+ }
+
+ @JsonIgnore
+ public String[] getVariables() {
+ return requestError.getVariables();
+ }
+
+ @JsonIgnore
+ public String getText(){
+ return requestError.getText();
+ }
+
+ @Override
+ @JsonIgnore
+ public String getMessage() {
+ return requestError.getFormattedMessage();
+ }
+
+} \ No newline at end of file
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/OkResponseInfo.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/OkResponseInfo.java
new file mode 100644
index 0000000..53bdf3e
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/OkResponseInfo.java
@@ -0,0 +1,8 @@
+package org.onap.sdc.dcae.errormng;
+
+public class OkResponseInfo extends AbstractSdncException {
+
+ public OkResponseInfo(String messageId, String text, String[] variables) {
+ super(messageId, text, variables);
+ }
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/PolicyException.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/PolicyException.java
new file mode 100644
index 0000000..3fc2d71
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/PolicyException.java
@@ -0,0 +1,11 @@
+package org.onap.sdc.dcae.errormng;
+
+public class PolicyException extends AbstractSdncException {
+
+ public PolicyException(String messageId, String text, String[] variables) {
+ super(messageId, text, variables);
+ }
+
+ public PolicyException() {
+ }
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/RequestError.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/RequestError.java
new file mode 100644
index 0000000..00fe3f2
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/RequestError.java
@@ -0,0 +1,65 @@
+package org.onap.sdc.dcae.errormng;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+import java.util.List;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class RequestError {
+ private PolicyException policyException;
+ private ServiceException serviceException;
+ private OkResponseInfo okResponseInfo;
+ private List<ServiceException> serviceExceptions;
+
+ public PolicyException getPolicyException() {
+ return policyException;
+ }
+
+ public ServiceException getServiceException() {
+ return serviceException;
+ }
+
+ public OkResponseInfo getOkResponseInfo() {
+ return okResponseInfo;
+ }
+
+ public void setPolicyException(PolicyException policyException) {
+ this.policyException = policyException;
+ }
+
+ void setServiceException(ServiceException serviceException) {
+ this.serviceException = serviceException;
+ }
+
+ void setOkResponseInfo(OkResponseInfo okResponseInfo) {
+ this.okResponseInfo = okResponseInfo;
+ }
+
+ public List<ServiceException> getServiceExceptions() {
+ return serviceExceptions;
+ }
+
+ void setServiceExceptions(List<ServiceException> serviceExceptions) {
+ this.serviceExceptions = serviceExceptions;
+ }
+
+ String getFormattedMessage() {
+ return getError().getFormattedErrorMessage();
+ }
+
+ String getMessageId() {
+ return getError().getMessageId();
+ }
+
+ String[] getVariables() {
+ return getError().getVariables();
+ }
+
+ String getText() {
+ return getError().getText();
+ }
+
+ AbstractSdncException getError() {
+ return null != serviceException ? serviceException : null != policyException ? policyException : okResponseInfo;
+ }
+} \ No newline at end of file
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/ResponseFormat.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/ResponseFormat.java
new file mode 100644
index 0000000..ffdce70
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/ResponseFormat.java
@@ -0,0 +1,75 @@
+package org.onap.sdc.dcae.errormng;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+import java.util.List;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ResponseFormat {
+
+ @JsonIgnore
+ private int status;
+ private RequestError requestError;
+ private String notes = "";
+
+ public String getNotes() {
+ return notes;
+ }
+
+ void setNotes(String notes) {
+ this.notes = notes;
+ }
+
+ public ResponseFormat() {
+ super();
+ }
+
+ public ResponseFormat(int status) {
+ super();
+ this.status = status;
+ }
+
+
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public RequestError getRequestError() {
+ return requestError;
+ }
+
+ public void setRequestError(RequestError requestError) {
+ this.requestError = requestError;
+ }
+
+ void setPolicyException(PolicyException policyException) {
+ this.requestError = new RequestError();
+ requestError.setPolicyException(policyException);
+ }
+
+ void setServiceException(ServiceException serviceException) {
+ this.requestError = new RequestError();
+ requestError.setServiceException(serviceException);
+ }
+
+ void setOkResponseInfo(OkResponseInfo okResponseInfo) {
+ this.requestError = new RequestError();
+ requestError.setOkResponseInfo(okResponseInfo);
+ }
+
+ void setServiceExceptions(List<ServiceException> serviceExceptions) {
+ this.requestError = new RequestError();
+ requestError.setServiceExceptions(serviceExceptions);
+ }
+
+ @Override
+ public String toString() {
+ return "ResponseFormat[" + "status=" + status + ", requestError=" + requestError + ']';
+ }
+
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/ServiceException.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/ServiceException.java
new file mode 100644
index 0000000..163a07f
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/errormng/ServiceException.java
@@ -0,0 +1,12 @@
+package org.onap.sdc.dcae.errormng;
+
+public class ServiceException extends AbstractSdncException {
+
+ public ServiceException(String messageId, String text, String[] variables) {
+ super(messageId, text, variables);
+ }
+
+ public ServiceException() {
+ }
+
+} \ No newline at end of file
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/utils/Normalizers.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/utils/Normalizers.java
new file mode 100644
index 0000000..4719607
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/utils/Normalizers.java
@@ -0,0 +1,34 @@
+package org.onap.sdc.dcae.utils;
+
+import org.apache.commons.lang3.text.WordUtils;
+
+import java.util.regex.Pattern;
+
+public final class Normalizers {
+
+ private static final Pattern COMPONENT_NAME_DELIMITER_PATTERN = Pattern.compile("[.\\-_]+");
+ private static final Pattern ARTIFACT_LABEL_DELIMITER_PATTERN = Pattern.compile("[ \\-+._]+");
+ private static final Pattern COMPONENT_INSTANCE_NAME_DELIMITER_PATTERN = Pattern.compile("[ \\-.]+");
+
+
+ public static String normalizeComponentName(String name) {
+ String normalizedName = name.toLowerCase();
+ normalizedName = COMPONENT_NAME_DELIMITER_PATTERN.matcher(normalizedName).replaceAll(" ");
+ String[] split = normalizedName.split(" ");
+ StringBuffer sb = new StringBuffer();
+ for (String splitElement : split) {
+ String capitalize = WordUtils.capitalize(splitElement);
+ sb.append(capitalize);
+ }
+ return sb.toString();
+ }
+
+ public static String normalizeArtifactLabel(String label) {
+ return ARTIFACT_LABEL_DELIMITER_PATTERN.matcher(label).replaceAll("").toLowerCase();
+ }
+
+ public static String normalizeComponentInstanceName(String name) {
+ return COMPONENT_INSTANCE_NAME_DELIMITER_PATTERN.matcher(name).replaceAll("").toLowerCase();
+ }
+
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/utils/SDCResponseErrorHandler.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/utils/SDCResponseErrorHandler.java
new file mode 100644
index 0000000..64da66a
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/utils/SDCResponseErrorHandler.java
@@ -0,0 +1,43 @@
+package org.onap.sdc.dcae.utils;
+
+import com.google.gson.Gson;
+import org.onap.sdc.dcae.catalog.asdc.ASDCException;
+import org.onap.sdc.dcae.errormng.RequestError;
+import org.onap.sdc.dcae.errormng.ResponseFormat;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.web.client.DefaultResponseErrorHandler;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.ResponseErrorHandler;
+
+import java.io.IOException;
+
+public class SDCResponseErrorHandler implements ResponseErrorHandler {
+
+ private ResponseErrorHandler errorHandler = new DefaultResponseErrorHandler();
+
+ private static Gson gson = new Gson();
+
+ public void handleError(ClientHttpResponse response) throws IOException {
+ try{
+ errorHandler.handleError(response);
+ } catch (HttpClientErrorException e) {
+ RequestError re = extractRequestError(e);
+ throw null == re ? e : new ASDCException(e.getStatusCode(), re);
+ }
+ }
+
+ public boolean hasError(ClientHttpResponse response) throws IOException{
+ return errorHandler.hasError(response);
+ }
+
+ private RequestError extractRequestError(HttpClientErrorException error) {
+ try {
+ String body = error.getResponseBodyAsString();
+ ResponseFormat responseFormat = gson.fromJson(body, ResponseFormat.class);
+ return responseFormat.getRequestError();
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+}
diff --git a/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/utils/SdcRestClientUtils.java b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/utils/SdcRestClientUtils.java
new file mode 100644
index 0000000..33c2f49
--- /dev/null
+++ b/dcaedt_catalog/asdc/src/main/java/org/onap/sdc/dcae/utils/SdcRestClientUtils.java
@@ -0,0 +1,85 @@
+package org.onap.sdc.dcae.utils;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.onap.sdc.dcae.composition.restmodels.sdc.Artifact;
+import org.onap.sdc.dcae.enums.ArtifactGroupType;
+import org.onap.sdc.dcae.enums.SdcConsumerInfo;
+import org.springframework.util.Base64Utils;
+import org.springframework.util.StringUtils;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class SdcRestClientUtils {
+
+ private static final String SDC_CATALOG_PATH = "/sdc/v1/catalog/";
+
+ // TODO consider moving params elsewhere (user/password/instanceId can be constant)
+ public static EnumMap<SdcConsumerInfo, String> extractConsumerInfoFromUri(URI configUri) {
+ EnumMap<SdcConsumerInfo, String> userInfoMap = new EnumMap<>(SdcConsumerInfo.class);
+ String userInfo = configUri.getUserInfo();
+ if (userInfo != null) {
+ userInfoMap.put(SdcConsumerInfo.AUTH, "Basic "+ Base64Utils.encodeToString(userInfo.getBytes()));
+ }
+ String fragment = configUri.getFragment();
+ if (fragment == null)
+ throw new IllegalArgumentException("The URI must contain a fragment specification, to be used as SDC instance id");
+ userInfoMap.put(SdcConsumerInfo.INSTANCE_ID, fragment);
+ try {
+ userInfoMap.put(SdcConsumerInfo.CATALOG_URL, new URI(configUri.getScheme(), null, configUri.getHost(), configUri.getPort(), configUri.getPath()+SDC_CATALOG_PATH, null, null).toString());
+ }
+ catch (URISyntaxException se) {
+ throw new IllegalArgumentException("Invalid uri", se);
+ }
+ return userInfoMap;
+ }
+
+ public static String buildResourceFilterQuery(String resourceType, String category, String subcategory) {
+ List<String> filters = new ArrayList<>();
+ if(!StringUtils.isEmpty(resourceType))
+ filters.add("resourceType="+resourceType);
+ if(!StringUtils.isEmpty(category))
+ filters.add("category="+category);
+ if(!StringUtils.isEmpty(subcategory))
+ filters.add("subCategory="+subcategory);
+ return "?"+filters.stream().collect(Collectors.joining("&"));
+ }
+
+ public static UserRemarks buildUserRemarksObject(String userRemarks) {
+ return new UserRemarks(userRemarks);
+ }
+
+ private static class UserRemarks {
+ private String userRemarks;
+
+ private UserRemarks(String userRemarks) {
+ this.userRemarks = userRemarks;
+ }
+
+ public String getUserRemarks() {
+ return userRemarks;
+ }
+ }
+
+ public static String artifactToString(Artifact artifact) throws JsonProcessingException {
+ ObjectMapper mapper = new ObjectMapper();
+ return mapper.writeValueAsString(artifact);
+ }
+
+ public static Artifact generateDeploymentArtifact(String description, String name, String type, String label, byte[] payload){
+ Artifact artifact = new Artifact();
+ artifact.setDescription(description);
+ artifact.setArtifactName(name);
+ artifact.setArtifactGroupType(ArtifactGroupType.DEPLOYMENT.name());
+ artifact.setArtifactType(type);
+ artifact.setArtifactLabel(label);
+ artifact.setPayloadData(Base64Utils.encodeToString(payload));
+ return artifact;
+ }
+}