ONAP adapter updates 74/1374/2
authorSerban Jora <sj2381@att.com>
Wed, 21 Mar 2018 04:36:16 +0000 (00:36 -0400)
committerSerban Jora <sj2381@att.com>
Wed, 21 Mar 2018 15:07:38 +0000 (11:07 -0400)
Change-Id: I78ce1e98fa7fca5bce98cf5c83beb033d4145698
Signed-off-by: Serban Jora <sj2381@att.com>
Issue-ID: ACUMOS-276

14 files changed:
gateway/src/main/java/org/acumos/federation/gateway/adapter/onap/ONAP.java
gateway/src/main/java/org/acumos/federation/gateway/adapter/onap/ONAPAdapterConfiguration.java [new file with mode: 0644]
gateway/src/main/java/org/acumos/federation/gateway/adapter/onap/ToscaLab.java [new file with mode: 0644]
gateway/src/main/java/org/acumos/federation/gateway/adapter/onap/sdc/ASDC.java
gateway/src/main/java/org/acumos/federation/gateway/adapter/onap/sdc/ASDCException.java
gateway/src/main/java/org/acumos/federation/gateway/controller/PeerPingController.java
gateway/src/main/java/org/acumos/federation/gateway/service/impl/CatalogServiceLocalImpl.java
gateway/src/main/java/org/acumos/federation/gateway/service/impl/PeerServiceLocalImpl.java
gateway/src/main/java/org/acumos/federation/gateway/task/PeerSubscriptionTask.java
gateway/src/test/resources/application-onap.properties [new file with mode: 0644]
gateway/src/test/resources/onap-catalog.json [new file with mode: 0644]
gateway/src/test/resources/onap-peers.json [new file with mode: 0644]
gateway/src/test/resources/onap.pkcs12 [new file with mode: 0644]
gateway/toscalab.xml [new file with mode: 0644]

index 01dad6d..46d3a06 100644 (file)
@@ -26,10 +26,16 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.Collections;
+import java.util.Comparator;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 
+import org.acumos.cds.ArtifactTypeCode;
 import org.acumos.cds.domain.MLPArtifact;
 import org.acumos.cds.domain.MLPPeer;
 import org.acumos.cds.domain.MLPSolution;
@@ -45,20 +51,22 @@ import org.acumos.federation.gateway.event.PeerSubscriptionEvent;
 import org.acumos.federation.gateway.common.Clients;
 import org.acumos.federation.gateway.common.FederationClient;
 import org.apache.commons.io.IOUtils;
+
 import org.json.JSONArray;
 import org.json.JSONObject;
+import org.json.JSONException;
+
 import org.springframework.beans.factory.BeanInitializationException;
 import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.context.annotation.Scope;
 import org.springframework.context.annotation.Conditional;
 import org.springframework.context.event.EventListener;
 import org.springframework.core.task.TaskExecutor;
-import org.springframework.http.HttpStatus;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Component;
 import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.util.StreamUtils;
 
 @Component("onap")
 @Scope("singleton")
