2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 2017-2018 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 package org.onap.aai.sparky.editattributes;
24 import java.util.HashMap;
25 import java.util.List;
27 import java.util.regex.Matcher;
28 import java.util.regex.Pattern;
30 import javax.ws.rs.core.UriBuilder;
32 import org.eclipse.persistence.dynamic.DynamicType;
33 import org.onap.aai.cl.api.Logger;
34 import org.onap.aai.cl.eelf.LoggerFactory;
35 import org.onap.aai.restclient.client.OperationResult;
36 import org.onap.aai.sparky.config.oxm.OxmEntityLookup;
37 import org.onap.aai.sparky.config.oxm.OxmModelLoader;
38 import org.onap.aai.sparky.dal.ActiveInventoryAdapter;
39 import org.onap.aai.sparky.editattributes.exception.AttributeUpdateException;
40 import org.onap.aai.sparky.logging.AaiUiMsgs;
42 import com.fasterxml.jackson.core.JsonProcessingException;
43 import com.fasterxml.jackson.databind.ObjectMapper;
44 import com.fasterxml.jackson.databind.ObjectWriter;
45 import com.fasterxml.jackson.databind.PropertyNamingStrategy;
48 * Class to process attribute updates on AAI objects.
52 public class AttributeUpdater {
55 * The Class AaiEditObject.
57 public class AaiEditObject {
65 * Instantiates a new aai edit object.
67 public AaiEditObject() {
72 * Instantiates a new aai edit object.
74 * @param objectType the object type
75 * @param idName the id name
76 * @param schemaVersion the schema version
78 public AaiEditObject(String objectType, String idName, String schemaVersion) {
80 this.objectType = objectType;
81 this.keyName = idName;
82 this.schemaVersion = schemaVersion;
85 public String getObjectType() {
89 public void setObjectType(String objectType) {
90 this.objectType = objectType;
93 public String getKeyName() {
97 public void setKeyName(String idName) {
98 this.keyName = idName;
101 public String getSchemaVersion() {
102 return schemaVersion;
105 public void setSchemaVersion(String schemaVersion) {
106 this.schemaVersion = schemaVersion;
109 public void setKeyValue(String keyValue) {
110 this.keyValue = keyValue;
113 public String getKeyValue() {
117 public String getRootElement() {
121 public void setRootElement(String rootElement) {
122 this.rootElement = rootElement;
127 private static final Logger LOG = LoggerFactory.getInstance().getLogger(AttributeUpdater.class);
128 private static final String MESSAGE_VERSION_EXTRACTION_REGEX = "\\/(v[0-9]+)";
129 private static final String ATTRIBUTES_UPDATED_SUCCESSFULLY = "Attributes updated successfully";
130 private static final String ATTRIBUTES_NOT_UPDATED = "Attributes not updated. ";
132 private ActiveInventoryAdapter aaiAdapter;
133 private UserValidator validator;
134 private OxmModelLoader oxmModelLoader;
135 private OxmEntityLookup oxmEntityLookup;
136 private String domain;
139 * Instantiates a new attribute updater.
140 * @throws AttributeUpdateException
142 public AttributeUpdater(OxmModelLoader oxmModelLoader, OxmEntityLookup oxmEntityLookup, ActiveInventoryAdapter activeInventoryAdapter,String domain) throws AttributeUpdateException {
144 this.oxmModelLoader = oxmModelLoader;
145 this.oxmEntityLookup = oxmEntityLookup;
146 this.aaiAdapter = activeInventoryAdapter;
147 this.domain = domain;
150 this.validator = new UserValidator();
151 } catch (Exception exc) {
152 LOG.error(AaiUiMsgs.ATTRIBUTES_ERROR_GETTING_AAI_CONFIG_OR_ADAPTER, exc.getLocalizedMessage());
153 throw new AttributeUpdateException(exc);
157 protected String getResourceBasePath() {
159 String versionStr = null;
160 if (oxmModelLoader != null) {
161 versionStr = String.valueOf(oxmModelLoader.getOxmApiVersion());
164 return "/" + domain + "/v" + versionStr;
168 protected URI getBaseUri() {
170 .fromUri("https://" + aaiAdapter.getEndpointConfig().getEndpointIpAddress() + ":"
171 + aaiAdapter.getEndpointConfig().getEndpointServerPort() + getResourceBasePath())
176 * Update object attribute.
178 * @param objectUri - Valid URI of the object as per OXM model.
179 * @param attributeValues - Map of (attribute-name & attribute-value) for
180 * any attributes to be updated to the value.
181 * @param attUid - ATTUID of the user requesting the update.
182 * @return - OperationResult with success or failure reason.
184 public OperationResult updateObjectAttribute(String objectUri, Map<String, Object> attributeValues, String attUid) {
185 OperationResult result = new OperationResult();
186 LOG.info(AaiUiMsgs.ATTRIBUTES_UPDATE_METHOD_CALLED, objectUri, attUid, String.valueOf(attributeValues));
187 if (!validator.isAuthorizedUser(attUid)) {
188 result.setResultCode(403);
189 result.setResult(String.format("User %s is not authorized for Attributes update ", attUid));
190 LOG.error(AaiUiMsgs.ATTRIBUTES_USER_NOT_AUTHORIZED_TO_UPDATE, attUid);
194 AaiEditObject object = null;
197 object = getEditObjectFromUri(objectUri);
198 } catch (AttributeUpdateException exc) {
199 result.setResultCode(400);
200 result.setResult(ATTRIBUTES_NOT_UPDATED);
201 LOG.error(AaiUiMsgs.ATTRIBUTES_NOT_UPDATED_EXCEPTION, exc.getLocalizedMessage());
205 String jsonPayload = convertEditRequestToJson(object, attributeValues);
206 String patchUri = getBaseUri().toString() + getRelativeUri(objectUri);
210 * FIX ME: Dave Adams, 8-Nov-2017
213 //result = aaiAdapter.doPatch(patchUri, jsonPayload, MediaType.APPLICATION_JSON);
215 result = new OperationResult();
216 result.setResultCode(404);
218 if (result.getResultCode() == 200) {
219 result.setResult(ATTRIBUTES_UPDATED_SUCCESSFULLY);
220 String message = result.getResult() + " for " + objectUri;
221 LOG.info(AaiUiMsgs.INFO_GENERIC, message);
223 String message = ATTRIBUTES_NOT_UPDATED + " For: " + objectUri + ". AAI PATCH Status Code : "
224 + result.getResultCode() + ". Error : " + result.getResult();
225 LOG.error(AaiUiMsgs.ATTRIBUTES_NOT_UPDATED_MESSAGE, message);
227 } catch (AttributeUpdateException exc) {
228 result.setResultCode(500);
229 result.setResult(ATTRIBUTES_NOT_UPDATED + exc.getLocalizedMessage());
230 LOG.error(AaiUiMsgs.ATTRIBUTES_NOT_UPDATED_EXCEPTION, exc.getLocalizedMessage());
237 * Gets the relative uri.
239 * @param objectUri the object uri
240 * @return the relative uri
242 public String getRelativeUri(String objectUri) {
243 String tempUri = objectUri;
244 final Pattern pattern = Pattern.compile(MESSAGE_VERSION_EXTRACTION_REGEX, Pattern.DOTALL);
245 Matcher matcher = pattern.matcher(objectUri);
246 while (matcher.find()) {
247 tempUri = objectUri.substring(matcher.end());
249 if (!tempUri.startsWith("/")) {
250 tempUri = "/" + tempUri;
256 * Gets the edits the object from uri.
258 * @param objectUri the object uri
259 * @return the edits the object from uri
260 * @throws AttributeUpdateException the attribute update exception
262 public AaiEditObject getEditObjectFromUri(String objectUri) throws AttributeUpdateException {
264 AaiEditObject object = new AaiEditObject();
265 String version = getVersionFromUri(objectUri);
267 if ( null == version ) {
268 version = "v" + String.valueOf(oxmModelLoader.getOxmApiVersion());
270 object.setSchemaVersion(version);
272 String[] values = objectUri.split("/");
273 if (values.length < 2) {
274 throw new AttributeUpdateException("Invalid or malformed object URI : " + objectUri);
276 String keyValue = values[values.length - 1];
277 String rootElement = values[values.length - 2];
279 object.setKeyValue(keyValue);
280 object.setRootElement(rootElement);
282 String objectJavaType = null;
283 Map<String, DynamicType> entityTypeLookup = oxmEntityLookup.getEntityTypeLookup();
284 DynamicType entity = entityTypeLookup.get(rootElement);
285 if ( null != entity ) {
286 objectJavaType = entity.getName();
287 String message = "Descriptor: Alias: " + objectJavaType + " : DefaultRootElement: "
289 LOG.debug(AaiUiMsgs.DEBUG_GENERIC, message);
293 if (objectJavaType == null) {
294 throw new AttributeUpdateException(
295 "Object type could not be determined from the URI : " + objectUri);
297 object.setObjectType(objectJavaType);
299 // Set key attribute name
300 final List<String> primaryKeys = entity.getDescriptor().getPrimaryKeyFieldNames();
302 if (primaryKeys.isEmpty()) {
303 throw new AttributeUpdateException("Object primary key not found in OXM version " + version);
306 for (int i = 0; i < primaryKeys.size(); i++) {
307 final String primaryKey = primaryKeys.get(i);
308 if (primaryKey.indexOf("/text()") != -1) {
309 primaryKeys.set(i, primaryKey.replace("/text()", ""));
312 object.setKeyName(primaryKeys.iterator().next());
318 * Gets the version from uri.
320 * @param objectUri the object uri
321 * @return the version from uri
322 * @throws AttributeUpdateException the attribute update exception
324 private String getVersionFromUri(String objectUri) throws AttributeUpdateException {
325 final Pattern pattern = Pattern.compile(MESSAGE_VERSION_EXTRACTION_REGEX, Pattern.DOTALL);
326 Matcher matcher = pattern.matcher(objectUri);
327 String messageSchemaVersion = null;
328 while (matcher.find()) {
329 messageSchemaVersion = matcher.group(1);
332 return messageSchemaVersion;
336 * Convert edit request to json.
338 * @param object the object
339 * @param attributeValues the attribute values
341 * @throws AttributeUpdateException the attribute update exception
343 private static String convertEditRequestToJson(AaiEditObject object,
344 Map<String, Object> attributeValues) throws AttributeUpdateException {
346 ObjectMapper mapper = new ObjectMapper();
347 mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.KebabCaseStrategy());
348 ObjectWriter ow = mapper.writer();
350 Map<String, Object> patchAttributes = new HashMap<>();
351 patchAttributes.put(object.getKeyName(), object.getKeyValue());
352 patchAttributes.putAll(attributeValues);
355 return ow.writeValueAsString(patchAttributes);
356 } catch (JsonProcessingException exc) {
357 throw new AttributeUpdateException("Caught a JPE while creating PATCH request body = ", exc);