Aharoni, Pavel (pa0916) | ca3cb01 | 2018-10-22 15:29:57 +0300 | [diff] [blame] | 1 | /*-
|
| 2 | * ============LICENSE_START=======================================================
|
| 3 | * OSAM
|
| 4 | * ================================================================================
|
| 5 | * Copyright (C) 2018 AT&T
|
| 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 |
|
| 22 |
|
| 23 | package org.onap.osam.aai;
|
| 24 |
|
| 25 | import com.fasterxml.jackson.databind.ObjectMapper;
|
| 26 | import org.apache.commons.lang3.StringUtils;
|
| 27 | import org.apache.http.HttpStatus;
|
| 28 | import org.apache.http.client.utils.URIBuilder;
|
| 29 | import org.json.simple.JSONArray;
|
| 30 | import org.json.simple.JSONObject;
|
| 31 | import org.json.simple.parser.JSONParser;
|
| 32 | import org.onap.osam.aai.model.AaiGetAicZone.AicZones;
|
| 33 | import org.onap.osam.aai.model.AaiGetInstanceGroupsByCloudRegion;
|
| 34 | import org.onap.osam.aai.model.AaiGetNetworkCollectionDetails.AaiGetNetworkCollectionDetails;
|
| 35 | import org.onap.osam.aai.model.AaiGetNetworkCollectionDetails.AaiGetNetworkCollectionDetailsHelper;
|
| 36 | import org.onap.osam.aai.model.AaiGetNetworkCollectionDetails.AaiGetRelatedInstanceGroupsByVnfId;
|
| 37 | import org.onap.osam.aai.model.AaiGetNetworkCollectionDetails.InstanceGroup;
|
| 38 | import org.onap.osam.aai.model.AaiGetNetworkCollectionDetails.Network;
|
| 39 | import org.onap.osam.aai.model.AaiGetOperationalEnvironments.OperationalEnvironmentList;
|
| 40 | import org.onap.osam.aai.model.AaiGetPnfResponse;
|
| 41 | import org.onap.osam.aai.model.AaiGetPnfs.Pnf;
|
| 42 | import org.onap.osam.aai.model.AaiGetPortMirroringSourcePorts;
|
| 43 | import org.onap.osam.aai.model.AaiGetServicesRequestModel.GetServicesAAIRespone;
|
| 44 | import org.onap.osam.aai.model.AaiGetTenatns.GetTenantsResponse;
|
| 45 | import org.onap.osam.aai.model.AaiNodeQueryResponse;
|
| 46 | import org.onap.osam.aai.model.GetServiceModelsByDistributionStatusResponse;
|
| 47 | import org.onap.osam.aai.model.LogicalLinkResponse;
|
| 48 | import org.onap.osam.aai.model.OwningEntityResponse;
|
| 49 | import org.onap.osam.aai.model.PortDetailsTranslator;
|
| 50 | import org.onap.osam.aai.model.ProjectResponse;
|
| 51 | import org.onap.osam.aai.model.Relationship;
|
| 52 | import org.onap.osam.aai.model.RelationshipData;
|
| 53 | import org.onap.osam.aai.model.RelationshipList;
|
| 54 | import org.onap.osam.aai.model.ResourceType;
|
| 55 | import org.onap.osam.aai.model.ServiceRelationships;
|
| 56 | import org.onap.osam.aai.util.AAIRestInterface;
|
| 57 | import org.onap.osam.exceptions.GenericUncheckedException;
|
| 58 | import org.onap.osam.model.SubscriberList;
|
| 59 | import org.onap.osam.model.probes.ErrorMetadata;
|
| 60 | import org.onap.osam.model.probes.ExternalComponentStatus;
|
| 61 | import org.onap.osam.model.probes.HttpRequestMetadata;
|
| 62 | import org.onap.osam.utils.Logging;
|
| 63 | import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
|
| 64 | import org.springframework.web.util.UriUtils;
|
| 65 |
|
| 66 | import javax.inject.Inject;
|
| 67 | import javax.ws.rs.WebApplicationException;
|
| 68 | import javax.ws.rs.core.Response;
|
| 69 | import java.io.IOException;
|
| 70 | import java.io.UnsupportedEncodingException;
|
| 71 | import java.net.URLEncoder;
|
| 72 | import java.text.DateFormat;
|
| 73 | import java.text.SimpleDateFormat;
|
| 74 | import java.util.Date;
|
| 75 | import java.util.LinkedHashMap;
|
| 76 | import java.util.List;
|
| 77 | import java.util.UUID;
|
| 78 |
|
| 79 | import static java.util.Collections.emptyList;
|
| 80 | import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
|
| 81 |
|
| 82 | public class AaiClient implements AaiClientInterface {
|
| 83 |
|
| 84 |
|
| 85 | public static final String QUERY_FORMAT_RESOURCE = "query?format=resource";
|
| 86 | public static final String SERVICE_SUBSCRIPTIONS_PATH = "/service-subscriptions/service-subscription/";
|
| 87 | public static final String MODEL_INVARIANT_ID = "&model-invariant-id=";
|
| 88 | public static final String QUERY_FORMAT_SIMPLE = "query?format=simple";
|
| 89 | public static final String BUSINESS_CUSTOMER = "/business/customers/customer/";
|
| 90 | public static final String SERVICE_INSTANCE = "/service-instances/service-instance/";
|
| 91 | public static final String BUSINESS_CUSTOMERS_CUSTOMER = "business/customers/customer/";
|
| 92 |
|
| 93 | protected String fromAppId = "VidAaiController";
|
| 94 |
|
| 95 | private PortDetailsTranslator portDetailsTranslator;
|
| 96 |
|
| 97 | private final AAIRestInterface restController;
|
| 98 |
|
| 99 | EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AaiClient.class);
|
| 100 |
|
| 101 | /**
|
| 102 | * The Constant dateFormat.
|
| 103 | */
|
| 104 | static final DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
|
| 105 |
|
| 106 | static final String GET_SERVICE_MODELS_RESPONSE_BODY = "{\"start\" : \"service-design-and-creation/models/\", \"query\" : \"query/serviceModels-byDistributionStatus?distributionStatus=DISTRIBUTION_COMPLETE_OK\"}";
|
| 107 |
|
| 108 | @Inject
|
| 109 | public AaiClient(AAIRestInterface restController, PortDetailsTranslator portDetailsTranslator) {
|
| 110 | this.restController = restController;
|
| 111 | this.portDetailsTranslator = portDetailsTranslator;
|
| 112 | }
|
| 113 |
|
| 114 |
|
| 115 | private static String checkForNull(String local) {
|
| 116 | if (local != null)
|
| 117 | return local;
|
| 118 | else
|
| 119 | return "";
|
| 120 |
|
| 121 | }
|
| 122 |
|
| 123 | @Override
|
| 124 | public AaiResponse getServicesByOwningEntityId(List<String> owningEntityIds){
|
| 125 | Response resp = doAaiGet(getUrlFromLIst("business/owning-entities?", "owning-entity-id=", owningEntityIds), false);
|
| 126 | return processAaiResponse(resp, OwningEntityResponse.class, null);
|
| 127 | }
|
| 128 |
|
| 129 | @Override
|
| 130 | public AaiResponse getServicesByProjectNames(List<String> projectNames){
|
| 131 | Response resp = doAaiGet(getUrlFromLIst("business/projects?", "project-name=", projectNames), false);
|
| 132 | return processAaiResponse(resp, ProjectResponse.class, null);
|
| 133 | }
|
| 134 |
|
| 135 | @Override
|
| 136 | public AaiResponse getServiceModelsByDistributionStatus() {
|
| 137 | Response resp = doAaiPut(QUERY_FORMAT_RESOURCE, GET_SERVICE_MODELS_RESPONSE_BODY, false);
|
| 138 | return processAaiResponse(resp, GetServiceModelsByDistributionStatusResponse.class, null);
|
| 139 | }
|
| 140 |
|
| 141 | @Override
|
| 142 | public AaiResponse getNetworkCollectionDetails(String serviceInstanceId) {
|
| 143 | Response resp = doAaiPut(QUERY_FORMAT_RESOURCE, "{\"start\": [\"nodes/service-instances/service-instance/" + serviceInstanceId + "\"],\"query\": \"query/network-collection-ByServiceInstance\"}\n", false);
|
| 144 | AaiResponse<AaiGetNetworkCollectionDetailsHelper> aaiResponse = processAaiResponse(resp, AaiGetNetworkCollectionDetailsHelper.class, null);
|
| 145 | return getNetworkCollectionDetailsResponse(aaiResponse);
|
| 146 | }
|
| 147 |
|
| 148 | @Override
|
| 149 | public AaiResponse getInstanceGroupsByCloudRegion(String cloudOwner, String cloudRegionId, String networkFunction) {
|
| 150 | Response resp = doAaiPut(QUERY_FORMAT_RESOURCE,
|
| 151 | "{\"start\": [\"cloud-infrastructure/cloud-regions/cloud-region/" + cloudOwner + "/" + cloudRegionId + "\"]," +
|
| 152 | "\"query\": \"query/instance-group-byCloudRegion?type=L3-NETWORK&role=SUB-INTERFACE&function=" + networkFunction + "\"}\n", false);
|
| 153 | return processAaiResponse(resp, AaiGetInstanceGroupsByCloudRegion.class, null);
|
| 154 | }
|
| 155 |
|
| 156 | private AaiResponse getNetworkCollectionDetailsResponse(AaiResponse<AaiGetNetworkCollectionDetailsHelper> aaiResponse){
|
| 157 | if(aaiResponse.getHttpCode() == 200) {
|
| 158 | com.fasterxml.jackson.databind.ObjectMapper om = new com.fasterxml.jackson.databind.ObjectMapper();
|
| 159 | AaiGetNetworkCollectionDetails aaiGetNetworkCollectionDetails = new AaiGetNetworkCollectionDetails();
|
| 160 | try {
|
| 161 | for (int i = 0; i < aaiResponse.getT().getResults().size(); i++) {
|
| 162 | LinkedHashMap<String, Object> temp = ((LinkedHashMap) aaiResponse.getT().getResults().get(i));
|
| 163 | if (temp.get("service-instance") != null)
|
| 164 | aaiGetNetworkCollectionDetails.getResults().setServiceInstance(om.readValue(om.writeValueAsString(temp.get("service-instance")), org.onap.osam.aai.model.AaiGetNetworkCollectionDetails.ServiceInstance.class));
|
| 165 | else if (temp.get("collection") != null)
|
| 166 | aaiGetNetworkCollectionDetails.getResults().setCollection(om.readValue(om.writeValueAsString(temp.get("collection")), org.onap.osam.aai.model.AaiGetNetworkCollectionDetails.Collection.class));
|
| 167 | else if (temp.get("instance-group") != null)
|
| 168 | aaiGetNetworkCollectionDetails.getResults().setInstanceGroup(om.readValue(om.writeValueAsString(temp.get("instance-group")), InstanceGroup.class));
|
| 169 | else if (temp.get("l3-network") != null)
|
| 170 | aaiGetNetworkCollectionDetails.getResults().getNetworks().add(om.readValue(om.writeValueAsString(temp.get("l3-network")), Network.class));
|
| 171 | }
|
| 172 | return new AaiResponse(aaiGetNetworkCollectionDetails, null, HttpStatus.SC_OK);
|
| 173 | }
|
| 174 | catch (com.fasterxml.jackson.databind.JsonMappingException e) {
|
| 175 | return new AaiResponse(e.getCause(), "AAI response parsing Error" , aaiResponse.getHttpCode());
|
| 176 | }
|
| 177 | catch (Exception e) {
|
| 178 | return new AaiResponse(e.getCause(), "Got " + aaiResponse.getHttpCode() + " from a&ai" , aaiResponse.getHttpCode());
|
| 179 | }
|
| 180 | }
|
| 181 | return aaiResponse;
|
| 182 | }
|
| 183 |
|
| 184 | @Override
|
| 185 | public AaiResponse getPNFData(String globalCustomerId, String serviceType, String modelVersionId, String modelInvariantId, String cloudRegion, String equipVendor, String equipModel) {
|
| 186 | String siQuery = BUSINESS_CUSTOMER + globalCustomerId + SERVICE_SUBSCRIPTIONS_PATH + encodePathSegment(serviceType) + "/service-instances?model-version-id=" + modelVersionId + MODEL_INVARIANT_ID + modelInvariantId;
|
| 187 | String pnfQuery = "query/pnf-fromModel-byRegion?cloudRegionId=" + encodePathSegment(cloudRegion) + "&equipVendor=" + encodePathSegment(equipVendor) + "&equipModel=" + encodePathSegment(equipModel);
|
| 188 | String payload = "{\"start\":\"" + siQuery + "\",\"query\":\"" + pnfQuery + "\"}";
|
| 189 | Response resp = doAaiPut(QUERY_FORMAT_SIMPLE, payload, false);
|
| 190 | return processAaiResponse(resp, AaiGetPnfResponse.class, null);
|
| 191 | }
|
| 192 |
|
| 193 |
|
| 194 | @Override
|
| 195 | public AaiResponse<Pnf> getSpecificPnf(String pnfId) {
|
| 196 | Response resp = doAaiGet("network/pnfs/pnf/"+pnfId, false);
|
| 197 | return processAaiResponse(resp, Pnf.class, null);
|
| 198 | }
|
| 199 |
|
| 200 |
|
| 201 | public AaiResponse getInstanceGroupsByVnfInstanceId(String vnfInstanceId){
|
| 202 | Response resp = doAaiGet("network/generic-vnfs/generic-vnf/" + vnfInstanceId + "?depth=0", false);
|
| 203 | return processAaiResponse(resp, AaiGetRelatedInstanceGroupsByVnfId.class , null);
|
| 204 | }
|
| 205 |
|
| 206 |
|
| 207 | @Override
|
| 208 | public List<PortDetailsTranslator.PortDetails> getPortMirroringSourcePorts(String configurationID) {
|
| 209 | String payload = "{\"start\":\"/network/configurations/configuration/" + configurationID + "\",\"query\":\"query/pserver-fromConfiguration\"}";
|
| 210 | Response resp = doAaiPut(QUERY_FORMAT_SIMPLE, payload, false);
|
| 211 | resp.bufferEntity(); // avoid later "Entity input stream has already been closed" problems
|
| 212 | String rawPayload = resp.readEntity(String.class);
|
| 213 | AaiResponse<AaiGetPortMirroringSourcePorts> aaiResponse = processAaiResponse(resp, AaiGetPortMirroringSourcePorts.class, rawPayload);
|
| 214 | return portDetailsTranslator.extractPortDetails(aaiResponse, rawPayload);
|
| 215 | }
|
| 216 |
|
| 217 |
|
| 218 |
|
| 219 | public AaiResponse getServiceInstance(String globalCustomerId, String serviceType, String serviceInstanceId) {
|
| 220 | String getServiceInstancePath = BUSINESS_CUSTOMERS_CUSTOMER + globalCustomerId+ SERVICE_SUBSCRIPTIONS_PATH +serviceType+ SERVICE_INSTANCE +serviceInstanceId;
|
| 221 | Response resp = doAaiGet(getServiceInstancePath , false);
|
| 222 | return processAaiResponse(resp, ServiceRelationships.class, null);
|
| 223 | }
|
| 224 |
|
| 225 | @Override
|
| 226 | public AaiResponse getLogicalLink(String link) {
|
| 227 | Response resp = doAaiGet("network/logical-links/logical-link/" + link , false);
|
| 228 | return processAaiResponse(resp, LogicalLinkResponse.class, null);
|
| 229 | }
|
| 230 |
|
| 231 | @Override
|
| 232 | public AaiResponse<AaiNodeQueryResponse> searchNodeTypeByName(String name, ResourceType type) {
|
| 233 | String path = String.format(
|
| 234 | "search/nodes-query?search-node-type=%s&filter=%s:EQUALS:%s",
|
| 235 | type.getAaiFormat(),
|
| 236 | type.getNameFilter(),
|
| 237 | name
|
| 238 | );
|
| 239 | return typedAaiGet(path, AaiNodeQueryResponse.class);
|
| 240 | }
|
| 241 |
|
| 242 | private <T> AaiResponse<T> typedAaiGet(String path, Class<T> clz) {
|
| 243 | Response resp = doAaiGet(path , false);
|
| 244 | return processAaiResponse(resp, clz, null);
|
| 245 | }
|
| 246 |
|
| 247 |
|
| 248 |
|
| 249 | private String getUrlFromLIst(String url, String paramKey, List<String> params){
|
| 250 | int i = 0;
|
| 251 | for(String param: params){
|
| 252 | i ++;
|
| 253 | url = url.concat(paramKey);
|
| 254 | String encodedParam= param;
|
| 255 | try {
|
| 256 | encodedParam= URLEncoder.encode(param, "UTF-8");
|
| 257 | } catch (UnsupportedEncodingException e) {
|
| 258 | String methodName = "getUrlFromList";
|
| 259 | logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
|
| 260 | logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
|
| 261 | }
|
| 262 | url = url.concat(encodedParam);
|
| 263 | if(i != params.size()){
|
| 264 | url = url.concat("&");
|
| 265 | }
|
| 266 | }
|
| 267 | return url;
|
| 268 | }
|
| 269 |
|
| 270 |
|
| 271 | @Override
|
| 272 | public AaiResponse<SubscriberList> getAllSubscribers() {
|
| 273 | return getAllSubscribers(false).getAaiResponse();
|
| 274 | }
|
| 275 |
|
| 276 | AaiResponseWithRequestInfo<SubscriberList> getAllSubscribers(boolean propagateExceptions){
|
| 277 | String depth = "0";
|
| 278 | ResponseWithRequestInfo aaiGetResult = doAaiGet("business/customers?subscriber-type=INFRA&depth=" + depth, false, propagateExceptions);
|
| 279 | AaiResponseWithRequestInfo<SubscriberList> responseWithRequestInfo = processAaiResponse(aaiGetResult, SubscriberList.class, propagateExceptions);
|
| 280 | responseWithRequestInfo.setRequestedUrl(aaiGetResult.getRequestUrl());
|
| 281 | responseWithRequestInfo.setHttpMethod(aaiGetResult.getRequestHttpMethod());
|
| 282 | return responseWithRequestInfo;
|
| 283 | }
|
| 284 |
|
| 285 |
|
| 286 | @Override
|
| 287 | public AaiResponse getAllAicZones() {
|
| 288 | Response resp = doAaiGet("network/zones", false);
|
| 289 | return processAaiResponse(resp, AicZones.class, null);
|
| 290 | }
|
| 291 |
|
| 292 |
|
| 293 | @Override
|
| 294 | public AaiResponse<String> getAicZoneForPnf(String globalCustomerId , String serviceType , String serviceId) {
|
| 295 | String aicZonePath = BUSINESS_CUSTOMERS_CUSTOMER + globalCustomerId + SERVICE_SUBSCRIPTIONS_PATH + serviceType + SERVICE_INSTANCE + serviceId;
|
| 296 | Response resp = doAaiGet(aicZonePath , false);
|
| 297 | AaiResponse<ServiceRelationships> aaiResponse = processAaiResponse(resp , ServiceRelationships.class , null);
|
| 298 | ServiceRelationships serviceRelationships = aaiResponse.getT();
|
| 299 | RelationshipList relationshipList = serviceRelationships.getRelationshipList();
|
| 300 | Relationship relationship = relationshipList.getRelationship().get(0);
|
| 301 | RelationshipData relationshipData= relationship.getRelationDataList().get(0);
|
| 302 | String aicZone = relationshipData.getRelationshipValue();
|
| 303 | return new AaiResponse(aicZone , null ,HttpStatus.SC_OK);
|
| 304 | }
|
| 305 |
|
| 306 |
|
| 307 | @Override
|
| 308 | public AaiResponse getVNFData() {
|
| 309 | String payload = "{\"start\": [\"/business/customers/customer/e433710f-9217-458d-a79d-1c7aff376d89/service-subscriptions/service-subscription/VIRTUAL%20USP/service-instances/service-instance/3f93c7cb-2fd0-4557-9514-e189b7b04f9d\"], \"query\": \"query/vnf-topology-fromServiceInstance\"}";
|
| 310 | Response resp = doAaiPut(QUERY_FORMAT_SIMPLE, payload, false);
|
| 311 | return processAaiResponse(resp, AaiGetVnfResponse.class, null);
|
| 312 | }
|
| 313 |
|
| 314 | @Override
|
| 315 | public Response getVNFData(String globalSubscriberId, String serviceType) {
|
| 316 | String payload = "{\"start\": [\"business/customers/customer/" + globalSubscriberId + SERVICE_SUBSCRIPTIONS_PATH + encodePathSegment(serviceType) +"/service-instances\"]," +
|
| 317 | "\"query\": \"query/vnf-topology-fromServiceInstance\"}";
|
| 318 | return doAaiPut(QUERY_FORMAT_SIMPLE, payload, false);
|
| 319 | }
|
| 320 |
|
| 321 | @Override
|
| 322 | public AaiResponse getVNFData(String globalSubscriberId, String serviceType, String serviceInstanceId) {
|
| 323 | String payload = "{\"start\": [\"/business/customers/customer/" + globalSubscriberId + SERVICE_SUBSCRIPTIONS_PATH + encodePathSegment(serviceType) + SERVICE_INSTANCE + serviceInstanceId + "\"], \"query\": \"query/vnf-topology-fromServiceInstance\"}";
|
| 324 | Response resp = doAaiPut(QUERY_FORMAT_SIMPLE, payload, false);
|
| 325 | return processAaiResponse(resp, AaiGetVnfResponse.class, null);
|
| 326 | }
|
| 327 |
|
| 328 | @Override
|
| 329 | public Response getVersionByInvariantId(List<String> modelInvariantId) {
|
| 330 | StringBuilder sb = new StringBuilder();
|
| 331 | for (String id : modelInvariantId){
|
| 332 | sb.append(MODEL_INVARIANT_ID);
|
| 333 | sb.append(id);
|
| 334 |
|
| 335 | }
|
| 336 | return doAaiGet("service-design-and-creation/models?depth=2"+ sb.toString(), false);
|
| 337 | }
|
| 338 |
|
| 339 | @Override
|
| 340 | public AaiResponse getSubscriberData(String subscriberId) {
|
| 341 | String depth = "2";
|
| 342 | AaiResponse subscriberDataResponse;
|
| 343 | Response resp = doAaiGet(BUSINESS_CUSTOMERS_CUSTOMER + subscriberId + "?depth=" + depth, false);
|
| 344 | subscriberDataResponse = processAaiResponse(resp, Services.class, null);
|
| 345 | return subscriberDataResponse;
|
| 346 | }
|
| 347 |
|
| 348 | @Override
|
| 349 | public AaiResponse getServices() {
|
| 350 | Response resp = doAaiGet("service-design-and-creation/services", false);
|
| 351 | return processAaiResponse(resp, GetServicesAAIRespone.class, null);
|
| 352 | }
|
| 353 |
|
| 354 | @Override
|
| 355 | public AaiResponse getOperationalEnvironments(String operationalEnvironmentType, String operationalEnvironmentStatus) {
|
| 356 | String url = "cloud-infrastructure/operational-environments";
|
| 357 | URIBuilder urlBuilder = new URIBuilder();
|
| 358 | if (operationalEnvironmentType != null)
|
| 359 | urlBuilder.addParameter("operational-environment-type", operationalEnvironmentType);
|
| 360 | if (operationalEnvironmentStatus != null)
|
| 361 | urlBuilder.addParameter("operational-environment-status", operationalEnvironmentStatus);
|
| 362 | url += urlBuilder.toString();
|
| 363 | Response resp = doAaiGet(url, false);
|
| 364 | return processAaiResponse(resp, OperationalEnvironmentList.class, null);
|
| 365 | }
|
| 366 |
|
| 367 | @Override
|
| 368 | public AaiResponse getTenants(String globalCustomerId, String serviceType) {
|
| 369 | AaiResponse aaiResponse;
|
| 370 |
|
| 371 | if ((globalCustomerId == null || globalCustomerId.isEmpty()) || ((serviceType == null) || (serviceType.isEmpty())) ){
|
| 372 | aaiResponse = new AaiResponse<>(null, "{\"statusText\":\" Failed to retrieve LCP Region & Tenants from A&AI, Subscriber ID or Service Type is missing.\"}", HttpStatus.SC_INTERNAL_SERVER_ERROR);
|
| 373 | return aaiResponse;
|
| 374 | }
|
| 375 |
|
| 376 | String url = BUSINESS_CUSTOMERS_CUSTOMER + globalCustomerId + SERVICE_SUBSCRIPTIONS_PATH + serviceType;
|
| 377 |
|
| 378 | Response resp = doAaiGet(url, false);
|
| 379 | String responseAsString = parseForTenantsByServiceSubscription(resp.readEntity(String.class));
|
| 380 | if (responseAsString.equals("")){
|
| 381 | return new AaiResponse<>(null, String.format("{\"statusText\":\" A&AI has no LCP Region & Tenants associated to subscriber '%s' and service type '%s'\"}", globalCustomerId, serviceType), HttpStatus.SC_INTERNAL_SERVER_ERROR);
|
| 382 | }
|
| 383 | else {
|
| 384 | return processAaiResponse(resp, GetTenantsResponse[].class, responseAsString);
|
| 385 | }
|
| 386 | }
|
| 387 |
|
| 388 | @Override
|
| 389 | public AaiResponse getNodeTemplateInstances(String globalCustomerId, String serviceType, String modelVersionId, String modelInvariantId, String cloudRegion) {
|
| 390 |
|
| 391 | String siQuery = BUSINESS_CUSTOMER + globalCustomerId + SERVICE_SUBSCRIPTIONS_PATH + encodePathSegment(serviceType) + "/service-instances?model-version-id=" + modelVersionId + MODEL_INVARIANT_ID + modelInvariantId;
|
| 392 | String vnfQuery = "query/queryvnfFromModelbyRegion?cloudRegionId=" + encodePathSegment(cloudRegion);
|
| 393 | String payload1 = "{\"start\":\"" + siQuery + "\",\"query\":\"" + vnfQuery + "\"}";
|
| 394 |
|
| 395 | Response resp1 = doAaiPut(QUERY_FORMAT_SIMPLE, payload1, false);
|
| 396 | AaiResponse aaiResponse1 = processAaiResponse(resp1, AaiGetVnfResponse.class, null);
|
| 397 | logger.debug(EELFLoggerDelegate.debugLogger, "getNodeTemplateInstances AAI's response: {}", aaiResponse1);
|
| 398 | return aaiResponse1;
|
| 399 | }
|
| 400 |
|
| 401 | private <T> AaiResponseWithRequestInfo<T> processAaiResponse(ResponseWithRequestInfo responseWithRequestInfo, Class<? extends T> classType, boolean propagateExceptions) {
|
| 402 | String responseBody = null;
|
| 403 | Integer responseHttpCode = null;
|
| 404 | try {
|
| 405 | Response response = responseWithRequestInfo.getResponse();
|
| 406 | responseHttpCode = (response != null) ? response.getStatus() : null;
|
| 407 | responseBody = (response != null) ? response.readEntity(String.class) : null;
|
| 408 | AaiResponse<T> processedAaiResponse = processAaiResponse(response, classType, responseBody, propagateExceptions);
|
| 409 | return new AaiResponseWithRequestInfo<>(responseWithRequestInfo.getRequestHttpMethod(), responseWithRequestInfo.getRequestUrl(), processedAaiResponse,
|
| 410 | responseBody);
|
| 411 | } catch (Exception e) {
|
| 412 | throw new ExceptionWithRequestInfo(responseWithRequestInfo.getRequestHttpMethod(),
|
| 413 | responseWithRequestInfo.getRequestUrl(), responseBody, responseHttpCode, e);
|
| 414 | }
|
| 415 | }
|
| 416 |
|
| 417 | private AaiResponse processAaiResponse(Response resp, Class classType, String responseBody) {
|
| 418 | return processAaiResponse(resp, classType, responseBody, false);
|
| 419 | }
|
| 420 |
|
| 421 | private AaiResponse processAaiResponse(Response resp, Class classType, String responseBody, boolean propagateExceptions) {
|
| 422 | AaiResponse subscriberDataResponse;
|
| 423 | if (resp == null) {
|
| 424 | subscriberDataResponse = new AaiResponse<>(null, null, HttpStatus.SC_INTERNAL_SERVER_ERROR);
|
| 425 | logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "Invalid response from AAI");
|
| 426 | } else {
|
| 427 | logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "getSubscribers() resp=" + resp.getStatusInfo().toString());
|
| 428 | if (resp.getStatus() != HttpStatus.SC_OK) {
|
| 429 | logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "Invalid response from AAI");
|
| 430 | String rawData = resp.readEntity(String.class);
|
| 431 | subscriberDataResponse = new AaiResponse<>(null, rawData, resp.getStatus());
|
| 432 | } else {
|
| 433 | subscriberDataResponse = processOkResponse(resp, classType, responseBody, propagateExceptions);
|
| 434 | }
|
| 435 | }
|
| 436 | return subscriberDataResponse;
|
| 437 | }
|
| 438 |
|
| 439 | private AaiResponse processOkResponse(Response resp, Class classType, String responseBody, boolean propagateExceptions) {
|
| 440 | AaiResponse subscriberDataResponse;
|
| 441 | String finalResponse = null;
|
| 442 | try {
|
| 443 | if (responseBody != null) {
|
| 444 | finalResponse = responseBody;
|
| 445 | } else {
|
| 446 | finalResponse = resp.readEntity(String.class);
|
| 447 | }
|
| 448 |
|
| 449 | subscriberDataResponse = parseFasterXmlObject(classType, finalResponse);
|
| 450 |
|
| 451 | } catch(Exception e){
|
| 452 | if (propagateExceptions) {
|
| 453 | throw new GenericUncheckedException(e);
|
| 454 | } else {
|
| 455 | subscriberDataResponse = new AaiResponse<>(null, null, HttpStatus.SC_INTERNAL_SERVER_ERROR);
|
| 456 | logger.error("Failed to parse aai response: \"{}\" to class {}", finalResponse, classType, e);
|
| 457 | }
|
| 458 | }
|
| 459 | return subscriberDataResponse;
|
| 460 | }
|
| 461 |
|
| 462 | private AaiResponse parseFasterXmlObject(Class classType, String finalResponse) throws IOException {
|
| 463 | ObjectMapper objectMapper = new ObjectMapper();
|
| 464 | return new AaiResponse<>((objectMapper.readValue(finalResponse, classType)), null, HttpStatus.SC_OK);
|
| 465 | }
|
| 466 |
|
| 467 | public Response doAaiGet(String uri, boolean xml) {
|
| 468 | return doAaiGet(uri, xml, false).getResponse();
|
| 469 | }
|
| 470 |
|
| 471 |
|
| 472 | public ResponseWithRequestInfo doAaiGet(String uri, boolean xml, boolean propagateExceptions) {
|
| 473 | String methodName = "doAaiGet";
|
| 474 | String transId = UUID.randomUUID().toString();
|
| 475 | logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
|
| 476 |
|
| 477 | ResponseWithRequestInfo resp;
|
| 478 | try {
|
| 479 | resp = restController.RestGet(fromAppId, transId, uri, xml, propagateExceptions);
|
| 480 |
|
| 481 | } catch (Exception e) {
|
| 482 | if (propagateExceptions) {
|
| 483 | throw (e instanceof RuntimeException) ? (RuntimeException)e : new GenericUncheckedException(e);
|
| 484 | } else {
|
| 485 | final Exception actual =
|
| 486 | e instanceof ExceptionWithRequestInfo ? (Exception) e.getCause() : e;
|
| 487 |
|
| 488 | final String message =
|
| 489 | actual instanceof WebApplicationException ? ((WebApplicationException) actual).getResponse().readEntity(String.class) : e.toString();
|
| 490 |
|
| 491 | //ToDo: change parameter of requestUrl to real url from RestGet function
|
| 492 | resp = new ResponseWithRequestInfo(null, null, org.springframework.http.HttpMethod.GET);
|
| 493 | logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + message);
|
| 494 | logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + message);
|
| 495 | }
|
| 496 | }
|
| 497 | return resp;
|
| 498 | }
|
| 499 |
|
| 500 | private String parseForTenantsByServiceSubscription(String resp) {
|
| 501 | String tenantList = "";
|
| 502 |
|
| 503 | try {
|
| 504 | JSONParser jsonParser = new JSONParser();
|
| 505 |
|
| 506 | JSONObject jsonObject = (JSONObject) jsonParser.parse(resp);
|
| 507 |
|
| 508 | return parseServiceSubscriptionObjectForTenants(jsonObject);
|
| 509 | } catch (Exception ex) {
|
| 510 | logger.debug(EELFLoggerDelegate.debugLogger, "parseForTenantsByServiceSubscription error while parsing tenants by service subscription", ex);
|
| 511 | }
|
| 512 | return tenantList;
|
| 513 | }
|
| 514 |
|
| 515 | protected Response doAaiPut(String uri, String payload, boolean xml) {
|
| 516 | String methodName = "doAaiPut";
|
| 517 | String transId = UUID.randomUUID().toString();
|
| 518 | logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
|
| 519 |
|
| 520 | Response resp = null;
|
| 521 | try {
|
| 522 |
|
| 523 | resp = restController.RestPut(fromAppId, uri, payload, xml);
|
| 524 |
|
| 525 | } catch (Exception e) {
|
| 526 | logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
|
| 527 | logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
|
| 528 | }
|
| 529 | return resp;
|
| 530 | }
|
| 531 |
|
| 532 |
|
| 533 | private String parseServiceSubscriptionObjectForTenants(JSONObject jsonObject) {
|
| 534 | JSONArray tenantArray = new JSONArray();
|
| 535 | boolean bconvert = false;
|
| 536 | try {
|
| 537 | JSONObject relationShipListsObj = (JSONObject) jsonObject.get("relationship-list");
|
| 538 | if (relationShipListsObj != null) {
|
| 539 | JSONArray rShipArray = (JSONArray) relationShipListsObj.get("relationship");
|
| 540 | for (Object innerObj : defaultIfNull(rShipArray, emptyList())) {
|
| 541 | if (innerObj != null) {
|
| 542 | bconvert = parseTenant(tenantArray, bconvert, (JSONObject) innerObj);
|
| 543 | }
|
| 544 | }
|
| 545 | }
|
| 546 | } catch (NullPointerException ex) {
|
| 547 | logger.debug(EELFLoggerDelegate.debugLogger, "parseServiceSubscriptionObjectForTenants. error while parsing service subscription object for tenants", ex);
|
| 548 | }
|
| 549 |
|
| 550 | if (bconvert)
|
| 551 | return tenantArray.toJSONString();
|
| 552 | else
|
| 553 | return "";
|
| 554 |
|
| 555 | }
|
| 556 |
|
| 557 | private static boolean parseTenant(JSONArray tenantArray, boolean bconvert, JSONObject inner1Obj) {
|
| 558 | String relatedTo = checkForNull((String) inner1Obj.get("related-to"));
|
| 559 | if (relatedTo.equalsIgnoreCase("tenant")) {
|
| 560 | JSONObject tenantNewObj = new JSONObject();
|
| 561 |
|
| 562 | String relatedLink = checkForNull((String) inner1Obj.get("related-link"));
|
| 563 | tenantNewObj.put("link", relatedLink);
|
| 564 |
|
| 565 | JSONArray rDataArray = (JSONArray) inner1Obj.get("relationship-data");
|
| 566 | for (Object innerObj : defaultIfNull(rDataArray, emptyList())) {
|
| 567 | parseRelationShip(tenantNewObj, (JSONObject) innerObj);
|
| 568 | }
|
| 569 |
|
| 570 | JSONArray relatedTPropArray = (JSONArray) inner1Obj.get("related-to-property");
|
| 571 | for (Object innerObj : defaultIfNull(relatedTPropArray, emptyList())) {
|
| 572 | parseRelatedTProp(tenantNewObj, (JSONObject) innerObj);
|
| 573 | }
|
| 574 | bconvert = true;
|
| 575 | tenantArray.add(tenantNewObj);
|
| 576 | }
|
| 577 | return bconvert;
|
| 578 | }
|
| 579 |
|
| 580 | private static void parseRelatedTProp(JSONObject tenantNewObj, JSONObject innerObj) {
|
| 581 | if (innerObj == null)
|
| 582 | return;
|
| 583 |
|
| 584 | String propKey = checkForNull((String) innerObj.get("property-key"));
|
| 585 | String propVal = checkForNull((String) innerObj.get("property-value"));
|
| 586 | if (propKey.equalsIgnoreCase("tenant.tenant-name")) {
|
| 587 | tenantNewObj.put("tenantName", propVal);
|
| 588 | }
|
| 589 | }
|
| 590 |
|
| 591 | private static void parseRelationShip(JSONObject tenantNewObj, JSONObject inner2Obj) {
|
| 592 | if (inner2Obj == null)
|
| 593 | return;
|
| 594 |
|
| 595 | String rShipKey = checkForNull((String) inner2Obj.get("relationship-key"));
|
| 596 | String rShipVal = checkForNull((String) inner2Obj.get("relationship-value"));
|
| 597 | if (rShipKey.equalsIgnoreCase("cloud-region.cloud-owner")) {
|
| 598 | tenantNewObj.put("cloudOwner", rShipVal);
|
| 599 | } else if (rShipKey.equalsIgnoreCase("cloud-region.cloud-region-id")) {
|
| 600 | tenantNewObj.put("cloudRegionID", rShipVal);
|
| 601 | }
|
| 602 |
|
| 603 | if (rShipKey.equalsIgnoreCase("tenant.tenant-id")) {
|
| 604 | tenantNewObj.put("tenantID", rShipVal);
|
| 605 | }
|
| 606 | }
|
| 607 |
|
| 608 | private static String encodePathSegment(String segmentToEncode) {
|
| 609 | try {
|
| 610 | return UriUtils.encodePathSegment(segmentToEncode, "UTF-8");
|
| 611 | } catch (UnsupportedEncodingException e) {
|
| 612 | throw new GenericUncheckedException("URI encoding failed unexpectedly", e);
|
| 613 | }
|
| 614 | }
|
| 615 |
|
| 616 | @Override
|
| 617 | public ExternalComponentStatus probeAaiGetAllSubscribers(){
|
| 618 | long startTime = System.currentTimeMillis();
|
| 619 | try {
|
| 620 | AaiResponseWithRequestInfo<SubscriberList> responseWithRequestInfo = getAllSubscribers(true);
|
| 621 | AaiResponse<SubscriberList> aaiResponse = responseWithRequestInfo.getAaiResponse();
|
| 622 | long duration = System.currentTimeMillis() - startTime;
|
| 623 |
|
| 624 | SubscriberList subscribersList = (aaiResponse != null) ? aaiResponse.getT() : null;
|
| 625 | boolean isAvailable = subscribersList != null && subscribersList.customer != null && !subscribersList.customer.isEmpty();
|
| 626 |
|
| 627 | HttpRequestMetadata metadata = new HttpRequestMetadata(
|
| 628 | responseWithRequestInfo.getHttpMethod(),
|
| 629 | (aaiResponse != null) ? aaiResponse.getHttpCode() : 0,
|
| 630 | responseWithRequestInfo.getRequestedUrl(),
|
| 631 | StringUtils.substring(responseWithRequestInfo.getRawData(), 0, 500),
|
| 632 | isAvailable ? "OK" : "No subscriber received",
|
| 633 | duration
|
| 634 | );
|
| 635 | return new ExternalComponentStatus(ExternalComponentStatus.Component.AAI, isAvailable, metadata);
|
| 636 |
|
| 637 | } catch (ExceptionWithRequestInfo e) {
|
| 638 | long duration = System.currentTimeMillis() - startTime;
|
| 639 | return new ExternalComponentStatus(ExternalComponentStatus.Component.AAI, false,
|
| 640 | new HttpRequestMetadata(
|
| 641 | e.getHttpMethod(),
|
| 642 | defaultIfNull(e.getHttpCode(), 0),
|
| 643 | e.getRequestedUrl(),
|
| 644 | e.getRawData(),
|
| 645 | Logging.exceptionToDescription(e.getCause()), duration));
|
| 646 | } catch (Exception e) {
|
| 647 | long duration = System.currentTimeMillis() - startTime;
|
| 648 | return new ExternalComponentStatus(ExternalComponentStatus.Component.AAI, false,
|
| 649 | new ErrorMetadata(Logging.exceptionToDescription(e), duration));
|
| 650 | }
|
| 651 | }
|
| 652 | }
|