c94b0d020860999a705b795c258f1f5f71a61d45
[federation.git] / gateway / src / main / java / org / acumos / federation / gateway / adapter / onap / ONAP.java
1 /*-
2  * ===============LICENSE_START=======================================================
3  * Acumos
4  * ===================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
6  * ===================================================================================
7  * This Acumos software file is distributed by AT&T and Tech Mahindra
8  * under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *  
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *  
14  * This file is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ===============LICENSE_END=========================================================
19  */
20
21 package org.acumos.federation.gateway.adapter.onap;
22
23 import java.io.ByteArrayInputStream;
24 import java.io.ByteArrayOutputStream;
25 import java.net.URI;
26 import java.time.Instant;
27 import java.util.Collections;
28 import java.util.Comparator;
29 import java.util.HashMap;
30 import java.util.LinkedList;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.UUID;
34
35 import javax.annotation.PostConstruct;
36 import javax.annotation.PreDestroy;
37
38 import org.acumos.cds.domain.MLPArtifact;
39 import org.acumos.cds.domain.MLPPeer;
40 import org.acumos.cds.domain.MLPPeerSubscription;
41 import org.acumos.cds.domain.MLPSolution;
42 import org.acumos.cds.domain.MLPSolutionRevision;
43 import org.acumos.federation.gateway.adapter.onap.sdc.ASDC;
44 import org.acumos.federation.gateway.adapter.onap.sdc.ASDC.ArtifactGroupType;
45 import org.acumos.federation.gateway.adapter.onap.sdc.ASDC.ArtifactType;
46 import org.acumos.federation.gateway.adapter.onap.sdc.ASDC.AssetType;
47 import org.acumos.federation.gateway.adapter.onap.sdc.ASDC.LifecycleState;
48 import org.acumos.federation.gateway.adapter.onap.sdc.ASDCException;
49 import org.acumos.federation.gateway.cds.ArtifactTypes;
50 import org.acumos.federation.gateway.common.Clients;
51 import org.acumos.federation.gateway.common.FederationClient;
52 import org.acumos.federation.gateway.event.PeerSubscriptionEvent;
53 import org.acumos.federation.gateway.util.Utils;
54 import org.json.JSONArray;
55 import org.json.JSONException;
56 import org.json.JSONObject;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59 import org.springframework.beans.factory.BeanInitializationException;
60 import org.springframework.beans.factory.annotation.Autowired;
61 import org.springframework.boot.context.properties.ConfigurationProperties;
62 import org.springframework.context.annotation.Conditional;
63 import org.springframework.context.annotation.Scope;
64 import org.springframework.context.event.EventListener;
65 import org.springframework.core.task.TaskExecutor;
66 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
67 import org.springframework.stereotype.Component;
68 import org.springframework.util.StreamUtils;
69
70 @Component("onap")
71 @Scope("singleton")
72 @ConfigurationProperties(prefix = "onap")
73 @Conditional(ONAPAdapterCondition.class)
74 public class ONAP {
75
76         private final Logger log = LoggerFactory.getLogger(ONAP.class);
77         private ASDC asdc = new ASDC();
78         private String asdcOperator;
79         private TaskExecutor taskExecutor;
80         private ToscaLab        toscalab = new ToscaLab();
81         @Autowired
82         private Clients clients;
83
84         public ONAP() {
85                 log.debug("ONAP::new");
86         }
87
88         public void setSdcUri(URI theUri) {
89                 this.asdc.setUri(theUri);
90         }
91
92         public void setSdcRootPath(String thePath) {
93                 this.asdc.setRootPath(thePath);
94         }
95
96         public void setSdcOperator(String theUid) {
97                 this.asdcOperator = theUid;
98         }
99
100         @PostConstruct
101         public void initOnap() {
102                 log.trace("initOnap");
103
104                 if (this.asdc.getUri() == null)
105                         throw new BeanInitializationException("Forgot to configure the SDC uri ('onap.sdcUri') ??");
106                 if (this.asdcOperator == null)
107                         throw new BeanInitializationException("Forgot to configure the SDC user ('onap.sdcOperator) ??");
108
109                 this.taskExecutor = new ThreadPoolTaskExecutor();
110                 ((ThreadPoolTaskExecutor) this.taskExecutor).setCorePoolSize(1);
111                 ((ThreadPoolTaskExecutor) this.taskExecutor).setMaxPoolSize(1);
112                 ((ThreadPoolTaskExecutor) this.taskExecutor).setQueueCapacity(25);
113                 ((ThreadPoolTaskExecutor) this.taskExecutor).initialize();
114
115                 // temporary
116                 cleanup();
117
118                 // Done
119                 log.trace("Onap available");
120         }
121
122         @PreDestroy
123         public void cleanupOnap() {
124                 log.trace("Onap destroyed");
125         }
126
127         @EventListener
128         public void handlePeerSubscriptionUpdate(PeerSubscriptionEvent theEvent) {
129                 log.info("received peer subscription update event " + theEvent);
130                 taskExecutor.execute(new ONAPPushTask(theEvent.getPeer(), theEvent.getSubscription()));
131         }
132
133         public class ONAPPushTask implements Runnable {
134
135                 private MLPPeer peer;
136                 private MLPPeerSubscription sub;
137
138                 public ONAPPushTask(MLPPeer thePeer, MLPPeerSubscription theSub) {
139                         this.peer = thePeer;
140                         this.sub = theSub;
141                 }
142
143                 public void run() {
144
145                         // list with category and subcategory currently used for onap
146                         // more dynamic mapping to come: based on solution information it will provide
147                         // sdc assettype, category and subcategory
148
149                         Map selector = null;
150                         try {
151                                 selector = Utils.jsonStringToMap(this.sub.getSelector());
152                         }
153                         catch(Exception x) {
154                                 log.error("Failed to parse selector for subscription {}", this.sub);
155                                 return;
156                         }
157                         Instant lastProcessed = this.sub.getProcessed();
158                         if (lastProcessed != null) {
159                                 selector.put("modified", lastProcessed);
160                         }
161                         lastProcessed = Instant.now();
162                         
163                         FederationClient acumosClient = clients.getFederationClient(this.peer.getApiUrl());
164                         if (acumosClient == null) {
165                                 log.error("Failed to get client for peer {}", this.peer);
166                                 return;
167                         }
168
169                         List<MLPSolution> acumosSolutions = null;
170                         try {
171                                 acumosSolutions = (List)acumosClient.getSolutions(selector).getContent();
172                         }
173                         catch(Exception x) {
174                                 log.error("Processing peer " + this.peer + " subscription " + this.sub.getSubId() + ": getSolutions failed.", x);
175                                 return;
176                         }
177                         log.info("Processing peer {} subscription {}, {} yielded solutions {}", this.peer, this.sub.getSubId(), selector, acumosSolutions);
178
179                         JSONArray sdcAssets = null;
180                         try {
181                                 sdcAssets = asdc.getAssets(AssetType.resource, JSONArray.class, "Generic", "Abstract").waitForResult();
182                         }
183                         catch (Exception x) {
184                                 log.error("Failed to list ONAP SDC assets: " + x.getCause(), x);
185                                 // if this is a 404 NotFound, continue, otherwise, fail
186                                 if (ASDCException.isNotFound(x))
187                                         sdcAssets = new JSONArray();
188                                 else
189                                         return;
190                         }
191                         log.info("Mapping received Acumos solutions \n{}\n to retrieved ONAP SDC assets \n{}",
192                         acumosSolutions, sdcAssets);
193
194                         for (MLPSolution acumosSolution : acumosSolutions) {
195
196                                 List<MLPSolutionRevision> acumosRevisions = null;
197                                 try {
198                                         acumosRevisions = (List<MLPSolutionRevision>) acumosClient
199                                                         .getSolutionRevisions(acumosSolution.getSolutionId()).getContent();
200                                 }
201                                 catch (Exception x) {
202                                         log.error("Failed to retrieve acumos revisions", x);
203                                         return;
204                                 }
205                                 sortAcumosSolutionRevisions(acumosRevisions);
206
207                                 try {
208                                         // does the solution already exist in sdc
209                                         JSONObject sdcAsset = lookupSdcAsset(acumosSolution, sdcAssets);
210                                         if (sdcAsset == null) {
211                                                 // new solution
212                                                 sdcAsset = createSdcAsset(acumosSolution, acumosRevisions.get(acumosRevisions.size()-1));
213                                         }
214                                         else {
215                                                 // ONAP.this.asdc.checkoutResource(UUID.fromString(sdcAsset.getString("artifactUUID")),
216                                                 // ONAP.this.asdcOperator, "updated solution import");
217                                                 sdcAsset = updateSdcAsset(sdcAsset, acumosSolution, acumosRevisions);
218                                         }
219                                         updateAssetArtifacts(sdcAsset, acumosSolution, acumosRevisions);
220                                         // ONAP.this.asdc.checkinResource(UUID.fromString(sdcAsset.getString("artifactUUID")),
221                                         // ONAP.this.asdcOperator, "solution imported " + " the acumos revision number
222                                         // ");
223                                 }
224                                 catch (Exception x) {
225                                         log.error("Mapping of acumos solution failed for: " + acumosSolution + ": " + x);
226                                 }
227                         }
228                 }
229
230                 public JSONObject lookupSdcAsset(MLPSolution theSolution, JSONArray theAssets) {
231                         if (theAssets == null || theAssets.length() == 0)
232                                 return null;
233                         for (int i = 0; i < theAssets.length(); i++) {
234                                 JSONObject asset = theAssets.optJSONObject(i);
235                                 if (sameId(theSolution, asset))
236                                         return asset;
237                         }
238                         return null;
239                 }
240
241                 public JSONObject createSdcAsset(MLPSolution theSolution, MLPSolutionRevision theRevision) throws Exception {
242                         log.info("Creating ONAP SDC VF for solution " + theSolution);
243
244                         try {
245                                 return ONAP.this.asdc.createVF()
246                                                 .withCategory("Generic")
247                                                 .withSubCategory("Abstract")
248                                                 .withName(theSolution.getName() + "-" + theSolution.getSolutionId()) // sdc names are unique,
249                                                                                                                                                                                                 // acumos ones not so
250                                                 .withDescription(theSolution.getTags().toString()) //the actual description has moved and is too large to fit in here
251                                                 .withVendorName("Acumos")
252                                                 .withVendorRelease(theRevision.getVersion()) //is this meaningful ? given that it cannot be updated ..
253                                                 .withTags("acumos", theSolution.getSolutionId()) // can I fit an UUID as tag ??
254                                                 .withOperator(ONAP.this.asdcOperator/* theSolution.getOwnerId() */) // probably won't work, SDC
255                                                                                                                                                                                         // expects an att uuid
256                                                 .execute().waitForResult();
257                         }
258                         catch (Exception x) {
259                                 log.error("Failed to create ONAP SDC VF", x);
260                                 throw x;
261                         }
262                 }
263
264                 /**
265                  * There is no such thing as updating an asset in the ASDC REST API, we can only
266                  * update the artifacts ..
267                  * 
268                  * @param theAssetInfo
269                  *            Asset info
270                  * @param theSolution
271                  *            solution
272                  * @param theRevisions revision
273                  * @return SDC Asset info
274                  */
275                 public JSONObject updateSdcAsset(JSONObject theAssetInfo, MLPSolution theSolution, List<MLPSolutionRevision> theRevisions) {
276                         log.info("Updating ONAP SDC VF " + theAssetInfo.optString("uuid") + " for Acumos solution " + theSolution);
277                         return theAssetInfo;
278                 }
279
280                 public void updateAssetArtifacts(JSONObject theAssetInfo, MLPSolution theSolution, List<MLPSolutionRevision> theRevisions)
281                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 throws Exception {
282                         try {
283                                 theAssetInfo = ONAP.this.asdc
284                                                 .getAsset(AssetType.resource, UUID.fromString(theAssetInfo.getString("uuid")), JSONObject.class)
285                                                 .waitForResult();
286                         }
287                         catch (Exception x) {
288                                 log.error("Failed to retrieve ONAP SDC asset metadata for " + theAssetInfo.getString("uuid") + " : " + x);
289                                 throw x;
290                         }
291
292                         JSONArray sdcArtifacts = theAssetInfo.optJSONArray("artifacts");
293                         if (sdcArtifacts == null) {
294                                 sdcArtifacts = new JSONArray();
295                         }
296
297                         //we could have a new model, a new model revision or updates to the currently mapped revision's artifacts.
298                         //currently we always fast-forward to the latest revision available in acumos
299                         MLPSolutionRevision mappedAcumosRevision = theRevisions.get(theRevisions.size() - 1);
300
301                         List<MLPArtifact> acumosArtifacts = null;
302                         try {
303                                 acumosArtifacts = (List<MLPArtifact>) clients.getFederationClient(this.peer.getApiUrl())
304                                         .getArtifacts(theSolution.getSolutionId(), mappedAcumosRevision.getRevisionId())
305                                                 .getContent();
306                         }
307                         catch (Exception x) {
308                                 log.error("Failed to retrieve acumos artifacts" + x);
309                                 throw x;
310                         }
311
312                         if (acumosArtifacts == null)
313                                 acumosArtifacts = new LinkedList<MLPArtifact>();
314
315                         //add an artifact to be mapped for revision tracking purposes
316                         {
317                                 MLPArtifact mapper = new MLPArtifact(mappedAcumosRevision.getVersion(),
318                                                                                                                                 ArtifactTypes.Metadata.getCode(),
319                                                                                                                                 "mapper",
320                                                                                                                                 null,
321                                                                                                                                 "", //owner: never sees CDS so irrelevant 
322                                                                                                                                 0);
323                                 mapper.setArtifactId("0");//a unique value among the other artifacts of this revision
324                                 acumosArtifacts.add(mapper);
325                         }
326
327                         // all this could be better writen but the 2 sets are expected to be small so we
328                         // favor readability
329
330                         //!! we support a 1-to-n mapping of artifacts from Acumos to SDC
331
332                         // acumos artifacts that do not exist locally need to be added
333                         List<MLPArtifact> newArtifacts = new LinkedList<MLPArtifact>();
334                         Map<MLPArtifact, JSONArray> updatedArtifacts = new HashMap<MLPArtifact, JSONArray>();
335                         // List<JSONObject> oldArtifacts = new LinkedList<JSONObject>();
336
337                         log.info("Acumos artifacts: " + acumosArtifacts);
338                         log.info("SDC artifacts: " + sdcArtifacts);
339
340                         for (MLPArtifact acumosArtifact : acumosArtifacts) {
341                                 JSONArray sdcMappedArtifacts = new JSONArray();
342                                 for (int i = 0; i < sdcArtifacts.length(); i++) {
343                                         JSONObject sdcArtifact = sdcArtifacts.getJSONObject(i);
344                                         if (sameId(acumosArtifact, sdcArtifact)) {
345                                                 sdcMappedArtifacts.put(sdcArtifact);
346                                         }
347                                 }
348
349                                 if (sdcMappedArtifacts.length() > 0) {
350                                         //sdc artifacts mapped to the acumos artifacts were found
351                                         //if not at the same version, update
352                                         //TODO: add a coherence check to make sure all sdcArtifacts are at the same (acumos) version
353                                         if (!sameVersion(acumosArtifact, sdcMappedArtifacts.getJSONObject(0))) {
354                                                 updatedArtifacts.put(acumosArtifact, sdcMappedArtifacts);
355                                         }
356                                 }
357                                 else {
358                                         newArtifacts.add(acumosArtifact);
359                                 }
360                         }
361
362                         log.info("New artifacts: " + newArtifacts);
363                         for (MLPArtifact acumosArtifact : newArtifacts) {
364                                 try {
365                                         for (ASDC.ArtifactUploadAction uploadAction:
366                                                                 mapNewArtifact(theAssetInfo, theSolution.getSolutionId(), mappedAcumosRevision.getRevisionId(),
367                                                                                                                          acumosArtifact)) {
368                                                 uploadAction.execute().waitForResult();
369                                         }
370                                 }
371                                 catch (Exception x) {
372                                         log.error("Failed to create ONAP SDC VF Artifacts for " + acumosArtifact, x);
373                                 }
374                         }
375
376                         log.warn("Updated SDC artifacts: " + updatedArtifacts.keySet());
377                         for (Map.Entry<MLPArtifact, JSONArray> updateEntry : updatedArtifacts.entrySet()) {
378                                 MLPArtifact acumosArtifact = updateEntry.getKey();
379                                 try {
380                                         for (ASDC.ArtifactUpdateAction updateAction: 
381                                                                 mapArtifact(theAssetInfo, theSolution.getSolutionId(), mappedAcumosRevision.getRevisionId(),
382                                                                                                                 updateEntry.getKey(), updateEntry.getValue())) {
383                                                 updateAction.execute().waitForResult();
384                                         }
385                                 }
386                                 catch (Exception x) {
387                                         log.error("Failed to update ONAP SDC VF Artifact for " + updateEntry.getKey(), x);
388                                 }
389                         }
390
391                         // sdc artifacts that do not have a acumos counterpart should be deleted (if
392                         // they are labeled as having
393                         // originated in acumos).
394                         List<JSONObject> deletedArtifacts = new LinkedList<JSONObject>();
395                         for (int i = 0; i < sdcArtifacts.length(); i++) {
396                                 JSONObject sdcArtifact = sdcArtifacts.getJSONObject(i);
397                                 boolean found = false;
398                                 for (MLPArtifact acumosArtifact : acumosArtifacts) {
399                                         if (sameId(acumosArtifact, sdcArtifact)) {
400                                                 found = true;
401                                                 break;
402                                         }
403                                 }
404                                 if (!found && isAcumosOriginated(sdcArtifact)) {
405                                         deletedArtifacts.add(sdcArtifact);
406                                 }
407                         }
408                         log.warn("Deleted SDC artifacts: " + deletedArtifacts);
409                         for (JSONObject sdcArtifact : deletedArtifacts) {
410                                 try {
411                                         asdc.deleteAssetArtifact(AssetType.resource, UUID.fromString(theAssetInfo.getString("uuid")),
412                                                         UUID.fromString(sdcArtifact.getString("artifactUUID"))).withOperator(ONAP.this.asdcOperator)
413                                                         .execute().waitForResult();
414                                 }
415                                 catch (Exception x) {
416                                         log.error("Failed to delete ONAP SDC VF Artifact", x);
417                                 }
418                         }
419                 }
420
421                 /**
422                  */
423                 private List<ASDC.ArtifactUploadAction> mapNewArtifact(
424                         JSONObject theSDCAsset,
425                         String theAcumosSolutionId, String theAcumosRevisionId, MLPArtifact theAcumosArtifact) {
426
427                         if (isDCAEComponentSpecification(theAcumosArtifact)) {
428
429                                 byte[] content = null;
430                                 try {
431                                         content = retrieveContent(theAcumosSolutionId, theAcumosRevisionId, theAcumosArtifact);
432                                 }
433                                 catch (Exception x) {
434                                         log.error("Failed to retrieve Acumoms artifact content from " + theAcumosArtifact.getUri(), x);
435                                         return Collections.EMPTY_LIST;
436                                 }
437
438                                 JSONObject models = null;
439                                 try {
440                                         models = new JSONObject(toscalab.create_model(new ByteArrayInputStream(content)));
441                                 }
442                                 catch (JSONException jsonx) {
443                                         log.error("Failed to parse toscalab output", jsonx);
444                                         return Collections.EMPTY_LIST;
445                                 }
446                                 catch (Exception x) {
447                                         log.error("Failed to process DCAE component specification from " + theAcumosArtifact, x);
448                                         return Collections.EMPTY_LIST;
449                                 }
450
451                                 List<ASDC.ArtifactUploadAction> actions = new LinkedList<ASDC.ArtifactUploadAction>();
452                                 for (String model: models.keySet()) {
453                                         actions.add(
454                                                 asdc.createAssetArtifact(AssetType.resource, UUID.fromString(theSDCAsset.getString("uuid")))
455                                                 .withOperator(ONAP.this.asdcOperator)
456                                                 .withEncodedContent(models.getString(model))
457                                                 .withLabel(theAcumosArtifact.getArtifactTypeCode())
458                                                 .withName(model/*theAcumosArtifact.getName()*/)
459                                                 .withDisplayName(theAcumosArtifact.getMetadata())
460                                                 .withType(ArtifactType.DCAE_TOSCA/*ArtifactType.OTHER*/)
461                                                 .withGroupType(ArtifactGroupType.DEPLOYMENT)
462                                                 .withDescription(theAcumosArtifact.getArtifactId() + "@" + theAcumosArtifact.getVersion())
463                                         );
464                                 }
465                                 return actions;
466                         }
467                         else if (isMapper(theAcumosArtifact)) {
468                                 return Collections.singletonList(
469                                         asdc.createAssetArtifact(AssetType.resource, UUID.fromString(theSDCAsset.getString("uuid")))
470                                                 .withOperator(ONAP.this.asdcOperator)
471                                                 .withContent("{}".getBytes())
472                                                 .withLabel(theAcumosArtifact.getArtifactTypeCode())
473                                                 .withName(theAcumosArtifact.getName())
474                                                 .withDisplayName("mapper")
475                                                 .withType(ArtifactType.OTHER)
476                                                 .withGroupType(ArtifactGroupType.DEPLOYMENT)
477                                                 .withDescription(theAcumosArtifact.getArtifactId() + "@" + theAcumosArtifact.getVersion())
478                                 );
479                         } 
480                         else {
481                                 //everything else gets ignored at this point
482                                 return Collections.EMPTY_LIST;
483                         }
484                 }
485                 
486                 private List<ASDC.ArtifactUpdateAction> mapArtifact(
487                         JSONObject theSDCAsset, String theAcumosSolutionId, String theAcumosRevisionId,
488                         MLPArtifact theAcumosArtifact, JSONArray theSDCArtifacts) {
489                         
490                         if (isDCAEComponentSpecification(theAcumosArtifact)) {
491                                 byte[] content = null;
492                                 try {
493                                         content = retrieveContent(theAcumosSolutionId, theAcumosRevisionId, theAcumosArtifact);
494                                 }
495                                 catch (Exception x) {
496                                         log.error("Failed to retrieve Acumoms artifact content from " + theAcumosArtifact.getUri(), x);
497                                         return Collections.EMPTY_LIST;
498                                 }
499
500                                 JSONObject models = null;
501                                 try {
502                                         models = new JSONObject(toscalab.create_model(new ByteArrayInputStream(content)));
503                                 }
504                                 catch (JSONException jsonx) {
505                                         log.error("Failed to parse toscalab output", jsonx);
506                                         return Collections.EMPTY_LIST;
507                                 }
508                                 catch (Exception x) {
509                                         log.error("Failed to process DCAE component specification from " + theAcumosArtifact, x);
510                                         return Collections.EMPTY_LIST;
511                                 }
512
513                                 List<ASDC.ArtifactUpdateAction> actions = new LinkedList<ASDC.ArtifactUpdateAction>();
514                                 for (int i = 0; i < theSDCArtifacts.length(); i++) {
515                                         JSONObject sdcArtifact = theSDCArtifacts.getJSONObject(i);
516                                         actions.add(
517                                                 asdc.updateAssetArtifact(AssetType.resource, UUID.fromString(theSDCAsset.getString("uuid")), sdcArtifact)
518                                                         .withOperator(ONAP.this.asdcOperator)
519                                                         .withEncodedContent(models.getString(sdcArtifact.getString("name")))
520                                                         .withName(sdcArtifact.getString("name"))
521                                                         .withDescription(theAcumosArtifact.getArtifactId() + "@"        + theAcumosArtifact.getVersion())
522                                         );
523                                 }
524                                 return actions;
525                         }
526                         else if (isMapper(theAcumosArtifact)) {
527                                 if (theSDCArtifacts.length() != 1)
528                                         log.warn("Found more than one mapper artifact {}", theSDCArtifacts);
529                                 return Collections.singletonList(
530                                                 asdc.updateAssetArtifact(AssetType.resource, UUID.fromString(theSDCAsset.getString("uuid")), theSDCArtifacts.getJSONObject(0))
531                                                         .withOperator(ONAP.this.asdcOperator)
532                                                         .withName(theAcumosArtifact.getName())
533                                                         .withDescription(theAcumosArtifact.getArtifactId() + "@"        + theAcumosArtifact.getVersion()));
534                         } 
535                         else {
536                                 log.error("Found sdc artifacts for mlp artifact we do not process {}: {} ", theAcumosArtifact, theSDCArtifacts);
537                                 return Collections.EMPTY_LIST;
538                         }
539                 }
540
541                 private boolean isDCAEComponentSpecification(MLPArtifact theArtifact) {
542                         return theArtifact.getName().equals("component-specification.json");
543                 }
544                 
545                 private boolean isMapper(MLPArtifact theArtifact) {
546                         return theArtifact.getName().equals("mapper");
547                 }
548
549                 private boolean sameId(MLPSolution theAcumosSolution, JSONObject theSDCAsset) {
550
551                         return theSDCAsset.optString("name", "")
552                                         .equals(theAcumosSolution.getName() + "-" + theAcumosSolution.getSolutionId());
553                 }
554
555                 private boolean sameId(MLPArtifact theAcumosArtifact, JSONObject theSDCArtifact) {
556                         return acumosArtifactId(theSDCArtifact).equals(theAcumosArtifact.getArtifactId());
557                 }
558
559                 /*
560                  * Only safe to call if 'same' returned true
561                  */
562                 private boolean sameVersion(MLPArtifact theAcumosArtifact, JSONObject theSDCArtifact) {
563                         return acumosArtifactVersion(theSDCArtifact).equals(theAcumosArtifact.getVersion());
564                 }
565
566                 private String acumosArtifactId(JSONObject theSDCArtifact) {
567                         return theSDCArtifact.optString("artifactDescription","@").split("@")[0];
568                 }
569
570                 private String acumosArtifactVersion(JSONObject theSDCArtifact) {
571                         return theSDCArtifact.optString("artifactDescription","@").split("@")[1];
572                 }
573
574                 private boolean isAcumosOriginated(JSONObject theSDCArtifact) {
575                         boolean isAcumos = theSDCArtifact.optString("artifactType").equals(ArtifactType.OTHER.toString())
576                                         && theSDCArtifact.optString("artifactGroupType").equals(ArtifactGroupType.DEPLOYMENT.toString());
577                         String[] parts = theSDCArtifact.optString("artifactDescription", "@").split("@");
578                         isAcumos &= (parts.length == 2); // and the first part can be parsed as an UUID
579                         return isAcumos;
580                 }
581
582                 private byte[] retrieveContent(
583                         String theAcumosSolutionId, String theAcumosRevisionId, MLPArtifact theAcumosArtifact)
584                                                                                                                                                                                                                                                                                                                                                         throws Exception {
585                         if (this.peer.isLocal()) {
586                                 return clients.getNexusClient().getForObject(theAcumosArtifact.getUri(), byte[].class);
587                         }
588                         else { //non-local peer
589                                 ByteArrayOutputStream bos = new ByteArrayOutputStream();
590                                 StreamUtils.copy(
591                                         clients.getFederationClient(this.peer.getApiUrl())
592                                                 .getArtifactContent(theAcumosSolutionId, theAcumosRevisionId, theAcumosArtifact.getArtifactId())
593                                                         .getInputStream(),
594                                         bos);
595                                 return bos.toByteArray();
596                         }
597                         //else {
598                         //      return IOUtils.toByteArray(new URI(theAcumosArtifact.getUri()));
599                         //}
600                 }
601         }
602
603
604         /**
605          * Removes all (non-commited) Acumos solutions imported into ONAP SDC
606          */
607         protected void cleanup() {
608
609                 JSONArray sdcAssets = null;
610                 try {
611                         sdcAssets = asdc.getAssets(AssetType.resource, JSONArray.class, "Generic", "Abstract").waitForResult();
612                 } catch (Throwable x) {
613                         log.info("Cleanup failed to list ONAP SDC assets: " + x.getCause(), x);
614                 }
615
616                 if (sdcAssets == null)
617                         return;
618
619                 for (int i = 0; i < sdcAssets.length(); i++) {
620                         JSONObject sdcAsset = sdcAssets.optJSONObject(i);
621                         String state = sdcAsset.optString("lifecycleState");
622                         if (state != null && "NOT_CERTIFIED_CHECKEOUT".equals(state)) {
623                                 try {
624                                         asdc.cycleAsset(AssetType.resource, UUID.fromString(sdcAsset.getString("uuid")),
625                                                         LifecycleState.undocheckout, ONAP.this.asdcOperator, null).waitForResult();
626                                 }
627                                 catch (Exception x) {
628                                         log.error("Cleanup ONAP SDC asset: " + sdcAsset.optString("uuid"), x);
629                                 }
630                         }
631                 }
632
633         }
634         
635         /** */
636         private void sortAcumosSolutionRevisions(List<MLPSolutionRevision> theRevisions) {
637
638                 Collections.sort(theRevisions,
639                                                                                  new Comparator<MLPSolutionRevision>() {
640                                                                                         @Override
641                                                                                         public int compare(MLPSolutionRevision theFirst, MLPSolutionRevision theSecond) {
642                                                                                                 return String.CASE_INSENSITIVE_ORDER.compare(theFirst.getVersion(), theSecond.getVersion());
643                                                                                         }
644                                                                                  });
645                                                                                 
646         }
647 }