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.exec;
32 import static org.onap.sdnc.northbound.util.MDSALUtil.networkInformation;
33 import static org.onap.sdnc.northbound.util.MDSALUtil.networkResponseInformation;
34 import static org.onap.sdnc.northbound.util.MDSALUtil.networkTopologyOperationInput;
35 import static org.onap.sdnc.northbound.util.MDSALUtil.networkTopologyOperationOutput;
36 import static org.onap.sdnc.northbound.util.MDSALUtil.requestInformation;
37 import static org.onap.sdnc.northbound.util.MDSALUtil.sdncRequestHeader;
38 import static org.onap.sdnc.northbound.util.MDSALUtil.service;
39 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceData;
40 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceInformationBuilder;
41 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceLevelOperStatus;
42 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceResponseInformation;
43 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceStatus;
45 import java.time.Instant;
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 import org.mockito.Mockito;
51 import org.mockito.runners.MockitoJUnitRunner;
52 import org.onap.sdnc.northbound.util.PropBuilder;
53 import org.opendaylight.mdsal.binding.api.DataBroker;
54 import org.opendaylight.mdsal.binding.api.TransactionChainClosedException;
55 import org.opendaylight.mdsal.binding.api.WriteTransaction;
56 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
57 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationInput;
58 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationOutput;
59 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.OperStatusData.LastAction;
60 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.OperStatusData.LastOrderStatus;
61 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.OperStatusData.LastRpcAction;
62 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.OperStatusData.OrderStatus;
63 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.request.information.RequestInformation;
64 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader;
65 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader.SvcAction;
66 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.data.ServiceData;
67 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.information.ServiceInformation;
68 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.model.infrastructure.Service;
69 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.status.ServiceStatus;
70 import org.opendaylight.yangtools.yang.common.RpcResult;
74 * This class test the NetworkTopologyOperation mdsal RPC.
76 @RunWith(MockitoJUnitRunner.class)
77 public class NetworkTopologyOperationRPCTest extends GenericResourceApiProviderTest {
80 final String SVC_OPERATION = "network-topology-operation";
84 public void setUp() throws Exception {
86 svcClient.setScvOperation(SVC_OPERATION);
90 public void should_fail_when_service_instance_id_not_present() throws Exception {
92 NetworkTopologyOperationInput input = networkTopologyOperationInput().build();
94 NetworkTopologyOperationOutput output =
95 exec(genericResourceApiProvider::networkTopologyOperation, input, RpcResult::getResult);
97 assertEquals("404", output.getResponseCode());
98 assertEquals(NULL_OR_EMPTY_ERROR_PARAM, output.getResponseMessage());
99 assertEquals("Y", output.getAckFinalIndicator());
104 public void should_fail_when_invalid_service_data() throws Exception {
106 NetworkTopologyOperationInput input = networkTopologyOperationInput()
107 .setServiceInformation(serviceInformationBuilder()
108 .setServiceInstanceId("test-service-instance-id").build()
111 NetworkTopologyOperationOutput output =
112 exec(genericResourceApiProvider::networkTopologyOperation, input, RpcResult::getResult);
114 assertEquals("404", output.getResponseCode());
115 assertEquals(INVALID_INPUT_ERROR_MESSAGE, output.getResponseMessage());
116 assertEquals("Y", output.getAckFinalIndicator());
121 public void should_fail_when_client_execution_failed() throws Exception {
123 svcClient.mockHasGraph(true);
124 svcClient.mockExecute(new RuntimeException("test exception"));
126 NetworkTopologyOperationInput input = networkTopologyOperationInput()
127 .setServiceInformation(serviceInformationBuilder()
128 .setServiceInstanceId("test-service-instance-id").build()
131 persistServiceInDataBroker(input);
133 NetworkTopologyOperationOutput output =
134 exec(genericResourceApiProvider::networkTopologyOperation, input, RpcResult::getResult);
136 assertEquals("500", output.getResponseCode());
137 assertEquals("test exception", output.getResponseMessage());
138 assertEquals("Y", output.getAckFinalIndicator());
142 public void should_fail_when_client_has_no_graph() throws Exception {
144 svcClient.mockHasGraph(false);
146 NetworkTopologyOperationInput input = networkTopologyOperationInput()
147 .setServiceInformation(serviceInformationBuilder()
148 .setServiceInstanceId("test-service-instance-id").build()
151 persistServiceInDataBroker(input);
153 NetworkTopologyOperationOutput output =
154 exec(genericResourceApiProvider::networkTopologyOperation, input, RpcResult::getResult);
156 assertEquals("503", output.getResponseCode());
157 assertEquals(NO_SERVICE_LOGIC_ACTIVE + APP_NAME + ": '" + SVC_OPERATION + "'", output.getResponseMessage());
158 assertEquals("Y", output.getAckFinalIndicator());
162 public void should_fail_when_failed_to_update_mdsal() throws Exception {
164 PropBuilder svcResultProp = svcClient.createExecuteOKResult();
165 svcClient.mockExecute(svcResultProp);
166 svcClient.mockHasGraph(true);
167 WriteTransaction mockWriteTransaction = mock(WriteTransaction.class);
168 when(mockWriteTransaction.commit()).thenThrow(new TransactionChainClosedException("test exception"));
170 DataBroker spyDataBroker = Mockito.spy(dataBroker);
171 when(spyDataBroker.newWriteOnlyTransaction()).thenReturn(mockWriteTransaction);
172 genericResourceApiProvider.setDataBroker(spyDataBroker);
174 NetworkTopologyOperationInput input = networkTopologyOperationInput()
175 .setServiceInformation(serviceInformationBuilder()
176 .setServiceInstanceId("test-service-instance-id").build()
179 persistServiceInDataBroker(input);
180 NetworkTopologyOperationOutput output =
181 exec(genericResourceApiProvider::networkTopologyOperation, input, RpcResult::getResult);
183 assertEquals("500", output.getResponseCode());
184 assertEquals("test exception", output.getResponseMessage());
185 assertEquals("Y", output.getAckFinalIndicator());
189 * Verify ServiceTopologyOperation RPC executes a DG then produces the expected {@link
190 * NetworkTopologyOperationOutput} and persisted the expected {@link Service} in the {@link DataBroker}
193 public void should_success_when_no_errors_encountered() throws Exception {
195 //mock svcClient to perform a successful execution with the expected parameters
196 svcClient.mockHasGraph(true);
197 PropBuilder svcResultProp = svcClient.createExecuteOKResult();
198 svcClient.mockExecute(svcResultProp);
200 //construct the input parameter for the NetworkTopologyOperation
201 NetworkTopologyOperationInput input = createNTOI();
203 //pre-populate the DataBroke with the required ServiceData.
204 Service service = persistServiceInDataBroker(input);
206 //execute the mdsal exec
207 NetworkTopologyOperationOutput output = exec(
208 genericResourceApiProvider::networkTopologyOperation
210 , RpcResult::getResult
213 assertEquals("200", output.getResponseCode());
214 assertEquals("OK", output.getResponseMessage());
215 assertEquals("Y", output.getAckFinalIndicator());
217 //verify the returned NetworkTopologyOperationOutput
218 NetworkTopologyOperationOutput expectedNetworkTopologyOperationOutput
219 = createExpectedNTOO(svcResultProp, input);
220 assertEquals(expectedNetworkTopologyOperationOutput, output);
222 //verify the persisted Service
223 Service actualService = db.read(
224 input.getServiceInformation().getServiceInstanceId(),
225 LogicalDatastoreType.CONFIGURATION
227 Service expectedService = createExpectedService(
228 expectedNetworkTopologyOperationOutput,
230 service.getServiceData(),
232 assertEquals(expectedService, actualService);
237 private NetworkTopologyOperationInput createNTOI() {
240 networkTopologyOperationInput()
241 .setSdncRequestHeader(sdncRequestHeader()
242 .setSvcRequestId("svc-request-id: xyz")
243 .setSvcAction(SvcAction.Assign).build()
245 .setRequestInformation(requestInformation()
246 .setRequestId("request-id: xyz")
247 .setRequestAction(RequestInformation.RequestAction.CreateServiceInstance).build()
249 .setServiceInformation(serviceInformationBuilder()
250 .setServiceInstanceId("service-instance-id: xyz").build()
252 .setNetworkInformation(networkInformation().build()
256 private Service persistServiceInDataBroker(
257 NetworkTopologyOperationInput networkTopologyOperationInput
261 .setServiceInstanceId(
262 networkTopologyOperationInput.getServiceInformation().getServiceInstanceId()
266 .setServiceLevelOperStatus(
267 serviceLevelOperStatus()
268 .setOrderStatus(OrderStatus.Created)
269 .setModifyTimestamp(Instant.now().toString())
270 .setLastSvcRequestId("svc-request-id: abc")
271 .setLastRpcAction(LastRpcAction.Activate)
272 .setLastOrderStatus(LastOrderStatus.PendingAssignment)
273 .setLastAction(LastAction.ActivateNetworkInstance)
274 .setCreateTimestamp(Instant.now().toString()).build()
278 db.write(true, service, LogicalDatastoreType.CONFIGURATION);
283 private NetworkTopologyOperationOutput createExpectedNTOO(
284 PropBuilder expectedSvcResultProp,
285 NetworkTopologyOperationInput expectedNetworkTopologyOperationInput) {
287 networkTopologyOperationOutput()
288 .setSvcRequestId(expectedNetworkTopologyOperationInput.getSdncRequestHeader().getSvcRequestId())
289 .setResponseCode(expectedSvcResultProp.get(svcClient.errorCode))
290 .setAckFinalIndicator(expectedSvcResultProp.get(svcClient.ackFinal))
291 .setResponseMessage(expectedSvcResultProp.get(svcClient.errorMessage))
292 .setServiceResponseInformation(serviceResponseInformation()
293 .setInstanceId(expectedNetworkTopologyOperationInput.getServiceInformation().getServiceInstanceId())
294 .setObjectPath(expectedSvcResultProp.get(svcClient.serviceObjectPath)).build()
296 .setNetworkResponseInformation(
297 networkResponseInformation()
298 .setInstanceId(expectedSvcResultProp.get(svcClient.networkId))
299 .setObjectPath(expectedSvcResultProp.get(svcClient.networkObjectPath)).build()
303 private Service createExpectedService(
304 NetworkTopologyOperationOutput expectedNetworkTopologyOperationOutput,
305 NetworkTopologyOperationInput expectedNetworkTopologyOperationInput,
306 ServiceData expectedServiceData,
307 Service actualService
310 //We cannot predict the timeStamp value so just steal it from the actual
311 //we need this to prevent the equals method from returning false as a result of the timestamp
312 String responseTimeStamp = actualService == null || actualService.getServiceStatus() == null ?
313 null : actualService.getServiceStatus().getResponseTimestamp();
315 SdncRequestHeader expectedSdncRequestHeader = expectedNetworkTopologyOperationInput.getSdncRequestHeader();
316 ServiceInformation expectedServiceInformation = expectedNetworkTopologyOperationInput.getServiceInformation();
317 RequestInformation expectedRequestInformation = expectedNetworkTopologyOperationInput.getRequestInformation();
321 .setServiceInstanceId(expectedServiceInformation.getServiceInstanceId())
322 .setServiceData(serviceData().build())
323 .setServiceData(expectedServiceData)
325 serviceStatus().build()
331 public ServiceStatus.RpcAction toRpcAction(SvcAction fromEnum) {
332 return fromEnum == null ? null : ServiceStatus.RpcAction.valueOf(fromEnum.name());