2 * ============LICENSE_START===================================================
3 * SPARKY (AAI UI service)
4 * ============================================================================
5 * Copyright © 2017 AT&T Intellectual Property.
6 * Copyright © 2017 Amdocs
8 * ============================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END=====================================================
22 * ECOMP and OpenECOMP are trademarks
23 * and service marks of AT&T Intellectual Property.
25 package org.onap.aai.sparky.editattributes;
28 import java.util.HashMap;
29 import java.util.List;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
34 import javax.ws.rs.core.UriBuilder;
36 import org.eclipse.persistence.dynamic.DynamicType;
37 import org.onap.aai.cl.api.Logger;
38 import org.onap.aai.cl.eelf.LoggerFactory;
39 import org.onap.aai.restclient.client.OperationResult;
40 import org.onap.aai.sparky.config.oxm.OxmEntityLookup;
41 import org.onap.aai.sparky.config.oxm.OxmModelLoader;
42 import org.onap.aai.sparky.dal.ActiveInventoryAdapter;
43 import org.onap.aai.sparky.editattributes.exception.AttributeUpdateException;
44 import org.onap.aai.sparky.logging.AaiUiMsgs;
46 import com.fasterxml.jackson.core.JsonProcessingException;
47 import com.fasterxml.jackson.databind.ObjectMapper;
48 import com.fasterxml.jackson.databind.ObjectWriter;
49 import com.fasterxml.jackson.databind.PropertyNamingStrategy;
52 * Class to process attribute updates on AAI objects.
56 public class AttributeUpdater {
59 * The Class AaiEditObject.
61 public class AaiEditObject {
69 * Instantiates a new aai edit object.
71 public AaiEditObject() {
76 * Instantiates a new aai edit object.
78 * @param objectType the object type
79 * @param idName the id name
80 * @param schemaVersion the schema version
82 public AaiEditObject(String objectType, String idName, String schemaVersion) {
84 this.objectType = objectType;
85 this.keyName = idName;
86 this.schemaVersion = schemaVersion;
89 public String getObjectType() {
93 public void setObjectType(String objectType) {
94 this.objectType = objectType;
97 public String getKeyName() {
101 public void setKeyName(String idName) {
102 this.keyName = idName;
105 public String getSchemaVersion() {
106 return schemaVersion;
109 public void setSchemaVersion(String schemaVersion) {
110 this.schemaVersion = schemaVersion;
113 public void setKeyValue(String keyValue) {
114 this.keyValue = keyValue;
117 public String getKeyValue() {
121 public String getRootElement() {
125 public void setRootElement(String rootElement) {
126 this.rootElement = rootElement;
131 private static final Logger LOG = LoggerFactory.getInstance().getLogger(AttributeUpdater.class);
132 private static final String MESSAGE_VERSION_EXTRACTION_REGEX = "\\/(v[0-9]+)";
133 private static final String ATTRIBUTES_UPDATED_SUCCESSFULLY = "Attributes updated successfully";
134 private static final String ATTRIBUTES_NOT_UPDATED = "Attributes not updated. ";
136 private ActiveInventoryAdapter aaiAdapter;
137 private UserValidator validator;
138 private OxmModelLoader oxmModelLoader;
139 private OxmEntityLookup oxmEntityLookup;
142 * Instantiates a new attribute updater.
143 * @throws AttributeUpdateException
145 public AttributeUpdater(OxmModelLoader oxmModelLoader, OxmEntityLookup oxmEntityLookup, ActiveInventoryAdapter activeInventoryAdapter) throws AttributeUpdateException {
147 this.oxmModelLoader = oxmModelLoader;
148 this.oxmEntityLookup = oxmEntityLookup;
149 this.aaiAdapter = activeInventoryAdapter;
152 this.validator = new UserValidator();
153 } catch (Exception exc) {
154 LOG.error(AaiUiMsgs.ATTRIBUTES_ERROR_GETTING_AAI_CONFIG_OR_ADAPTER, exc.getLocalizedMessage());
155 throw new AttributeUpdateException(exc);
159 protected String getResourceBasePath() {
161 String versionStr = null;
162 if (oxmModelLoader != null) {
163 versionStr = String.valueOf(oxmModelLoader.getLatestVersionNum());
166 return "/aai/v" + versionStr;
170 protected URI getBaseUri() {
172 .fromUri("https://" + aaiAdapter.getEndpointConfig().getEndpointIpAddress() + ":"
173 + aaiAdapter.getEndpointConfig().getEndpointServerPort() + getResourceBasePath())
178 * Update object attribute.
180 * @param objectUri - Valid URI of the object as per OXM model.
181 * @param attributeValues - Map of (attribute-name & attribute-value) for
182 * any attributes to be updated to the value.
183 * @param attUid - ATTUID of the user requesting the update.
184 * @return - OperationResult with success or failure reason.
186 public OperationResult updateObjectAttribute(String objectUri, Map<String, Object> attributeValues, String attUid) {
187 OperationResult result = new OperationResult();
188 LOG.info(AaiUiMsgs.ATTRIBUTES_UPDATE_METHOD_CALLED, objectUri, attUid, String.valueOf(attributeValues));
189 if (!validator.isAuthorizedUser(attUid)) {
190 result.setResultCode(403);
191 result.setResult(String.format("User %s is not authorized for Attributes update ", attUid));
192 LOG.error(AaiUiMsgs.ATTRIBUTES_USER_NOT_AUTHORIZED_TO_UPDATE, attUid);
196 AaiEditObject object = null;
199 object = getEditObjectFromUri(objectUri);
200 } catch (AttributeUpdateException exc) {
201 result.setResultCode(400);
202 result.setResult(ATTRIBUTES_NOT_UPDATED);
203 LOG.error(AaiUiMsgs.ATTRIBUTES_NOT_UPDATED_EXCEPTION, exc.getLocalizedMessage());
207 String jsonPayload = convertEditRequestToJson(object, attributeValues);
208 String patchUri = getBaseUri().toString() + getRelativeUri(objectUri);
212 * FIX ME: Dave Adams, 8-Nov-2017
215 //result = aaiAdapter.doPatch(patchUri, jsonPayload, MediaType.APPLICATION_JSON);
217 result = new OperationResult();
218 result.setResultCode(404);
220 if (result.getResultCode() == 200) {
221 result.setResult(ATTRIBUTES_UPDATED_SUCCESSFULLY);
222 String message = result.getResult() + " for " + objectUri;
223 LOG.info(AaiUiMsgs.INFO_GENERIC, message);
225 String message = ATTRIBUTES_NOT_UPDATED + " For: " + objectUri + ". AAI PATCH Status Code : "
226 + result.getResultCode() + ". Error : " + result.getResult();
227 LOG.error(AaiUiMsgs.ATTRIBUTES_NOT_UPDATED_MESSAGE, message);
229 } catch (AttributeUpdateException exc) {
230 result.setResultCode(500);
231 result.setResult(ATTRIBUTES_NOT_UPDATED + exc.getLocalizedMessage());
232 LOG.error(AaiUiMsgs.ATTRIBUTES_NOT_UPDATED_EXCEPTION, exc.getLocalizedMessage());
239 * Gets the relative uri.
241 * @param objectUri the object uri
242 * @return the relative uri
244 public String getRelativeUri(String objectUri) {
245 String tempUri = objectUri;
246 final Pattern pattern = Pattern.compile(MESSAGE_VERSION_EXTRACTION_REGEX, Pattern.DOTALL);
247 Matcher matcher = pattern.matcher(objectUri);
248 while (matcher.find()) {
249 tempUri = objectUri.substring(matcher.end());
251 if (!tempUri.startsWith("/")) {
252 tempUri = "/" + tempUri;
258 * Gets the edits the object from uri.
260 * @param objectUri the object uri
261 * @return the edits the object from uri
262 * @throws AttributeUpdateException the attribute update exception
264 public AaiEditObject getEditObjectFromUri(String objectUri) throws AttributeUpdateException {
266 AaiEditObject object = new AaiEditObject();
267 String version = getVersionFromUri(objectUri);
269 if ( null == version ) {
270 version = "v" + String.valueOf(oxmModelLoader.getLatestVersionNum());
272 object.setSchemaVersion(version);
274 String[] values = objectUri.split("/");
275 if (values.length < 2) {
276 throw new AttributeUpdateException("Invalid or malformed object URI : " + objectUri);
278 String keyValue = values[values.length - 1];
279 String rootElement = values[values.length - 2];
281 object.setKeyValue(keyValue);
282 object.setRootElement(rootElement);
284 String objectJavaType = null;
285 Map<String, DynamicType> entityTypeLookup = oxmEntityLookup.getEntityTypeLookup();
286 DynamicType entity = entityTypeLookup.get(rootElement);
287 if ( null != entity ) {
288 objectJavaType = entity.getName();
289 String message = "Descriptor: Alias: " + objectJavaType + " : DefaultRootElement: "
291 LOG.debug(AaiUiMsgs.DEBUG_GENERIC, message);
295 if (objectJavaType == null) {
296 throw new AttributeUpdateException(
297 "Object type could not be determined from the URI : " + objectUri);
299 object.setObjectType(objectJavaType);
301 // Set key attribute name
302 final List<String> primaryKeys = entity.getDescriptor().getPrimaryKeyFieldNames();
304 if (primaryKeys.isEmpty()) {
305 throw new AttributeUpdateException("Object primary key not found in OXM version " + version);
308 for (int i = 0; i < primaryKeys.size(); i++) {
309 final String primaryKey = primaryKeys.get(i);
310 if (primaryKey.indexOf("/text()") != -1) {
311 primaryKeys.set(i, primaryKey.replace("/text()", ""));
314 object.setKeyName(primaryKeys.iterator().next());
320 * Gets the version from uri.
322 * @param objectUri the object uri
323 * @return the version from uri
324 * @throws AttributeUpdateException the attribute update exception
326 private String getVersionFromUri(String objectUri) throws AttributeUpdateException {
327 final Pattern pattern = Pattern.compile(MESSAGE_VERSION_EXTRACTION_REGEX, Pattern.DOTALL);
328 Matcher matcher = pattern.matcher(objectUri);
329 String messageSchemaVersion = null;
330 while (matcher.find()) {
331 messageSchemaVersion = matcher.group(1);
334 return messageSchemaVersion;
338 * Convert edit request to json.
340 * @param object the object
341 * @param attributeValues the attribute values
343 * @throws AttributeUpdateException the attribute update exception
345 private static String convertEditRequestToJson(AaiEditObject object,
346 Map<String, Object> attributeValues) throws AttributeUpdateException {
348 ObjectMapper mapper = new ObjectMapper();
349 mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.KebabCaseStrategy());
350 ObjectWriter ow = mapper.writer();
352 Map<String, Object> patchAttributes = new HashMap<>();
353 patchAttributes.put(object.getKeyName(), object.getKeyValue());
354 patchAttributes.putAll(attributeValues);
357 return ow.writeValueAsString(patchAttributes);
358 } catch (JsonProcessingException exc) {
359 throw new AttributeUpdateException("Caught a JPE while creating PATCH request body = ", exc);