faacd2205ab6be9fd9594f395c53830c78e2391d
[sdnc/northbound.git] / generic-resource-api / provider / src / test / java / org / onap / sdnc / northbound / ServiceTopologyOperationRPCTest.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.NO_SERVICE_LOGIC_ACTIVE;
29 import static org.onap.sdnc.northbound.GenericResourceApiProvider.NULL_OR_EMPTY_ERROR_PARAM;
30 import static org.onap.sdnc.northbound.util.MDSALUtil.build;
31 import static org.onap.sdnc.northbound.util.MDSALUtil.exec;
32 import static org.onap.sdnc.northbound.util.MDSALUtil.requestInformation;
33 import static org.onap.sdnc.northbound.util.MDSALUtil.sdncRequestHeader;
34 import static org.onap.sdnc.northbound.util.MDSALUtil.service;
35 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceData;
36 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceInformationBuilder;
37 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceResponseInformation;
38 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceStatus;
39 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceTopologyOperationInput;
40 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceTopologyOperationOutput;
41
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 import org.mockito.Mockito;
46 import org.mockito.runners.MockitoJUnitRunner;
47 import org.onap.sdnc.northbound.util.PropBuilder;
48 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
49 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
50 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
51 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainClosedException;
52 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ServiceTopologyOperationInput;
53 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ServiceTopologyOperationOutput;
54 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.request.information.RequestInformation;
55 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader;
56 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader.SvcAction;
57 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.information.ServiceInformation;
58 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.model.infrastructure.Service;
59 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.status.ServiceStatus;
60 import org.opendaylight.yangtools.yang.common.RpcResult;
61
62
63 /**
64  * This class test the ServiceTopologyOperation mdsal RPC.
65  */
66 @RunWith(MockitoJUnitRunner.class)
67 public class ServiceTopologyOperationRPCTest extends GenericResourceApiProviderTest {
68
69     final String SVC_OPERATION = "service-topology-operation";
70
71     @Before
72     public void setUp() throws Exception {
73         super.setUp();
74         svcClient.setScvOperation(SVC_OPERATION);
75     }
76
77     /**
78      * Verify  ServiceTopologyOperation RPC executes a DG then produces the expected {@link
79      * ServiceTopologyOperationOutput} and persisted the expected {@link Service} in the {@link DataBroker}
80      */
81     @Test
82     public void testServiceTopologyOperationRPC_ExecuteDG_Success() throws Exception {
83
84         //mock svcClient to perform a successful execution with the expected parameters
85         svcClient.mockHasGraph(true);
86         PropBuilder svcResultProp = svcClient.createExecuteOKResult();
87         svcClient.mockExecute(svcResultProp);
88
89         // create the ServiceTopologyOperationInput from the template
90         ServiceTopologyOperationInput input = createSTOI();
91
92         //execute the mdsal exec
93         ServiceTopologyOperationOutput output = exec(
94             genericResourceApiProvider::serviceTopologyOperation
95             , input
96             , RpcResult::getResult
97         );
98
99         assertEquals("200", output.getResponseCode());
100         assertEquals("OK", output.getResponseMessage());
101         assertEquals("Y", output.getAckFinalIndicator());
102
103         //verify the returned ServiceTopologyOperationOutput
104         ServiceTopologyOperationOutput expectedServiceTopologyOperationOutput = createExpectedSTOO(svcResultProp,
105             input);
106         assertEquals(expectedServiceTopologyOperationOutput, output);
107
108         //verify the persisted Service
109         Service actualService = db.read(input.getServiceInformation().getServiceInstanceId(),
110             LogicalDatastoreType.CONFIGURATION);
111         Service expectedService = createExpectedService(
112             expectedServiceTopologyOperationOutput,
113             input,
114             actualService);
115         assertEquals(expectedService, actualService);
116
117         LOG.debug("done");
118     }
119
120     @Test
121     public void should_fail_when_service_info_not_present() throws Exception {
122         // create the ServiceTopologyOperationInput from the template
123         ServiceTopologyOperationInput input = build(
124             serviceTopologyOperationInput()
125                 .setSdncRequestHeader(build(sdncRequestHeader()
126                     .setSvcRequestId("svc-request-id: xyz")
127                     .setSvcAction(SvcAction.Assign)
128                 ))
129                 .setRequestInformation(build(requestInformation()
130                     .setRequestId("request-id: xyz")
131                     .setRequestAction(RequestInformation.RequestAction.CreateServiceInstance)
132                 )));
133
134         //execute the mdsal exec
135         ServiceTopologyOperationOutput output = exec(
136             genericResourceApiProvider::serviceTopologyOperation
137             , input
138             , RpcResult::getResult
139         );
140
141         assertEquals("404", output.getResponseCode());
142         assertEquals(NULL_OR_EMPTY_ERROR_PARAM, output.getResponseMessage());
143         assertEquals("Y", output.getAckFinalIndicator());
144     }
145
146
147     @Test
148     public void should_fail_when_client_execution_failed() throws Exception {
149         svcClient.mockHasGraph(true);
150         svcClient.mockExecute(new RuntimeException("test exception"));
151
152         ServiceTopologyOperationInput input = createSTOI();
153
154         //execute the mdsal exec
155         ServiceTopologyOperationOutput output = exec(
156             genericResourceApiProvider::serviceTopologyOperation
157             , input
158             , RpcResult::getResult
159         );
160
161         assertEquals("500", output.getResponseCode());
162         assertEquals("test exception", output.getResponseMessage());
163         assertEquals("Y", output.getAckFinalIndicator());
164     }
165
166     @Test
167     public void should_fail_when_client_has_no_graph() throws Exception {
168         svcClient.mockHasGraph(false);
169
170         ServiceTopologyOperationInput input = createSTOI();
171
172         //execute the mdsal exec
173         ServiceTopologyOperationOutput output = exec(
174             genericResourceApiProvider::serviceTopologyOperation
175             , input
176             , RpcResult::getResult
177         );
178
179         assertEquals("503", output.getResponseCode());
180         assertEquals(NO_SERVICE_LOGIC_ACTIVE + APP_NAME + ": '" + SVC_OPERATION + "'", output.getResponseMessage());
181         assertEquals("Y", output.getAckFinalIndicator());
182     }
183
184
185     @Test
186     public void should_fail_when_failed_to_update_mdsal() throws Exception {
187
188         svcClient.mockHasGraph(true);
189         WriteTransaction mockWriteTransaction = mock(WriteTransaction.class);
190         when(mockWriteTransaction.submit()).thenThrow(new TransactionChainClosedException("test exception"));
191
192         DataBroker spyDataBroker = Mockito.spy(dataBroker);
193         when(spyDataBroker.newWriteOnlyTransaction()).thenReturn(mockWriteTransaction);
194         genericResourceApiProvider.setDataBroker(spyDataBroker);
195
196         ServiceTopologyOperationInput input = createSTOI();
197
198         //execute the mdsal exec
199         ServiceTopologyOperationOutput output = exec(
200             genericResourceApiProvider::serviceTopologyOperation
201             , input
202             , RpcResult::getResult
203         );
204
205         assertEquals("500", output.getResponseCode());
206         assertEquals("test exception", output.getResponseMessage());
207         assertEquals("Y", output.getAckFinalIndicator());
208     }
209
210     private ServiceTopologyOperationInput createSTOI() {
211
212         return build(
213             serviceTopologyOperationInput()
214                 .setSdncRequestHeader(build(sdncRequestHeader()
215                     .setSvcRequestId("svc-request-id: xyz")
216                     .setSvcAction(SvcAction.Assign)
217                 ))
218                 .setRequestInformation(build(requestInformation()
219                     .setRequestId("request-id: xyz")
220                     .setRequestAction(RequestInformation.RequestAction.CreateServiceInstance)
221                 ))
222                 .setServiceInformation(build(serviceInformationBuilder()
223                     .setServiceInstanceId("service-instance-id: xyz")
224                 ))
225         );
226     }
227
228
229     private ServiceTopologyOperationOutput createExpectedSTOO(PropBuilder expectedSvcResultProp,
230         ServiceTopologyOperationInput expectedServiceTopologyOperationInput) {
231         return build(
232             serviceTopologyOperationOutput()
233                 .setSvcRequestId(expectedServiceTopologyOperationInput.getSdncRequestHeader().getSvcRequestId())
234                 .setResponseCode(expectedSvcResultProp.get(svcClient.errorCode))
235                 .setAckFinalIndicator(expectedSvcResultProp.get(svcClient.ackFinal))
236                 .setResponseMessage(expectedSvcResultProp.get(svcClient.errorMessage))
237                 .setServiceResponseInformation(build(serviceResponseInformation()
238                     .setInstanceId(expectedServiceTopologyOperationInput.getServiceInformation().getServiceInstanceId())
239                     .setObjectPath(expectedSvcResultProp.get(svcClient.serviceObjectPath))
240                 ))
241         );
242     }
243
244     private Service createExpectedService(
245         ServiceTopologyOperationOutput expectedServiceTopologyOperationOutput,
246         ServiceTopologyOperationInput expectedServiceTopologyOperationInput,
247         Service actualService
248     ) {
249
250         //We cannot predict the timeStamp value so just steal it from the actual
251         //we need this to prevent the equals method from returning false as a result of the timestamp
252         String responseTimeStamp = actualService == null || actualService.getServiceStatus() == null ?
253             null : actualService.getServiceStatus().getResponseTimestamp();
254
255         SdncRequestHeader expectedSdncRequestHeader = expectedServiceTopologyOperationInput.getSdncRequestHeader();
256         ServiceInformation expectedServiceInformation = expectedServiceTopologyOperationInput.getServiceInformation();
257         RequestInformation expectedRequestInformation = expectedServiceTopologyOperationInput.getRequestInformation();
258
259         return build(
260             service()
261                 .setServiceInstanceId(expectedServiceInformation.getServiceInstanceId())
262                 .setServiceData(build(serviceData()))
263                 .setServiceStatus(
264                     build(
265                         serviceStatus()
266                             .setAction(expectedRequestInformation.getRequestAction().name())
267                             .setFinalIndicator(expectedServiceTopologyOperationOutput.getAckFinalIndicator())
268                             .setResponseCode(expectedServiceTopologyOperationOutput.getResponseCode())
269                             .setResponseMessage(expectedServiceTopologyOperationOutput.getResponseMessage())
270                             .setRpcAction(toRpcAction(expectedSdncRequestHeader.getSvcAction()))
271                             .setRpcName(SVC_OPERATION)
272                             .setRequestStatus(ServiceStatus.RequestStatus.Synccomplete)
273                             .setResponseTimestamp(responseTimeStamp)
274                     )
275                 )
276         );
277
278     }
279
280     public ServiceStatus.RpcAction toRpcAction(SvcAction fromEnum) {
281         return fromEnum == null ? null : ServiceStatus.RpcAction.valueOf(fromEnum.name());
282     }
283
284
285 }