Catalog alignment
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / RepresentationUtils.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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.sdc.be.servlets;
22
23 import com.fasterxml.jackson.annotation.JsonFilter;
24 import com.fasterxml.jackson.annotation.JsonInclude;
25 import com.fasterxml.jackson.databind.DeserializationFeature;
26 import com.fasterxml.jackson.databind.ObjectMapper;
27 import com.fasterxml.jackson.databind.SerializationFeature;
28 import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter.SerializeExceptFilter;
29 import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
30 import com.google.common.collect.ImmutableMap;
31 import com.google.gson.Gson;
32 import com.google.gson.JsonElement;
33 import com.google.gson.JsonObject;
34 import org.apache.commons.lang.StringUtils;
35 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
36 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
37 import org.openecomp.sdc.be.config.BeEcompErrorManager;
38 import org.openecomp.sdc.be.dao.api.ActionStatus;
39 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
40 import org.openecomp.sdc.be.model.ArtifactDefinition;
41 import org.openecomp.sdc.be.model.InterfaceDefinition;
42 import org.openecomp.sdc.be.model.Resource;
43 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
44 import org.openecomp.sdc.common.api.Constants;
45 import org.openecomp.sdc.common.log.wrappers.Logger;
46
47 import java.io.IOException;
48 import java.util.ArrayList;
49 import java.util.Collection;
50 import java.util.HashMap;
51 import java.util.HashSet;
52 import java.util.List;
53 import java.util.Set;
54
55 public class RepresentationUtils {
56
57     private static final Logger log = Logger.getLogger(RepresentationUtils.class);
58
59     public static ArtifactDefinition convertJsonToArtifactDefinitionForUpdate(String content, Class<ArtifactDefinition> clazz) {
60
61         JsonObject jsonElement = new JsonObject();
62         ArtifactDefinition resourceInfo = null;
63
64         try {
65             Gson gson = new Gson();
66             jsonElement = gson.fromJson(content, jsonElement.getClass());
67             String payload = null;
68             jsonElement.remove(Constants.ARTIFACT_GROUP_TYPE);
69             //in update the group type is ignored but this spagheti code makes it too complex to remove this field.
70             jsonElement.addProperty(Constants.ARTIFACT_GROUP_TYPE, ArtifactGroupTypeEnum.INFORMATIONAL.getType());
71             JsonElement artifactPayload = jsonElement.get(Constants.ARTIFACT_PAYLOAD_DATA);
72             if (artifactPayload != null && !artifactPayload.isJsonNull()) {
73                 payload = artifactPayload.getAsString();
74             }
75             jsonElement.remove(Constants.ARTIFACT_PAYLOAD_DATA);
76             String json = gson.toJson(jsonElement);
77             ObjectMapper mapper = new ObjectMapper();
78             mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
79             mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
80             mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
81
82             resourceInfo = mapper.readValue(json, clazz);
83             resourceInfo.setPayloadData(payload);
84
85         } catch (Exception e) {
86             BeEcompErrorManager.getInstance().logBeArtifactInformationInvalidError("Artifact Upload / Update");
87             log.debug("Failed to convert the content {} to object.", content.substring(0, Math.min(50, content.length())), e);
88         }
89
90         return resourceInfo;
91     }
92
93
94     public static class ResourceRep {
95
96     }
97
98     /**
99      * Build Representation of given Object
100      *
101      * @param elementToRepresent
102      * @return
103      * @throws IOException
104      */
105     public static <T> Object toRepresentation(T elementToRepresent) throws IOException {
106
107         ObjectMapper mapper = new ObjectMapper();
108         mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
109         mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
110         return mapper.writeValueAsString(elementToRepresent);
111     }
112
113     public static <T> T fromRepresentation(String json, Class<T> clazz) {
114         ObjectMapper mapper = new ObjectMapper();
115         T object = null;
116         mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
117         mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
118         mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
119         try {
120             object = mapper.readValue(json, clazz);
121         } catch (Exception e) {
122             log.error("Error when parsing JSON of object of type {}", clazz.getSimpleName(), e);
123         } // return null in case of exception
124
125         return object;
126     }
127
128     public static ArtifactDefinition convertJsonToArtifactDefinition(String content, Class<ArtifactDefinition> clazz, boolean validateTimeout) {
129
130         JsonObject jsonElement = new JsonObject();
131         ArtifactDefinition resourceInfo = null;
132
133         if (StringUtils.isEmpty(content)) {
134             throw new ByActionStatusComponentException(ActionStatus.MISSING_BODY);
135         }
136
137         try {
138             Gson gson = new Gson();
139             jsonElement = gson.fromJson(content, jsonElement.getClass());
140             JsonElement artifactGroupValue = jsonElement.get(Constants.ARTIFACT_GROUP_TYPE);
141             HashMap<String, JsonElement> elementsToValidate = new HashMap<>();
142             elementsToValidate.put(Constants.ARTIFACT_GROUP_TYPE, artifactGroupValue);
143             elementsToValidate.put(Constants.ARTIFACT_TYPE, jsonElement.get(Constants.ARTIFACT_TYPE));
144             elementsToValidate.put(Constants.ARTIFACT_LABEL, (jsonElement.get(Constants.ARTIFACT_LABEL)));
145             if (validateTimeout) {
146                 elementsToValidate.put(Constants.ARTIFACT_TIMEOUT, jsonElement.get(Constants.ARTIFACT_TIMEOUT));
147             }
148             validateMandatoryProperties(elementsToValidate);
149
150             if (artifactGroupValue != null && !artifactGroupValue.isJsonNull()) {
151                 String groupValueUpper = artifactGroupValue.getAsString().toUpperCase();
152                 if (!ArtifactGroupTypeEnum.getAllTypes().contains(groupValueUpper)) {
153                     StringBuilder sb = new StringBuilder();
154                     for (String value : ArtifactGroupTypeEnum.getAllTypes()) {
155                         sb.append(value).append(", ");
156                     }
157                     log.debug("artifactGroupType is {}. valid values are: {}", groupValueUpper, sb);
158                     return null;
159                 } else {
160                     jsonElement.remove(Constants.ARTIFACT_GROUP_TYPE);
161                     jsonElement.addProperty(Constants.ARTIFACT_GROUP_TYPE, groupValueUpper);
162                 }
163             }
164             String payload = null;
165             JsonElement artifactPayload = jsonElement.get(Constants.ARTIFACT_PAYLOAD_DATA);
166             if (artifactPayload != null && !artifactPayload.isJsonNull()) {
167                 payload = artifactPayload.getAsString();
168             }
169             jsonElement.remove(Constants.ARTIFACT_PAYLOAD_DATA);
170             String json = gson.toJson(jsonElement);
171             ObjectMapper mapper = new ObjectMapper();
172             mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
173             mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
174             mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
175
176             resourceInfo = mapper.readValue(json, clazz);
177             resourceInfo.setPayloadData(payload);
178
179         } catch (ComponentException ce) {
180             BeEcompErrorManager.getInstance().logBeArtifactInformationInvalidError("Artifact Upload / Update");
181             log.debug("Failed to convert the content {} to object.", content.substring(0, Math.min(50, content.length())), ce);
182             throw ce;
183         }
184         catch (Exception e) {
185             BeEcompErrorManager.getInstance().logBeArtifactInformationInvalidError("Artifact Upload / Update");
186             log.debug("Failed to convert the content {} to object.", content.substring(0, Math.min(50, content.length())), e);
187         }
188
189         return resourceInfo;
190     }
191
192     private static void validateMandatoryProperties(HashMap<String, JsonElement> elementsByName) {
193         elementsByName.forEach((name, element) -> {
194             if (element == null) {
195                 throw new ByActionStatusComponentException(ActionStatus.MISSING_MANDATORY_PROPERTY, name);
196             }
197             if (element.isJsonNull()) {
198                 throw new ByActionStatusComponentException(ActionStatus.MANDATORY_PROPERTY_MISSING_VALUE, name);
199             }
200         });
201     }
202
203     public static <T> Object toFilteredRepresentation(T elementToRepresent) throws IOException {
204         ObjectMapper mapper = new ObjectMapper();
205         mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
206         mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
207         mapper.setMixIns(IS_EMPTY_FILTER_MIXIN);
208         return mapper.writer(new SimpleFilterProvider().addFilter(REMOVE_IS_EMPTY_FROM_COLLECTIONS_FILTER,
209                 SerializeExceptFilter.serializeAllExcept(EMPTY))).writeValueAsString(elementToRepresent);
210     }
211
212     @JsonFilter(REMOVE_IS_EMPTY_FROM_COLLECTIONS_FILTER)
213     private static class IsEmptyFilterMixIn {}
214
215     private static final String EMPTY = "empty";
216     private static final String REMOVE_IS_EMPTY_FROM_COLLECTIONS_FILTER = "removeIsEmptyFromCollections";
217     private static final ImmutableMap<Class<?>,Class<?>> IS_EMPTY_FILTER_MIXIN =
218             ImmutableMap.<Class<?>,Class<?>>builder()
219                     .put(Collection.class,IsEmptyFilterMixIn.class)
220                     .put(List.class,IsEmptyFilterMixIn.class)
221                     .put(Set.class,IsEmptyFilterMixIn.class)
222                     .put(HashMap.class,IsEmptyFilterMixIn.class)
223                     .put(ArrayList.class,IsEmptyFilterMixIn.class)
224                     .put(HashSet.class,IsEmptyFilterMixIn.class)
225                     .put(InterfaceDefinition.class,IsEmptyFilterMixIn.class)
226                     .put(Resource.class,IsEmptyFilterMixIn.class)
227                     .put(ToscaDataDefinition.class,IsEmptyFilterMixIn.class)
228                     .build();
229
230 }