GenericResourceApiProvider unit tests part 6.
[sdnc/northbound.git] / generic-resource-api / provider / src / test / java / org / onap / sdnc / northbound / NetworkTopologyOperationRPCTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                             reserved.
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
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
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=========================================================
20  */
21
22 package org.onap.sdnc.northbound;
23
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.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.OperStatusData.LastAction;
46 import static org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.OperStatusData.LastOrderStatus;
47 import static org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.OperStatusData.LastRpcAction;
48 import static org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.OperStatusData.OrderStatus;
49
50 import java.time.Instant;
51 import org.junit.Before;
52 import org.junit.Test;
53 import org.junit.runner.RunWith;
54 import org.mockito.Mockito;
55 import org.mockito.runners.MockitoJUnitRunner;
56 import org.onap.sdnc.northbound.util.PropBuilder;
57 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
58 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
59 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
60 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainClosedException;
61 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationInput;
62 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.NetworkTopologyOperationOutput;
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;
71
72
73 /**
74  * This class test the NetworkTopologyOperation mdsal RPC.
75  */
76 @RunWith(MockitoJUnitRunner.class)
77 public class NetworkTopologyOperationRPCTest extends GenericResourceApiProviderTest {
78
79
80     final String SVC_OPERATION = "network-topology-operation";
81
82
83     @Before
84     public void setUp() throws Exception {
85         super.setUp();
86         svcClient.setScvOperation(SVC_OPERATION);
87     }
88
89     @Test
90     public void should_fail_when_service_instance_id_not_present() throws Exception {
91
92         NetworkTopologyOperationInput input = build(networkTopologyOperationInput());
93
94         NetworkTopologyOperationOutput output =
95             exec(genericResourceApiProvider::networkTopologyOperation, input, RpcResult::getResult);
96
97         assertEquals("404", output.getResponseCode());
98         assertEquals(NULL_OR_EMPTY_ERROR_PARAM, output.getResponseMessage());
99         assertEquals("Y", output.getAckFinalIndicator());
100     }
101
102
103     @Test
104     public void should_fail_when_invalid_service_data() throws Exception {
105
106         NetworkTopologyOperationInput input = build(networkTopologyOperationInput()
107             .setServiceInformation(build(serviceInformationBuilder()
108                 .setServiceInstanceId("test-service-instance-id")
109             ))
110         );
111
112         NetworkTopologyOperationOutput output =
113             exec(genericResourceApiProvider::networkTopologyOperation, input, RpcResult::getResult);
114
115         assertEquals("404", output.getResponseCode());
116         assertEquals(INVALID_INPUT_ERROR_MESSAGE, output.getResponseMessage());
117         assertEquals("Y", output.getAckFinalIndicator());
118     }
119
120
121     @Test
122     public void should_fail_when_client_execution_failed() throws Exception {
123
124         svcClient.mockHasGraph(true);
125         svcClient.mockExecute(new RuntimeException("test exception"));
126
127         NetworkTopologyOperationInput input = build(networkTopologyOperationInput()
128             .setServiceInformation(build(serviceInformationBuilder()
129                 .setServiceInstanceId("test-service-instance-id")
130             ))
131         );
132
133         persistServiceInDataBroker(input);
134
135         NetworkTopologyOperationOutput output =
136             exec(genericResourceApiProvider::networkTopologyOperation, input, RpcResult::getResult);
137
138         assertEquals("500", output.getResponseCode());
139         assertEquals("test exception", output.getResponseMessage());
140         assertEquals("Y", output.getAckFinalIndicator());
141     }
142
143     @Test
144     public void should_fail_when_client_has_no_graph() throws Exception {
145
146         svcClient.mockHasGraph(false);
147
148         NetworkTopologyOperationInput input = build(networkTopologyOperationInput()
149             .setServiceInformation(build(serviceInformationBuilder()
150                 .setServiceInstanceId("test-service-instance-id")
151             ))
152         );
153
154         persistServiceInDataBroker(input);
155
156         NetworkTopologyOperationOutput output =
157             exec(genericResourceApiProvider::networkTopologyOperation, input, RpcResult::getResult);
158
159         assertEquals("503", output.getResponseCode());
160         assertEquals(NO_SERVICE_LOGIC_ACTIVE + APP_NAME + ": '" + SVC_OPERATION + "'", output.getResponseMessage());
161         assertEquals("Y", output.getAckFinalIndicator());
162     }
163
164     @Test
165     public void should_fail_when_failed_to_update_mdsal() throws Exception {
166
167         PropBuilder svcResultProp = svcClient.createExecuteOKResult();
168         svcClient.mockExecute(svcResultProp);
169         svcClient.mockHasGraph(true);
170         WriteTransaction mockWriteTransaction = mock(WriteTransaction.class);
171         when(mockWriteTransaction.submit()).thenThrow(new TransactionChainClosedException("test exception"));
172
173         DataBroker spyDataBroker = Mockito.spy(dataBroker);
174         when(spyDataBroker.newWriteOnlyTransaction()).thenReturn(mockWriteTransaction);
175         genericResourceApiProvider.setDataBroker(spyDataBroker);
176
177         NetworkTopologyOperationInput input = build(networkTopologyOperationInput()
178             .setServiceInformation(build(serviceInformationBuilder()
179                 .setServiceInstanceId("test-service-instance-id")
180             ))
181         );
182
183         persistServiceInDataBroker(input);
184         NetworkTopologyOperationOutput output =
185             exec(genericResourceApiProvider::networkTopologyOperation, input, RpcResult::getResult);
186
187         assertEquals("500", output.getResponseCode());
188         assertEquals("test exception", output.getResponseMessage());
189         assertEquals("Y", output.getAckFinalIndicator());
190     }
191
192     /**
193      * Verify  ServiceTopologyOperation RPC executes a DG then produces the expected {@link
194      * NetworkTopologyOperationOutput} and persisted the expected {@link Service} in the {@link DataBroker}
195      */
196     @Test
197     public void should_success_when_no_errors_encountered() throws Exception {
198
199         //mock svcClient to perform a successful execution with the expected parameters
200         svcClient.mockHasGraph(true);
201         PropBuilder svcResultProp = svcClient.createExecuteOKResult();
202         svcClient.mockExecute(svcResultProp);
203
204         //construct the input parameter for the NetworkTopologyOperation
205         NetworkTopologyOperationInput input = createNTOI();
206
207         //pre-populate the DataBroke with the required ServiceData.
208         Service service = persistServiceInDataBroker(input);
209
210         //execute the mdsal exec
211         NetworkTopologyOperationOutput output = exec(
212             genericResourceApiProvider::networkTopologyOperation
213             , input
214             , RpcResult::getResult
215         );
216
217         assertEquals("200", output.getResponseCode());
218         assertEquals("OK", output.getResponseMessage());
219         assertEquals("Y", output.getAckFinalIndicator());
220
221         //verify the returned NetworkTopologyOperationOutput
222         NetworkTopologyOperationOutput expectedNetworkTopologyOperationOutput
223             = createExpectedNTOO(svcResultProp, input);
224         assertEquals(expectedNetworkTopologyOperationOutput, output);
225
226         //verify the persisted Service
227         Service actualService = db.read(
228             input.getServiceInformation().getServiceInstanceId(),
229             LogicalDatastoreType.CONFIGURATION
230         );
231         Service expectedService = createExpectedService(
232             expectedNetworkTopologyOperationOutput,
233             input,
234             service.getServiceData(),
235             actualService);
236         assertEquals(expectedService, actualService);
237
238     }
239
240
241     private NetworkTopologyOperationInput createNTOI() {
242
243         return build(
244             networkTopologyOperationInput()
245                 .setSdncRequestHeader(build(sdncRequestHeader()
246                     .setSvcRequestId("svc-request-id: xyz")
247                     .setSvcAction(SvcAction.Assign)
248                 ))
249                 .setRequestInformation(build(requestInformation()
250                     .setRequestId("request-id: xyz")
251                     .setRequestAction(RequestInformation.RequestAction.CreateServiceInstance)
252                 ))
253                 .setServiceInformation(build(serviceInformationBuilder()
254                     .setServiceInstanceId("service-instance-id: xyz")
255                 ))
256                 .setNetworkInformation(build(
257                     networkInformation()
258                 ))
259         );
260     }
261
262     private Service persistServiceInDataBroker(
263         NetworkTopologyOperationInput networkTopologyOperationInput
264     ) throws Exception {
265         Service service = build(
266             service()
267                 .setServiceInstanceId(
268                     networkTopologyOperationInput.getServiceInformation().getServiceInstanceId()
269                 )
270                 .setServiceData(build(
271                     serviceData()
272                         .setServiceLevelOperStatus(build(
273                             serviceLevelOperStatus()
274                                 .setOrderStatus(OrderStatus.Created)
275                                 .setModifyTimestamp(Instant.now().toString())
276                                 .setLastSvcRequestId("svc-request-id: abc")
277                                 .setLastRpcAction(LastRpcAction.Activate)
278                                 .setLastOrderStatus(LastOrderStatus.PendingAssignment)
279                                 .setLastAction(LastAction.ActivateNetworkInstance)
280                                 .setCreateTimestamp(Instant.now().toString())
281                         ))
282                 ))
283
284         );
285         db.write(true, service, LogicalDatastoreType.CONFIGURATION);
286         return service;
287     }
288
289
290     private NetworkTopologyOperationOutput createExpectedNTOO(
291         PropBuilder expectedSvcResultProp,
292         NetworkTopologyOperationInput expectedNetworkTopologyOperationInput) {
293         return build(
294             networkTopologyOperationOutput()
295                 .setSvcRequestId(expectedNetworkTopologyOperationInput.getSdncRequestHeader().getSvcRequestId())
296                 .setResponseCode(expectedSvcResultProp.get(svcClient.errorCode))
297                 .setAckFinalIndicator(expectedSvcResultProp.get(svcClient.ackFinal))
298                 .setResponseMessage(expectedSvcResultProp.get(svcClient.errorMessage))
299                 .setServiceResponseInformation(build(serviceResponseInformation()
300                     .setInstanceId(expectedNetworkTopologyOperationInput.getServiceInformation().getServiceInstanceId())
301                     .setObjectPath(expectedSvcResultProp.get(svcClient.serviceObjectPath))
302                 ))
303                 .setNetworkResponseInformation(build(
304                     networkResponseInformation()
305                         .setInstanceId(expectedSvcResultProp.get(svcClient.networkId))
306                         .setObjectPath(expectedSvcResultProp.get(svcClient.networkObjectPath))
307                 ))
308         );
309     }
310
311     private Service createExpectedService(
312         NetworkTopologyOperationOutput expectedNetworkTopologyOperationOutput,
313         NetworkTopologyOperationInput expectedNetworkTopologyOperationInput,
314         ServiceData expectedServiceData,
315         Service actualService
316     ) {
317
318         //We cannot predict the timeStamp value so just steal it from the actual
319         //we need this to prevent the equals method from returning false as a result of the timestamp
320         String responseTimeStamp = actualService == null || actualService.getServiceStatus() == null ?
321             null : actualService.getServiceStatus().getResponseTimestamp();
322
323         SdncRequestHeader expectedSdncRequestHeader = expectedNetworkTopologyOperationInput.getSdncRequestHeader();
324         ServiceInformation expectedServiceInformation = expectedNetworkTopologyOperationInput.getServiceInformation();
325         RequestInformation expectedRequestInformation = expectedNetworkTopologyOperationInput.getRequestInformation();
326
327         return build(
328             service()
329                 .setServiceInstanceId(expectedServiceInformation.getServiceInstanceId())
330                 .setServiceData(build(serviceData()))
331                 .setServiceData(expectedServiceData)
332                 .setServiceStatus(
333                     build(
334                         serviceStatus()
335                     )
336                 )
337         );
338
339     }
340
341     public ServiceStatus.RpcAction toRpcAction(SvcAction fromEnum) {
342         return fromEnum == null ? null : ServiceStatus.RpcAction.valueOf(fromEnum.name());
343     }
344
345
346 }