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