Give better messages than NPE for missing data 61/117561/2
authorJim Hahn <jrh3@att.com>
Fri, 5 Feb 2021 16:13:31 +0000 (11:13 -0500)
committerJim Hahn <jrh3@att.com>
Fri, 5 Feb 2021 17:52:50 +0000 (12:52 -0500)
When data is not available to actor operations, an NPE is generally
thrown.  Modified the code to provide more info about what is missing
than simply NPE.

Issue-ID: POLICY-2913
Change-Id: I37b6eadd966e0693508a6d552b7db4edf5410018
Signed-off-by: Jim Hahn <jrh3@att.com>
20 files changed:
models-interactions/model-actors/actor.aai/src/main/java/org/onap/policy/controlloop/actor/aai/AaiGetPnfOperation.java
models-interactions/model-actors/actor.aai/src/main/java/org/onap/policy/controlloop/actor/aai/AaiGetTenantOperation.java
models-interactions/model-actors/actor.aai/src/test/java/org/onap/policy/controlloop/actor/aai/AaiGetPnfOperationTest.java
models-interactions/model-actors/actor.aai/src/test/java/org/onap/policy/controlloop/actor/aai/AaiGetTenantOperationTest.java
models-interactions/model-actors/actor.appclcm/src/main/java/org/onap/policy/controlloop/actor/appclcm/AppcLcmOperation.java
models-interactions/model-actors/actor.appclcm/src/test/java/org/onap/policy/controlloop/actor/appclcm/AppcLcmOperationTest.java
models-interactions/model-actors/actor.sdnc/src/main/java/org/onap/policy/controlloop/actor/sdnc/BandwidthOnDemandOperation.java
models-interactions/model-actors/actor.sdnc/src/test/java/org/onap/policy/controlloop/actor/sdnc/BandwidthOnDemandOperationTest.java
models-interactions/model-actors/actor.sdnr/src/main/java/org/onap/policy/controlloop/actor/sdnr/SdnrOperation.java
models-interactions/model-actors/actor.sdnr/src/test/java/org/onap/policy/controlloop/actor/sdnr/SdnrOperationTest.java
models-interactions/model-actors/actor.so/src/main/java/org/onap/policy/controlloop/actor/so/ModifyNssi.java
models-interactions/model-actors/actor.so/src/main/java/org/onap/policy/controlloop/actor/so/SoOperation.java
models-interactions/model-actors/actor.so/src/main/java/org/onap/policy/controlloop/actor/so/VfModuleCreate.java
models-interactions/model-actors/actor.so/src/main/java/org/onap/policy/controlloop/actor/so/VfModuleDelete.java
models-interactions/model-actors/actor.so/src/test/java/org/onap/policy/controlloop/actor/so/ModifyNssiTest.java
models-interactions/model-actors/actor.so/src/test/java/org/onap/policy/controlloop/actor/so/SoOperationTest.java
models-interactions/model-actors/actor.so/src/test/java/org/onap/policy/controlloop/actor/so/VfModuleCreateTest.java
models-interactions/model-actors/actor.so/src/test/java/org/onap/policy/controlloop/actor/so/VfModuleDeleteTest.java
models-interactions/model-actors/actor.so/src/test/resources/VfModuleDelete.json
models-interactions/model-actors/actor.so/src/test/resources/vfModuleCreate.json

