Bug 6457 - Delete Cars configuration from Follower produces HTTP 500 Error
[netconf.git] / restconf / sal-rest-connector / src / test / java / org / opendaylight / controller / sal / restconf / impl / test / RestPutOperationTest.java
1 /*
2  * Copyright (c) 2014 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 package org.opendaylight.controller.sal.restconf.impl.test;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.mockito.Matchers.any;
12 import static org.mockito.Mockito.doReturn;
13 import static org.mockito.Mockito.doThrow;
14 import static org.mockito.Mockito.mock;
15 import static org.mockito.Mockito.when;
16 import com.google.common.base.Optional;
17 import com.google.common.util.concurrent.CheckedFuture;
18 import com.google.common.util.concurrent.Futures;
19 import java.io.FileNotFoundException;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.UnsupportedEncodingException;
23 import java.net.URISyntaxException;
24 import javax.ws.rs.client.Entity;
25 import javax.ws.rs.core.Application;
26 import javax.ws.rs.core.MediaType;
27 import javax.ws.rs.core.Response;
28 import javax.ws.rs.core.Response.Status;
29 import org.glassfish.jersey.server.ResourceConfig;
30 import org.glassfish.jersey.test.JerseyTest;
31 import org.junit.BeforeClass;
32 import org.junit.Ignore;
33 import org.junit.Test;
34 import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException;
35 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
36 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
37 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
38 import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader;
39 import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeJsonBodyWriter;
40 import org.opendaylight.netconf.sal.rest.impl.NormalizedNodeXmlBodyWriter;
41 import org.opendaylight.netconf.sal.rest.impl.RestconfDocumentedExceptionMapper;
42 import org.opendaylight.netconf.sal.rest.impl.XmlNormalizedNodeBodyReader;
43 import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
44 import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
45 import org.opendaylight.netconf.sal.restconf.impl.PutResult;
46 import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
47 import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
48 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
49 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
50 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
51 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
52
53 //TODO UNSTABLE TESTS - FIX ME
54 @Ignore
55 public class RestPutOperationTest extends JerseyTest {
56
57     private static String xmlData;
58     private static String xmlData2;
59     private static String xmlData3;
60
61     private static BrokerFacade brokerFacade;
62     private static RestconfImpl restconfImpl;
63     private static SchemaContext schemaContextYangsIetf;
64     private static SchemaContext schemaContextTestModule;
65
66     @BeforeClass
67     public static void init() throws IOException, ReactorException {
68         schemaContextYangsIetf = TestUtils.loadSchemaContext("/full-versions/yangs");
69         schemaContextTestModule = TestUtils.loadSchemaContext("/full-versions/test-module");
70         final ControllerContext controllerContext = ControllerContext.getInstance();
71         controllerContext.setSchemas(schemaContextYangsIetf);
72         brokerFacade = mock(BrokerFacade.class);
73         restconfImpl = RestconfImpl.getInstance();
74         restconfImpl.setBroker(brokerFacade);
75         restconfImpl.setControllerContext(controllerContext);
76         loadData();
77     }
78
79     private static void loadData() throws IOException {
80         final InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
81         xmlData = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
82         final InputStream xmlStream2 = RestconfImplTest.class.getResourceAsStream("/full-versions/test-data2/data2.xml");
83         xmlData2 = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream2));
84         final InputStream xmlStream3 = RestconfImplTest.class.getResourceAsStream("/full-versions/test-data2/data7.xml");
85         xmlData3 = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream3));
86     }
87
88     @Override
89     protected Application configure() {
90         /* enable/disable Jersey logs to console */
91         // enable(TestProperties.LOG_TRAFFIC);
92         // enable(TestProperties.DUMP_ENTITY);
93         // enable(TestProperties.RECORD_LOG_LEVEL);
94         // set(TestProperties.RECORD_LOG_LEVEL, Level.ALL.intValue());
95         ResourceConfig resourceConfig = new ResourceConfig();
96         resourceConfig = resourceConfig.registerInstances(restconfImpl,new XmlNormalizedNodeBodyReader(),
97                 new NormalizedNodeXmlBodyWriter(), new JsonNormalizedNodeBodyReader(), new NormalizedNodeJsonBodyWriter());
98         resourceConfig.registerClasses(RestconfDocumentedExceptionMapper.class);
99         return resourceConfig;
100     }
101
102     /**
103      * Tests of status codes for "/config/{identifier}".
104      */
105     @Test
106     public void putConfigStatusCodes() throws UnsupportedEncodingException {
107         final String uri = "/config/ietf-interfaces:interfaces/interface/eth0";
108         mockCommitConfigurationDataPutMethod(true);
109         assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
110
111         mockCommitConfigurationDataPutMethod(false);
112         assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
113
114         assertEquals(400, put(uri, MediaType.APPLICATION_JSON, ""));
115     }
116
117     @Test
118     public void putConfigStatusCodesEmptyBody() throws UnsupportedEncodingException {
119         final String uri = "/config/ietf-interfaces:interfaces/interface/eth0";
120         @SuppressWarnings("unused")
121         final Response resp = target(uri).request(MediaType.APPLICATION_JSON).put(
122                 Entity.entity("", MediaType.APPLICATION_JSON));
123         assertEquals(400, put(uri, MediaType.APPLICATION_JSON, ""));
124     }
125
126     @Test
127     public void testRpcResultCommitedToStatusCodesWithMountPoint() throws UnsupportedEncodingException,
128             FileNotFoundException, URISyntaxException {
129         final CheckedFuture<Void, TransactionCommitFailedException> dummyFuture = Futures.immediateCheckedFuture(null);
130         final PutResult result = mock(PutResult.class);
131         when(
132                 brokerFacade.commitMountPointDataPut(any(DOMMountPoint.class), any(YangInstanceIdentifier.class),
133                         any(NormalizedNode.class))).thenReturn(result);
134         when(result.getFutureOfPutData()).thenReturn(dummyFuture);
135         when(result.getStatus()).thenReturn(Status.OK);
136
137         final DOMMountPoint mountInstance = mock(DOMMountPoint.class);
138         when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
139         final DOMMountPointService mockMountService = mock(DOMMountPointService.class);
140         when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountInstance));
141
142         ControllerContext.getInstance().setMountService(mockMountService);
143
144         String uri = "/config/ietf-interfaces:interfaces/interface/0/yang-ext:mount/test-module:cont";
145         assertEquals(200, put(uri, MediaType.APPLICATION_XML, xmlData2));
146
147         uri = "/config/ietf-interfaces:interfaces/yang-ext:mount/test-module:cont";
148         assertEquals(200, put(uri, MediaType.APPLICATION_XML, xmlData2));
149     }
150
151     @Test
152     public void putDataMountPointIntoHighestElement() throws UnsupportedEncodingException, URISyntaxException {
153         final CheckedFuture<Void, TransactionCommitFailedException> dummyFuture = Futures.immediateCheckedFuture(null);
154         final PutResult result = mock(PutResult.class);
155         doReturn(result).when(brokerFacade).commitMountPointDataPut(any(DOMMountPoint.class),
156                 any(YangInstanceIdentifier.class), any(NormalizedNode.class));
157         when(result.getFutureOfPutData()).thenReturn(dummyFuture);
158         when(result.getStatus()).thenReturn(Status.OK);
159
160         final DOMMountPoint mountInstance = mock(DOMMountPoint.class);
161         when(mountInstance.getSchemaContext()).thenReturn(schemaContextTestModule);
162         final DOMMountPointService mockMountService = mock(DOMMountPointService.class);
163         when(mockMountService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountInstance));
164
165         ControllerContext.getInstance().setMountService(mockMountService);
166
167         final String uri = "/config/ietf-interfaces:interfaces/yang-ext:mount";
168         assertEquals(200, put(uri, MediaType.APPLICATION_XML, xmlData3));
169     }
170
171     @Test
172     public void putWithOptimisticLockFailedException() throws UnsupportedEncodingException {
173
174         final String uri = "/config/ietf-interfaces:interfaces/interface/eth0";
175
176         doThrow(OptimisticLockFailedException.class).
177             when(brokerFacade).commitConfigurationDataPut(
178                         any(SchemaContext.class), any(YangInstanceIdentifier.class), any(NormalizedNode.class));
179
180         assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
181
182         doThrow(OptimisticLockFailedException.class).doReturn(mock(PutResult.class)).when(brokerFacade)
183                 .commitConfigurationDataPut(any(SchemaContext.class), any(YangInstanceIdentifier.class),
184                         any(NormalizedNode.class));
185
186         assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
187     }
188
189     @Test
190     public void putWithTransactionCommitFailedException() throws UnsupportedEncodingException {
191
192         final String uri = "/config/ietf-interfaces:interfaces/interface/eth0";
193
194         doThrow(TransactionCommitFailedException.class).
195             when(brokerFacade).commitConfigurationDataPut(
196                         any(SchemaContext.class), any(YangInstanceIdentifier.class), any(NormalizedNode.class));
197
198         assertEquals(500, put(uri, MediaType.APPLICATION_XML, xmlData));
199     }
200
201     private int put(final String uri, final String mediaType, final String data) throws UnsupportedEncodingException {
202         return target(uri).request(mediaType).put(Entity.entity(data, mediaType)).getStatus();
203     }
204
205     private void mockCommitConfigurationDataPutMethod(final boolean noErrors) {
206         final PutResult putResMock = mock(PutResult.class);
207         if (noErrors) {
208             doReturn(putResMock).when(brokerFacade).commitConfigurationDataPut(
209                     any(SchemaContext.class), any(YangInstanceIdentifier.class), any(NormalizedNode.class));
210         } else {
211             doThrow(RestconfDocumentedException.class).when(brokerFacade).commitConfigurationDataPut(
212                     any(SchemaContext.class), any(YangInstanceIdentifier.class), any(NormalizedNode.class));
213         }
214     }
215
216 }