Bug 5679 - implement ietf-restconf-monitoring - capabilities
[netconf.git] / restconf / sal-rest-connector / src / test / java / org / opendaylight / restconf / rest / services / impl / RestconfStreamsServiceTest.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  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
9 package org.opendaylight.restconf.rest.services.impl;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertFalse;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertTrue;
15 import static org.mockito.Mockito.when;
16 import static org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.EMPTY;
17 import com.google.common.collect.Iterables;
18 import com.google.common.collect.Lists;
19 import java.util.AbstractMap;
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.Collection;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26 import org.junit.AfterClass;
27 import org.junit.Before;
28 import org.junit.BeforeClass;
29 import org.junit.Rule;
30 import org.junit.Test;
31 import org.junit.rules.ExpectedException;
32 import org.mockito.Mock;
33 import org.mockito.MockitoAnnotations;
34 import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
35 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
36 import org.opendaylight.netconf.sal.streams.listeners.Notificator;
37 import org.opendaylight.restconf.Draft18;
38 import org.opendaylight.restconf.base.services.api.RestconfStreamsService;
39 import org.opendaylight.restconf.base.services.impl.RestconfStreamsServiceImpl;
40 import org.opendaylight.restconf.handlers.SchemaContextHandler;
41 import org.opendaylight.restconf.utils.mapping.RestconfMappingNodeConstants;
42 import org.opendaylight.restconf.utils.mapping.RestconfMappingStreamConstants;
43 import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
44 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
45 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
46 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
47 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
48 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
49 import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableDataContainerAttrNode;
50 import org.opendaylight.yangtools.yang.model.api.Module;
51 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
52
53 /**
54  * Unit tests for {@link RestconfStreamsServiceImpl}
55  */
56 public class RestconfStreamsServiceTest {
57     private static final List<String> expectedStreams = Arrays.asList(new String[] {"stream-1", "stream-2", "stream-3"});
58
59     @Rule public ExpectedException thrown = ExpectedException.none();
60
61     @Mock private SchemaContextHandler contextHandler;
62     @Mock private SchemaContext mockSchemaContext;
63
64     // service under test
65     private RestconfStreamsService streamsService;
66
67     // schema context with testing Restconf modules
68     private SchemaContext schemaContext;
69
70     @Before
71     public void setup() throws Exception {
72         MockitoAnnotations.initMocks(this);
73
74         this.schemaContext = TestRestconfUtils.loadSchemaContext("/modules/restconf-module-testing");
75         this.streamsService = new RestconfStreamsServiceImpl(this.contextHandler);
76     }
77
78     @BeforeClass
79     public static void setupTestStreams() {
80         // clean
81         Notificator.removeAllListeners();
82
83         // put test streams
84         Notificator.createListener(EMPTY, RestconfStreamsServiceTest.expectedStreams.get(0),
85                 NotificationOutputType.XML);
86         Notificator.createListener(EMPTY, RestconfStreamsServiceTest.expectedStreams.get(1),
87                 NotificationOutputType.XML);
88         Notificator.createListener(EMPTY, RestconfStreamsServiceTest.expectedStreams.get(2),
89                 NotificationOutputType.XML);
90     }
91
92     @AfterClass
93     public static void removeTestStreams() {
94         Notificator.removeAllListeners();
95     }
96
97     /**
98      * Test of successful initialization of streams service.
99      */
100     @Test
101     public void restconfStreamsServiceImplInitTest() {
102         assertNotNull("Streams service should be initialized and not null", this.streamsService);
103     }
104
105     /**
106      * Positive test to get all available streams supported by the server. Loaded streams are compared to expected
107      * streams.
108      */
109     @Test
110     public void getAvailableStreamsTest() throws Exception {
111         // prepare conditions - get correct Restconf module
112         when(this.contextHandler.get()).thenReturn(this.mockSchemaContext);
113         when(this.mockSchemaContext.findModuleByNamespaceAndRevision(Draft18.RestconfModule.IETF_RESTCONF_QNAME
114                 .getNamespace(), Draft18.RestconfModule.IETF_RESTCONF_QNAME.getRevision()))
115                 .thenReturn(getTestingRestconfModule("ietf-restconf"));
116
117         // make test
118         final NormalizedNodeContext nodeContext = this.streamsService.getAvailableStreams(null);
119
120         // verify loaded streams
121         assertNotNull("Normalized node context should not be null", nodeContext);
122         verifyStreams(((ContainerNode) nodeContext.getData()).getValue());
123     }
124
125     /**
126      * Try to get all available streams supported by the server when current <code>SchemaContext</code> is
127      * <code>null</code> expecting <code>NullPointerException</code>.
128      */
129     @Test
130     public void getAvailableStreamsNullSchemaContextNegativeTest() {
131         // prepare conditions - returned SchemaContext is null
132         when(this.contextHandler.get()).thenReturn(null);
133
134         // make test
135         this.thrown.expect(NullPointerException.class);
136         this.streamsService.getAvailableStreams(null);
137     }
138
139     /**
140      * Try to get all available streams supported by the server when Restconf module is missing in
141      * <code>SchemaContext</code> expecting <code>NullPointerException</code>.
142      */
143     @Test
144     public void getAvailableStreamsMissingRestconfModuleNegativeTest() {
145         // prepare conditions - get null Restconf module
146         when(this.contextHandler.get()).thenReturn(this.mockSchemaContext);
147         when(this.mockSchemaContext.findModuleByNamespaceAndRevision(Draft18.RestconfModule.IETF_RESTCONF_QNAME
148                 .getNamespace(), Draft18.RestconfModule.IETF_RESTCONF_QNAME.getRevision())).thenReturn(null);
149
150         // make test
151         this.thrown.expect(NullPointerException.class);
152         this.streamsService.getAvailableStreams(null);
153     }
154
155     /**
156      * There are multiple testing Restconf modules for different test cases. It is possible to distinguish them by
157      * name or by namespace. This method is looking for Restconf test module by its name.
158      * @param s Testing Restconf module name
159      * @return Restconf module
160      */
161     private Module getTestingRestconfModule(final String s) {
162         return this.schemaContext.findModuleByName(s, Draft18.RestconfModule.IETF_RESTCONF_QNAME.getRevision());
163     }
164
165     /**
166      * Verify loaded streams
167      * @param streams Streams to be verified
168      */
169     private void verifyStreams(final Collection<DataContainerChild<? extends PathArgument, ?>> streams) {
170         assertNotNull("Collection of streams should not be empty", streams);
171         assertFalse("Collection of streams should not be empty", Iterables.isEmpty(streams));
172         final Iterator<DataContainerChild<? extends PathArgument, ?>> iterator = streams.iterator();
173
174         final List<String> loadedStreams = new ArrayList<>();
175         for (final Object stream : (Collection<?>) iterator.next().getValue()) {
176             final Iterator mapEntries = ((AbstractImmutableDataContainerAttrNode) stream)
177                     .getChildren().entrySet().iterator();
178
179             final List<String> allowedKeys = Lists.newArrayList(
180                     RestconfMappingNodeConstants.NAME,
181                     RestconfMappingNodeConstants.DESCRIPTION,
182                     RestconfMappingNodeConstants.REPLAY_SUPPORT,
183                     RestconfMappingNodeConstants.REPLAY_LOG,
184                     RestconfMappingNodeConstants.EVENTS);
185
186             while (mapEntries.hasNext()) {
187                 final Map.Entry e = ((AbstractMap.SimpleImmutableEntry) mapEntries.next());
188                 final String key = ((NodeIdentifier) e.getKey()).getNodeType().getLocalName();
189
190                 assertTrue("Not allowed key", allowedKeys.contains(key));
191
192                 switch (key) {
193                     case RestconfMappingNodeConstants.NAME :
194                         loadedStreams.add((String) ((LeafNode) e.getValue()).getValue());
195                         break;
196                     case RestconfMappingNodeConstants.DESCRIPTION :
197                         assertEquals("Stream description value is not as expected",
198                                 RestconfMappingStreamConstants.DESCRIPTION, ((LeafNode) e.getValue()).getValue());
199                         break;
200                     case RestconfMappingNodeConstants.REPLAY_SUPPORT :
201                         assertEquals("Stream replay support value is not as expected",
202                                 RestconfMappingStreamConstants.REPLAY_SUPPORT, ((LeafNode) e.getValue()).getValue());
203                         break;
204                     case RestconfMappingNodeConstants.REPLAY_LOG :
205                         assertEquals("Stream replay log value is not as expected",
206                                 RestconfMappingStreamConstants.REPLAY_LOG, ((LeafNode) e.getValue()).getValue());
207                         break;
208                     case RestconfMappingNodeConstants.EVENTS :
209                         assertEquals("Stream events value is not as expected",
210                                 RestconfMappingStreamConstants.EVENTS, ((LeafNode) e.getValue()).getValue());
211                         break;
212                 }
213             }
214         }
215
216         // sort and compare
217         loadedStreams.sort((s1, s2) -> s1.compareTo(s2));
218         assertEquals("Returned streams are not as expected", expectedStreams, loadedStreams);
219     }
220 }