Bump upstream dependencies to Ca
[transportpce.git] / servicehandler / src / test / java / org / opendaylight / transportpce / servicehandler / listeners / ServiceListenerTest.java
1 /*
2  * Copyright © 2021 Orange.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.transportpce.servicehandler.listeners;
9
10 import static org.junit.jupiter.api.Assertions.fail;
11 import static org.mockito.ArgumentMatchers.any;
12 import static org.mockito.ArgumentMatchers.anyString;
13 import static org.mockito.Mockito.mock;
14 import static org.mockito.Mockito.never;
15 import static org.mockito.Mockito.times;
16 import static org.mockito.Mockito.verify;
17 import static org.mockito.Mockito.when;
18
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Optional;
23 import org.junit.jupiter.api.Test;
24 import org.junit.jupiter.api.extension.ExtendWith;
25 import org.mockito.Mock;
26 import org.mockito.junit.jupiter.MockitoExtension;
27 import org.opendaylight.mdsal.binding.api.DataObjectModification;
28 import org.opendaylight.mdsal.binding.api.DataTreeModification;
29 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
30 import org.opendaylight.mdsal.binding.api.RpcService;
31 import org.opendaylight.transportpce.common.ResponseCodes;
32 import org.opendaylight.transportpce.pce.service.PathComputationService;
33 import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperations;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.node.types.rev210528.NodeIdType;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.ConnectionType;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.Restorable;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.configuration.response.common.ConfigurationResponseCommonBuilder;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.sdnc.request.header.SdncRequestHeaderBuilder;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.ServiceAEndBuilder;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.ServiceZEndBuilder;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.RxDirection;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.RxDirectionBuilder;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.RxDirectionKey;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.TxDirection;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.TxDirectionBuilder;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.TxDirectionKey;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.lgx.LgxBuilder;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.port.PortBuilder;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.resiliency.ServiceResiliency;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.resiliency.ServiceResiliencyBuilder;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.format.rev191129.ServiceFormat;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreate;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreateOutputBuilder;
56 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceDelete;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceDeleteOutputBuilder;
58 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceReroute;
59 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceRerouteOutputBuilder;
60 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.list.Services;
61 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.list.ServicesBuilder;
62 import org.opendaylight.yang.gen.v1.nbi.notifications.rev230728.PublishNotificationAlarmService;
63 import org.opendaylight.yang.gen.v1.nbi.notifications.rev230728.PublishNotificationAlarmServiceBuilder;
64 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
65 import org.opendaylight.yangtools.yang.common.Uint32;
66 import org.opendaylight.yangtools.yang.common.Uint8;
67
68 @ExtendWith(MockitoExtension.class)
69 public class ServiceListenerTest {
70
71     @Mock
72     private RpcService rpcService;
73     @Mock
74     private ServiceDataStoreOperations serviceDataStoreOperations;
75     @Mock
76     private NotificationPublishService notificationPublishService;
77     @Mock
78     private PathComputationService pathComputationService;
79     @Mock
80     private ServiceDelete serviceDelete;
81     @Mock
82     private ServiceReroute serviceReroute;
83     @Mock
84     private ServiceCreate serviceCreate;
85
86     @Test
87     void testOnDataTreeChangedWhenDeleteService() {
88         @SuppressWarnings("unchecked") final DataObjectModification<Services> service =
89                 mock(DataObjectModification.class);
90         final List<DataTreeModification<Services>> changes = new ArrayList<>();
91         @SuppressWarnings("unchecked") final DataTreeModification<Services> ch = mock(DataTreeModification.class);
92         changes.add(ch);
93         when(ch.getRootNode()).thenReturn(service);
94
95         when(service.modificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
96         when(service.dataBefore()).thenReturn(buildService(State.InService, AdminStates.InService));
97         ServiceListener listener = new ServiceListener(rpcService, serviceDataStoreOperations,
98                 notificationPublishService);
99         listener.onDataTreeChanged(changes);
100         verify(ch, times(1)).getRootNode();
101         verify(service, times(1)).modificationType();
102         verify(service, times(2)).dataBefore();
103         verify(service, never()).dataAfter();
104         try {
105             verify(notificationPublishService, never()).putNotification(any(PublishNotificationAlarmService.class));
106         } catch (InterruptedException e) {
107             fail("Failed publishing notification");
108         }
109     }
110
111     @Test
112     void testOnDataTreeChangedWhenServiceBecomesOutOfService() {
113         @SuppressWarnings("unchecked") final DataObjectModification<Services> service =
114                 mock(DataObjectModification.class);
115         final List<DataTreeModification<Services>> changes = new ArrayList<>();
116         @SuppressWarnings("unchecked") final DataTreeModification<Services> ch = mock(DataTreeModification.class);
117         changes.add(ch);
118         when(ch.getRootNode()).thenReturn(service);
119
120         Services serviceDown = buildService(State.OutOfService, AdminStates.InService);
121         when(service.modificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
122         when(service.dataBefore()).thenReturn(buildService(State.InService, AdminStates.InService));
123         when(service.dataAfter()).thenReturn(serviceDown);
124         ServiceListener listener = new ServiceListener(rpcService, serviceDataStoreOperations,
125                 notificationPublishService);
126         listener.onDataTreeChanged(changes);
127         verify(ch, times(1)).getRootNode();
128         verify(service, times(1)).modificationType();
129         verify(service, times(3)).dataBefore();
130         verify(service, times(1)).dataAfter();
131         try {
132             verify(notificationPublishService, times(1))
133                     .putNotification(buildNotificationAlarmService(serviceDown, "The service is now outOfService"));
134         } catch (InterruptedException e) {
135             fail("Failed publishing notification");
136         }
137     }
138
139     @Test
140     void testOnDataTreeChangedWhenShouldNeverHappen() {
141         @SuppressWarnings("unchecked") final DataObjectModification<Services> service =
142                 mock(DataObjectModification.class);
143         final List<DataTreeModification<Services>> changes = new ArrayList<>();
144         @SuppressWarnings("unchecked") final DataTreeModification<Services> ch = mock(DataTreeModification.class);
145         changes.add(ch);
146         when(ch.getRootNode()).thenReturn(service);
147
148         when(service.modificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);
149         when(service.dataBefore()).thenReturn(buildService(State.InService, AdminStates.InService));
150         ServiceListener listener = new ServiceListener(rpcService, serviceDataStoreOperations,
151                 notificationPublishService);
152         listener.onDataTreeChanged(changes);
153         verify(ch, times(1)).getRootNode();
154         verify(service, times(2)).modificationType();
155         verify(service, times(2)).dataBefore();
156         verify(service, never()).dataAfter();
157         try {
158             verify(notificationPublishService, never()).putNotification(any(PublishNotificationAlarmService.class));
159         } catch (InterruptedException e) {
160             fail("Failed publishing notification");
161         }
162     }
163
164     @Test
165     void testOnDataTreeChangedWhenServiceDegradedShouldBeRerouted() {
166         @SuppressWarnings("unchecked") final DataObjectModification<Services> service =
167                 mock(DataObjectModification.class);
168         final List<DataTreeModification<Services>> changes = new ArrayList<>();
169         @SuppressWarnings("unchecked") final DataTreeModification<Services> ch = mock(DataTreeModification.class);
170         changes.add(ch);
171         when(ch.getRootNode()).thenReturn(service);
172
173         ServiceResiliency serviceResiliency = new ServiceResiliencyBuilder().setResiliency(Restorable.VALUE).build();
174         Services serviceAfter = new ServicesBuilder(buildService(State.OutOfService, AdminStates.InService))
175                 .setServiceResiliency(serviceResiliency)
176                 .build();
177         when(service.modificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
178         when(service.dataBefore())
179             .thenReturn(new ServicesBuilder(buildService(State.InService, AdminStates.InService))
180                         .setServiceResiliency(serviceResiliency)
181                         .build());
182         when(service.dataAfter()).thenReturn(serviceAfter);
183         when(serviceDataStoreOperations.getService(anyString())).thenReturn(Optional.of(serviceAfter));
184         when(rpcService.getRpc(ServiceDelete.class)).thenReturn(serviceDelete);
185         when(serviceDelete.invoke(any()))
186             .thenReturn(RpcResultBuilder.success(new ServiceDeleteOutputBuilder()
187                                 .setConfigurationResponseCommon(new ConfigurationResponseCommonBuilder()
188                                                 .setResponseCode(ResponseCodes.RESPONSE_OK)
189                                                 .build())
190                                 .build())
191                         .buildFuture());
192         when(rpcService.getRpc(ServiceReroute.class)).thenReturn(serviceReroute);
193         when(serviceReroute.invoke(any()))
194             .thenReturn(RpcResultBuilder.success(new ServiceRerouteOutputBuilder()
195                                 .setConfigurationResponseCommon(new ConfigurationResponseCommonBuilder()
196                                                 .setResponseCode(ResponseCodes.RESPONSE_OK)
197                                                 .build())
198                                 .build())
199                         .buildFuture());
200         when(rpcService.getRpc(ServiceCreate.class)).thenReturn(serviceCreate);
201         when(serviceCreate.invoke(any()))
202             .thenReturn(RpcResultBuilder.success(new ServiceCreateOutputBuilder()
203                                 .setConfigurationResponseCommon(new ConfigurationResponseCommonBuilder()
204                                                 .setResponseCode(ResponseCodes.RESPONSE_OK)
205                                                 .build())
206                                 .build())
207                         .buildFuture());
208         ServiceListener listener = new ServiceListener(rpcService, serviceDataStoreOperations,
209                 notificationPublishService);
210         listener.onDataTreeChanged(changes);
211         verify(ch, times(1)).getRootNode();
212         verify(service, times(1)).modificationType();
213         verify(service, times(3)).dataBefore();
214         verify(service, times(1)).dataAfter();
215 //        verify(servicehandler, times(1)).serviceDelete(any());
216
217         when(service.modificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
218         listener.onDataTreeChanged(changes);
219 //        verify(servicehandler, times(1)).serviceCreate(any());
220     }
221
222     @Test
223     void testOnDataTreeChangedWhenServiceDegradedShouldNotBeRerouted() {
224         @SuppressWarnings("unchecked") final DataObjectModification<Services> service =
225                 mock(DataObjectModification.class);
226         final List<DataTreeModification<Services>> changes = new ArrayList<>();
227         @SuppressWarnings("unchecked") final DataTreeModification<Services> ch = mock(DataTreeModification.class);
228         changes.add(ch);
229         when(ch.getRootNode()).thenReturn(service);
230
231         Services serviceAfter = buildService(State.OutOfService, AdminStates.InService);
232         when(service.modificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
233         when(service.dataBefore()).thenReturn(buildService(State.InService, AdminStates.InService));
234         when(service.dataAfter()).thenReturn(serviceAfter);
235         ServiceListener listener = new ServiceListener(rpcService, serviceDataStoreOperations,
236                 notificationPublishService);
237         listener.onDataTreeChanged(changes);
238         verify(ch, times(1)).getRootNode();
239         verify(service, times(1)).modificationType();
240         verify(service, times(3)).dataBefore();
241         verify(service, times(1)).dataAfter();
242 //        verify(servicehandler, times(0)).serviceDelete(any());
243
244         when(service.modificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
245         listener.onDataTreeChanged(changes);
246 //        verify(servicehandler, times(0)).serviceCreate(any());
247     }
248
249     private Services buildService(State state, AdminStates adminStates) {
250         return new ServicesBuilder()
251                 .setSdncRequestHeader(new SdncRequestHeaderBuilder().build())
252                 .setCommonId("commonId")
253                 .setConnectionType(ConnectionType.Service)
254                 .setCustomer("Customer")
255                 .setServiceName("service 1")
256                 .setServiceAEnd(getServiceAEndBuild().build())
257                 .setServiceZEnd(new ServiceZEndBuilder()
258                         .setClli("clli")
259                         .setServiceFormat(ServiceFormat.Ethernet)
260                         .setServiceRate(Uint32.valueOf(1))
261                         .setNodeId(new NodeIdType("XPONDER-3-2"))
262                         .setTxDirection(Map.of(new TxDirectionKey(getTxDirection().key()), getTxDirection()))
263                         .setRxDirection(Map.of(new RxDirectionKey(getRxDirection().key()), getRxDirection()))
264                         .build())
265                 .setOperationalState(state)
266                 .setAdministrativeState(adminStates)
267                 .build();
268     }
269
270     private ServiceAEndBuilder getServiceAEndBuild() {
271         return new ServiceAEndBuilder()
272                 .setClli("clli")
273                 .setServiceFormat(ServiceFormat.Ethernet)
274                 .setServiceRate(Uint32.valueOf(1))
275                 .setNodeId(new NodeIdType("XPONDER-1-2"))
276                 .setTxDirection(Map.of(new TxDirectionKey(getTxDirection().key()), getTxDirection()))
277                 .setRxDirection(Map.of(new RxDirectionKey(getRxDirection().key()), getRxDirection()));
278     }
279
280     private TxDirection getTxDirection() {
281         return new TxDirectionBuilder()
282                 .setPort(new PortBuilder()
283                         .setPortDeviceName("device name")
284                         .setPortName("port name")
285                         .setPortRack("port rack")
286                         .setPortShelf("port shelf")
287                         .setPortSlot("port slot")
288                         .setPortSubSlot("port subslot")
289                         .setPortType("port type")
290                         .build())
291                 .setLgx(new LgxBuilder()
292                         .setLgxDeviceName("lgx device name")
293                         .setLgxPortName("lgx port name")
294                         .setLgxPortRack("lgx port rack")
295                         .setLgxPortShelf("lgx port shelf")
296                         .build())
297                 .setIndex(Uint8.ZERO)
298                 .build();
299     }
300
301     private RxDirection getRxDirection() {
302         return new RxDirectionBuilder()
303                 .setPort(new PortBuilder()
304                         .setPortDeviceName("device name")
305                         .setPortName("port name")
306                         .setPortRack("port rack")
307                         .setPortShelf("port shelf")
308                         .setPortSlot("port slot")
309                         .setPortSubSlot("port subslot")
310                         .setPortType("port type")
311                         .build())
312                 .setLgx(new LgxBuilder()
313                         .setLgxDeviceName("lgx device name")
314                         .setLgxPortName("lgx port name")
315                         .setLgxPortRack("lgx port rack")
316                         .setLgxPortShelf("lgx port shelf")
317                         .build())
318                 .setIndex(Uint8.ZERO)
319                 .build();
320     }
321
322     private PublishNotificationAlarmService buildNotificationAlarmService(Services services, String message) {
323         return new PublishNotificationAlarmServiceBuilder()
324                 .setServiceName("service 1")
325                 .setConnectionType(ConnectionType.Service)
326                 .setMessage(message)
327                 .setOperationalState(services.getOperationalState())
328                 .setPublisherName("ServiceListener")
329                 .build();
330     }
331 }