diff options
author | Marcus G K Williams <marcus.williams@intel.com> | 2019-04-08 21:59:29 -0700 |
---|---|---|
committer | Marcus G K Williams <marcus.williams@intel.com> | 2019-04-09 10:52:34 -0700 |
commit | 6efc32aa77960316bcb1ea93bf042e5b1b2dd303 (patch) | |
tree | 4ff9380bc27bfa2c996e2360cd069ae10ed391ec /bpmn/so-bpmn-tasks/src/main | |
parent | c6d3ec1230b2d68548587b28d4a9b02e9e96101f (diff) |
Refactor OofHomingV2
Refactor OofHomingV2 Java
to working state and fix IT tests.
Issue-ID: SO-1469
Change-Id: I8647058adf5ed41c5bebebee79f9dbc4d80c2974
Signed-off-by: Marcus G K Williams <marcus.williams@intel.com>
Diffstat (limited to 'bpmn/so-bpmn-tasks/src/main')
6 files changed, 212 insertions, 66 deletions
diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/buildingblock/OofHomingV2.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/buildingblock/OofHomingV2.java index 2524fc7892..2696313daf 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/buildingblock/OofHomingV2.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/buildingblock/OofHomingV2.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP - SO * ================================================================================ - * Copyright (C) 2017 - 2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019 Intel Corp. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ package org.onap.so.bpmn.buildingblock; import org.apache.commons.lang.SerializationUtils; +import org.apache.commons.lang.exception.ExceptionUtils; import org.camunda.bpm.engine.delegate.BpmnError; import java.util.ArrayList; import org.json.JSONArray; @@ -38,7 +39,6 @@ import org.onap.so.bpmn.servicedecomposition.bbobjects.VpnBondingLink; import org.onap.so.bpmn.servicedecomposition.entities.GeneralBuildingBlock; import org.onap.so.bpmn.servicedecomposition.generalobjects.License; import org.onap.so.bpmn.servicedecomposition.generalobjects.RequestContext; -import org.onap.so.bpmn.servicedecomposition.generalobjects.RequestParameters; import org.onap.so.bpmn.servicedecomposition.homingobjects.Candidate; import org.onap.so.bpmn.servicedecomposition.homingobjects.CandidateType; import org.onap.so.bpmn.servicedecomposition.homingobjects.SolutionCandidates; @@ -49,13 +49,14 @@ import org.onap.so.client.exception.BadResponseException; import org.onap.so.client.exception.ExceptionBuilder; import org.onap.so.client.oof.OofClient; import org.onap.so.client.oof.OofValidator; +import org.onap.so.client.oof.beans.LicenseDemand; +import org.onap.so.client.oof.beans.LicenseInfo; import org.onap.so.client.oof.beans.ModelInfo; import org.onap.so.client.oof.beans.OofRequest; import org.onap.so.client.oof.beans.OofRequestParameters; import org.onap.so.client.oof.beans.PlacementDemand; import org.onap.so.client.oof.beans.PlacementInfo; import org.onap.so.client.oof.beans.RequestInfo; -import org.onap.so.client.oof.beans.ResourceModelInfo; import org.onap.so.client.oof.beans.ServiceInfo; import org.onap.so.client.oof.beans.SubscriberInfo; import org.onap.so.db.catalog.beans.OrchestrationStatus; @@ -85,7 +86,7 @@ public class OofHomingV2 { @Autowired private Environment env; @Autowired - private OofClient client; + private OofClient oofClient; @Autowired private OofValidator oofValidator; @Autowired @@ -98,7 +99,6 @@ public class OofHomingV2 { private static final String RESOURCE_MODULE_NAME = "resourceModuleName"; private static final String RESOURCE_MODEL_INFO = "resourceModelInfo"; private static final String IDENTIFIER_TYPE = "identifierType"; - private static final String INVENTORY_TYPE = "inventoryType"; private static final String SOLUTIONS = "solutions"; private static final String RESOURCE_MISSING_DATA = "Resource does not contain: "; private static final String SERVICE_MISSING_DATA = "Service Instance does not contain: "; @@ -111,12 +111,11 @@ public class OofHomingV2 { * @param execution */ public void callOof(BuildingBlockExecution execution) { - logger.trace("Started Sniro Homing Call Sniro"); + logger.trace("Started Oof Homing Call Oof"); try { GeneralBuildingBlock bb = execution.getGeneralBuildingBlock(); RequestContext requestContext = bb.getRequestContext(); - RequestParameters requestParams = requestContext.getRequestParameters(); String requestId = requestContext.getMsoRequestId(); ServiceInstance serviceInstance = bb.getCustomer().getServiceSubscription().getServiceInstances().get(0); @@ -127,28 +126,24 @@ public class OofHomingV2 { timeout = env.getProperty("oof.timeout", "PT30M"); } - OofRequest request = new OofRequest(); + OofRequest oofRequest = new OofRequest(); RequestInfo requestInfo = (RequestInfo) buildRequestInfo(requestId, timeout); - request.setRequestInformation(requestInfo); + oofRequest.setRequestInformation(requestInfo); ServiceInfo serviceInfo = buildServiceInfo(serviceInstance); - request.setServiceInformation(serviceInfo); + oofRequest.setServiceInformation(serviceInfo); - PlacementInfo placementInfo = buildPlacementInfo(customer, requestParams); + PlacementInfo placementInfo = buildPlacementInfo(customer); - ArrayList<PlacementDemand> placementDemands = buildPlacementDemands(serviceInstance); - placementInfo.setPlacementDemands(placementDemands); - request.setPlacementInformation(placementInfo); + placementInfo = buildPlacementDemands(serviceInstance, placementInfo); + oofRequest.setPlacementInformation(placementInfo); - JSONObject licenseInfo = new JSONObject(); + LicenseInfo licenseInfo = buildLicenseInfo(serviceInstance); + oofRequest.setLicenseInformation(licenseInfo); - JSONArray licenseDemands = buildLicenseDemands(serviceInstance); - licenseInfo.put("licenseDemands", licenseDemands); - request.setLicenseInformation(licenseInfo.toString()); - - if (placementDemands.size() > 0 || licenseDemands.length() > 0) { - client.postDemands(request); + if (!placementInfo.getPlacementDemands().isEmpty() || !licenseInfo.getLicenseDemands().isEmpty()) { + oofClient.postDemands(oofRequest); } else { logger.debug(SERVICE_MISSING_DATA + " resources eligible for homing or licensing"); throw new BpmnError(UNPROCESSABLE, @@ -162,12 +157,15 @@ public class OofHomingV2 { logger.trace("Completed Oof Homing Call Oof"); } catch (BpmnError e) { + logger.debug(" Error - while preparing oof request: " + e.getStackTrace()); exceptionUtil.buildAndThrowWorkflowException(execution, Integer.parseInt(e.getErrorCode()), e.getMessage()); } catch (BadResponseException e) { + logger.debug(" Error - while preparing oof request: " + e.getStackTrace()); exceptionUtil.buildAndThrowWorkflowException(execution, 400, e.getMessage()); } catch (Exception e) { - exceptionUtil.buildAndThrowWorkflowException(execution, INTERNAL, - "Internal Error - occurred while preparing oof request: " + e.getMessage()); + logger.debug(" Error - while preparing oof request: " + e.getStackTrace()); + exceptionUtil.buildAndThrowWorkflowException(execution, INTERNAL, "Internal Error - occurred while " + + "preparing oof request: " + e + " Stack:" + ExceptionUtils.getFullStackTrace(e)); } } @@ -240,6 +238,10 @@ public class OofHomingV2 { requestInfo.setSourceId("mso"); requestInfo.setRequestType("create"); requestInfo.setTimeout(timeoutSeconds); + requestInfo.setNumSolutions(1); + ArrayList optimizers = new ArrayList(); + optimizers.add("placement"); + requestInfo.setOptimizers(optimizers); } else { throw new BpmnError(UNPROCESSABLE, "Request Context does not contain: requestId"); } @@ -270,7 +272,7 @@ public class OofHomingV2 { * Builds initial section of placement info for the homing/licensing request * */ - private PlacementInfo buildPlacementInfo(Customer customer, RequestParameters requestParams) { + private PlacementInfo buildPlacementInfo(Customer customer) { PlacementInfo placementInfo = new PlacementInfo(); if (customer != null) { logger.debug("Adding subscriber to placement information"); @@ -279,22 +281,11 @@ public class OofHomingV2 { subscriberInfo.setSubscriberName(customer.getSubscriberName()); subscriberInfo.setSubscriberCommonSiteId(customer.getSubscriberCommonSiteId()); placementInfo.setSubscriberInfo(subscriberInfo); - if (requestParams != null) { - logger.debug("Adding request parameters to placement information"); - OofRequestParameters oofRequestParams = new OofRequestParameters(); - for (Map requestParam : requestParams.getUserParams()) { - if (requestParam.containsKey("customerLatitude")) { - oofRequestParams.setCustomerLatitude(requestParam.get("customerLatitude").toString()); - } - if (requestParam.containsKey("customerLongitude")) { - oofRequestParams.setCustomerLongitude(requestParam.get("customerLongitude").toString()); - } - if (requestParam.containsKey("customerName")) { - oofRequestParams.setCustomerName(requestParam.get("customerName").toString()); - } - } - placementInfo.setRequestParameters(oofRequestParams); - } + OofRequestParameters oofRequestParams = new OofRequestParameters(); + oofRequestParams.setCustomerLatitude(customer.getCustomerLatitude()); + oofRequestParams.setCustomerLongitude(customer.getCustomerLongitude()); + oofRequestParams.setCustomerName(customer.getSubscriberName()); + placementInfo.setRequestParameters(oofRequestParams); } else { throw new BpmnError(UNPROCESSABLE, SERVICE_MISSING_DATA + "customer"); } @@ -306,9 +297,8 @@ public class OofHomingV2 { * Builds the placement demand list for the homing/licensing request * */ - private ArrayList<PlacementDemand> buildPlacementDemands(ServiceInstance serviceInstance) { + private PlacementInfo buildPlacementDemands(ServiceInstance serviceInstance, PlacementInfo placementInfo) { logger.trace("Building placement information demands"); - ArrayList<PlacementDemand> placementDemands = new ArrayList(); List<AllottedResource> allottedResourceList = serviceInstance.getAllottedResources(); if (!allottedResourceList.isEmpty()) { @@ -319,7 +309,7 @@ public class OofHomingV2 { } PlacementDemand demand = buildDemand(ar.getId(), ar.getModelInfoAllottedResource()); // addCandidates(ar, demand); - placementDemands.add(demand); + placementInfo.getPlacementDemands().add(demand); } } List<VpnBondingLink> vpnBondingLinkList = serviceInstance.getVpnBondingLinks(); @@ -333,42 +323,43 @@ public class OofHomingV2 { } PlacementDemand demand = buildDemand(sp.getId(), sp.getModelInfoServiceProxy()); // addCandidates(sp, demand); - placementDemands.add(demand); + placementInfo.getPlacementDemands().add(demand); } } } - return placementDemands; + return placementInfo; } /** * Builds the license demand list for the homing/licensing request * */ - private JSONArray buildLicenseDemands(ServiceInstance serviceInstance) { + private LicenseInfo buildLicenseInfo(ServiceInstance serviceInstance) { logger.trace("Building license information"); - JSONArray licenseDemands = new JSONArray(); + LicenseInfo licenseInfo = new LicenseInfo(); List<GenericVnf> vnfList = serviceInstance.getVnfs(); if (!vnfList.isEmpty()) { logger.debug("Adding vnfs to license demands list"); for (GenericVnf vnf : vnfList) { - JSONObject demand = buildLicenseDemand(vnf.getVnfId(), vnf.getModelInfoGenericVnf()); - licenseDemands.put(demand); + LicenseDemand demand = buildLicenseDemand(vnf.getVnfId(), vnf.getModelInfoGenericVnf()); + licenseInfo.getLicenseDemands().add(demand); } } - return licenseDemands; + return licenseInfo; } /** * Builds a single license demand object * */ - private JSONObject buildLicenseDemand(String id, ModelInfoMetadata metadata) { + private LicenseDemand buildLicenseDemand(String id, ModelInfoMetadata metadata) { logger.debug("Building demand for service or resource: " + id); - JSONObject demand = new JSONObject(); + LicenseDemand demand = new LicenseDemand(); if (isNotBlank(id) && isNotBlank(metadata.getModelInstanceName())) { - demand.put(SERVICE_RESOURCE_ID, id); - demand.put(RESOURCE_MODULE_NAME, metadata.getModelInstanceName()); - demand.put(RESOURCE_MODEL_INFO, buildModelInfo(metadata)); + + demand.setServiceResourceId(id); + demand.setResourceModuleName(metadata.getModelInstanceName()); + demand.setResourceModelInfo(buildModelInfo(metadata)); } else { throw new BpmnError(UNPROCESSABLE, RESOURCE_MISSING_DATA + "modelInstanceName"); } @@ -385,7 +376,7 @@ public class OofHomingV2 { if (isNotBlank(id) && isNotBlank(metadata.getModelInstanceName())) { placementDemand.setServiceResourceId(id); placementDemand.setResourceModuleName(metadata.getModelInstanceName()); - placementDemand.setResourceModelInfo((ResourceModelInfo) buildModelInfo(metadata)); + placementDemand.setResourceModelInfo(buildModelInfo(metadata)); } else { throw new BpmnError(UNPROCESSABLE, RESOURCE_MISSING_DATA + "modelInstanceName"); } @@ -525,11 +516,11 @@ public class OofHomingV2 { JSONArray assignments = placement.getJSONArray("assignmentInfo"); Map<String, String> assignmentsMap = jsonUtils.entryArrayToMap(assignments.toString(), "key", "value"); solutionInfo.setRehome(Boolean.parseBoolean(assignmentsMap.get("isRehome"))); - String type = placement.getString(INVENTORY_TYPE); + String type = identifierType; ServiceInstance si = new ServiceInstance(); CloudRegion cloud = setCloud(assignmentsMap); - if (type.equals("service")) { + if (type.equals("serviceInstanceId")) { if (identifierType.equals(CandidateType.SERVICE_INSTANCE_ID.toString())) { solutionInfo.setHomed(true); si.setServiceInstanceId(identifierValue); @@ -556,7 +547,7 @@ public class OofHomingV2 { logger.debug(invalidMessage + IDENTIFIER_TYPE); throw new BpmnError(UNPROCESSABLE, invalidMessage + IDENTIFIER_TYPE); } - } else if (type.equals("cloud")) { + } else if (type.equals("cloudRegionId")) { if (identifierType.equals(CandidateType.CLOUD_REGION_ID.toString())) { logger.debug("Resources has been homed to a cloud region"); cloud.setLcpCloudRegionId(identifierValue); @@ -567,9 +558,6 @@ public class OofHomingV2 { logger.debug(invalidMessage + IDENTIFIER_TYPE); throw new BpmnError(UNPROCESSABLE, invalidMessage + IDENTIFIER_TYPE); } - } else { - logger.debug(invalidMessage + INVENTORY_TYPE); - throw new BpmnError(UNPROCESSABLE, invalidMessage + INVENTORY_TYPE); } si.setSolutionInfo(solutionInfo); return si; diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/LicenseDemand.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/LicenseDemand.java new file mode 100644 index 0000000000..e64a5450b5 --- /dev/null +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/LicenseDemand.java @@ -0,0 +1,97 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2019 Intel Corp. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.client.oof.beans; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonRootName; +import java.io.Serializable; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({"resourceModuleName", "serviceResourceId", "tenantId", "resourceModelInfo"}) +@JsonRootName("licenseDemand") +public class LicenseDemand implements Serializable { + + private static final long serialVersionUID = -759180997599143791L; + + @JsonProperty("resourceModuleName") + private String resourceModuleName; + @JsonProperty("serviceResourceId") + private String serviceResourceId; + @JsonProperty("tenantId") + private String tenantId; + @JsonProperty("resourceModelInfo") + private ResourceModelInfo resourceModelInfo; + + @JsonProperty("resourceModuleName") + public String getResourceModuleName() { + return resourceModuleName; + } + + @JsonProperty("resourceModuleName") + public void setResourceModuleName(String resourceModuleName) { + this.resourceModuleName = resourceModuleName; + } + + @JsonProperty("serviceResourceId") + public String getServiceResourceId() { + return serviceResourceId; + } + + @JsonProperty("serviceResourceId") + public void setServiceResourceId(String serviceResourceId) { + this.serviceResourceId = serviceResourceId; + } + + @JsonProperty("tenantId") + public String getTenantId() { + return tenantId; + } + + @JsonProperty("tenantId") + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + @JsonProperty("resourceModelInfo") + public ResourceModelInfo getResourceModelInfo() { + return resourceModelInfo; + } + + @JsonProperty("resourceModelInfo") + public void setResourceModelInfo(ResourceModelInfo resourceModelInfo) { + this.resourceModelInfo = resourceModelInfo; + } + + public void setResourceModelInfo(ModelInfo modelInfo) { + ResourceModelInfo localResourceModelInfo = new ResourceModelInfo(); + localResourceModelInfo.setModelVersionId(modelInfo.getModelVersionId()); + localResourceModelInfo.setModelVersionId(modelInfo.getModelVersionId()); + localResourceModelInfo.setModelVersion(modelInfo.getModelVersion()); + localResourceModelInfo.setModelName(modelInfo.getModelName()); + localResourceModelInfo.setModelType(modelInfo.getModelType()); + localResourceModelInfo.setModelInvariantId(modelInfo.getModelInvariantId()); + localResourceModelInfo.setModelCustomizationName(modelInfo.getModelCustomizationName()); + this.resourceModelInfo = localResourceModelInfo; + } + +} diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/LicenseInfo.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/LicenseInfo.java new file mode 100644 index 0000000000..74ff9339d3 --- /dev/null +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/LicenseInfo.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2019 Intel Corp. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.client.oof.beans; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonRootName; +import java.io.Serializable; +import java.util.ArrayList; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonRootName("licenseInfo") +public class LicenseInfo implements Serializable { + + private static final long serialVersionUID = -759180997599143791L; + + @JsonProperty("licenseDemands") + private ArrayList<LicenseDemand> licenseDemands = new ArrayList<>(); + + + @JsonProperty("licenseDemands") + public ArrayList<LicenseDemand> getLicenseDemands() { + return licenseDemands; + } + + @JsonProperty("licenseDemands") + public void setLicenseDemands(ArrayList<LicenseDemand> licenseDemands) { + this.licenseDemands = licenseDemands; + } + +} diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/OofRequest.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/OofRequest.java index e3c29fe04d..f8896240ba 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/OofRequest.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/OofRequest.java @@ -46,7 +46,7 @@ public class OofRequest implements Serializable { private PlacementInfo placementInformation; @JsonProperty("licenseInfo") - private String licenseInformation; + private LicenseInfo licenseInformation; public RequestInfo getRequestInformation() { @@ -73,11 +73,11 @@ public class OofRequest implements Serializable { this.placementInformation = placementInformation; } - public String getLicenseInformation() { + public LicenseInfo getLicenseInformation() { return licenseInformation; } - public void setLicenseInformation(String licenseInformation) { + public void setLicenseInformation(LicenseInfo licenseInformation) { this.licenseInformation = licenseInformation; } diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/PlacementDemand.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/PlacementDemand.java index 73c100df6d..631b3707d4 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/PlacementDemand.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/PlacementDemand.java @@ -82,4 +82,16 @@ public class PlacementDemand implements Serializable { this.resourceModelInfo = resourceModelInfo; } + public void setResourceModelInfo(ModelInfo modelInfo) { + ResourceModelInfo localResourceModelInfo = new ResourceModelInfo(); + localResourceModelInfo.setModelVersionId(modelInfo.getModelVersionId()); + localResourceModelInfo.setModelVersionId(modelInfo.getModelVersionId()); + localResourceModelInfo.setModelVersion(modelInfo.getModelVersion()); + localResourceModelInfo.setModelName(modelInfo.getModelName()); + localResourceModelInfo.setModelType(modelInfo.getModelType()); + localResourceModelInfo.setModelInvariantId(modelInfo.getModelInvariantId()); + localResourceModelInfo.setModelCustomizationName(modelInfo.getModelCustomizationName()); + this.resourceModelInfo = localResourceModelInfo; + } + } diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/PlacementInfo.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/PlacementInfo.java index 0eb14d991a..7519e8c87e 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/PlacementInfo.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/client/oof/beans/PlacementInfo.java @@ -39,7 +39,7 @@ public class PlacementInfo implements Serializable { @JsonProperty("subscriberInfo") private SubscriberInfo subscriberInfo; @JsonProperty("placementDemands") - private ArrayList<PlacementDemand> placementDemands = null; + private ArrayList<PlacementDemand> placementDemands = new ArrayList<>(); @JsonProperty("requestParameters") public OofRequestParameters getRequestParameters() { |