2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 2017 Amdocs
7 * ================================================================================
8 * Licensed 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
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
21 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
23 package org.onap.aai.sparky.editattributes;
26 import java.util.HashMap;
27 import java.util.List;
29 import java.util.regex.Matcher;
30 import java.util.regex.Pattern;
32 import javax.ws.rs.core.UriBuilder;
34 import org.eclipse.persistence.dynamic.DynamicType;
35 import org.onap.aai.cl.api.Logger;
36 import org.onap.aai.cl.eelf.LoggerFactory;
37 import org.onap.aai.restclient.client.OperationResult;
38 import org.onap.aai.sparky.config.oxm.OxmEntityLookup;
39 import org.onap.aai.sparky.config.oxm.OxmModelLoader;
40 import org.onap.aai.sparky.dal.ActiveInventoryAdapter;
41 import org.onap.aai.sparky.dal.aai.config.ActiveInventoryConfig;
42 import org.onap.aai.sparky.editattributes.exception.AttributeUpdateException;
43 import org.onap.aai.sparky.logging.AaiUiMsgs;
45 import com.fasterxml.jackson.core.JsonProcessingException;
46 import com.fasterxml.jackson.databind.ObjectMapper;
47 import com.fasterxml.jackson.databind.ObjectWriter;
48 import com.fasterxml.jackson.databind.PropertyNamingStrategy;
51 * Class to process attribute updates on AAI objects.
55 public class AttributeUpdater {
58 * The Class AaiEditObject.
60 public class AaiEditObject {
68 * Instantiates a new aai edit object.
70 public AaiEditObject() {
75 * Instantiates a new aai edit object.
77 * @param objectType the object type
78 * @param idName the id name
79 * @param schemaVersion the schema version
81 public AaiEditObject(String objectType, String idName, String schemaVersion) {
83 this.objectType = objectType;
84 this.keyName = idName;
85 this.schemaVersion = schemaVersion;
88 public String getObjectType() {
92 public void setObjectType(String objectType) {
93 this.objectType = objectType;
96 public String getKeyName() {
100 public void setKeyName(String idName) {
101 this.keyName = idName;
104 public String getSchemaVersion() {
105 return schemaVersion;
108 public void setSchemaVersion(String schemaVersion) {
109 this.schemaVersion = schemaVersion;
112 public void setKeyValue(String keyValue) {
113 this.keyValue = keyValue;
116 public String getKeyValue() {
120 public String getRootElement() {
124 public void setRootElement(String rootElement) {
125 this.rootElement = rootElement;
130 private static final Logger LOG = LoggerFactory.getInstance().getLogger(AttributeUpdater.class);
131 private static final String MESSAGE_VERSION_EXTRACTION_REGEX = "\\/(v[0-9]+)";
132 private static final String ATTRIBUTES_UPDATED_SUCCESSFULLY = "Attributes updated successfully";
133 private static final String ATTRIBUTES_NOT_UPDATED = "Attributes not updated. ";
134 private ActiveInventoryConfig aaiConfig;
135 private ActiveInventoryAdapter aaiAdapter;
136 private UserValidator validator;
137 private OxmModelLoader oxmModelLoader;
138 private OxmEntityLookup oxmEntityLookup;
141 * Instantiates a new attribute updater.
143 * @throws AttributeUpdateException
145 public AttributeUpdater(OxmModelLoader oxmModelLoader, OxmEntityLookup oxmEntityLookup,
146 ActiveInventoryAdapter activeInventoryAdapter) throws AttributeUpdateException {
148 this.oxmModelLoader = oxmModelLoader;
149 this.oxmEntityLookup = oxmEntityLookup;
150 this.aaiAdapter = activeInventoryAdapter;
153 this.aaiConfig = ActiveInventoryConfig.getConfig(); // TODO -> Config to become a bean
154 this.validator = new UserValidator();
155 } catch (Exception exc) {
156 LOG.error(AaiUiMsgs.ATTRIBUTES_ERROR_GETTING_AAI_CONFIG_OR_ADAPTER,
157 exc.getLocalizedMessage());
158 throw new AttributeUpdateException(exc);
162 protected String getResourceBasePath() {
164 String versionStr = null;
165 if (oxmModelLoader != null) {
166 versionStr = String.valueOf(oxmModelLoader.getLatestVersionNum());
169 return "/aai/v" + versionStr;
173 protected URI getBaseUri() {
174 return UriBuilder.fromUri("https://" + aaiConfig.getAaiRestConfig().getHost() + ":"
175 + aaiConfig.getAaiRestConfig().getPort() + getResourceBasePath()).build();
179 * Update object attribute.
181 * @param objectUri - Valid URI of the object as per OXM model.
182 * @param attributeValues - Map of (attribute-name & attribute-value) for any attributes to be
183 * updated to the value.
184 * @param attUid - ATTUID of the user requesting the update.
185 * @return - OperationResult with success or failure reason.
187 public OperationResult updateObjectAttribute(String objectUri,
188 Map<String, Object> attributeValues, String attUid) {
189 OperationResult result = new OperationResult();
190 LOG.info(AaiUiMsgs.ATTRIBUTES_UPDATE_METHOD_CALLED, objectUri, attUid,
191 String.valueOf(attributeValues));
192 if (!validator.isAuthorizedUser(attUid)) {
193 result.setResultCode(403);
194 result.setResult(String.format("User %s is not authorized for Attributes update ", attUid));
195 LOG.error(AaiUiMsgs.ATTRIBUTES_USER_NOT_AUTHORIZED_TO_UPDATE, attUid);
199 AaiEditObject object = null;
202 object = getEditObjectFromUri(objectUri);
203 } catch (AttributeUpdateException exc) {
204 result.setResultCode(400);
205 result.setResult(ATTRIBUTES_NOT_UPDATED);
206 LOG.error(AaiUiMsgs.ATTRIBUTES_NOT_UPDATED_EXCEPTION, exc.getLocalizedMessage());
210 String jsonPayload = convertEditRequestToJson(object, attributeValues);
211 String patchUri = getBaseUri().toString() + getRelativeUri(objectUri);
215 * FIX ME: Dave Adams, 8-Nov-2017
218 // result = aaiAdapter.doPatch(patchUri, jsonPayload, MediaType.APPLICATION_JSON);
220 result = new OperationResult();
221 result.setResultCode(404);
223 if (result.getResultCode() == 200) {
224 result.setResult(ATTRIBUTES_UPDATED_SUCCESSFULLY);
225 String message = result.getResult() + " for " + objectUri;
226 LOG.info(AaiUiMsgs.INFO_GENERIC, message);
229 ATTRIBUTES_NOT_UPDATED + " For: " + objectUri + ". AAI PATCH Status Code : "
230 + result.getResultCode() + ". Error : " + result.getResult();
231 LOG.error(AaiUiMsgs.ATTRIBUTES_NOT_UPDATED_MESSAGE, message);
233 } catch (AttributeUpdateException exc) {
234 result.setResultCode(500);
235 result.setResult(ATTRIBUTES_NOT_UPDATED + exc.getLocalizedMessage());
236 LOG.error(AaiUiMsgs.ATTRIBUTES_NOT_UPDATED_EXCEPTION, exc.getLocalizedMessage());
243 * Gets the relative uri.
245 * @param objectUri the object uri
246 * @return the relative uri
248 public String getRelativeUri(String objectUri) {
249 String tempUri = objectUri;
250 final Pattern pattern = Pattern.compile(MESSAGE_VERSION_EXTRACTION_REGEX, Pattern.DOTALL);
251 Matcher matcher = pattern.matcher(objectUri);
252 while (matcher.find()) {
253 tempUri = objectUri.substring(matcher.end());
255 if (!tempUri.startsWith("/")) {
256 tempUri = "/" + tempUri;
262 * Gets the edits the object from uri.
264 * @param objectUri the object uri
265 * @return the edits the object from uri
266 * @throws AttributeUpdateException the attribute update exception
268 public AaiEditObject getEditObjectFromUri(String objectUri) throws AttributeUpdateException {
270 AaiEditObject object = new AaiEditObject();
271 String version = getVersionFromUri(objectUri);
273 if (null == version) {
274 version = "v" + String.valueOf(oxmModelLoader.getLatestVersionNum());
276 object.setSchemaVersion(version);
278 String[] values = objectUri.split("/");
279 if (values.length < 2) {
280 throw new AttributeUpdateException("Invalid or malformed object URI : " + objectUri);
282 String keyValue = values[values.length - 1];
283 String rootElement = values[values.length - 2];
285 object.setKeyValue(keyValue);
286 object.setRootElement(rootElement);
288 String objectJavaType = null;
289 Map<String, DynamicType> entityTypeLookup = oxmEntityLookup.getEntityTypeLookup();
290 DynamicType entity = entityTypeLookup.get(rootElement);
291 if (null != entity) {
292 objectJavaType = entity.getName();
294 "Descriptor: Alias: " + objectJavaType + " : DefaultRootElement: " + rootElement;
295 LOG.debug(AaiUiMsgs.DEBUG_GENERIC, message);
299 if (objectJavaType == null) {
300 throw new AttributeUpdateException(
301 "Object type could not be determined from the URI : " + objectUri);
303 object.setObjectType(objectJavaType);
305 // Set key attribute name
306 final List<String> primaryKeys = entity.getDescriptor().getPrimaryKeyFieldNames();
308 if (primaryKeys.isEmpty()) {
309 throw new AttributeUpdateException("Object primary key not found in OXM version " + version);
312 for (int i = 0; i < primaryKeys.size(); i++) {
313 final String primaryKey = primaryKeys.get(i);
314 if (primaryKey.indexOf("/text()") != -1) {
315 primaryKeys.set(i, primaryKey.replace("/text()", ""));
318 object.setKeyName(primaryKeys.iterator().next());
324 * Gets the version from uri.
326 * @param objectUri the object uri
327 * @return the version from uri
328 * @throws AttributeUpdateException the attribute update exception
330 private String getVersionFromUri(String objectUri) throws AttributeUpdateException {
331 final Pattern pattern = Pattern.compile(MESSAGE_VERSION_EXTRACTION_REGEX, Pattern.DOTALL);
332 Matcher matcher = pattern.matcher(objectUri);
333 String messageSchemaVersion = null;
334 while (matcher.find()) {
335 messageSchemaVersion = matcher.group(1);
338 return messageSchemaVersion;
342 * Convert edit request to json.
344 * @param object the object
345 * @param attributeValues the attribute values
347 * @throws AttributeUpdateException the attribute update exception
349 private static String convertEditRequestToJson(AaiEditObject object,
350 Map<String, Object> attributeValues) throws AttributeUpdateException {
352 ObjectMapper mapper = new ObjectMapper();
353 mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.KebabCaseStrategy());
354 ObjectWriter ow = mapper.writer();
356 Map<String, Object> patchAttributes = new HashMap<>();
357 patchAttributes.put(object.getKeyName(), object.getKeyValue());
358 patchAttributes.putAll(attributeValues);
361 return ow.writeValueAsString(patchAttributes);
362 } catch (JsonProcessingException exc) {
363 throw new AttributeUpdateException("Caught a JPE while creating PATCH request body = ", exc);