2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.sdnc.northbound;
24 import static org.junit.Assert.assertEquals;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.when;
27 import static org.onap.sdnc.northbound.GenericResourceApiProvider.APP_NAME;
28 import static org.onap.sdnc.northbound.GenericResourceApiProvider.INVALID_INPUT_ERROR_MESSAGE;
29 import static org.onap.sdnc.northbound.GenericResourceApiProvider.NO_SERVICE_LOGIC_ACTIVE;
30 import static org.onap.sdnc.northbound.GenericResourceApiProvider.NULL_OR_EMPTY_ERROR_PARAM;
31 import static org.onap.sdnc.northbound.util.MDSALUtil.build;
32 import static org.onap.sdnc.northbound.util.MDSALUtil.exec;
33 import static org.onap.sdnc.northbound.util.MDSALUtil.networkInformation;
34 import static org.onap.sdnc.northbound.util.MDSALUtil.networkResponseInformation;
35 import static org.onap.sdnc.northbound.util.MDSALUtil.networkTopologyOperationInput;
36 import static org.onap.sdnc.northbound.util.MDSALUtil.networkTopologyOperationOutput;
37 import static org.onap.sdnc.northbound.util.MDSALUtil.requestInformation;
38 import static org.onap.sdnc.northbound.util.MDSALUtil.sdncRequestHeader;
39 import static org.onap.sdnc.northbound.util.MDSALUtil.service;
40 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceData;
41 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceInformationBuilder;
42 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceLevelOperStatus;
43 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceResponseInformation;
44 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceStatus;
45 import static org.onap.sdnc.northbound.util.MDSALUtil.vnfInformationBuilder;
46 import static org.onap.sdnc.northbound.util.MDSALUtil.vnfTopologyOperationInput;
47 import static org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.OperStatusData.LastAction;
48 import static org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.OperStatusData.LastOrderStatus;
49 import static org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.OperStatusData.LastRpcAction;
50 import static org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.OperStatusData.OrderStatus;
52 import java.time.Instant;
53 import org.junit.Before;
54 import org.junit.Test;
55 import org.junit.runner.RunWith;
56 import org.mockito.Mockito;
57 import org.mockito.runners.MockitoJUnitRunner;
58 import org.onap.sdnc.northbound.util.PropBuilder;
59 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
60 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
61 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
62 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainClosedException;
63 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationInput;
64 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationOutput;
65 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationInput;
66 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.VnfTopologyOperationOutput;
67 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.request.information.RequestInformation;
68 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader;
69 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader.SvcAction;
70 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.data.ServiceData;
71 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.information.ServiceInformation;
72 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.model.infrastructure.Service;
73 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.status.ServiceStatus;
74 import org.opendaylight.yangtools.yang.common.RpcResult;
78 * This class test the NetworkTopologyOperation mdsal RPC.
80 @RunWith(MockitoJUnitRunner.class)
81 public class NetworkTopologyOperationRPCTest extends GenericResourceApiProviderTest {
84 final String SVC_OPERATION = "network-topology-operation";
88 public void setUp() throws Exception {
90 svcClient.setScvOperation(SVC_OPERATION);
94 public void should_fail_when_service_instance_id_not_present() throws Exception {
96 NetworkTopologyOperationInput input = build(networkTopologyOperationInput());
98 NetworkTopologyOperationOutput output =
99 exec(genericResourceApiProvider::networkTopologyOperation, input, RpcResult::getResult);
101 assertEquals("404", output.getResponseCode());
102 assertEquals(NULL_OR_EMPTY_ERROR_PARAM, output.getResponseMessage());
103 assertEquals("Y", output.getAckFinalIndicator());
108 public void should_fail_when_invalid_service_data() throws Exception {
110 NetworkTopologyOperationInput input = build(networkTopologyOperationInput()
111 .setServiceInformation(build(serviceInformationBuilder()
112 .setServiceInstanceId("test-service-instance-id")
116 NetworkTopologyOperationOutput output =
117 exec(genericResourceApiProvider::networkTopologyOperation, input, RpcResult::getResult);
119 assertEquals("404", output.getResponseCode());
120 assertEquals(INVALID_INPUT_ERROR_MESSAGE, output.getResponseMessage());
121 assertEquals("Y", output.getAckFinalIndicator());
126 public void should_fail_when_client_execution_failed() throws Exception {
128 svcClient.mockHasGraph(true);
129 svcClient.mockExecute(new RuntimeException("test exception"));
131 NetworkTopologyOperationInput input = build(networkTopologyOperationInput()
132 .setServiceInformation(build(serviceInformationBuilder()
133 .setServiceInstanceId("test-service-instance-id")
137 persistServiceInDataBroker(input);
139 NetworkTopologyOperationOutput output =
140 exec(genericResourceApiProvider::networkTopologyOperation, input, RpcResult::getResult);
142 assertEquals("500", output.getResponseCode());
143 assertEquals("test exception", output.getResponseMessage());
144 assertEquals("Y", output.getAckFinalIndicator());
148 public void should_fail_when_client_has_no_graph() throws Exception {
150 svcClient.mockHasGraph(false);
152 NetworkTopologyOperationInput input = build(networkTopologyOperationInput()
153 .setServiceInformation(build(serviceInformationBuilder()
154 .setServiceInstanceId("test-service-instance-id")
158 persistServiceInDataBroker(input);
160 NetworkTopologyOperationOutput output =
161 exec(genericResourceApiProvider::networkTopologyOperation, input, RpcResult::getResult);
163 assertEquals("503", output.getResponseCode());
164 assertEquals(NO_SERVICE_LOGIC_ACTIVE + APP_NAME + ": '" + SVC_OPERATION + "'", output.getResponseMessage());
165 assertEquals("Y", output.getAckFinalIndicator());
169 public void should_fail_when_failed_to_update_mdsal() throws Exception {
171 PropBuilder svcResultProp = svcClient.createExecuteOKResult();
172 svcClient.mockExecute(svcResultProp);
173 svcClient.mockHasGraph(true);
174 WriteTransaction mockWriteTransaction = mock(WriteTransaction.class);
175 when(mockWriteTransaction.submit()).thenThrow(new TransactionChainClosedException("test exception"));
177 DataBroker spyDataBroker = Mockito.spy(dataBroker);
178 when(spyDataBroker.newWriteOnlyTransaction()).thenReturn(mockWriteTransaction);
179 genericResourceApiProvider.setDataBroker(spyDataBroker);
181 NetworkTopologyOperationInput input = build(networkTopologyOperationInput()
182 .setServiceInformation(build(serviceInformationBuilder()
183 .setServiceInstanceId("test-service-instance-id")
187 persistServiceInDataBroker(input);
188 NetworkTopologyOperationOutput output =
189 exec(genericResourceApiProvider::networkTopologyOperation, input, RpcResult::getResult);
191 assertEquals("500", output.getResponseCode());
192 assertEquals("test exception", output.getResponseMessage());
193 assertEquals("Y", output.getAckFinalIndicator());
197 * Verify ServiceTopologyOperation RPC executes a DG then produces the expected
198 * {@link NetworkTopologyOperationOutput} and persisted the expected {@link Service} in the {@link DataBroker}
201 public void should_success_when_no_errors_encountered() throws Exception {
203 //mock svcClient to perform a successful execution with the expected parameters
204 svcClient.mockHasGraph(true);
205 PropBuilder svcResultProp = svcClient.createExecuteOKResult();
206 svcClient.mockExecute(svcResultProp);
209 //construct the input parameter for the NetworkTopologyOperation
210 NetworkTopologyOperationInput networkTopologyOperationInput = createNTOI();
213 //pre-populate the DataBroke with the required ServiceData.
214 Service service = persistServiceInDataBroker(networkTopologyOperationInput);
218 //execute the mdsal exec
219 NetworkTopologyOperationOutput actualNetworkTopologyOperationOutput = exec(
220 genericResourceApiProvider::networkTopologyOperation
221 , networkTopologyOperationInput
222 , RpcResult::getResult
225 //verify the returned NetworkTopologyOperationOutput
226 NetworkTopologyOperationOutput expectedNetworkTopologyOperationOutput
227 = createExpectedNTOO(svcResultProp,networkTopologyOperationInput);
228 assertEquals(expectedNetworkTopologyOperationOutput,actualNetworkTopologyOperationOutput);
231 //verify the persisted Service
232 Service actualService = db.read(
233 networkTopologyOperationInput.getServiceInformation().getServiceInstanceId(),
234 LogicalDatastoreType.CONFIGURATION
236 Service expectedService = createExpectedService(
237 expectedNetworkTopologyOperationOutput,
238 networkTopologyOperationInput,
239 service.getServiceData(),
241 assertEquals(expectedService,actualService);
246 private NetworkTopologyOperationInput createNTOI()
250 networkTopologyOperationInput()
251 .setSdncRequestHeader(build(sdncRequestHeader()
252 .setSvcRequestId("svc-request-id: xyz")
253 .setSvcAction(SvcAction.Assign)
255 .setRequestInformation(build(requestInformation()
256 .setRequestId("request-id: xyz")
257 .setRequestAction(RequestInformation.RequestAction.CreateServiceInstance)
259 .setServiceInformation(build(serviceInformationBuilder()
260 .setServiceInstanceId("service-instance-id: xyz")
262 .setNetworkInformation(build(
268 private Service persistServiceInDataBroker(
269 NetworkTopologyOperationInput networkTopologyOperationInput
271 Service service = build(
273 .setServiceInstanceId(
274 networkTopologyOperationInput.getServiceInformation().getServiceInstanceId()
276 .setServiceData(build(
278 .setServiceLevelOperStatus(build(
279 serviceLevelOperStatus()
280 .setOrderStatus(OrderStatus.Created)
281 .setModifyTimestamp(Instant.now().toString())
282 .setLastSvcRequestId("svc-request-id: abc")
283 .setLastRpcAction(LastRpcAction.Activate)
284 .setLastOrderStatus(LastOrderStatus.PendingAssignment)
285 .setLastAction(LastAction.ActivateNetworkInstance)
286 .setCreateTimestamp(Instant.now().toString())
291 db.write(true,service, LogicalDatastoreType.CONFIGURATION);
300 private NetworkTopologyOperationOutput createExpectedNTOO(
301 PropBuilder expectedSvcResultProp,
302 NetworkTopologyOperationInput expectedNetworkTopologyOperationInput){
304 networkTopologyOperationOutput()
305 .setSvcRequestId(expectedNetworkTopologyOperationInput.getSdncRequestHeader().getSvcRequestId())
306 .setResponseCode(expectedSvcResultProp.get(svcClient.errorCode))
307 .setAckFinalIndicator(expectedSvcResultProp.get(svcClient.ackFinal))
308 .setResponseMessage(expectedSvcResultProp.get(svcClient.errorMessage))
309 .setServiceResponseInformation(build(serviceResponseInformation()
310 .setInstanceId(expectedNetworkTopologyOperationInput.getServiceInformation().getServiceInstanceId())
311 .setObjectPath(expectedSvcResultProp.get(svcClient.serviceObjectPath))
313 .setNetworkResponseInformation(build(
314 networkResponseInformation()
315 .setInstanceId(expectedSvcResultProp.get(svcClient.networkId))
316 .setObjectPath(expectedSvcResultProp.get(svcClient.networkObjectPath))
321 private Service createExpectedService(
322 NetworkTopologyOperationOutput expectedNetworkTopologyOperationOutput,
323 NetworkTopologyOperationInput expectedNetworkTopologyOperationInput,
324 ServiceData expectedServiceData,
325 Service actualService
329 //We cannot predict the timeStamp value so just steal it from the actual
330 //we need this to prevent the equals method from returning false as a result of the timestamp
331 String responseTimeStamp = actualService == null || actualService.getServiceStatus() == null?
332 null : actualService.getServiceStatus().getResponseTimestamp();
334 SdncRequestHeader expectedSdncRequestHeader = expectedNetworkTopologyOperationInput.getSdncRequestHeader();
335 ServiceInformation expectedServiceInformation = expectedNetworkTopologyOperationInput.getServiceInformation();
336 RequestInformation expectedRequestInformation = expectedNetworkTopologyOperationInput.getRequestInformation();
340 .setServiceInstanceId(expectedServiceInformation.getServiceInstanceId())
341 .setServiceData(build(serviceData()))
342 .setServiceData(expectedServiceData)
352 public ServiceStatus.RpcAction toRpcAction(SvcAction fromEnum){
353 return fromEnum == null? null : ServiceStatus.RpcAction.valueOf(fromEnum.name());