Initial OpenECOMP A&AI Model Loader commit
[aai/model-loader.git] / src / main / java / org / openecomp / modelloader / entity / catalog / VnfCatalogArtifactHandler.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * MODEL LOADER SERVICE
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License 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.openecomp.modelloader.entity.catalog;
22
23 import com.sun.jersey.api.client.ClientResponse;
24
25 import generated.VnfCatalog;
26 import generated.VnfCatalog.PartNumberList;
27
28 import inventory.aai.openecomp.org.v8.VnfImage;
29
30 import org.eclipse.persistence.jaxb.MarshallerProperties;
31 import org.openecomp.cl.api.Logger;
32 import org.openecomp.cl.eelf.LoggerFactory;
33 import org.openecomp.modelloader.config.ModelLoaderConfig;
34 import org.openecomp.modelloader.entity.Artifact;
35 import org.openecomp.modelloader.entity.ArtifactHandler;
36 import org.openecomp.modelloader.restclient.AaiRestClient;
37 import org.openecomp.modelloader.restclient.AaiRestClient.MimeType;
38 import org.openecomp.modelloader.service.ModelLoaderMsgs;
39
40 import java.io.StringReader;
41 import java.io.StringWriter;
42 import java.util.ArrayList;
43 import java.util.List;
44 import java.util.UUID;
45
46 import javax.ws.rs.core.Response;
47 import javax.xml.bind.JAXBContext;
48 import javax.xml.bind.JAXBException;
49 import javax.xml.bind.Marshaller;
50 import javax.xml.bind.Unmarshaller;
51
52
53 public class VnfCatalogArtifactHandler extends ArtifactHandler {
54
55   private static Logger logger = LoggerFactory.getInstance()
56       .getLogger(VnfCatalogArtifactHandler.class.getName());
57
58   public VnfCatalogArtifactHandler(ModelLoaderConfig config) {
59     super(config);
60   }
61
62   @Override
63   public boolean pushArtifacts(List<Artifact> artifacts, String distributionId) {
64     for (Artifact art : artifacts) {
65       VnfCatalogArtifact vnfCatalog = (VnfCatalogArtifact) art;
66       String artifactPayload = vnfCatalog.getPayload();
67
68       AaiRestClient restClient = new AaiRestClient(this.config);
69       List<VnfImage> putImages = new ArrayList<VnfImage>();
70
71       try {
72         JAXBContext inputContext = JAXBContext.newInstance(VnfCatalog.class);
73         Unmarshaller unmarshaller = inputContext.createUnmarshaller();
74         StringReader reader = new StringReader(artifactPayload);
75         VnfCatalog cat = (VnfCatalog) unmarshaller.unmarshal(reader);
76
77         int numParts = cat.getPartNumberList().size();
78
79         for (int i = 0; i < numParts; i++) {
80
81           PartNumberList pnl = cat.getPartNumberList().get(i);
82
83           String application = pnl.getVendorInfo().getVendorModel();
84           String applicationVendor = pnl.getVendorInfo().getVendorName();
85
86           int numVersions = pnl.getSoftwareVersionList().size();
87
88           for (int j = 0; j < numVersions; j++) {
89             String applicationVersion = pnl.getSoftwareVersionList().get(j).getSoftwareVersion();
90
91             String imageId = "vnf image " + applicationVendor + " " + application + " "
92                 + applicationVersion;
93
94             String getUrl = config.getAaiBaseUrl() + config.getAaiVnfImageUrl()
95                 + "?application-vendor=" + applicationVendor + "&application=" + application
96                 + "&application-version=" + applicationVersion;
97
98             ClientResponse tryGet = restClient.getResource(getUrl, distributionId, MimeType.JSON);
99             if (tryGet == null) {
100               logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
101                   "Ingestion failed on " + imageId + ". Rolling back distribution.");
102               failureCleanup(putImages, restClient, distributionId);
103               return false;
104             }
105             if (tryGet.getStatus() == Response.Status.NOT_FOUND.getStatusCode()) {
106               // this vnf-image not already in the db, need to add
107               // only do this on 404 bc other error responses could mean there
108               // are problems that
109               // you might not want to try to PUT against
110
111               VnfImage image = new VnfImage();
112               image.setApplication(application);
113               image.setApplicationVendor(applicationVendor);
114               image.setApplicationVersion(applicationVersion);
115               String uuid = UUID.randomUUID().toString();
116               image.setUuid(uuid); // need to create uuid
117
118               System.setProperty("javax.xml.bind.context.factory",
119                   "org.eclipse.persistence.jaxb.JAXBContextFactory");
120               JAXBContext jaxbContext = JAXBContext.newInstance(VnfImage.class);
121               Marshaller marshaller = jaxbContext.createMarshaller();
122               marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
123               marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false);
124               marshaller.setProperty(MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, true);
125               marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
126               StringWriter writer = new StringWriter();
127               marshaller.marshal(image, writer);
128               String payload = writer.toString();
129
130               String putUrl = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/"
131                   + uuid;
132
133               ClientResponse putResp = restClient.putResource(putUrl, payload, distributionId,
134                   MimeType.JSON);
135               if (putResp == null
136                   || putResp.getStatus() != Response.Status.CREATED.getStatusCode()) {
137                 logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
138                     "Ingestion failed on vnf-image " + imageId + ". Rolling back distribution.");
139                 failureCleanup(putImages, restClient, distributionId);
140                 return false;
141               }
142               putImages.add(image);
143               logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, imageId + " successfully ingested.");
144             } else if (tryGet.getStatus() == Response.Status.OK.getStatusCode()) {
145               logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT,
146                   imageId + " already exists.  Skipping ingestion.");
147             } else {
148               // if other than 404 or 200, something went wrong
149               logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
150                   "Ingestion failed on vnf-image " + imageId + " with status " + tryGet.getStatus()
151                       + ". Rolling back distribution.");
152               failureCleanup(putImages, restClient, distributionId);
153               return false;
154             }
155           }
156         }
157
158       } catch (JAXBException e) {
159         logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
160             "Ingestion failed. " + e.getMessage() + ". Rolling back distribution.");
161         failureCleanup(putImages, restClient, distributionId);
162         return false;
163       }
164     }
165
166     return true;
167   }
168
169   /*
170    * if something fails in the middle of ingesting the catalog we want to
171    * rollback any changes to the db
172    */
173   private void failureCleanup(List<VnfImage> putImages, AaiRestClient restClient, String transId) {
174     for (VnfImage image : putImages) {
175       String url = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/"
176           + image.getUuid();
177       restClient.getAndDeleteResource(url, transId); // try to delete the image,
178                                                      // if something goes wrong
179                                                      // we can't really do
180                                                      // anything here
181     }
182   }
183
184 }