index c1582c5..1f19918 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. 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.
@@ -72,7 +72,7 @@ public class AaiGetPnfOperation extends AaiGetOperation {
 
         StringBuilder str = new StringBuilder(getClient().getBaseUrl());
 
-        String target = getProperty(OperationProperties.AAI_TARGET_ENTITY);
+        String target = getRequiredProperty(OperationProperties.AAI_TARGET_ENTITY, "target entity");
         String path = getPath() + URI_SEP + URLEncoder.encode(target, StandardCharsets.UTF_8);
         WebTarget web = getClient().getWebTarget().path(path);
         str.append(path);
index b3bf4ce..412e463 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. 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.
@@ -73,7 +73,7 @@ public class AaiGetTenantOperation extends AaiGetOperation {
         WebTarget web = getClient().getWebTarget().path(path);
         str.append(path);
 
-        String target = getProperty(OperationProperties.AAI_TARGET_ENTITY);
+        String target = getRequiredProperty(OperationProperties.AAI_TARGET_ENTITY, "target entity");
 
         web = addQuery(web, str, "?", "search-node-type", "vserver");
         web = addQuery(web, str, "&", "filter", "vserver-name:EQUALS:" + target);
index 9e72fe2..a5c115b 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. 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.policy.controlloop.actor.aai;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -164,6 +165,20 @@ public class AaiGetPnfOperationTest extends BasicAaiOperation {
         assertEquals(OperationResult.FAILURE, future2.get().getResult());
     }
 
+    /**
+     * Tests startOperationAsync() when a property is missing.
+     */
+    @Test
+    public void testStartOperationAsyncMissingProperty() throws Exception {
+        oper = new AaiGetPnfOperation(params, config);
+
+        oper.generateSubRequestId(1);
+        outcome.setSubRequestId(oper.getSubRequestId());
+
+        assertThatIllegalStateException().isThrownBy(() -> oper.startOperationAsync(1, outcome))
+                        .withMessageContaining("missing target entity");
+    }
+
     @Test
     public void testGetKey() {
         assertEquals("AAI.Pnf." + TARGET_ENTITY, AaiGetPnfOperation.getKey(TARGET_ENTITY));
index a79a8f7..86c52ae 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. 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.policy.controlloop.actor.aai;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -164,6 +165,20 @@ public class AaiGetTenantOperationTest extends BasicAaiOperation {
         assertEquals(OperationResult.FAILURE, future2.get().getResult());
     }
 
+    /**
+     * Tests startOperationAsync() when a property is missing.
+     */
+    @Test
+    public void testStartOperationAsyncMissingProperty() throws Exception {
+        oper = new AaiGetTenantOperation(params, config);
+
+        oper.generateSubRequestId(1);
+        outcome.setSubRequestId(oper.getSubRequestId());
+
+        assertThatIllegalStateException().isThrownBy(() -> oper.startOperationAsync(1, outcome))
+                        .withMessageContaining("missing target entity");
+    }
+
     @Test
     public void testGetKey() {
         assertEquals("AAI.Tenant." + TARGET_ENTITY, AaiGetTenantOperation.getKey(TARGET_ENTITY));
index bf20478..559709e 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. 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.
@@ -84,7 +84,7 @@ public class AppcLcmOperation extends BidirectionalTopicOperation<AppcLcmDmaapWr
          * Action Identifiers are required for APPC LCM requests. For R1, the recipes
          * supported by Policy only require a vnf-id.
          */
-        String target = getProperty(OperationProperties.AAI_TARGET_ENTITY);
+        String target = getRequiredProperty(OperationProperties.AAI_TARGET_ENTITY, "target entity");
         inputRequest.setActionIdentifiers(Map.of(VNF_ID_KEY, target));
 
         /*
index b9999f4..3649645 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. 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.
@@ -22,7 +22,7 @@ package org.onap.policy.controlloop.actor.appclcm;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -159,6 +159,18 @@ public class AppcLcmOperationTest extends BasicBidirectionalTopicOperation<AppcL
         assertEquals(subreq, request.getBody().getInput().getCommonHeader().getSubRequestId());
     }
 
+    /**
+     * Tests makeRequest() when a property is missing.
+     */
+    @Test
+    public void testMakeRequestMissingProperty() throws Exception {
+        oper = new AppcLcmOperation(params, config);
+        oper.generateSubRequestId(1);
+
+        assertThatIllegalStateException().isThrownBy(() -> oper.makeRequest(1))
+                        .withMessageContaining("missing target entity");
+    }
+
     @Test
     public void testConvertPayload() {
         // only builds a payload for ConfigModify
@@ -183,9 +195,11 @@ public class AppcLcmOperationTest extends BasicBidirectionalTopicOperation<AppcL
             }
         };
 
+        oper.setProperty(OperationProperties.AAI_TARGET_ENTITY, TARGET_ENTITY);
         oper.generateSubRequestId(2);
 
-        assertThatThrownBy(() -> oper.makeRequest(2)).isInstanceOf(NullPointerException.class);
+        assertThatIllegalArgumentException().isThrownBy(() -> oper.makeRequest(2))
+                        .withMessageContaining("Cannot convert payload");
     }
 
     @Test
index 2946a20..61bf838 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. 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.
@@ -73,11 +73,13 @@ public class BandwidthOnDemandOperation extends SdncOperation {
 
         SdncHealVfModuleParameter bandwidth = new SdncHealVfModuleParameter();
         bandwidth.setName(BANDWIDTH);
-        bandwidth.setValue(getProperty(OperationProperties.ENRICHMENT_BANDWIDTH));
+        bandwidth.setValue(getRequiredProperty(OperationProperties.ENRICHMENT_BANDWIDTH,
+                        "bandwidth from enrichment data"));
 
         SdncHealVfModuleParameter timeStamp = new SdncHealVfModuleParameter();
         timeStamp.setName(BANDWIDTH_CHANGE_TIME);
-        timeStamp.setValue(getProperty(OperationProperties.ENRICHMENT_BANDWIDTH_CHANGE_TIME));
+        timeStamp.setValue(getRequiredProperty(OperationProperties.ENRICHMENT_BANDWIDTH_CHANGE_TIME,
+                        "bandwidth change time from enrichment data"));
 
         SdncHealVfModuleParametersInfo vfParametersInfo = new SdncHealVfModuleParametersInfo();
         vfParametersInfo.addParameters(bandwidth);
@@ -102,7 +104,7 @@ public class BandwidthOnDemandOperation extends SdncOperation {
         request.setUrl("/" + getPath());
 
         SdncHealVnfInfo vnfInfo = new SdncHealVnfInfo();
-        vnfInfo.setVnfId(getProperty(OperationProperties.ENRICHMENT_VNF_ID));
+        vnfInfo.setVnfId(getRequiredProperty(OperationProperties.ENRICHMENT_VNF_ID, "VNF id from enrichment data"));
 
         SdncHealVfModuleInfo vfModuleInfo = new SdncHealVfModuleInfo();
         vfModuleInfo.setVfModuleId("");
index 8c12be8..ebfc04d 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. 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.policy.controlloop.actor.sdnc;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
@@ -118,4 +119,50 @@ public class BandwidthOnDemandOperationTest extends BasicSdncOperation {
 
         verifyRequest("bod.json", verifyOperation(oper), IGNORE_FIELDS);
     }
+
+    /*
+     * Tests makeRequest() when a property is missing.
+     */
+
+    @Test
+    public void testMakeRequestMissingBandwidth() throws Exception {
+        oper = new BandwidthOnDemandOperation(params, config);
+        oper.setProperty(OperationProperties.ENRICHMENT_SERVICE_ID, MY_SERVICE);
+        oper.setProperty(OperationProperties.ENRICHMENT_BANDWIDTH_CHANGE_TIME, MY_CHANGE_TIME);
+        oper.setProperty(OperationProperties.ENRICHMENT_VNF_ID, MY_VNF);
+
+        oper.generateSubRequestId(1);
+        outcome.setSubRequestId(oper.getSubRequestId());
+
+        assertThatIllegalStateException().isThrownBy(() -> oper.makeRequest(1))
+                        .withMessageContaining("missing bandwidth from enrichment data");
+    }
+
+    @Test
+    public void testMakeRequestMissingBandwidthChangeTime() throws Exception {
+        oper = new BandwidthOnDemandOperation(params, config);
+        oper.setProperty(OperationProperties.ENRICHMENT_SERVICE_ID, MY_SERVICE);
+        oper.setProperty(OperationProperties.ENRICHMENT_BANDWIDTH, MY_BANDWIDTH);
+        oper.setProperty(OperationProperties.ENRICHMENT_VNF_ID, MY_VNF);
+
+        oper.generateSubRequestId(1);
+        outcome.setSubRequestId(oper.getSubRequestId());
+
+        assertThatIllegalStateException().isThrownBy(() -> oper.makeRequest(1))
+                        .withMessageContaining("missing bandwidth change time from enrichment data");
+    }
+
+    @Test
+    public void testMakeRequestMissingVnfId() throws Exception {
+        oper = new BandwidthOnDemandOperation(params, config);
+        oper.setProperty(OperationProperties.ENRICHMENT_SERVICE_ID, MY_SERVICE);
+        oper.setProperty(OperationProperties.ENRICHMENT_BANDWIDTH, MY_BANDWIDTH);
+        oper.setProperty(OperationProperties.ENRICHMENT_BANDWIDTH_CHANGE_TIME, MY_CHANGE_TIME);
+
+        oper.generateSubRequestId(1);
+        outcome.setSubRequestId(oper.getSubRequestId());
+
+        assertThatIllegalStateException().isThrownBy(() -> oper.makeRequest(1))
+                        .withMessageContaining("missing VNF id from enrichment data");
+    }
 }
index 14f77a6..ebfbaba 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * SdnrOperation
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. 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.
@@ -150,7 +150,7 @@ public class SdnrOperation extends BidirectionalTopicOperation<PciMessage, PciMe
         requestCommonHeader.setSubRequestId(subRequestId);
 
         sdnrRequest.setCommonHeader(requestCommonHeader);
-        sdnrRequest.setPayload(getProperty(OperationProperties.EVENT_PAYLOAD));
+        sdnrRequest.setPayload(getRequiredProperty(OperationProperties.EVENT_PAYLOAD, "event payload"));
         sdnrRequest.setAction(params.getOperation());
 
         /*
index 3a8f0b7..ba3a600 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * SdnrOperation
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. 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.policy.controlloop.actor.sdnr;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertSame;
@@ -67,6 +68,7 @@ public class SdnrOperationTest extends BasicSdnrOperation {
         super.setUp();
 
         operation = new SdnrOperation(params, config);
+        operation.setProperty(OperationProperties.EVENT_PAYLOAD, "my payload");
     }
 
     @After
@@ -106,6 +108,20 @@ public class SdnrOperationTest extends BasicSdnrOperation {
         assertEquals(params.getRequestId(), header.getRequestId());
     }
 
+    /**
+     * Tests makeRequest() when a property is missing.
+     */
+    @Test
+    public void testMakeRequestMissingProperty() throws Exception {
+        operation = new SdnrOperation(params, config);
+
+        operation.generateSubRequestId(1);
+        outcome.setSubRequestId(operation.getSubRequestId());
+
+        assertThatIllegalStateException().isThrownBy(() -> operation.makeRequest(1))
+                        .withMessageContaining("missing event payload");
+    }
+
     @Test
     public void testGetExpectedKeyValues() {
         operation.generateSubRequestId(1);
@@ -127,6 +143,7 @@ public class SdnrOperationTest extends BasicSdnrOperation {
         params = params.toBuilder().retry(0).timeoutSec(5).executor(blockingExecutor).build();
 
         operation = new SdnrOperation(params, config);
+        operation.setProperty(OperationProperties.EVENT_PAYLOAD, "my payload");
 
         outcome = operation.start().get();
         assertEquals(OperationResult.SUCCESS, outcome.getResult());
index 2c50388..5386d96 100644 (file)
@@ -3,6 +3,7 @@
  * ONAP
  * ================================================================================
  * Copyright (C) 2020 Wipro Limited.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. 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.
@@ -67,9 +68,9 @@ public class ModifyNssi extends SoOperation {
         return handleResponse(outcome, url, callback -> getClient().put(callback, path, entity, headers));
     }
 
-    private SoRequest3gpp makeRequest() {
+    protected SoRequest3gpp makeRequest() {
 
-        String payload = getProperty(OperationProperties.EVENT_PAYLOAD);
+        String payload = getRequiredProperty(OperationProperties.EVENT_PAYLOAD, "event payload");
         try {
             return getCoder().convert(payload, SoRequest3gpp.class);
         } catch (CoderException e) {
index e3328e9..8d3fb59 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
  * Modifications Copyright (C) 2020 Wipro Limited.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -324,11 +324,26 @@ public abstract class SoOperation extends HttpOperation<SoResponse> {
      */
     protected SoCloudConfiguration constructCloudConfiguration(Tenant tenantItem, CloudRegion cloudRegionItem) {
         SoCloudConfiguration cloudConfiguration = new SoCloudConfiguration();
-        cloudConfiguration.setTenantId(tenantItem.getTenantId());
-        cloudConfiguration.setLcpCloudRegionId(cloudRegionItem.getCloudRegionId());
+        cloudConfiguration.setTenantId(getRequiredText("tenant ID", tenantItem.getTenantId()));
+        cloudConfiguration.setLcpCloudRegionId(getRequiredText("cloud region ID", cloudRegionItem.getCloudRegionId()));
         return cloudConfiguration;
     }
 
+    /**
+     * Verifies that a value is not {@code null}.
+     *
+     * @param name value name
+     * @param value value to check
+     * @return the value
+     */
+    protected String getRequiredText(String name, String value) {
+        if (value == null) {
+            throw new IllegalArgumentException("missing " + name);
+        }
+
+        return value;
+    }
+
     /**
      * Create simple HTTP headers for unauthenticated requests to SO.
      *
index b778c10..3d753bb 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
  * Modifications Copyright (C) 2020 Wipro Limited.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -197,8 +197,8 @@ public class VfModuleCreate extends SoOperation {
         buildConfigurationParameters().ifPresent(request.getRequestDetails()::setConfigurationParameters);
 
         // compute the path
-        String path = PATH_PREFIX + vnfServiceItem.getServiceInstanceId() + "/vnfs/" + vnfItem.getVnfId()
-                        + "/vfModules/scaleOut";
+        String svcId = getRequiredText("service instance ID", vnfServiceItem.getServiceInstanceId());
+        String path = PATH_PREFIX + svcId + "/vnfs/" + vnfItem.getVnfId() + "/vfModules/scaleOut";
 
         return Pair.of(path, request);
     }
index b824440..1881b5c 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
  * Modifications Copyright (C) 2020 Wipro Limited.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -239,8 +239,8 @@ public class VfModuleDelete extends SoOperation {
          */
 
         // compute the path
-        String path = PATH_PREFIX + vnfServiceItem.getServiceInstanceId() + "/vnfs/" + vnfItem.getVnfId()
-                        + "/vfModules/null";
+        String svcId = getRequiredText("service instance ID", vnfServiceItem.getServiceInstanceId());
+        String path = PATH_PREFIX + svcId + "/vnfs/" + vnfItem.getVnfId() + "/vfModules/null";
 
         return Pair.of(path, request);
     }
index 2ef9caa..29a7d08 100644 (file)
@@ -3,7 +3,7 @@
  * ONAP
  * ================================================================================
  * Copyright (C) 2020 Wipro Limited.
- * Modifications Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
  * Modifications Copyright (C) 2020 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,6 +24,7 @@ package org.onap.policy.controlloop.actor.so;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -102,5 +103,15 @@ public class ModifyNssiTest extends BasicSoOperation {
         return ResourceUtils.getResourceAsString("src/test/resources/ModifyNSSI.json");
     }
 
+    /**
+     * Tests makeRequest() when a property is missing.
+     */
+    @Test
+    public void testMakeRequestMissingProperty() throws Exception {
+        oper = new ModifyNssi(params, config);
+
+        assertThatIllegalStateException().isThrownBy(() -> oper.makeRequest())
+                        .withMessageContaining("missing event payload");
+    }
 
 }
index 6f4ac0e..50bbfee 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
  * Modifications Copyright (C) 2020 Wipro Limited.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -37,6 +37,8 @@ import java.util.List;
 import java.util.Map;
 import org.junit.Before;
 import org.junit.Test;
+import org.onap.aai.domain.yang.CloudRegion;
+import org.onap.aai.domain.yang.Tenant;
 import org.onap.policy.common.utils.coder.Coder;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.controlloop.ControlLoopOperation;
@@ -205,6 +207,38 @@ public class SoOperationTest extends BasicSoOperation {
         assertTrue(oper.buildConfigurationParameters().isEmpty());
     }
 
+    @Test
+    public void testConstructCloudConfiguration() throws Exception {
+        Tenant tenantItem = new Tenant();
+        tenantItem.setTenantId("my-tenant-id");
+
+        CloudRegion cloudRegionItem = new CloudRegion();
+        cloudRegionItem.setCloudRegionId("my-cloud-id");
+
+        assertThatCode(() -> oper.constructCloudConfiguration(tenantItem, cloudRegionItem)).doesNotThrowAnyException();
+
+        tenantItem.setTenantId(null);
+        assertThatIllegalArgumentException()
+                        .isThrownBy(() -> oper.constructCloudConfiguration(tenantItem, cloudRegionItem))
+                        .withMessageContaining("missing tenant ID");
+        tenantItem.setTenantId("my-tenant-id");
+
+        cloudRegionItem.setCloudRegionId(null);
+        assertThatIllegalArgumentException()
+                        .isThrownBy(() -> oper.constructCloudConfiguration(tenantItem, cloudRegionItem))
+                        .withMessageContaining("missing cloud region ID");
+        cloudRegionItem.setCloudRegionId("my-cloud-id");
+    }
+
+    @Test
+    public void testGetRequiredText() throws Exception {
+
+        assertThatCode(() -> oper.getRequiredText("some value", "my value")).doesNotThrowAnyException();
+
+        assertThatIllegalArgumentException().isThrownBy(() -> oper.getRequiredText("some value", null))
+                        .withMessageContaining("missing some value");
+    }
+
     @Test
     public void testGetCoder() throws CoderException {
         Coder opcoder = oper.getCoder();
index dfd5c92..7168ec4 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
  * Modifications Copyright (C) 2020 Wipro Limited.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -212,6 +212,20 @@ public class VfModuleCreateTest extends BasicSoOperation {
         verifyRequest("vfModuleCreate.json", pair.getRight());
     }
 
+    /**
+     * Tests makeRequest() when a property is missing.
+     */
+    @Test
+    public void testMakeRequestMissingProperty() throws Exception {
+        loadProperties();
+
+        ServiceInstance instance = new ServiceInstance();
+        oper.setProperty(OperationProperties.AAI_SERVICE, instance);
+
+        assertThatIllegalArgumentException().isThrownBy(() -> oper.makeRequest())
+                        .withMessageContaining("missing service instance ID");
+    }
+
     private void loadProperties() {
         // set the properties
         ServiceInstance instance = new ServiceInstance();
@@ -229,8 +243,13 @@ public class VfModuleCreateTest extends BasicSoOperation {
         vnf.setVnfId(VNF_ID);
         oper.setProperty(OperationProperties.AAI_VNF, vnf);
 
-        oper.setProperty(OperationProperties.AAI_DEFAULT_CLOUD_REGION, new CloudRegion());
-        oper.setProperty(OperationProperties.AAI_DEFAULT_TENANT, new Tenant());
+        CloudRegion cloudRegion = new CloudRegion();
+        cloudRegion.setCloudRegionId("my-cloud-id");
+        oper.setProperty(OperationProperties.AAI_DEFAULT_CLOUD_REGION, cloudRegion);
+
+        Tenant tenant = new Tenant();
+        tenant.setTenantId("my-tenant-id");
+        oper.setProperty(OperationProperties.AAI_DEFAULT_TENANT, tenant);
 
         oper.setProperty(OperationProperties.DATA_VF_COUNT, VF_COUNT);
     }
index ce76201..cc11f95 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
  * Modifications Copyright (C) 2020 Wipro Limited.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -351,6 +351,20 @@ public class VfModuleDeleteTest extends BasicSoOperation {
         assertEquals("Basic " + encoded, valueCaptor.getValue());
     }
 
+    /**
+     * Tests makeRequest() when a property is missing.
+     */
+    @Test
+    public void testMakeRequestMissingProperty() throws Exception {
+        loadProperties();
+
+        ServiceInstance instance = new ServiceInstance();
+        oper.setProperty(OperationProperties.AAI_SERVICE, instance);
+
+        assertThatIllegalArgumentException().isThrownBy(() -> oper.makeRequest())
+                        .withMessageContaining("missing service instance ID");
+    }
+
     @Test
     public void testMakeHttpClient() {
         // must use a real operation to invoke this method
@@ -393,8 +407,13 @@ public class VfModuleDeleteTest extends BasicSoOperation {
         vnf.setVnfId(VNF_ID);
         oper.setProperty(OperationProperties.AAI_VNF, vnf);
 
-        oper.setProperty(OperationProperties.AAI_DEFAULT_CLOUD_REGION, new CloudRegion());
-        oper.setProperty(OperationProperties.AAI_DEFAULT_TENANT, new Tenant());
+        CloudRegion cloudRegion = new CloudRegion();
+        cloudRegion.setCloudRegionId("my-cloud-id");
+        oper.setProperty(OperationProperties.AAI_DEFAULT_CLOUD_REGION, cloudRegion);
+
+        Tenant tenant = new Tenant();
+        tenant.setTenantId("my-tenant-id");
+        oper.setProperty(OperationProperties.AAI_DEFAULT_TENANT, tenant);
 
         oper.setProperty(OperationProperties.DATA_VF_COUNT, VF_COUNT);
     }
index 5b7cce5..f83344d 100644 (file)
@@ -8,7 +8,10 @@
       "modelVersion": "my-model-version",
       "modelCustomizationId": "my-model-customization-id"
     },
-    "cloudConfiguration": {},
+    "cloudConfiguration": {
+      "lcpCloudRegionId": "my-cloud-id",
+      "tenantId": "my-tenant-id"
+    },
     "requestInfo": {
       "source": "POLICY",
       "suppressRollback": false,
index 06258f3..c28d73e 100644 (file)
@@ -8,7 +8,10 @@
       "modelVersion": "my-model-version",
       "modelCustomizationId": "my-model-customization-id"
     },
-    "cloudConfiguration": {},
+    "cloudConfiguration": {
+      "lcpCloudRegionId": "my-cloud-id",
+      "tenantId": "my-tenant-id"
+    },
     "requestInfo": {
       "instanceName": "vfModuleName",
       "source": "POLICY",