summaryrefslogtreecommitdiffstats
path: root/netconf/restconf/restconf-nb-bierman02/src/test/java/org/opendaylight/controller/sal/restconf/impl/input/to/cnsn/test/RestPutListDataTest.java
blob: 71406ca7742590c94374721e1880589ecac7ca33 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/*
 * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.controller.sal.restconf.impl.input.to.cnsn.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.google.common.util.concurrent.FluentFuture;
import java.io.FileNotFoundException;
import java.util.List;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mockito;
import org.opendaylight.controller.md.sal.rest.common.TestRestconfUtils;
import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeContext;
import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
import org.opendaylight.netconf.sal.restconf.impl.PutResult;
import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
import org.opendaylight.restconf.common.errors.RestconfError;
import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
import org.opendaylight.yangtools.yang.data.api.schema.builder.NormalizedNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.SchemaAwareBuilders;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid.DataValidationException;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;

public class RestPutListDataTest {
    private static EffectiveModelContext schemaContextTestModule;

    private static BrokerFacade brokerFacade;
    private static RestconfImpl restconfImpl;

    private static final String TEST_MODULE_NS_STRING = "test:module";
    private static final String TEST_MODULE_REVISION = "2014-01-09";

    @BeforeClass
    public static void staticSetup() throws FileNotFoundException {
        schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
    }

    @Before
    public void initialize() throws FileNotFoundException {
        final ControllerContext controllerContext = TestRestconfUtils.newControllerContext(schemaContextTestModule);
        brokerFacade = mock(BrokerFacade.class);
        restconfImpl = RestconfImpl.newInstance(brokerFacade, controllerContext);
        final PutResult result = mock(PutResult.class);
        when(brokerFacade.commitConfigurationDataPut(any(EffectiveModelContext.class),
                any(YangInstanceIdentifier.class), any(NormalizedNode.class), Mockito.anyString(), Mockito.anyString()))
                        .thenReturn(result);
        when(result.getFutureOfPutData()).thenReturn(mock(FluentFuture.class));
        when(result.getStatus()).thenReturn(Status.OK);
    }

    /**
     * Tests whether no exception is raised if number and values of keys in URI
     * and payload are equal.
     */
    @Test
    @Ignore
    public void testValidKeys() {
        putListDataTest("key1value", "15", "key1value", (short) 15);
    }

    /**
     * Tests whether an exception is raised if key values in URI and payload are
     * different.
     *
     * <p>
     * The exception should be raised from validation method
     * {@code RestconfImpl#validateListEqualityOfListInDataAndUri}
     */
    @Test
    @Ignore // RestconfDocumentedExceptionMapper needs update
    public void testUriAndPayloadKeysDifferent() {
        try {
            putListDataTest("key1value", "15", "key1value", (short) 16);
            fail("RestconfDocumentedException expected");
        } catch (final RestconfDocumentedException e) {
            verifyException(e, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
        }

        try {
            putListDataTest("key1value", "15", "key1value1", (short) 16);
            fail("RestconfDocumentedException expected");
        } catch (final RestconfDocumentedException e) {
            verifyException(e, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE);
        }
    }

    /**
     * Tests whether an exception is raised if URI contains less key values then
     * payload.
     *
     * <p>
     * The exception is raised during {@code InstanceIdentifier} instance is
     * built from URI
     */
    @Test
    @Ignore
    public void testMissingKeysInUri() {
        try {
            putListDataTest("key1value", null, "key1value", (short) 15);
            fail("RestconfDocumentedException expected");
        } catch (final RestconfDocumentedException e) {
            verifyException(e, ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
        }
    }

    /**
     * Tests whether an exception is raised if URI contains more key values then
     * payload.
     *
     * <p>
     * The exception should be raised from validation method
     * {@code RestconfImpl#validateListEqualityOfListInDataAndUri}
     */
    @Test
    public void testMissingKeysInPayload() {
        try {
            putListDataTest("key1value", "15", "key1value", null);
            fail("RestconfDocumentedException expected");
        } catch (final DataValidationException e) {
            // FIXME: thing about different approach for testing the Exception states
            // RestconfDocumentedException is not rise in new API because you get
            // DataValidationException from putListDataTest before you call the real rest service
//            verifyException(e, ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
        }
    }

    private static void verifyException(final RestconfDocumentedException restDocumentedException,
                                        final ErrorType errorType, final ErrorTag errorTag) {
        final List<RestconfError> errors = restDocumentedException.getErrors();
        assertEquals("getErrors() size", 1, errors.size());
        assertEquals("RestconfError getErrorType()", errorType, errors.get(0).getErrorType());
        assertEquals("RestconfError getErrorTag()", errorTag, errors.get(0).getErrorTag());
    }

    public void putListDataTest(final String uriKey1, final String uriKey2, final String payloadKey1,
            final Short payloadKey2) {
        final QName lstWithCompositeKey =
                QName.create(TEST_MODULE_NS_STRING, TEST_MODULE_REVISION, "lst-with-composite-key");
        final QName key1 = QName.create(TEST_MODULE_NS_STRING, TEST_MODULE_REVISION, "key1");
        final QName key2 = QName.create(TEST_MODULE_NS_STRING, TEST_MODULE_REVISION, "key2");

        final DataSchemaNode testNodeSchemaNode = schemaContextTestModule.getDataChildByName(lstWithCompositeKey);
        assertTrue(testNodeSchemaNode != null);
        assertTrue(testNodeSchemaNode instanceof ListSchemaNode);
        final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> testNodeContainer =
            SchemaAwareBuilders.mapEntryBuilder((ListSchemaNode) testNodeSchemaNode);

        var testChildren = ControllerContext.findInstanceDataChildrenByName(
                (ListSchemaNode) testNodeSchemaNode, key1.getLocalName());
        assertTrue(testChildren != null);
        final DataSchemaNode testLeafKey1SchemaNode = testChildren.get(0).child;
        assertTrue(testLeafKey1SchemaNode != null);
        assertTrue(testLeafKey1SchemaNode instanceof LeafSchemaNode);
        final NormalizedNodeBuilder<NodeIdentifier, Object, LeafNode<Object>> leafKey1 =
            SchemaAwareBuilders.leafBuilder((LeafSchemaNode) testLeafKey1SchemaNode);
        leafKey1.withValue(payloadKey1);
        testNodeContainer.withChild(leafKey1.build());

        if (payloadKey2 != null) {
            testChildren = ControllerContext.findInstanceDataChildrenByName(
                    (ListSchemaNode) testNodeSchemaNode, key2.getLocalName());
            assertTrue(testChildren != null);
            final DataSchemaNode testLeafKey2SchemaNode = testChildren.get(0).child;
            assertNotNull(testLeafKey2SchemaNode);
            assertTrue(testLeafKey2SchemaNode instanceof LeafSchemaNode);
            final NormalizedNodeBuilder<NodeIdentifier, Object, LeafNode<Object>> leafKey2 =
                SchemaAwareBuilders.leafBuilder((LeafSchemaNode) testLeafKey2SchemaNode);
            leafKey2.withValue(payloadKey2);
            testNodeContainer.withChild(leafKey2.build());
        }

        final NormalizedNodeContext testCompositeContext = new NormalizedNodeContext(
            InstanceIdentifierContext.ofStack(
                SchemaInferenceStack.ofDataTreePath(schemaContextTestModule, lstWithCompositeKey)),
            testNodeContainer.build());

        final UriInfo uriInfo = Mockito.mock(UriInfo.class);
        restconfImpl.updateConfigurationData(toUri(uriKey1, uriKey2), testCompositeContext, uriInfo);
    }

    public void putListDataWithWrapperTest(final String uriKey1, final String uriKey2, final String payloadKey1,
            final Short payloadKey2) {
        putListDataTest(uriKey1, uriKey2, payloadKey1, payloadKey2);
    }

    private static String toUri(final String uriKey1, final String uriKey2) {
        final StringBuilder uriBuilder = new StringBuilder("/test-module:lst-with-composite-key/");
        uriBuilder.append(uriKey1);
        if (uriKey2 != null) {
            uriBuilder.append("/");
            uriBuilder.append(uriKey2);
        }
        return uriBuilder.toString();
    }
}