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.
26 package org.openecomp.sparky.dal.aai;
28 import java.io.IOException;
29 import java.net.URLEncoder;
30 import java.nio.ByteBuffer;
31 import java.util.List;
32 import java.util.NoSuchElementException;
34 import org.apache.http.client.utils.URIBuilder;
35 import org.openecomp.cl.api.Logger;
36 import org.openecomp.cl.eelf.LoggerFactory;
37 import org.openecomp.sparky.config.oxm.OxmEntityDescriptor;
38 import org.openecomp.sparky.config.oxm.OxmModelLoader;
39 import org.openecomp.sparky.dal.aai.config.ActiveInventoryConfig;
40 import org.openecomp.sparky.dal.aai.config.ActiveInventoryRestConfig;
41 import org.openecomp.sparky.dal.aai.enums.RestAuthenticationMode;
42 import org.openecomp.sparky.dal.exception.ElasticSearchOperationException;
43 import org.openecomp.sparky.dal.rest.OperationResult;
44 import org.openecomp.sparky.dal.rest.RestClientBuilder;
45 import org.openecomp.sparky.dal.rest.RestfulDataAccessor;
46 import org.openecomp.sparky.logging.AaiUiMsgs;
47 import org.openecomp.sparky.security.SecurityContextFactory;
48 import org.openecomp.sparky.util.NodeUtils;
50 import com.sun.jersey.api.client.Client;
51 import com.sun.jersey.api.client.WebResource.Builder;
55 * The Class ActiveInventoryAdapter.
62 public class ActiveInventoryAdapter extends RestfulDataAccessor
63 implements ActiveInventoryDataProvider {
65 private static final Logger LOG =
66 LoggerFactory.getInstance().getLogger(ActiveInventoryAdapter.class);
68 private static final String HEADER_TRANS_ID = "X-TransactionId";
69 private static final String HEADER_FROM_APP_ID = "X-FromAppId";
70 private static final String HEADER_AUTHORIZATION = "Authorization";
72 private static final String TRANSACTION_ID_PREFIX = "txnId-";
73 private static final String UI_APP_NAME = "AAI-UI";
76 private ActiveInventoryConfig config;
79 * Instantiates a new active inventory adapter.
81 * @param restClientBuilder the rest client builder
82 * @throws ElasticSearchOperationException the elastic search operation exception
83 * @throws IOException Signals that an I/O exception has occurred.
85 public ActiveInventoryAdapter(RestClientBuilder restClientBuilder)
86 throws ElasticSearchOperationException, IOException {
87 super(restClientBuilder);
90 this.config = ActiveInventoryConfig.getConfig();
91 } catch (Exception exc) {
92 throw new ElasticSearchOperationException("Error getting active inventory configuration",
96 clientBuilder.setUseHttps(true);
98 clientBuilder.setValidateServerHostname(config.getAaiSslConfig().isValidateServerHostName());
100 SecurityContextFactory sslContextFactory = clientBuilder.getSslContextFactory();
102 sslContextFactory.setServerCertificationChainValidationEnabled(
103 config.getAaiSslConfig().isValidateServerCertificateChain());
105 if (config.getAaiRestConfig().getAuthenticationMode() == RestAuthenticationMode.SSL_CERT) {
106 sslContextFactory.setClientCertFileName(config.getAaiSslConfig().getKeystoreFilename());
107 sslContextFactory.setClientCertPassword(config.getAaiSslConfig().getKeystorePassword());
108 sslContextFactory.setTrustStoreFileName(config.getAaiSslConfig().getTruststoreFilename());
111 clientBuilder.setConnectTimeoutInMs(config.getAaiRestConfig().getConnectTimeoutInMs());
112 clientBuilder.setReadTimeoutInMs(config.getAaiRestConfig().getReadTimeoutInMs());
117 * @see org.openecomp.sparky.dal.rest.RestfulDataAccessor#setClientDefaults(com.sun.jersey.api.client.Client, java.lang.String, java.lang.String, java.lang.String)
120 protected Builder setClientDefaults(Client client, String url, String payloadContentType,
121 String acceptContentType) {
122 Builder builder = super.setClientDefaults(client, url, payloadContentType, acceptContentType);
124 builder = builder.header(HEADER_FROM_APP_ID, UI_APP_NAME);
125 byte bytes[] = new byte[6];
126 txnIdGenerator.nextBytes(bytes);
128 builder.header(HEADER_TRANS_ID, TRANSACTION_ID_PREFIX + ByteBuffer.wrap(bytes).getInt());
130 if (config.getAaiRestConfig().getAuthenticationMode() == RestAuthenticationMode.SSL_BASIC) {
131 builder = builder.header(HEADER_AUTHORIZATION,
132 config.getAaiSslConfig().getBasicAuthenticationCredentials());
141 * @param args the arguments
143 public static void main(String[] args) {
145 // TODO Auto-generated method stub
146 RestClientBuilder builder = new RestClientBuilder();
147 RestfulDataAccessor accessor;
149 accessor = new ActiveInventoryAdapter(builder);
151 accessor.doGet("/cloud-infrastructure/pservers/pserver/SQLTEST006", "application/json");
152 String jsonPatch = "{ \"hostname\" : \"SQLTEST006\", \"prov-status\" : \"PREPROV\","
153 + " \"in-maint\" : \"false\", \"is-closed-loop\" : \"false\" }";
154 or = accessor.doPatch("/cloud-infrastructure/pservers/pserver/SQLTEST006", jsonPatch,
156 // System.out.println("PATCH or = " + or.getResultCode() + " : " + or.toString());
157 } catch (ElasticSearchOperationException | IOException exc) {
158 // TODO Auto-generated catch block
159 exc.printStackTrace();
167 * @param resourceUrl the resource url
168 * @return the full url
169 * @throws Exception the exception
171 private String getFullUrl(String resourceUrl) throws Exception {
172 ActiveInventoryRestConfig aaiRestConfig = ActiveInventoryConfig.getConfig().getAaiRestConfig();
173 final String host = aaiRestConfig.getHost();
174 final String port = aaiRestConfig.getPort();
175 final String basePath = aaiRestConfig.getResourceBasePath();
176 return String.format("https://%s:%s%s%s", host, port, basePath, resourceUrl);
179 public String getGenericQueryForSelfLink(String startNodeType, List<String> queryParams) throws Exception {
181 URIBuilder urlBuilder = new URIBuilder(getFullUrl("/search/generic-query"));
183 for( String queryParam : queryParams) {
184 urlBuilder.addParameter("key", queryParam);
187 urlBuilder.addParameter("start-node-type", startNodeType);
188 urlBuilder.addParameter("include", startNodeType);
190 final String constructedLink = urlBuilder.toString();
192 // TODO: debug log for constructed link
194 return constructedLink;
200 * @see org.openecomp.sparky.dal.aai.ActiveInventoryDataProvider#getSelfLinksByEntityType(java.lang.String)
203 public OperationResult getSelfLinksByEntityType(String entityType) throws Exception {
206 * For this one, I want to dynamically construct the nodes-query for self-link discovery as a
207 * utility method that will use the OXM model entity data to drive the query as well.
210 if (entityType == null) {
211 throw new NullPointerException(
212 "Failed to getSelfLinksByEntityType() because entityType is null");
215 OxmEntityDescriptor entityDescriptor =
216 OxmModelLoader.getInstance().getEntityDescriptor(entityType);
218 if (entityDescriptor == null) {
219 throw new NoSuchElementException("Failed to getSelfLinksByEntityType() because could"
220 + " not find entity descriptor from OXM with type = " + entityType);
224 final String primaryKeyStr =
225 NodeUtils.concatArray(entityDescriptor.getPrimaryKeyAttributeName(), "/");
227 link = getFullUrl("/search/nodes-query?search-node-type=" + entityType + "&filter="
228 + primaryKeyStr + ":EXISTS");
232 return doGet(link, "application/json");
237 * @see org.openecomp.sparky.dal.aai.ActiveInventoryDataProvider#getSelfLinkForEntity(java.lang.String, java.lang.String, java.lang.String)
240 public OperationResult getSelfLinkForEntity(String entityType, String primaryKeyName,
241 String primaryKeyValue) throws Exception {
243 if (entityType == null) {
244 throw new NullPointerException("Failed to getSelfLinkForEntity() because entityType is null");
247 if (primaryKeyName == null) {
248 throw new NullPointerException(
249 "Failed to getSelfLinkForEntity() because primaryKeyName is null");
252 if (primaryKeyValue == null) {
253 throw new NullPointerException(
254 "Failed to getSelfLinkForEntity() because primaryKeyValue is null");
257 // https://aai-int1.test.att.com:8443/aai/v8/search/generic-query?key=complex.physical-location-id:atlngade&start-node-type=complex
260 * Try to protect ourselves from illegal URI formatting exceptions caused by characters that
261 * aren't natively supported in a URI, but can be escaped to make them legal.
264 String encodedEntityType = URLEncoder.encode(entityType, "UTF-8");
265 String encodedPrimaryKeyName = URLEncoder.encode(primaryKeyName, "UTF-8");
266 String encodedPrimaryKeyValue = URLEncoder.encode(primaryKeyValue, "UTF-8");
270 if ("service-instance".equals(entityType)) {
272 link = getFullUrl("/search/generic-query?key=" + encodedEntityType + "."
273 + encodedPrimaryKeyName + ":" + encodedPrimaryKeyValue + "&start-node-type="
274 + encodedEntityType + "&include=customer&depth=2");
279 getFullUrl("/search/generic-query?key=" + encodedEntityType + "." + encodedPrimaryKeyName
280 + ":" + encodedPrimaryKeyValue + "&start-node-type=" + encodedEntityType);
284 return queryActiveInventoryWithRetries(link, "application/json",
285 this.config.getAaiRestConfig().getNumRequestRetries());
291 * Our retry conditions should be very specific.
294 * @return true, if successful
296 private boolean shouldRetryRequest(OperationResult r) {
302 int rc = r.getResultCode();
317 * Query active inventory.
320 * @param acceptContentType the accept content type
321 * @return the operation result
323 // package protected for test classes instead of private
324 OperationResult queryActiveInventory(String url, String acceptContentType) {
325 return doGet(url, acceptContentType);
329 * @see org.openecomp.sparky.dal.aai.ActiveInventoryDataProvider#queryActiveInventoryWithRetries(java.lang.String, java.lang.String, int)
332 public OperationResult queryActiveInventoryWithRetries(String url, String responseType,
335 OperationResult result = null;
337 for (int x = 0; x < numRetries; x++) {
339 LOG.debug(AaiUiMsgs.QUERY_AAI_RETRY_SEQ, url, String.valueOf(x + 1));
341 result = queryActiveInventory(url, responseType);
344 * Record number of times we have attempted the request to later summarize how many times we
345 * are generally retrying over thousands of messages in a sync.
347 * If the number of retries is surprisingly high, then we need to understand why that is as
348 * the number of retries is also causing a heavier load on AAI beyond the throttling controls
349 * we already have in place in term of the transaction rate controller and number of
350 * parallelized threads per task processor.
353 result.setNumRequestRetries(x);
355 if (!shouldRetryRequest(result)) {
358 * if (myConfig.getAaiRestConfig().isCacheEnabled()) {
360 * CachedHttpRequest cachedRequest = new CachedHttpRequest();
361 * cachedRequest.setHttpRequestMethod("GET"); cachedRequest.setPayload("");
362 * cachedRequest.setPayloadMimeType(""); cachedRequest.setUrl(url);
363 * cachedRequest.setOperationType( TransactionStorageType.ACTIVE_INVENTORY_QUERY.getIndex()
366 * CachedHttpResponse cachedResponse = new CachedHttpResponse();
367 * cachedResponse.setPayload(result.getResult());
368 * cachedResponse.setPayloadMimeType("application/json");
369 * cachedResponse.setStatusCode(result.getResultCode());
371 * CachedHttpTransaction txn = new CachedHttpTransaction(cachedRequest, cachedResponse);
372 * storageProvider.persistTransaction(txn);
378 result.setResolvedLinkFromServer(true);
379 LOG.debug(AaiUiMsgs.QUERY_AAI_RETRY_DONE_SEQ, url, String.valueOf(x + 1));
386 * Sleep between re-tries to be nice to the target system.
389 } catch (InterruptedException exc) {
390 LOG.error(AaiUiMsgs.QUERY_AAI_WAIT_INTERRUPTION, exc.getLocalizedMessage());
393 LOG.error(AaiUiMsgs.QUERY_AAI_RETRY_FAILURE_WITH_SEQ, url, String.valueOf(x + 1));
397 result.setResolvedLinkFailure(true);
398 LOG.info(AaiUiMsgs.QUERY_AAI_RETRY_MAXED_OUT, url);
405 * @see org.openecomp.sparky.dal.rest.RestfulDataAccessor#shutdown()
408 public void shutdown() {
409 // TODO Auto-generated method stub
411 if (entityCache != null) {
412 entityCache.shutdown();