@@ -70,6 +78,7 @@ public class ONAP {
        private ASDC asdc = new ASDC();
        private String asdcOperator;
        private TaskExecutor taskExecutor;
+       private ToscaLab        toscalab = new ToscaLab();
        @Autowired
        private Clients clients;
 
@@ -136,41 +145,52 @@ public class ONAP {
 
                        // list with category and subcategory currently used for onap
                        // more dynamic mapping to come: based on solution information it will provide
-                       // sdc assettype, categoty and subcategoty
+                       // sdc assettype, category and subcategory
+                       log.info(EELFLoggerDelegate.debugLogger, "Processing {} Acumos solutions received from {}", solutions.size(), peer);
 
                        JSONArray sdcAssets = null;
                        try {
                                sdcAssets = asdc.getAssets(AssetType.resource, JSONArray.class, "Generic", "Abstract").waitForResult();
                        }
-                       catch (Throwable x) {
+                       catch (Exception x) {
                                log.error(EELFLoggerDelegate.errorLogger, "Failed to list ONAP SDC assets: " + x.getCause(), x);
                                // if this is a 404 NotFound, continue, otherwise, fail
-                               if (x instanceof ASDCException && x.getCause() instanceof HttpClientErrorException
-                                               && ((HttpClientErrorException) x.getCause()).getStatusCode() == HttpStatus.NOT_FOUND) {
+                               if (ASDCException.isNotFound(x))
                                        sdcAssets = new JSONArray();
-                               }
                                else
                                        return;
                        }
-                       // log.info(EELFLoggerDelegate.debugLogger, "Retrieved ONAP SDC assets: " +
-                       // sdcAssets);
-                       // log.info(EELFLoggerDelegate.debugLogger, "Received Acumos solutions: " +
-                       // this.solutions);
+                       log.info(EELFLoggerDelegate.debugLogger, "Mapping received Acumos solutions \n{}\n to retrieved ONAP SDC assets \n{}",
+                       this.solutions, sdcAssets);
 
                        for (MLPSolution acumosSolution : this.solutions) {
+
+                               FederationClient fedClient = clients.getFederationClient(this.peer.getApiUrl());
+
+                               List<MLPSolutionRevision> acumosRevisions = null;
                                try {
-                                       // does it already exist in sdc
+                                       acumosRevisions = (List<MLPSolutionRevision>) fedClient
+                                                       .getSolutionRevisions(acumosSolution.getSolutionId()).getContent();
+                               }
+                               catch (Exception x) {
+                                       log.error(EELFLoggerDelegate.errorLogger, "Failed to retrieve acumos revisions", x);
+                                       throw x;
+                               }
+                               sortAcumosSolutionRevisions(acumosRevisions);
+
+                               try {
+                                       // does the solution already exist in sdc
                                        JSONObject sdcAsset = lookupSdcAsset(acumosSolution, sdcAssets);
                                        if (sdcAsset == null) {
                                                // new solution
-                                               sdcAsset = createSdcAsset(acumosSolution);
+                                               sdcAsset = createSdcAsset(acumosSolution, acumosRevisions.get(acumosRevisions.size()-1));
                                        }
                                        else {
                                                // ONAP.this.asdc.checkoutResource(UUID.fromString(sdcAsset.getString("artifactUUID")),
                                                // ONAP.this.asdcOperator, "updated solution import");
-                                               sdcAsset = updateSdcAsset(sdcAsset, acumosSolution);
+                                               sdcAsset = updateSdcAsset(sdcAsset, acumosSolution, acumosRevisions);
                                        }
-                                       updateAssetArtifacts(sdcAsset, acumosSolution);
+                                       updateAssetArtifacts(sdcAsset, acumosSolution, acumosRevisions);
                                        // ONAP.this.asdc.checkinResource(UUID.fromString(sdcAsset.getString("artifactUUID")),
                                        // ONAP.this.asdcOperator, "solution imported " + " the acumos revision number
                                        // ");
@@ -187,33 +207,32 @@ public class ONAP {
                                return null;
                        for (int i = 0; i < theAssets.length(); i++) {
                                JSONObject asset = theAssets.optJSONObject(i);
-                               if (same(theSolution, asset))
+                               if (sameId(theSolution, asset))
                                        return asset;
                        }
                        return null;
                }
 
-               public JSONObject createSdcAsset(MLPSolution theSolution) throws Exception {
+               public JSONObject createSdcAsset(MLPSolution theSolution, MLPSolutionRevision theRevision) throws Exception {
                        log.info(EELFLoggerDelegate.debugLogger, "Creating ONAP SDC VF for solution " + theSolution);
 
                        String description = null;// theSolution.getDescription();
-                       if (description == null)
-                               description = theSolution.getSolutionId();// + "@acumos";
+                       if (description == null) {
+                               description = theRevision.getDescription();
+                               if (description == null) {
+                                       description = theSolution.getSolutionId();// + "@acumos";
+                               }
+                       }
 
                        try {
-                               return ONAP.this.asdc.createVF().withCategory("Generic").withSubCategory("Abstract")
+                               return ONAP.this.asdc.createVF()
+                                               .withCategory("Generic")
+                                               .withSubCategory("Abstract")
                                                .withName(theSolution.getName() + "-" + theSolution.getSolutionId()) // sdc names are unique,
                                                                                                                                                                                                // acumos ones not so
-                                               .withDescription(description).withVendorName("AcumosInc").withVendorRelease("1.0") // cannot
-                                                                                                                                                                                                                       // update so
-                                                                                                                                                                                                                       // .. but
-                                                                                                                                                                                                                       // might
-                                                                                                                                                                                                                       // want to
-                                                                                                                                                                                                                       // fetch the
-                                                                                                                                                                                                                       // last
-                                                                                                                                                                                                                       // Acumos
-                                                                                                                                                                                                                       // revision
-                                                                                                                                                                                                                       // version
+                                               .withDescription(description)
+                                               .withVendorName("Acumos")
+                                               .withVendorRelease(theRevision.getVersion()) //is this meaningful ? given that it cannot be updated ..
                                                .withTags("acumos", theSolution.getSolutionId()) // can I fit an UUID as tag ??
                                                .withOperator(ONAP.this.asdcOperator/* theSolution.getOwnerId() */) // probably won't work, SDC
                                                                                                                                                                                        // expects an att uuid
@@ -235,125 +254,117 @@ public class ONAP {
                 *            solution
                 * @return SDC Asset info
                 */
-               public JSONObject updateSdcAsset(JSONObject theAssetInfo, MLPSolution theSolution) {
+               public JSONObject updateSdcAsset(JSONObject theAssetInfo, MLPSolution theSolution, List<MLPSolutionRevision> theRevisions) {
                        log.info(EELFLoggerDelegate.debugLogger,
-                                       "Updating ONAP SDC VF " + theAssetInfo.optString("uuid") + " for Acumosb solution " + theSolution);
+                                       "Updating ONAP SDC VF " + theAssetInfo.optString("uuid") + " for Acumos solution " + theSolution);
                        return theAssetInfo;
                }
 
-               public void updateAssetArtifacts(JSONObject theAssetInfo, MLPSolution theSolution) throws Exception {
-                       // fetch the solution artifacts: for now we'll do this for the latest acumos
-                       // revision
-                       FederationClient fedClient = clients.getFederationClient(this.peer.getApiUrl());
-
-                       List<MLPSolutionRevision> acumosRevisions = null;
+               public void updateAssetArtifacts(JSONObject theAssetInfo, MLPSolution theSolution, List<MLPSolutionRevision> theRevisions)
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                               throws Exception {
                        try {
-                               acumosRevisions = (List<MLPSolutionRevision>) fedClient
-                                               .getSolutionRevisions(theSolution.getSolutionId()).getContent();
+                               theAssetInfo = ONAP.this.asdc
+                                               .getAsset(AssetType.resource, UUID.fromString(theAssetInfo.getString("uuid")), JSONObject.class)
+                                               .waitForResult();
                        }
                        catch (Exception x) {
-                               log.error(EELFLoggerDelegate.errorLogger, "Failed to retrieve acumos revisions: " + x);
+                               log.error(EELFLoggerDelegate.errorLogger,
+                                               "Failed to retrieve ONAP SDC asset metadata for " + theAssetInfo.getString("uuid") + " : " + x);
                                throw x;
                        }
 
+                       JSONArray sdcArtifacts = theAssetInfo.optJSONArray("artifacts");
+                       if (sdcArtifacts == null) {
+                               sdcArtifacts = new JSONArray();
+                       }
+
+                       //we could have a new model, a new model revision or updates to the currently mapped revision's artifacts.
+                       //currently we always fast-forward to the latest revision available in acumos
+                       MLPSolutionRevision mappedAcumosRevision = mappedAcumosRevision = theRevisions.get(theRevisions.size() - 1);
+
                        List<MLPArtifact> acumosArtifacts = null;
                        try {
-                               acumosArtifacts = (List<MLPArtifact>) fedClient.getArtifacts(theSolution.getSolutionId(),
-                                               acumosRevisions.get(acumosRevisions.size() - 1).getRevisionId()).getContent();
+                               acumosArtifacts = (List<MLPArtifact>) clients.getFederationClient(this.peer.getApiUrl())
+                                       .getArtifacts(theSolution.getSolutionId(), mappedAcumosRevision.getRevisionId())
+                                               .getContent();
                        }
                        catch (Exception x) {
                                log.error(EELFLoggerDelegate.errorLogger, "Failed to retrieve acumos artifacts" + x);
                                throw x;
                        }
 
-                       try {
-                               theAssetInfo = ONAP.this.asdc
-                                               .getAsset(AssetType.resource, UUID.fromString(theAssetInfo.getString("uuid")), JSONObject.class)
-                                               .waitForResult();
+                       if (acumosArtifacts == null)
+                               acumosArtifacts = new LinkedList<MLPArtifact>();
+
+                       //add an artifact to be mapped for revision tracking purposes
+                       {
+                               MLPArtifact mapper = new MLPArtifact(mappedAcumosRevision.getVersion(),
+                                                                                                                               ArtifactTypeCode.MD.toString(),
+                                                                                                                               "mapper",
+                                                                                                                               null,
+                                                                                                                               "", //owner: never sees CDS so irrelevant 
+                                                                                                                               0);
+                               mapper.setArtifactId("0");//a unique value among the other artifacts of this revision
+                               acumosArtifacts.add(mapper);
                        }
-                       catch (Exception x) {
-                               log.error(EELFLoggerDelegate.errorLogger,
-                                               "Failed to retrieve ONAP SDC asset metadata for " + theAssetInfo.getString("uuid") + " : " + x);
-                               throw x;
-                       }
-
-                       JSONArray sdcArtifacts = theAssetInfo.optJSONArray("artifacts");
-                       if (sdcArtifacts == null)
-                               sdcArtifacts = new JSONArray();
 
                        // all this could be better writen but the 2 sets are expected to be small so we
                        // favor readability
 
+                       //!! we support a 1-to-n mapping of artifacts from Acumos to SDC
+
                        // acumos artifacts that do not exist locally need to be added
                        List<MLPArtifact> newArtifacts = new LinkedList<MLPArtifact>();
-                       Map<MLPArtifact, JSONObject> updatedArtifacts = new HashMap<MLPArtifact, JSONObject>();
+                       Map<MLPArtifact, JSONArray> updatedArtifacts = new HashMap<MLPArtifact, JSONArray>();
                        // List<JSONObject> oldArtifacts = new LinkedList<JSONObject>();
 
                        log.info(EELFLoggerDelegate.debugLogger, "Acumos artifacts: " + acumosArtifacts);
-                       log.info(EELFLoggerDelegate.debugLogger, "ONAP SDC artifacts: " + sdcArtifacts);
+                       log.info(EELFLoggerDelegate.debugLogger, "SDC artifacts: " + sdcArtifacts);
 
                        for (MLPArtifact acumosArtifact : acumosArtifacts) {
-                               boolean found = false;
-                               for (int i = 0; !found && i < sdcArtifacts.length(); i++) {
+                               JSONArray sdcMappedArtifacts = new JSONArray();
+                               for (int i = 0; i < sdcArtifacts.length(); i++) {
                                        JSONObject sdcArtifact = sdcArtifacts.getJSONObject(i);
-                                       String sdcArtifactDescription = sdcArtifact.optString("artifactDescription");
-                                       if (sdcArtifactDescription != null) {
-                                               String[] parts = sdcArtifactDescription.split("@");
-                                               if (parts.length == 2) {
-                                                       if (parts[0].equals(acumosArtifact.getArtifactId())) {
-                                                               found = true;
-                                                               // compare the versions so that we find the
-                                                               if (!parts[1].equals(acumosArtifact.getVersion()))
-                                                                       updatedArtifacts.put(acumosArtifact, sdcArtifact);
-                                                       }
-                                               }
+                                       if (sameId(acumosArtifact, sdcArtifact)) {
+                                               sdcMappedArtifacts.put(sdcArtifact);
+                                       }
+                               }
+
+                               if (sdcMappedArtifacts.length() > 0) {
+                                       //sdc artifacts mapped to the acumos artifacts were found
+                                       //if not at the same version, update
+                                       //TODO: add a coherence check to make sure all sdcArtifacts are at the same (acumos) version
+                                       if (!sameVersion(acumosArtifact, sdcMappedArtifacts.getJSONObject(0))) {
+                                               updatedArtifacts.put(acumosArtifact, sdcMappedArtifacts);
                                        }
                                }
-                               if (!found)
+                               else {
                                        newArtifacts.add(acumosArtifact);
+                               }
                        }
 
-                       log.info(EELFLoggerDelegate.debugLogger, "New SDC artifacts: " + newArtifacts);
+                       log.info(EELFLoggerDelegate.debugLogger, "New artifacts: " + newArtifacts);
                        for (MLPArtifact acumosArtifact : newArtifacts) {
                                try {
-                                       byte[] content = IOUtils.toByteArray(new URI(acumosArtifact.getUri()));
-                                       if (content == null)
-                                               throw new Exception("Unable to fetch artifact content from " + acumosArtifact.getUri());
-                                       if (content.length == 0)
-                                               log.warn(EELFLoggerDelegate.debugLogger,
-                                                               "Acumos artifact has empty content, not acceptable in ONAP SDC");
-                                       // more sophisticated mapping needed here
-                                       asdc.createAssetArtifact(AssetType.resource, UUID.fromString(theAssetInfo.getString("uuid")))
-                                                       .withOperator(ONAP.this.asdcOperator).withContent(content)
-                                                       .withLabel(acumosArtifact.getArtifactTypeCode()).withName(acumosArtifact.getName())
-                                                       .withDisplayName(acumosArtifact.getMetadata()).withType(ArtifactType.OTHER)
-                                                       .withGroupType(ArtifactGroupType.DEPLOYMENT)
-                                                       .withDescription(acumosArtifact.getArtifactId() + "@"
-                                                                       + acumosArtifact.getVersion()/* acumosArtifact.getDescription() */)
-                                                       .execute().waitForResult();
+                                       for (ASDC.ArtifactUploadAction uploadAction:  mapNewArtifact(theAssetInfo, acumosArtifact)) {
+                                               uploadAction.execute().waitForResult();
+                                       }
                                }
                                catch (Exception x) {
-                                       log.error(EELFLoggerDelegate.errorLogger, "Failed to create ONAP SDC VF Artifact", x);
+                                       log.error(EELFLoggerDelegate.errorLogger, "Failed to create ONAP SDC VF Artifacts for " + acumosArtifact, x);
                                }
                        }
 
                        log.warn(EELFLoggerDelegate.debugLogger, "Updated SDC artifacts: " + updatedArtifacts.keySet());
-                       for (Map.Entry<MLPArtifact, JSONObject> updateEntry : updatedArtifacts.entrySet()) {
+                       for (Map.Entry<MLPArtifact, JSONArray> updateEntry : updatedArtifacts.entrySet()) {
                                MLPArtifact acumosArtifact = updateEntry.getKey();
                                try {
-                                       byte[] content = IOUtils.toByteArray(new URI(acumosArtifact.getUri()));
-                                       if (content == null)
-                                               throw new Exception("Unable to fetch artifact content from " + acumosArtifact.getUri());
-                                       // more sophisticated mapping needed here
-                                       asdc.updateAssetArtifact(AssetType.resource, UUID.fromString(theAssetInfo.getString("uuid")),
-                                                       updateEntry.getValue()).withOperator(ONAP.this.asdcOperator).withContent(content)
-                                                       // .withName(acumosArtifact.getName())
-                                                       .withDescription(acumosArtifact.getArtifactId() + "@"
-                                                                       + acumosArtifact.getVersion()/* acumosArtifact.getDescription() */)
-                                                       .execute().waitForResult();
+                                       for (ASDC.ArtifactUpdateAction updateAction:  mapArtifact(theAssetInfo, updateEntry.getKey(), updateEntry.getValue())) {
+                                               updateAction.execute().waitForResult();
+                                       }
                                }
                                catch (Exception x) {
-                                       log.error(EELFLoggerDelegate.errorLogger, "Failed to update ONAP SDC VF Artifact", x);
+                                       log.error(EELFLoggerDelegate.errorLogger, "Failed to update ONAP SDC VF Artifact for " + updateEntry.getKey(), x);
                                }
                        }
 
@@ -365,7 +376,7 @@ public class ONAP {
                                JSONObject sdcArtifact = sdcArtifacts.getJSONObject(i);
                                boolean found = false;
                                for (MLPArtifact acumosArtifact : acumosArtifacts) {
-                                       if (same(acumosArtifact, sdcArtifact)) {
+                                       if (sameId(acumosArtifact, sdcArtifact)) {
                                                found = true;
                                                break;
                                        }
@@ -387,33 +398,154 @@ public class ONAP {
                        }
                }
 
-               private boolean same(MLPSolution theAcumosSolution, JSONObject theSDCAsset) {
+               /**
+                */
+               private List<ASDC.ArtifactUploadAction> mapNewArtifact(JSONObject theSDCAsset, MLPArtifact theAcumosArtifact) {
 
-                       return theSDCAsset.optString("name", "")
-                                       .equals(theAcumosSolution.getName() + "-" + theAcumosSolution.getSolutionId());
+                       if (isDCAEComponentSpecification(theAcumosArtifact)) {
+
+                               byte[] content = null;
+                               try {
+                                       content = retrieveContent(theAcumosArtifact);
+                               }
+                               catch (Exception x) {
+                                       log.error(EELFLoggerDelegate.errorLogger, "Failed to retrieve Acumoms artifact content from " + theAcumosArtifact.getUri(), x);
+                                       return Collections.EMPTY_LIST;
+                               }
+
+                               JSONObject models = null;
+                               try {
+                                       models = new JSONObject(toscalab.create_model(new ByteArrayInputStream(content)));
+                               }
+                               catch (JSONException jsonx) {
+                                       log.error(EELFLoggerDelegate.errorLogger, "Failed to parse toscalab output", jsonx);
+                                       return Collections.EMPTY_LIST;
+                               }
+                               catch (Exception x) {
+                                       log.error(EELFLoggerDelegate.errorLogger, "Failed to process DCAE component specification from " + theAcumosArtifact, x);
+                                       return Collections.EMPTY_LIST;
+                               }
+
+                               List<ASDC.ArtifactUploadAction> actions = new LinkedList<ASDC.ArtifactUploadAction>();
+                               for (String model: models.keySet()) {
+                                       actions.add(
+                                               asdc.createAssetArtifact(AssetType.resource, UUID.fromString(theSDCAsset.getString("uuid")))
+                                               .withOperator(ONAP.this.asdcOperator)
+                                               .withEncodedContent(models.getString(model))
+                                               .withLabel(theAcumosArtifact.getArtifactTypeCode())
+                                               .withName(model/*theAcumosArtifact.getName()*/)
+                                               .withDisplayName(theAcumosArtifact.getMetadata())
+                                               .withType(ArtifactType.DCAE_TOSCA/*ArtifactType.OTHER*/)
+                                               .withGroupType(ArtifactGroupType.DEPLOYMENT)
+                                               .withDescription(theAcumosArtifact.getArtifactId() + "@" + theAcumosArtifact.getVersion())
+                                       );
+                               }
+                               return actions;
+                       }
+                       else if (isMapper(theAcumosArtifact)) {
+                               return Collections.singletonList(
+                                       asdc.createAssetArtifact(AssetType.resource, UUID.fromString(theSDCAsset.getString("uuid")))
+                                               .withOperator(ONAP.this.asdcOperator)
+                                               .withContent("{}".getBytes())
+                                               .withLabel(theAcumosArtifact.getArtifactTypeCode())
+                                               .withName(theAcumosArtifact.getName())
+                                               .withDisplayName("mapper")
+                                               .withType(ArtifactType.OTHER)
+                                               .withGroupType(ArtifactGroupType.DEPLOYMENT)
+                                               .withDescription(theAcumosArtifact.getArtifactId() + "@" + theAcumosArtifact.getVersion())
+                               );
+                       } 
+                       else {
+                               //everything else gets ignored at this point
+                               return Collections.EMPTY_LIST;
+                       }
                }
+               
+               private List<ASDC.ArtifactUpdateAction> mapArtifact(JSONObject theSDCAsset, MLPArtifact theAcumosArtifact, JSONArray theSDCArtifacts) {
+                       
+                       if (isDCAEComponentSpecification(theAcumosArtifact)) {
+                               byte[] content = null;
+                               try {
+                                       content = retrieveContent(theAcumosArtifact);
+                               }
+                               catch (Exception x) {
+                                       log.error(EELFLoggerDelegate.errorLogger, "Failed to retrieve Acumoms artifact content from " + theAcumosArtifact.getUri(), x);
+                                       return Collections.EMPTY_LIST;
+                               }
 
-               private boolean same(MLPArtifact theAcumosArtifact, JSONObject theSDCArtifact) {
+                               JSONObject models = null;
+                               try {
+                                       models = new JSONObject(toscalab.create_model(new ByteArrayInputStream(content)));
+                               }
+                               catch (JSONException jsonx) {
+                                       log.error(EELFLoggerDelegate.errorLogger, "Failed to parse toscalab output", jsonx);
+                                       return Collections.EMPTY_LIST;
+                               }
+                               catch (Exception x) {
+                                       log.error(EELFLoggerDelegate.errorLogger, "Failed to process DCAE component specification from " + theAcumosArtifact, x);
+                                       return Collections.EMPTY_LIST;
+                               }
 
-                       String sdcArtifactDescription = theSDCArtifact.optString("artifactDescription");
-                       if (sdcArtifactDescription != null) {
-                               String[] parts = sdcArtifactDescription.split("@");
-                               if (parts.length == 2) {
-                                       if (parts[0].equals(theAcumosArtifact.getArtifactId())) {
-                                               return true;
-                                       }
+                               List<ASDC.ArtifactUpdateAction> actions = new LinkedList<ASDC.ArtifactUpdateAction>();
+                               for (int i = 0; i < theSDCArtifacts.length(); i++) {
+                                       JSONObject sdcArtifact = theSDCArtifacts.getJSONObject(i);
+                                       actions.add(
+                                               asdc.updateAssetArtifact(AssetType.resource, UUID.fromString(theSDCAsset.getString("uuid")), sdcArtifact)
+                                                       .withOperator(ONAP.this.asdcOperator)
+                                                       .withEncodedContent(models.getString(sdcArtifact.getString("name")))
+                                                       .withName(sdcArtifact.getString("name"))
+                                                       .withDescription(theAcumosArtifact.getArtifactId() + "@"        + theAcumosArtifact.getVersion())
+                                       );
                                }
+                               return actions;
+                       }
+                       else if (isMapper(theAcumosArtifact)) {
+                               if (theSDCArtifacts.length() != 1)
+                                       log.warn(EELFLoggerDelegate.errorLogger, "Found more than one mapper artifact {}", theSDCArtifacts);
+                               return Collections.singletonList(
+                                               asdc.updateAssetArtifact(AssetType.resource, UUID.fromString(theSDCAsset.getString("uuid")), theSDCArtifacts.getJSONObject(0))
+                                                       .withOperator(ONAP.this.asdcOperator)
+                                                       .withName(theAcumosArtifact.getName())
+                                                       .withDescription(theAcumosArtifact.getArtifactId() + "@"        + theAcumosArtifact.getVersion()));
+                       } 
+                       else {
+                               log.error(EELFLoggerDelegate.errorLogger, "Found sdc artifacts for mlp artifact we do not process {}: {} ", theAcumosArtifact, theSDCArtifacts);
+                               return Collections.EMPTY_LIST;
                        }
-                       return false;
                }
 
-               // only safe to call if 'same' returned true
+               private boolean isDCAEComponentSpecification(MLPArtifact theArtifact) {
+                       return theArtifact.getName().equals("component-specification.json");
+               }
+               
+               private boolean isMapper(MLPArtifact theArtifact) {
+                       return theArtifact.getName().equals("mapper");
+               }
+
+               private boolean sameId(MLPSolution theAcumosSolution, JSONObject theSDCAsset) {
+
+                       return theSDCAsset.optString("name", "")
+                                       .equals(theAcumosSolution.getName() + "-" + theAcumosSolution.getSolutionId());
+               }
+
+               private boolean sameId(MLPArtifact theAcumosArtifact, JSONObject theSDCArtifact) {
+                       return acumosArtifactId(theSDCArtifact).equals(theAcumosArtifact.getArtifactId());
+               }
+
                /*
-                * private boolean sameVersion(MLPArtifact theAcumosArtifact, JSONObject
-                * theSDCArtifact) { return
-                * theSDCArtifact.optString("artifactDescription","@").split("@")[1].equals(
-                * theAcumosArtifact.getVersion()); }
+                * Only safe to call if 'same' returned true
                 */
+               private boolean sameVersion(MLPArtifact theAcumosArtifact, JSONObject theSDCArtifact) {
+                       return acumosArtifactVersion(theSDCArtifact).equals(theAcumosArtifact.getVersion());
+               }
+
+               private String acumosArtifactId(JSONObject theSDCArtifact) {
+                       return theSDCArtifact.optString("artifactDescription","@").split("@")[0];
+               }
+
+               private String acumosArtifactVersion(JSONObject theSDCArtifact) {
+                       return theSDCArtifact.optString("artifactDescription","@").split("@")[1];
+               }
 
                private boolean isAcumosOriginated(JSONObject theSDCArtifact) {
                        boolean isAcumos = theSDCArtifact.optString("artifactType").equals(ArtifactType.OTHER.toString())
@@ -422,8 +554,26 @@ public class ONAP {
                        isAcumos &= (parts.length == 2); // and the first part can be parsed as an UUID
                        return isAcumos;
                }
+
+               private byte[] retrieveContent(MLPArtifact theAcumosArtifact) throws Exception {
+
+                       if (this.peer.isLocal()) {
+                               return clients.getNexusClient().getArtifact(theAcumosArtifact.getUri()).toByteArray();
+                       }
+                       else { //non-local peer
+                               ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                               StreamUtils.copy(
+                                       clients.getFederationClient(this.peer.getApiUrl()).downloadArtifact(theAcumosArtifact.getArtifactId()).getInputStream(),
+                                       bos);
+                               return bos.toByteArray();
+                       }
+                       //else {
+                       //      return IOUtils.toByteArray(new URI(theAcumosArtifact.getUri()));
+                       //}
+               }
        }
 
+
        /**
         * Removes all (non-commited) Acumos solutions imported into ONAP SDC
         */
@@ -454,4 +604,17 @@ public class ONAP {
                }
 
        }
+       
+       /** */
+       private void sortAcumosSolutionRevisions(List<MLPSolutionRevision> theRevisions) {
+
+               Collections.sort(theRevisions,
+                                                                                new Comparator<MLPSolutionRevision>() {
+                                                                                       @Override
+                                                                                       public int compare(MLPSolutionRevision theFirst, MLPSolutionRevision theSecond) {
+                                                                                               return String.CASE_INSENSITIVE_ORDER.compare(theFirst.getVersion(), theSecond.getVersion());
+                                                                                       }
+                                                                                });
+                                                                               
+       }
 }
diff --git a/gateway/src/main/java/org/acumos/federation/gateway/adapter/onap/ONAPAdapterConfiguration.java b/gateway/src/main/java/org/acumos/federation/gateway/adapter/onap/ONAPAdapterConfiguration.java
new file mode 100644 (file)
index 0000000..7706d8d
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * ===============LICENSE_START=======================================================
+ * Acumos
+ * ===================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+ * ===================================================================================
+ * This Acumos software file is distributed by AT&T and Tech Mahindra
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * This file is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ===============LICENSE_END=========================================================
+ */
+
+package org.acumos.federation.gateway.adapter.onap;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Profile;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Configuration;
+
+import org.acumos.federation.gateway.config.AdapterConfiguration;
+
+
+/**
+ * Adds the specifics of a Test adapter to the generic adapter configuration.
+ */
+@Configuration
+@Conditional({ONAPAdapterCondition.class})
+public class ONAPAdapterConfiguration extends AdapterConfiguration  {
+
+       @Bean
+       public ONAP onapAdapter() {
+               return new ONAP();
+       }
+
+}
diff --git a/gateway/src/main/java/org/acumos/federation/gateway/adapter/onap/ToscaLab.java b/gateway/src/main/java/org/acumos/federation/gateway/adapter/onap/ToscaLab.java
new file mode 100644 (file)
index 0000000..a0dbd2c
--- /dev/null
@@ -0,0 +1,78 @@
+/*-
+ * ===============LICENSE_START=======================================================
+ * Acumos
+ * ===================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+ * ===================================================================================
+ * This Acumos software file is distributed by AT&T and Tech Mahindra
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * This file is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ===============LICENSE_END=========================================================
+ */
+package org.acumos.federation.gateway.adapter.onap;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.ByteArrayOutputStream;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.Properties;
+
+import org.python.util.PythonInterpreter;
+
+/**
+ * Java interface to ToscaLab python code
+ */
+public class ToscaLab {
+
+       public static void main(String[] theArgs) throws Exception {
+               ToscaLab lab = new ToscaLab();
+               for (String spec: theArgs)
+                       System.out.println(
+                               lab.create_model(new FileInputStream(spec)));
+       }
+
+
+       //private PythonInterpreter create_model_interpreter = null;
+       //private PyCode create_model = null;
+
+       public ToscaLab() {
+               //the problem here is that if we use jython anywhere else this static initialization will be reflected
+               Properties props = new Properties();
+               props.put("python.console.encoding", "UTF-8");
+               props.put("python.import.site","false");
+               props.put("python.path", "/");
+               
+               PythonInterpreter.initialize(System.getProperties(), props, new String[] {"-i","stdin", "-o", "WEB", "-m", "/data/meta_model/meta_tosca_schema.yaml"});
+       }
+
+       public String create_model(InputStream theSpec) throws Exception {
+
+               //if (this.create_model_interpreter == null) {
+                       PythonInterpreter python = new PythonInterpreter();
+                       python.setIn(theSpec);
+                       ByteArrayOutputStream out = new ByteArrayOutputStream();
+                       python.setOut(out);
+
+                       InputStream script = ClassLoader.getSystemResourceAsStream("model_create.py");
+                       if (script == null)
+                               throw new Exception("Failed to load 'model_create.py' script");
+                       else
+                               python.execfile(script);
+
+                       return out.toString();
+               //}
+       } 
+}
+
+
index a6a452e..8d98965 100644 (file)
@@ -587,6 +587,10 @@ public class ASDC {
                        return this;
                }
 
+               public ArtifactUploadAction withEncodedContent(String theContent) {
+                       return with("payloadData", theContent);
+               }
+
                public ArtifactUploadAction withContent(byte[] theContent) {
                        return with("payloadData", Base64Utils.encodeToString(theContent));
                }
@@ -651,6 +655,10 @@ public class ASDC {
                public ArtifactUpdateAction withContent(byte[] theContent) {
                        return with("payloadData", Base64Utils.encodeToString(theContent));
                }
+               
+               public ArtifactUpdateAction withEncodedContent(String theContent) {
+                       return with("payloadData", theContent);
+               }
 
                public ArtifactUpdateAction withContent(File theFile) throws IOException {
                        return withContent(FileUtils.readFileToByteArray(theFile));
index 0287b35..2783a8a 100644 (file)
@@ -22,6 +22,7 @@ package org.acumos.federation.gateway.adapter.onap.sdc;
 
 import java.util.Arrays;
 
+import org.springframework.http.HttpStatus;
 import org.springframework.web.client.HttpClientErrorException;
 
 import org.json.JSONObject;
@@ -72,4 +73,10 @@ public class ASDCException extends Exception {
        public String getMessage() {
                return "ASDC " + getASDCMessageId() + " " + getASDCMessage() + "\n" + super.getMessage();
        }
+
+       public static boolean isNotFound(Exception theX) {
+
+               return theX instanceof ASDCException && theX.getCause() instanceof HttpClientErrorException
+                                       && ((HttpClientErrorException) theX.getCause()).getStatusCode() == HttpStatus.NOT_FOUND;
+       }
 }
index 0c10750..b1bdf17 100644 (file)
@@ -75,9 +75,16 @@ public class PeerPingController extends AbstractController {
                log.debug(EELFLoggerDelegate.debugLogger, API.Roots.LOCAL + "" + API.Paths.PING);
                try {
                        MLPPeer peer = this.peerService.getPeerById(thePeerId);
-                       response = this.clients.getFederationClient(peer.getApiUrl()).ping();
-
-                       theHttpResponse.setStatus(HttpServletResponse.SC_OK);
+                       if (peer == null) {
+                               response = JsonResponse.<MLPPeer> buildErrorResponse()
+                                                                                                                                .withMessage("No peer with id " + thePeerId + " found.")
+                                                                                                                                .build();
+                               theHttpResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
+                       }
+                       else {
+                               response = this.clients.getFederationClient(peer.getApiUrl()).ping();
+                               theHttpResponse.setStatus(HttpServletResponse.SC_OK);
+                       }
                } 
                catch (Exception x) {
                        response = JsonResponse.<MLPPeer> buildErrorResponse()
index 4610343..cfce00b 100644 (file)
@@ -119,12 +119,22 @@ public class CatalogServiceLocalImpl extends AbstractServiceLocalImpl implements
 
                log.debug(EELFLoggerDelegate.debugLogger, "getSolutions");
                String modelTypeSelector = theSelector == null ? null : (String) theSelector.get("modelTypeCode");
+               String toolkitTypeSelector = theSelector == null ? null : (String) theSelector.get("toolkitTypeCode");
                final List<String> modelTypes = modelTypeSelector == null ? null : Arrays.asList(modelTypeSelector.split(","));
-               return solutions.stream().filter(solution -> {
-                       log.debug(EELFLoggerDelegate.debugLogger,
-                                       "getPeerCatalogSolutionsList: looking for " + modelTypes + ", has " + solution.getModelTypeCode());
-                       return modelTypes == null || modelTypes.contains(solution.getModelTypeCode());
-               }).collect(Collectors.toList());
+               final List<String> toolkitTypes = toolkitTypeSelector == null ? null : Arrays.asList(toolkitTypeSelector.split(","));
+
+               return solutions.stream()
+                       .filter(solution -> {
+                               log.debug(EELFLoggerDelegate.debugLogger,
+                                       "getPeerCatalogSolutionsList: looking for model type " + modelTypes + ", has " + solution.getModelTypeCode());
+                               return modelTypes == null || modelTypes.contains(solution.getModelTypeCode());
+                       })
+                       .filter(solution -> {
+                               log.debug(EELFLoggerDelegate.debugLogger,
+                                       "getPeerCatalogSolutionsList: looking for toolkit type " + toolkitTypes + ", has " + solution.getToolkitTypeCode());
+                               return toolkitTypes == null || toolkitTypes.contains(solution.getToolkitTypeCode());
+                       })
+                       .collect(Collectors.toList());
        }
 
        @Override
index b206717..e6aeb57 100644 (file)
@@ -182,7 +182,17 @@ public class PeerServiceLocalImpl extends AbstractServiceLocalImpl implements Pe
        /** */
        @Override
        public boolean updatePeerSubscription(MLPPeerSubscription theSub) {
-               throw new UnsupportedOperationException();
+               for (FLPPeer peer : this.peers) {
+                       for (int i = 0; i < peer.getSubscriptions().size(); i++) {
+                               MLPPeerSubscription peerSub = peer.getSubscriptions().get(i);
+                               if (theSub.getSubId().equals(peerSub.getSubId()) &&
+                                               theSub.getPeerId().equals(peerSub.getPeerId())) {
+                                       peer.getSubscriptions().set(i, theSub);
+                                       return true;
+                               }
+                       }
+               }
+               return false;
        }
 
        /** */
index 838eb4c..474172b 100644 (file)
@@ -32,6 +32,8 @@ import org.acumos.federation.gateway.event.PeerSubscriptionEvent;
 import org.acumos.federation.gateway.common.Clients;
 import org.acumos.federation.gateway.common.FederationClient;
 import org.acumos.federation.gateway.util.Utils;
+import org.acumos.federation.gateway.service.PeerSubscriptionService;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.annotation.Scope;
@@ -49,14 +51,16 @@ public class PeerSubscriptionTask implements Runnable {
 
        private final EELFLoggerDelegate log = EELFLoggerDelegate.getLogger(getClass().getName());
 
-       @Autowired
-       private ApplicationEventPublisher eventPublisher;
 
        private MLPPeer peer;
        private MLPPeerSubscription subscription;
 
+       @Autowired
+       private ApplicationEventPublisher eventPublisher;
        @Autowired
        private Clients clients;
+       @Autowired
+       private PeerSubscriptionService peerSubscriptionService;
 
        public PeerSubscriptionTask() {
        }
@@ -98,7 +102,7 @@ public class PeerSubscriptionTask implements Runnable {
                        }
 
                        this.subscription.setProcessed(new Date());
-                       this.clients.getCDSClient().updatePeerSubscription(this.subscription);
+                       this.peerSubscriptionService.updatePeerSubscription(this.subscription);
                }
                catch (Exception x) {
                        log.error(EELFLoggerDelegate.errorLogger, "Peer task failed for " + peer.getName() + ", " + peer.getApiUrl() + ", " + subscription.getSelector(), x);
diff --git a/gateway/src/test/resources/application-onap.properties b/gateway/src/test/resources/application-onap.properties
new file mode 100644 (file)
index 0000000..678ef8c
--- /dev/null
@@ -0,0 +1,24 @@
+federation.addr = 10.0.2.67
+federation.server.port = 9009
+federation.ssl.key-store = src/test/resources/onap.pkcs12
+federation.ssl.key-store-password = onap
+federation.ssl.key-store-type = PKCS12
+federation.ssl.key-password = onap
+federation.ssl.trust-store = src/test/resources/acumosTrustStore.jks
+federation.ssl.trust-store-password = acumos
+federation.ssl.client-auth = need
+
+local.addr = 127.0.0.1
+local.server.port = 9099
+local.ssl.key-store = src/test/resources/onap.pkcs12
+local.ssl.key-store-password = onap
+local.ssl.key-store-type = PKCS12
+local.ssl.key-password = onap
+
+#pretend we are an adapter so that we can use local peer config
+federation.instance=adapter
+federation.instance.name=onap
+
+#replace 
+peersLocal.source=file:///{path_to_src}/acumos/federation/gateway/src/test/resources/onap-peers.json
+catalogLocal.source=file:///{path_to_src}acumos/federation/gateway/src/test/resources/onap-catalog.json
diff --git a/gateway/src/test/resources/onap-catalog.json b/gateway/src/test/resources/onap-catalog.json
new file mode 100644 (file)
index 0000000..fe51488
--- /dev/null
@@ -0,0 +1 @@
+[]
diff --git a/gateway/src/test/resources/onap-peers.json b/gateway/src/test/resources/onap-peers.json
new file mode 100644 (file)
index 0000000..6b6e9e4
--- /dev/null
@@ -0,0 +1,32 @@
+[      {
+               "peerId":"9c579bb5-7304-406a-923c-73566d4ff480",
+               "name":"onap",
+               "subjectName":"gateway.onap.org",
+               "description":"onap",
+               "statusCode":"AC",
+    "self":"true",
+               "apiUrl":"https://gateway.onap.org:9009",
+               "subscriptions":[]
+       },      
+       {
+               "peerId":"babababa-baba-baba-baba-babababababa",
+               "name":"acumosa",
+               "subjectName":"gateway.acumosa.org",
+               "description":"acumosa",
+               "statusCode":"AC",
+    "self":"false",
+               "apiUrl":"https://gateway.acumosa.org:9001",
+               "subscriptions":[
+                       {
+                               "subId":1,
+                   "peerId":"babababa-baba-baba-baba-babababababa",
+                               "selector":"{\"toolkitTypeCode\":\"ON\"}",
+                               "refreshInterval":"120",
+                               "maxArtifactSize":"2048",
+                               "created":"2017-09-21",
+                               "modified":"2017-10-10"
+                       }
+               ]
+       }
+]
+
diff --git a/gateway/src/test/resources/onap.pkcs12 b/gateway/src/test/resources/onap.pkcs12
new file mode 100644 (file)
index 0000000..370c15a
Binary files /dev/null and b/gateway/src/test/resources/onap.pkcs12 differ
diff --git a/gateway/toscalab.xml b/gateway/toscalab.xml
new file mode 100644 (file)
index 0000000..7809da9
--- /dev/null
@@ -0,0 +1,233 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.cognita</groupId>
+  <artifactId>dcae-toscalab</artifactId>
+  <version>1.0.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+
+  <name>dcae-toscalab</name>
+
+       <profiles>
+               <profile>
+                       <id>clone</id>
+                       <activation>
+        <file>
+                                       <!-- <missing>${project.build.directory}/TOSCA_Lab</missing> -->
+                                       <missing>target/TOSCA_Lab</missing>
+               <!-- <missing>target/pyyaml</missing> -->
+                               </file>
+      </activation>
+               <build>
+                               <plugins>
+                                       <plugin>
+                               <groupId>org.codehaus.mojo</groupId>
+                                 <artifactId>exec-maven-plugin</artifactId>
+                               <version>1.6.0</version>
+
+                                               <executions>
+                                                       <execution>
+                                                               <id>toscalab-clone</id>
+                                                               <goals>
+                                                                       <goal>exec</goal>
+                                                               </goals>
+                                                               <phase>generate-resources</phase>
+
+                                                               <configuration>
+                                                                       <executable>git</executable>
+                                                                       <arguments>
+                                                                               <argument>clone</argument>
+                                                                               <argument>-b</argument>
+                                                                               <!-- <argument>master</argument> -->
+                                                                               <argument>acumos</argument>
+                                                                               <argument>--single-branch</argument>
+                                                                               <argument>https://gitlab.research.att.com/shushi/TOSCA_Lab</argument>
+                                                                               <argument>${project.build.directory}/TOSCA_Lab</argument>
+                                                                       </arguments>
+                                                               </configuration>
+                                                       </execution>
+
+                                                       <execution>
+                                                               <id>pyyaml-clone</id>
+                                                               <goals>
+                                                                       <goal>exec</goal>
+                                                               </goals>
+                                                               <phase>generate-resources</phase>
+       
+                                                               <configuration>
+                                                                       <executable>git</executable>
+                                                                       <arguments>
+                                                                               <argument>clone</argument>
+                                                                               <argument>-b</argument>
+                                                                               <argument>master</argument>
+                                                                               <argument>https://github.com/yaml/pyyaml.git</argument>
+                                                                               <argument>${project.build.directory}/pyyaml</argument>
+                                                                       </arguments>
+                                                               </configuration>
+                                                       </execution>
+
+                                                       <execution>
+                                                               <id>setuptools-clone</id>
+                                                               <goals>
+                                                                       <goal>exec</goal>
+                                                               </goals>
+                                                               <phase>generate-resources</phase>
+       
+                                                               <configuration>
+                                                                       <executable>git</executable>
+                                                                       <arguments>
+                                                                               <argument>clone</argument>
+                                                                               <argument>-b</argument>
+                                                                               <argument>master</argument>
+                                                                               <argument>https://github.com/pypa/setuptools.git</argument>
+                                                                               <argument>${project.build.directory}/setuptools</argument>
+                                                                       </arguments>
+                                                               </configuration>
+                                                       </execution>
+       
+
+                                               </executions>
+                                       </plugin>
+
+                               </plugins>
+                       </build>
+               </profile>
+
+               <profile>
+                       <id>pull</id>
+                       <activation>
+        <file><exists>target/TOSCA_lab</exists></file>
+        <!-- <file><exists>${project.build.directory}/TOSCA_lab</exists></file> 
+[WARNING] 'profiles.profile[pull].activation.file.exists' Failed to interpolate file location ${project.build.directory}/TOSCA_lab for profile pull: ${project.*} expressions are not supported during profile activation
+-->
+        <!-- <file><exists>target/pyyaml</exists></file> -->
+      </activation>
+               <build>
+                               <plugins>
+                                       <plugin>
+                               <groupId>org.codehaus.mojo</groupId>
+                                 <artifactId>exec-maven-plugin</artifactId>
+                               <version>1.6.0</version>
+
+                                               <executions>
+                                                       <execution>
+                                                               <id>toscalab-pull</id>
+                                                               <goals>
+                                                                       <goal>exec</goal>
+                                                               </goals>
+                                                               <phase>generate-resources</phase>
+
+                                                               <configuration>
+                                                                       <executable>git</executable>
+                                                                       <workingDirectory>${project.build.directory}/TOSCA_Lab</workingDirectory>
+                                                                       <arguments>
+                                                                               <argument>pull</argument>
+                                                                       </arguments>
+                                                               </configuration>
+                                                       </execution>
+
+                                                       <execution>
+                                                               <id>pyyaml-pull</id>
+                                                               <goals>
+                                                                       <goal>exec</goal>
+                                                               </goals>
+                                                               <phase>generate-resources</phase>
+       
+                                                               <configuration>
+                                                                       <executable>git</executable>
+                                                                       <workingDirectory>${project.build.directory}/pyyaml</workingDirectory>
+                                                                       <arguments>
+                                                                               <argument>pull</argument>
+                                                                       </arguments>
+                                                               </configuration>
+                                                       </execution>
+                                               </executions>
+                                       </plugin>
+
+                               </plugins>
+                       </build>
+               </profile>
+
+       </profiles>
+       
+       <build>
+               <plugins>
+
+                       <plugin>
+                               <artifactId>maven-resources-plugin</artifactId>
+                               <version>3.0.2</version>
+                               <executions>
+                                       <execution>
+            <id>copy-yaml</id>
+            <phase>package</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${project.build.directory}/TOSCA_Lab/yaml</outputDirectory>
+              <resources>          
+                <resource>
+                  <directory>${project.build.directory}/pyyaml/lib/yaml</directory>
+                  <filtering>true</filtering>
+                </resource>
+              </resources>              
+            </configuration>            
+          </execution>
+        </executions>
+      </plugin>
+
+                       <plugin>
+                               <artifactId>maven-resources-plugin</artifactId>
+                               <version>3.0.2</version>
+                               <executions>
+                                       <execution>
+            <id>copy-pkg-resources</id>
+            <phase>package</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${project.build.directory}/TOSCA_Lab/pkg_resources</outputDirectory>
+              <resources>          
+                <resource>
+                  <directory>${project.build.directory}/setuptools/pkg_resources</directory>
+                  <filtering>true</filtering>
+                </resource>
+              </resources>              
+            </configuration>            
+          </execution>
+        </executions>
+      </plugin>
+
+                       <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>3.0.2</version>
+        <executions>
+          <execution>
+                                               <id>package-toscalab</id>
+            <phase>package</phase>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+            <configuration>
+              <classifier>toscalab</classifier>
+              <classesDirectory>${project.build.directory}/TOSCA_Lab</classesDirectory>
+              <!-- <finalName>toscalab.jar</finalName> -->
+                       <includes>
+                       <include>**/*.py</include>
+                       <include>**/meta_model/**/*</include>
+                       <include>**/tosca_model/**/*</include>
+                       <include>**/shared_model/**/*</include>
+                       </includes>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+               </plugins>      
+       </build>
+
+</project>
+