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.Matchers.any;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.when;
28 import static org.onap.sdnc.northbound.GenericResourceApiProvider.APP_NAME;
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.requestInformation;
34 import static org.onap.sdnc.northbound.util.MDSALUtil.sdncRequestHeader;
35 import static org.onap.sdnc.northbound.util.MDSALUtil.service;
36 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceData;
37 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceInformationBuilder;
38 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceResponseInformation;
39 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceStatus;
40 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceTopologyOperationInput;
41 import static org.onap.sdnc.northbound.util.MDSALUtil.serviceTopologyOperationOutput;
43 import javax.xml.crypto.Data;
44 import org.junit.After;
45 import org.junit.Before;
46 import org.junit.Test;
47 import org.junit.runner.RunWith;
48 import org.mockito.Mockito;
49 import org.mockito.runners.MockitoJUnitRunner;
50 import org.onap.sdnc.northbound.util.PropBuilder;
51 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
52 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
53 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
54 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainClosedException;
55 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ServiceTopologyOperationInput;
56 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.ServiceTopologyOperationOutput;
57 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.request.information.RequestInformation;
58 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader;
59 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.sdnc.request.header.SdncRequestHeader.SvcAction;
60 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.information.ServiceInformation;
61 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.model.infrastructure.Service;
62 import org.opendaylight.yang.gen.v1.org.onap.sdnc.northbound.generic.resource.rev170824.service.status.ServiceStatus;
63 import org.opendaylight.yangtools.yang.binding.DataObject;
64 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
65 import org.opendaylight.yangtools.yang.common.RpcResult;
69 * This class test the ServiceTopologyOperation mdsal RPC.
71 @RunWith(MockitoJUnitRunner.class)
72 public class ServiceTopologyOperationRPCTest extends GenericResourceApiProviderTest {
75 final String SVC_OPERATION = "service-topology-operation";
79 public void setUp() throws Exception {
81 svcClient.setScvOperation(SVC_OPERATION);
86 * Verify ServiceTopologyOperation RPC executes a DG then produces the expected {@link
87 * ServiceTopologyOperationOutput} and persisted the expected {@link Service} in the {@link DataBroker}
90 public void testServiceTopologyOperationRPC_ExecuteDG_Success() throws Exception {
92 //mock svcClient to perform a successful execution with the expected parameters
93 svcClient.mockHasGraph(true);
94 PropBuilder svcResultProp = svcClient.createExecuteOKResult();
95 svcClient.mockExecute(svcResultProp);
97 // create the ServiceTopologyOperationInput from the template
98 ServiceTopologyOperationInput serviceTopologyOperationInput = createSTOI();
100 //execute the mdsal exec
101 ServiceTopologyOperationOutput actualServiceTopologyOperationOutput = exec(
102 genericResourceApiProvider::serviceTopologyOperation
103 , serviceTopologyOperationInput
104 , RpcResult::getResult
107 //verify the returned ServiceTopologyOperationOutput
108 ServiceTopologyOperationOutput expectedServiceTopologyOperationOutput = createExpectedSTOO(svcResultProp,
109 serviceTopologyOperationInput);
110 assertEquals(expectedServiceTopologyOperationOutput, actualServiceTopologyOperationOutput);
112 //verify the persisted Service
113 Service actualService = db.read(serviceTopologyOperationInput.getServiceInformation().getServiceInstanceId(),
114 LogicalDatastoreType.CONFIGURATION);
115 Service expectedService = createExpectedService(
116 expectedServiceTopologyOperationOutput,
117 serviceTopologyOperationInput,
119 assertEquals(expectedService, actualService);
125 public void serviceTopologyOperation_should_fail_when_service_info_not_present() throws Exception {
126 // create the ServiceTopologyOperationInput from the template
127 ServiceTopologyOperationInput input = build(
128 serviceTopologyOperationInput()
129 .setSdncRequestHeader(build(sdncRequestHeader()
130 .setSvcRequestId("svc-request-id: xyz")
131 .setSvcAction(SvcAction.Assign)
133 .setRequestInformation(build(requestInformation()
134 .setRequestId("request-id: xyz")
135 .setRequestAction(RequestInformation.RequestAction.CreateServiceInstance)
138 //execute the mdsal exec
139 ServiceTopologyOperationOutput output = exec(
140 genericResourceApiProvider::serviceTopologyOperation
142 , RpcResult::getResult
145 assertEquals("404", output.getResponseCode());
146 assertEquals(NULL_OR_EMPTY_ERROR_PARAM, output.getResponseMessage());
147 assertEquals("Y", output.getAckFinalIndicator());
152 public void serviceTopologyOperation_should_fail_when_client_execution_failed() throws Exception {
153 svcClient.mockHasGraph(true);
154 svcClient.mockExecute(new RuntimeException("test exception"));
156 ServiceTopologyOperationInput input = createSTOI();
158 //execute the mdsal exec
159 ServiceTopologyOperationOutput output = exec(
160 genericResourceApiProvider::serviceTopologyOperation
162 , RpcResult::getResult
165 assertEquals("500", output.getResponseCode());
166 assertEquals("test exception", output.getResponseMessage());
167 assertEquals("Y", output.getAckFinalIndicator());
171 public void serviceTopologyOperation_should_fail_when_client_has_no_graph() throws Exception {
172 svcClient.mockHasGraph(false);
174 ServiceTopologyOperationInput input = createSTOI();
176 //execute the mdsal exec
177 ServiceTopologyOperationOutput output = exec(
178 genericResourceApiProvider::serviceTopologyOperation
180 , RpcResult::getResult
183 assertEquals("503", output.getResponseCode());
184 assertEquals(NO_SERVICE_LOGIC_ACTIVE + APP_NAME + ": '" + SVC_OPERATION + "'", output.getResponseMessage());
185 assertEquals("Y", output.getAckFinalIndicator());
190 public void serviceTopologyOperation_should_fail_when_failed_to_update_mdsal() throws Exception {
192 svcClient.mockHasGraph(true);
193 WriteTransaction mockWriteTransaction = mock(WriteTransaction.class);
194 when(mockWriteTransaction.submit()).thenThrow(new TransactionChainClosedException("test exception"));
196 DataBroker spyDataBroker = Mockito.spy(dataBroker);
197 when(spyDataBroker.newWriteOnlyTransaction()).thenReturn(mockWriteTransaction);
198 genericResourceApiProvider.setDataBroker(spyDataBroker);
200 ServiceTopologyOperationInput input = createSTOI();
202 //execute the mdsal exec
203 ServiceTopologyOperationOutput output = exec(
204 genericResourceApiProvider::serviceTopologyOperation
206 , RpcResult::getResult
209 assertEquals("500", output.getResponseCode());
210 assertEquals("test exception", output.getResponseMessage());
211 assertEquals("Y", output.getAckFinalIndicator());
216 private ServiceTopologyOperationInput createSTOI() {
219 serviceTopologyOperationInput()
220 .setSdncRequestHeader(build(sdncRequestHeader()
221 .setSvcRequestId("svc-request-id: xyz")
222 .setSvcAction(SvcAction.Assign)
224 .setRequestInformation(build(requestInformation()
225 .setRequestId("request-id: xyz")
226 .setRequestAction(RequestInformation.RequestAction.CreateServiceInstance)
228 .setServiceInformation(build(serviceInformationBuilder()
229 .setServiceInstanceId("service-instance-id: xyz")
235 private ServiceTopologyOperationOutput createExpectedSTOO(PropBuilder expectedSvcResultProp,
236 ServiceTopologyOperationInput expectedServiceTopologyOperationInput) {
238 serviceTopologyOperationOutput()
239 .setSvcRequestId(expectedServiceTopologyOperationInput.getSdncRequestHeader().getSvcRequestId())
240 .setResponseCode(expectedSvcResultProp.get(svcClient.errorCode))
241 .setAckFinalIndicator(expectedSvcResultProp.get(svcClient.ackFinal))
242 .setResponseMessage(expectedSvcResultProp.get(svcClient.errorMessage))
243 .setServiceResponseInformation(build(serviceResponseInformation()
244 .setInstanceId(expectedServiceTopologyOperationInput.getServiceInformation().getServiceInstanceId())
245 .setObjectPath(expectedSvcResultProp.get(svcClient.serviceObjectPath))
250 private Service createExpectedService(
251 ServiceTopologyOperationOutput expectedServiceTopologyOperationOutput,
252 ServiceTopologyOperationInput expectedServiceTopologyOperationInput,
253 Service actualService
256 //We cannot predict the timeStamp value so just steal it from the actual
257 //we need this to prevent the equals method from returning false as a result of the timestamp
258 String responseTimeStamp = actualService == null || actualService.getServiceStatus() == null ?
259 null : actualService.getServiceStatus().getResponseTimestamp();
261 SdncRequestHeader expectedSdncRequestHeader = expectedServiceTopologyOperationInput.getSdncRequestHeader();
262 ServiceInformation expectedServiceInformation = expectedServiceTopologyOperationInput.getServiceInformation();
263 RequestInformation expectedRequestInformation = expectedServiceTopologyOperationInput.getRequestInformation();
267 .setServiceInstanceId(expectedServiceInformation.getServiceInstanceId())
268 .setServiceData(build(serviceData()))
272 .setAction(expectedRequestInformation.getRequestAction().name())
273 .setFinalIndicator(expectedServiceTopologyOperationOutput.getAckFinalIndicator())
274 .setResponseCode(expectedServiceTopologyOperationOutput.getResponseCode())
275 .setResponseMessage(expectedServiceTopologyOperationOutput.getResponseMessage())
276 .setRpcAction(toRpcAction(expectedSdncRequestHeader.getSvcAction()))
277 .setRpcName(SVC_OPERATION)
278 .setRequestStatus(ServiceStatus.RequestStatus.Synccomplete)
279 .setResponseTimestamp(responseTimeStamp)
286 public ServiceStatus.RpcAction toRpcAction(SvcAction fromEnum) {
287 return fromEnum == null ? null : ServiceStatus.RpcAction.valueOf(fromEnum.name());