summaryrefslogtreecommitdiffstats
path: root/vnfapi/provider/src
diff options
context:
space:
mode:
authorJoey Sullivan <joey.sullivan@amdocs.com>2017-11-22 21:22:02 +0000
committerJoey Sullivan <joey.sullivan@amdocs.com>2017-11-22 21:37:44 +0000
commit69453d796578d46f1c0b98964b3a786718a86863 (patch)
tree3be3bf39287351978fdef2c54984aca9a8ee8cf5 /vnfapi/provider/src
parent1240ccff36e26154de009bb16a024e221566fb80 (diff)
Deleting missing vnf-list entry cause infiniteLoop
Deleting a vnf-list entry that does not exist from the databoker throws a ModifiedNodeDoesNotExistException. This conflicted with the optimistic locking retry mechanism causing a infinite loop. Change-Id: I216a31eabf710ed365c8d928e4df0e866848eeca Issue-ID: SDNC-156 Signed-off-by: Joey Sullivan <joey.sullivan@amdocs.com>
Diffstat (limited to 'vnfapi/provider/src')
-rw-r--r--vnfapi/provider/src/main/java/org/onap/sdnc/vnfapi/vnfapiProvider.java25
-rw-r--r--vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/VnfApiProviderTest.java75
-rw-r--r--vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/VnfTopologyOperationRPCTest.java174
-rw-r--r--vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/DataBrokerUtil.java94
-rw-r--r--vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/MDSALUtil.java113
-rw-r--r--vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/PropBuilder.java62
-rw-r--r--vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/VNFSDNSvcLogicServiceClientMockUtil.java130
7 files changed, 662 insertions, 11 deletions
diff --git a/vnfapi/provider/src/main/java/org/onap/sdnc/vnfapi/vnfapiProvider.java b/vnfapi/provider/src/main/java/org/onap/sdnc/vnfapi/vnfapiProvider.java
index e8a9e716..30f85859 100644
--- a/vnfapi/provider/src/main/java/org/onap/sdnc/vnfapi/vnfapiProvider.java
+++ b/vnfapi/provider/src/main/java/org/onap/sdnc/vnfapi/vnfapiProvider.java
@@ -771,30 +771,33 @@ public class vnfapiProvider implements AutoCloseable, VNFAPIService, DataChangeL
InstanceIdentifier.<Vnfs>builder(Vnfs.class).child(VnfList.class, entry.getKey());
InstanceIdentifier<VnfList> path = vnfListIdBuilder.build();
- int tries = 2;
- while (true) {
+ int optimisticLockTries = 2;
+ boolean tryAgain =true;
+ while (tryAgain) {
+ tryAgain = false;
try {
WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
tx.delete(storeType, path);
tx.submit().checkedGet();
log.debug("DataStore delete succeeded");
- break;
} catch (final TransactionCommitFailedException e) {
if (e instanceof OptimisticLockFailedException) {
- if (--tries <= 0) {
+ if (--optimisticLockTries <= 0) {
log.debug("Got OptimisticLockFailedException on last try - failing ");
throw new IllegalStateException(e);
}
log.debug("Got OptimisticLockFailedException - trying again ");
+ tryAgain = true;
+ continue;
}
- else {
- if (e.getCause() instanceof ModifiedNodeDoesNotExistException) {
- log.debug("Ignoring MpdifiedNodeDoesNotExistException");
- } else {
- log.debug("Delete DataStore failed");
- throw new IllegalStateException(e);
- }
+
+ if (e.getCause() instanceof ModifiedNodeDoesNotExistException) {
+ log.debug("Ignoring MpdifiedNodeDoesNotExistException");
+ break;
}
+
+ log.debug("Delete DataStore failed");
+ throw new IllegalStateException(e);
}
}
}
diff --git a/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/VnfApiProviderTest.java b/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/VnfApiProviderTest.java
new file mode 100644
index 00000000..c74ce534
--- /dev/null
+++ b/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/VnfApiProviderTest.java
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 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.
+ * 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.sdnc.vnfapi;
+
+import org.junit.Before;
+import org.mockito.Mock;
+import org.onap.sdnc.vnfapi.util.DataBrokerUtil;
+import org.onap.sdnc.vnfapi.util.PropBuilder;
+import org.onap.sdnc.vnfapi.util.VNFSDNSvcLogicServiceClientMockUtil;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
+import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class VnfApiProviderTest extends AbstractConcurrentDataBrokerTest {
+
+ protected vnfapiProvider vnfapiProvider;
+ protected DataBroker dataBroker;
+ protected @Mock NotificationPublishService mockNotificationPublishService;
+ protected @Mock RpcProviderRegistry mockRpcProviderRegistry;
+ protected @Mock VNFSDNSvcLogicServiceClient mockVNFSDNSvcLogicServiceClient;
+ protected static final Logger LOG = LoggerFactory.getLogger(vnfapiProvider.class);
+
+
+ protected DataBrokerUtil db;
+ protected VNFSDNSvcLogicServiceClientMockUtil svcClient;
+
+
+ @Before
+ public void setUp() throws Exception {
+ svcClient = new VNFSDNSvcLogicServiceClientMockUtil(mockVNFSDNSvcLogicServiceClient);
+ dataBroker = getDataBroker();
+ db = new DataBrokerUtil(dataBroker);
+ try {
+ vnfapiProvider = new vnfapiProvider(
+ dataBroker,
+ mockNotificationPublishService,
+ mockRpcProviderRegistry,
+ mockVNFSDNSvcLogicServiceClient
+ );
+ } catch (Exception e) {
+ LOG.error("Caught exception on setUp", e);
+ throw e;
+ }
+ }
+
+
+ public static PropBuilder prop(){
+ return (new PropBuilder());
+ }
+
+
+}
diff --git a/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/VnfTopologyOperationRPCTest.java b/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/VnfTopologyOperationRPCTest.java
new file mode 100644
index 00000000..422a6adb
--- /dev/null
+++ b/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/VnfTopologyOperationRPCTest.java
@@ -0,0 +1,174 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 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.
+ * 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.sdnc.vnfapi;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.sdnc.vnfapi.util.PropBuilder;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.VnfTopologyOperationInput;
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.VnfTopologyOperationOutput;
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.sdnc.request.header.SdncRequestHeader.SvcAction;
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.vnf.model.infrastructure.VnfList;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import static org.onap.sdnc.vnfapi.util.MDSALUtil.build;
+import static org.onap.sdnc.vnfapi.util.MDSALUtil.exec;
+import static org.onap.sdnc.vnfapi.util.MDSALUtil.sdncRequestHeader;
+import static org.onap.sdnc.vnfapi.util.MDSALUtil.serviceData;
+import static org.onap.sdnc.vnfapi.util.MDSALUtil.serviceInformation;
+import static org.onap.sdnc.vnfapi.util.MDSALUtil.vnfInformation;
+import static org.onap.sdnc.vnfapi.util.MDSALUtil.vnfList;
+import static org.onap.sdnc.vnfapi.util.MDSALUtil.vnfRequestInformation;
+import static org.onap.sdnc.vnfapi.util.MDSALUtil.vnfTopologyOperationInput;
+import static org.onap.sdnc.vnfapi.util.MDSALUtil.vnfTopologyOperationOutput;
+
+
+/**
+ * This class test the VnfTopologyOperation mdsal RPC.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class VnfTopologyOperationRPCTest extends VnfApiProviderTest {
+
+
+ final String SVC_OPERATION = "vnf-topology-operation";
+
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ svcClient.setScvOperation(SVC_OPERATION);
+ }
+
+
+ /**
+ * Verify VnfTopologyOperation RPC executes Delete VNFList entry
+ * {@link VnfTopologyOperationOutput} and persisted the expected {@link VnfList} in the {@link DataBroker}
+ */
+ @Test
+ public void testVnfTopologyOperationRPC_Delete_VNFList_Entry_Success() throws Exception {
+
+
+ //mock svcClient to perform a successful execution with the expected parameters
+ svcClient.mockHasGraph(true);
+ PropBuilder svcResultProp = svcClient.createExecuteOKResult();
+ svcClient.mockExecute(svcResultProp);
+
+ // create the VnfTopologyOperationInput from the template
+ VnfTopologyOperationInput vnfTopologyOperationInput = createVTOI();
+
+ //persist a vnfList entry in the dataBroker
+ persistVnfListBroker(vnfTopologyOperationInput);
+
+ //execute the mdsal exec
+ VnfTopologyOperationOutput actualVnfTopologyOperationOutput = exec(
+ vnfapiProvider::vnfTopologyOperation
+ , vnfTopologyOperationInput
+ , RpcResult::getResult
+ );
+
+
+ //verify the returned VnfTopologyOperationOutput
+ VnfTopologyOperationOutput expectedVnfTopologyOperationOutput = createExpectedVTOO(svcResultProp,vnfTopologyOperationInput);
+ Assert.assertEquals(expectedVnfTopologyOperationOutput,actualVnfTopologyOperationOutput);
+
+
+ //verify the persisted VnfList
+ VnfList actualVnfList = db.read(vnfTopologyOperationInput.getVnfRequestInformation().getVnfId(), LogicalDatastoreType.CONFIGURATION);
+ VnfList expectedVnfList = null;
+ Assert.assertEquals(expectedVnfList,actualVnfList);
+
+ LOG.debug("done");
+ }
+
+
+ public VnfTopologyOperationInput createVTOI(){
+ return build(vnfTopologyOperationInput()
+ .setServiceInformation(
+ build(serviceInformation()
+ .setServiceId("serviceId: xyz")
+ .setServiceInstanceId("serviceInstanceId: xyz")
+ .setServiceType("serviceType: xyz")
+ .setSubscriberName("subscriberName: xyz")
+ )
+ )
+ .setVnfRequestInformation(
+ build(vnfRequestInformation()
+ .setVnfId("vnfId: xyz")
+ .setVnfName("vnfName: xyz")//defect if missing
+ .setVnfType("vnfType: xyz")//defect if missing
+
+
+ )
+ )
+ .setSdncRequestHeader(
+ build(sdncRequestHeader()
+ .setSvcAction(SvcAction.Delete)
+ )
+ )
+ );
+
+ }
+
+
+
+ private VnfList persistVnfListBroker(
+ VnfTopologyOperationInput vnfTopologyOperationInput
+ ) throws Exception{
+ VnfList service = build(
+ vnfList()
+ .setVnfId(vnfTopologyOperationInput.getVnfRequestInformation().getVnfId())
+ .setServiceData(
+ build(serviceData()
+ .setVnfId(vnfTopologyOperationInput.getVnfRequestInformation().getVnfId())
+ )
+ )
+ );
+ db.write(true,service, LogicalDatastoreType.CONFIGURATION);
+ return service;
+ }
+
+
+
+
+
+ private VnfTopologyOperationOutput createExpectedVTOO(PropBuilder expectedSvcResultProp,VnfTopologyOperationInput expectedVnfTopologyOperationInput){
+ return build(
+ vnfTopologyOperationOutput()
+ .setSvcRequestId(expectedVnfTopologyOperationInput.getSdncRequestHeader().getSvcRequestId())
+ .setResponseCode(expectedSvcResultProp.get(svcClient.errorCode))
+ .setAckFinalIndicator(expectedSvcResultProp.get(svcClient.ackFinal))
+ .setResponseMessage(expectedSvcResultProp.get(svcClient.errorMessage))
+ .setVnfInformation(build(vnfInformation()
+ .setVnfId(expectedVnfTopologyOperationInput.getVnfRequestInformation().getVnfId())
+ ))
+ );
+ }
+
+
+
+
+}
diff --git a/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/DataBrokerUtil.java b/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/DataBrokerUtil.java
new file mode 100644
index 00000000..d791fa97
--- /dev/null
+++ b/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/DataBrokerUtil.java
@@ -0,0 +1,94 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 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.
+ * 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.sdnc.vnfapi.util;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.Vnfs;
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.vnf.model.infrastructure.VnfList;
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.vnf.model.infrastructure.VnfListKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+
+/**
+ * This util class provides utility to read and write {@link VnfList} data objects from the {@link DataBroker}
+ *
+ */
+public class DataBrokerUtil {
+
+
+ private final DataBroker dataBroker;
+
+ public DataBrokerUtil(DataBroker dataBroker) {
+ this.dataBroker = dataBroker;
+ }
+
+ /** @return VnfList - the VnfList object read from the DataBroker or null if none was found */
+ public VnfList read(String VnfListKey, LogicalDatastoreType logicalDatastoreType) throws Exception {
+ InstanceIdentifier VnfListInstanceIdentifier = InstanceIdentifier.<Vnfs>builder(Vnfs.class)
+ .child(VnfList.class, new VnfListKey(VnfListKey)).build();
+ ReadOnlyTransaction readTx = dataBroker.newReadOnlyTransaction();
+ Optional<VnfList> data = (Optional<VnfList>) readTx.read(logicalDatastoreType, VnfListInstanceIdentifier).get();
+ if(!data.isPresent()){
+ return null;
+ }
+ return data.get();
+ }
+
+
+ /**
+ * Write the {@link VnfList} object to the {@link DataBroker}
+ * @param isReplace - false specifies the new data is to be merged into existing data, where as true cause the
+ * existing data to be replaced.
+ * @param VnfList - the {@link VnfList} data object to be presisted in the db.
+ * @param logicalDatastoreType - The logicalDatastoreType
+ */
+ public void write(boolean isReplace,VnfList VnfList, LogicalDatastoreType logicalDatastoreType) throws Exception {
+ // Each entry will be identifiable by a unique key, we have to create that
+ // identifier
+ InstanceIdentifier.InstanceIdentifierBuilder<VnfList> VnfListBuilder = InstanceIdentifier
+ .<Vnfs>builder(Vnfs.class).child(VnfList.class, VnfList.getKey());
+ InstanceIdentifier<VnfList> path = VnfListBuilder.build();
+
+ WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+ if (!isReplace) {
+ tx.merge(logicalDatastoreType, path, VnfList);
+ } else {
+ tx.put(logicalDatastoreType, path, VnfList);
+ }
+ CheckedFuture<Void,TransactionCommitFailedException> cf = tx.submit();
+ cf.checkedGet();
+
+ }
+
+
+
+
+
+
+
+}
diff --git a/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/MDSALUtil.java b/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/MDSALUtil.java
new file mode 100644
index 00000000..b28139c7
--- /dev/null
+++ b/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/MDSALUtil.java
@@ -0,0 +1,113 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 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.
+ * 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.sdnc.vnfapi.util;
+
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.VnfTopologyOperationInputBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.VnfTopologyOperationOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.sdnc.request.header.SdncRequestHeaderBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.service.data.ServiceDataBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.service.information.ServiceInformationBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.vnf.information.VnfInformationBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.vnf.model.infrastructure.VnfListBuilder;
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.vnf.request.information.VnfRequestInformationBuilder;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import java.util.concurrent.Future;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+
+/**
+ * This uill class provides utility to build yang objects using a recursive syntax that resembles the tree structure
+ * when defining the same yang object in json format.
+ *
+ * For Example
+ * <pre>
+ * {@code
+ * import static org.onap.sdnc.northbound.util.MDSALUtil.*;
+ * VnfTopologyOperationInput input = build(vnfTopologyOperationInput()
+ * .setServiceInformation(
+ * build(serviceInformation()
+ * .setServiceId("serviceId: xyz")
+ * .setServiceInstanceId("serviceInstanceId: xyz")
+ * .setServiceType("serviceType: xyz")
+ * .setSubscriberName("subscriberName: xyz")
+ * )
+ * )
+ * .setVnfRequestInformation(
+ * build(vnfRequestInformation()
+ * .setVnfId("vnfId: xyz")
+ * .setVnfName("vnfName: xyz")//defect if missing
+ * .setVnfType("vnfType: xyz")//defect if missing
+ * )
+ * )
+ * .setSdncRequestHeader(
+ * build(sdncRequestHeader()
+ * .setSvcAction(SvcAction.Delete)
+ * )
+ * )
+ * );
+ * );
+ * }
+ * </pre>
+ */
+public class MDSALUtil {
+
+ public static VnfTopologyOperationInputBuilder vnfTopologyOperationInput(){return new VnfTopologyOperationInputBuilder();}
+ public static VnfTopologyOperationOutputBuilder vnfTopologyOperationOutput(){return new VnfTopologyOperationOutputBuilder();}
+
+ public static ServiceInformationBuilder serviceInformation(){return new ServiceInformationBuilder();}
+ public static VnfRequestInformationBuilder vnfRequestInformation(){return new VnfRequestInformationBuilder();}
+ public static VnfListBuilder vnfList(){return new VnfListBuilder();}
+ public static ServiceDataBuilder serviceData() { return new ServiceDataBuilder();}
+ public static SdncRequestHeaderBuilder sdncRequestHeader(){return new SdncRequestHeaderBuilder();}
+ public static VnfInformationBuilder vnfInformation(){return new VnfInformationBuilder();}
+
+
+ public static <P> P build(Builder<P> b) {
+ return b == null? null :b.build();
+ }
+
+ public static <P,B extends Builder<P>> P build(Function<P,B> builderConstructor,P sourceDataObject){
+ if(sourceDataObject == null){
+ return null;
+ }
+ B bp = builderConstructor.apply(sourceDataObject);
+ return bp.build();
+ }
+
+ public static <P,B extends Builder<P>> P build(Function<P,B> builderConstructor,P sourceDataObject,Consumer<B> builder){
+ if(sourceDataObject == null){
+ return null;
+ }
+ B bp = builderConstructor.apply(sourceDataObject);
+ builder.accept(bp);
+ return bp.build();
+ }
+
+ public static <I,O> O exec(Function<I,Future<RpcResult<O>>> rpc,I rpcParameter,Function<RpcResult<O>,O> rpcResult) throws Exception {
+ Future<RpcResult<O>> future = rpc.apply(rpcParameter);
+ return rpcResult.apply(future.get());
+ }
+
+}
diff --git a/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/PropBuilder.java b/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/PropBuilder.java
new file mode 100644
index 00000000..6ecc94c8
--- /dev/null
+++ b/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/PropBuilder.java
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 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.
+ * 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.sdnc.vnfapi.util;
+
+import org.opendaylight.yangtools.concepts.Builder;
+
+import java.util.Properties;
+
+/**
+ * A Util class that adds method chaining to the {@link #set(String, String)} to reducing the syntax needed to populate
+ * {@link Properties}
+ */
+public class PropBuilder implements Builder<Properties> {
+
+
+ final Properties prop;
+
+ public PropBuilder(Properties prop) {
+ this.prop = prop;
+ }
+
+ public PropBuilder() {
+ this.prop = new Properties();
+ }
+
+ public Properties build(){
+ return prop;
+ }
+
+ public PropBuilder set(String key, String value) {
+ prop.setProperty(key, value);
+ return this;
+ }
+
+ public String get(String key) {
+ return prop.getProperty(key);
+ }
+
+
+ public static PropBuilder propBuilder(){
+ return (new PropBuilder());
+ }
+} \ No newline at end of file
diff --git a/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/VNFSDNSvcLogicServiceClientMockUtil.java b/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/VNFSDNSvcLogicServiceClientMockUtil.java
new file mode 100644
index 00000000..d4d94ca8
--- /dev/null
+++ b/vnfapi/provider/src/test/java/org/onap/sdnc/vnfapi/util/VNFSDNSvcLogicServiceClientMockUtil.java
@@ -0,0 +1,130 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 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.
+ * 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.sdnc.vnfapi.util;
+
+import org.onap.sdnc.vnfapi.VNFSDNSvcLogicServiceClient;
+import org.opendaylight.yang.gen.v1.org.onap.sdnctl.vnf.rev150720.service.data.ServiceDataBuilder;
+
+import java.util.Properties;
+
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.isA;
+import static org.mockito.Mockito.when;
+import static org.onap.sdnc.vnfapi.util.MDSALUtil.build;
+import static org.onap.sdnc.vnfapi.util.PropBuilder.propBuilder;
+
+
+/**
+ * VNFSDNSvcLogicServiceClientMockUtil provides a set of util methods for quickly configuring method
+ * behaviour on the Mock VNFSDNSvcLogicServiceClient
+ */
+public class VNFSDNSvcLogicServiceClientMockUtil {
+
+
+ private final String MODULE = "VNF-API";
+ private final String MODE = "sync";
+ private final String VERSION = null;
+ private String scvOperation = null;
+
+
+ public final String errorCode = "error-code";
+ public final String errorMessage = "error-message";
+ public final String ackFinal = "ack-final";
+ public final String serviceObjectPath = "service-object-path";
+ public final String networkObjectPath = "network-object-path";
+ public final String networkId = "networkId";
+
+
+ private final VNFSDNSvcLogicServiceClient mockVNFSDNSvcLogicServiceClient;
+
+
+
+ public VNFSDNSvcLogicServiceClientMockUtil(VNFSDNSvcLogicServiceClient mockVNFSDNSvcLogicServiceClient) {
+ this.mockVNFSDNSvcLogicServiceClient = mockVNFSDNSvcLogicServiceClient;
+ }
+
+
+ /** @param scvOperation - The scvOperation parameter to use on the {@link VNFSDNSvcLogicServiceClient} methods */
+ public void setScvOperation(String scvOperation) {
+ this.scvOperation = scvOperation;
+ }
+
+ /**
+ * Configure {@link VNFSDNSvcLogicServiceClient#hasGraph(String, String, String, String)}
+ * to return the specified value when when invoked with the parameters
+ * {@link #MODULE}, {@link #MODE}, {@link #VERSION} and {@link #scvOperation}
+ */
+ public void mockHasGraph(Boolean isHasGraph) throws Exception {
+ when(
+ mockVNFSDNSvcLogicServiceClient
+ .hasGraph(
+ eq(MODULE),
+ eq(scvOperation),
+ eq(VERSION),
+ eq(MODE)
+ )
+ )
+ .thenReturn(isHasGraph);
+ }
+
+
+ /**
+ * @return
+ * PropBuilder - A PropBuilder populated with the expected properties returned from
+ * {@link VNFSDNSvcLogicServiceClient#execute(String, String, String, String, ServiceDataBuilder, Properties)}
+ */
+ public PropBuilder createExecuteOKResult(){
+ return propBuilder()
+ .set(errorCode,"200")
+ .set(errorMessage,"OK")
+ .set(ackFinal,"Y")
+ .set(serviceObjectPath,"serviceObjectPath: XYZ")
+ .set(networkObjectPath,"networkObjectPath: XYZ")
+ .set(networkId,"networkId: XYZ");
+
+ }
+
+
+ /**
+ * Configure
+ * {@link VNFSDNSvcLogicServiceClient#execute(String, String, String, String, ServiceDataBuilder, Properties)}
+ * to return the specified svcResultProp when when invoked with the parameters
+ * {@link #MODULE}, {@link #MODE}, {@link #VERSION} and {@link #scvOperation}
+ */
+ public void mockExecute(PropBuilder svcResultProp) throws Exception{
+ when(
+ mockVNFSDNSvcLogicServiceClient
+ .execute(
+ eq(MODULE),
+ eq(scvOperation),
+ eq(VERSION),
+ eq(MODE),
+ isA(ServiceDataBuilder.class),
+ isA(Properties.class)
+ )
+ )
+ .thenReturn(build(
+ svcResultProp
+ ));
+ }
+
+}