diff options
author | Joey Sullivan <joey.sullivan@amdocs.com> | 2017-11-22 21:22:02 +0000 |
---|---|---|
committer | Joey Sullivan <joey.sullivan@amdocs.com> | 2017-11-22 21:37:44 +0000 |
commit | 69453d796578d46f1c0b98964b3a786718a86863 (patch) | |
tree | 3be3bf39287351978fdef2c54984aca9a8ee8cf5 | |
parent | 1240ccff36e26154de009bb16a024e221566fb80 (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>
8 files changed, 692 insertions, 11 deletions
diff --git a/vnfapi/provider/pom.xml b/vnfapi/provider/pom.xml index aac430a3..35021adb 100644 --- a/vnfapi/provider/pom.xml +++ b/vnfapi/provider/pom.xml @@ -60,6 +60,36 @@ <artifactId>sli-provider</artifactId> <version>${sdnctl.sli.version}</version> </dependency> + + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-test-model</artifactId> + <version>${odl.mdsal.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.netconf</groupId> + <artifactId>sal-rest-connector</artifactId> + <version>${odl.mdsal.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-broker-impl</artifactId> + <version>${odl.mdsal.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-broker-impl</artifactId> + <version>${odl.mdsal.version}</version> + <type>test-jar</type> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> 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 + )); + } + +} |