--- /dev/null
+/*
+ * Copyright (c) 2013 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.rest.api;
+
+public class Draft01 {
+ public static class MediaTypes {
+ public static final String API = "application/vnd.yang.api";
+ public static final String DATASTORE = "application/vnd.yang.datastore";
+ public static final String DATA = "application/vnd.yang.data";
+ public static final String EVENT = "application/vnd.yang.event";
+ public static final String OPERATION = "application/vnd.yang.operation";
+ public static final String PATCH = "application/vnd.yang.patch";
+ }
+}
*/
package org.opendaylight.controller.sal.rest.api;
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.opendaylight.controller.sal.restconf.impl.StructuredData;
@GET
@Path("/modules")
- @Produces({API+JSON,API+XML})
+ @Produces({Draft01.MediaTypes.API+JSON,Draft01.MediaTypes.API+XML,
+ Draft02.MediaTypes.API+JSON,Draft02.MediaTypes.API+XML})
public StructuredData getModules();
@POST
@Path("/operations/{identifier}")
- @Produces({Draft02.MediaTypes.API+JSON,Draft02.MediaTypes.API+XML,API+JSON,API+XML})
+ @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML,
+ Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
+ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public StructuredData invokeRpc(@PathParam("identifier") String identifier, CompositeNode payload);
@GET
@Path("/config/{identifier:.+}")
- @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML})
+ @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
+ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public StructuredData readConfigurationData(@PathParam("identifier") String identifier);
- @PUT
+ @POST
@Path("/config/{identifier:.+}")
- @Produces({API+JSON,API+XML})
+ @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
+ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public Response createConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
- @POST
+ @PUT
@Path("/config/{identifier:.+}")
- @Produces({API+JSON,API+XML})
+ @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
+ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public Response updateConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
@GET
@Path("/operational/{identifier:.+}")
- @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML})
+ @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
+ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public StructuredData readOperationalData(@PathParam("identifier") String identifier);
- @PUT
+ @POST
@Path("/operational/{identifier:.+}")
- @Produces({API+JSON,API+XML})
+ @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
+ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public Response createOperationalData(@PathParam("identifier") String identifier, CompositeNode payload);
- @POST
+ @PUT
@Path("/operational/{identifier:.+}")
- @Produces({API+JSON,API+XML})
+ @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML,
+ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public Response updateOperationalData(@PathParam("identifier") String identifier, CompositeNode payload);
}
package org.opendaylight.controller.sal.rest.api;
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.opendaylight.controller.sal.restconf.impl.StructuredData;
@Deprecated
@GET
@Path("/datastore")
- @Produces({API+JSON,API+XML})
+ @Produces({Draft01.MediaTypes.DATASTORE+JSON,Draft01.MediaTypes.DATASTORE+XML})
public StructuredData readAllData();
@Deprecated
@GET
@Path("/datastore/{identifier:.+}")
- @Produces({API+JSON,API+XML})
+ @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML,
+ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public StructuredData readData(@PathParam("identifier") String identifier);
@Deprecated
- @PUT
+ @POST
@Path("/datastore/{identifier:.+}")
- @Produces({API+JSON,API+XML})
+ @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML,
+ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public Response createConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
@Deprecated
- @POST
+ @PUT
@Path("/datastore/{identifier:.+}")
- @Produces({API+JSON,API+XML})
+ @Produces({Draft01.MediaTypes.DATA+JSON,Draft01.MediaTypes.DATA+XML,
+ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public Response updateConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
}
private void writeValueOfNodeByType(JsonWriter writer, SimpleNode<?> node, TypeDefinition<?> type)
throws IOException {
- if (!(node.getValue() instanceof String)) {
- throw new IllegalStateException("Value in SimpleNode should be type String");
- }
- String value = (String) node.getValue();
+ String value = String.valueOf(node.getValue());
// TODO check Leafref, InstanceIdentifierTypeDefinition,
// IdentityrefTypeDefinition, UnionTypeDefinition
TypeDefinition<?> baseType = resolveBaseTypeFrom(type);
} else if (baseType instanceof EmptyTypeDefinition) {
writeEmptyDataTypeToJson(writer);
} else {
- writer.value(value != null ? value : "");
+ writer.value(value.equals("null") ? "" : value);
}
}
package org.opendaylight.controller.sal.rest.impl;
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
+import org.opendaylight.controller.sal.rest.api.Draft01;
+import org.opendaylight.controller.sal.rest.api.Draft02;
import org.opendaylight.controller.sal.rest.api.RestconfService;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
@Provider
-@Consumes({API+RestconfService.JSON})
+@Consumes({ Draft01.MediaTypes.DATA + RestconfService.JSON, Draft02.MediaTypes.DATA + RestconfService.JSON,
+ MediaType.APPLICATION_JSON })
public enum JsonToCompositeNodeProvider implements MessageBodyReader<CompositeNode> {
INSTANCE;
-
+
@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return true;
try {
return jsonReader.read(entityStream);
} catch (UnsupportedFormatException e) {
- throw new WebApplicationException(e,Response.status(Response.Status.BAD_REQUEST)
- .entity(e.getMessage()).build());
+ throw new WebApplicationException(e, Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage())
+ .build());
}
}
package org.opendaylight.controller.sal.rest.impl;
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
+import org.opendaylight.controller.sal.rest.api.Draft01;
+import org.opendaylight.controller.sal.rest.api.Draft02;
import org.opendaylight.controller.sal.rest.api.RestconfService;
import org.opendaylight.controller.sal.restconf.impl.StructuredData;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import com.google.gson.stream.JsonWriter;
@Provider
-@Produces({ API + RestconfService.JSON })
+@Produces({ Draft01.MediaTypes.DATA + RestconfService.JSON, Draft02.MediaTypes.DATA + RestconfService.JSON,
+ MediaType.APPLICATION_JSON })
public enum StructuredDataToJsonProvider implements MessageBodyWriter<StructuredData> {
INSTANCE;
package org.opendaylight.controller.sal.rest.impl;
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
+import org.opendaylight.controller.sal.rest.api.Draft01;
+import org.opendaylight.controller.sal.rest.api.Draft02;
import org.opendaylight.controller.sal.rest.api.RestconfService;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
import org.opendaylight.controller.sal.restconf.impl.StructuredData;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.impl.NodeUtils;
import org.w3c.dom.Document;
@Provider
-@Produces({API+RestconfService.XML})
+@Produces({ Draft01.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.DATA + RestconfService.XML,
+ MediaType.APPLICATION_XML, MediaType.TEXT_XML })
public enum StructuredDataToXmlProvider implements MessageBodyWriter<StructuredData> {
INSTANCE;
-
+
private final static Logger logger = LoggerFactory.getLogger(StructuredDataToXmlProvider.class);
@Override
throws IOException, WebApplicationException {
CompositeNode data = t.getData();
if (data == null) {
- throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build());
+ throw new ResponseException(Response.Status.NOT_FOUND, "No data exists.");
}
-
+
Document domTree = NodeUtils.buildShadowDomTree(data);
try {
TransformerFactory tf = TransformerFactory.newInstance();
transformer.transform(new DOMSource(domTree), new StreamResult(entityStream));
} catch (TransformerException e) {
logger.error("Error during translation of Document to OutputStream", e);
- throw new WebApplicationException(Response.status(Response.Status.INTERNAL_SERVER_ERROR).build());
+ throw new ResponseException(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage());
}
}
package org.opendaylight.controller.sal.rest.impl;
-import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
-
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import javax.ws.rs.ext.Provider;
import javax.xml.stream.XMLStreamException;
+import org.opendaylight.controller.sal.rest.api.Draft01;
+import org.opendaylight.controller.sal.rest.api.Draft02;
import org.opendaylight.controller.sal.rest.api.RestconfService;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
@Provider
-@Consumes({ API + RestconfService.XML })
+@Consumes({ Draft01.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.DATA + RestconfService.XML,
+ MediaType.APPLICATION_XML, MediaType.TEXT_XML })
public enum XmlToCompositeNodeProvider implements MessageBodyReader<CompositeNode> {
INSTANCE;
try {
return xmlReader.read(entityStream);
} catch (XMLStreamException | UnsupportedFormatException e) {
- throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage())
- .build());
+ throw new ResponseException(Response.Status.BAD_REQUEST, e.getMessage());
}
}
private def void checkPreconditions() {
if (context === null || dataService === null) {
- throw new WebApplicationException(Response.status(Response.Status.SERVICE_UNAVAILABLE)
- .entity(RestconfProvider::NOT_INITALIZED_MSG).build())
+ throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG)
}
}
import java.util.List
import java.util.Map
import java.util.concurrent.ConcurrentHashMap
-import javax.ws.rs.WebApplicationException
import javax.ws.rs.core.Response
import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
import org.opendaylight.controller.sal.rest.impl.RestconfProvider
private def void checkPreconditions() {
if (schemas === null) {
- throw new WebApplicationException(Response.status(Response.Status.SERVICE_UNAVAILABLE)
- .entity(RestconfProvider::NOT_INITALIZED_MSG).build())
+ throw new ResponseException(Response.Status.SERVICE_UNAVAILABLE, RestconfProvider::NOT_INITALIZED_MSG)
}
}
private def DataSchemaNode collectPathArguments(InstanceIdentifierBuilder builder, List<String> strings,
DataNodeContainer parentNode) {
checkNotNull(strings)
+ if (parentNode === null) {
+ return null;
+ }
if (strings.empty) {
return parentNode as DataSchemaNode;
}
+++ /dev/null
-/*
- * Copyright (c) 2013 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;
-
-public class MediaTypes {
- public static final String API = "application/vnd.yang.api";
- public static final String DATASTORE = "application/vnd.yang.datastore";
- public static final String DATA = "application/vnd.yang.data";
- public static final String EVENT = "application/vnd.yang.event";
- public static final String OPERATION = "application/vnd.yang.operation";
- public static final String PATCH = "application/vnd.yang.patch";
-}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+public class ResponseException extends WebApplicationException {
+
+ private static final long serialVersionUID = -5320114450593021655L;
+
+ public ResponseException(Status status, String msg) {
+ super(Response.status(status).type(MediaType.TEXT_PLAIN_TYPE).entity(msg).build());
+ }
+}
private def InstanceIdWithSchemaNode resolveInstanceIdentifier(String identifier) {
val identifierWithSchemaNode = identifier.toInstanceIdentifier
if (identifierWithSchemaNode === null) {
- throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST).entity("URI has bad format")
- .build());
+ throw new ResponseException(Response.Status.BAD_REQUEST, "URI has bad format");
}
return identifierWithSchemaNode
}
import org.junit.BeforeClass;
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.rest.api.Draft01;
import org.opendaylight.controller.sal.rest.api.RestconfService;
import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
import org.opendaylight.controller.sal.restconf.impl.BrokerFacade;
import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
-import org.opendaylight.controller.sal.restconf.impl.MediaTypes;
import org.opendaylight.controller.sal.restconf.impl.RestconfImpl;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
private static ControllerContext controllerContext;
private static BrokerFacade brokerFacade;
private static RestconfImpl restconfImpl;
- private static final MediaType MEDIA_TYPE = new MediaType("application", "vnd.yang.api+xml");
+ private static final MediaType MEDIA_TYPE = new MediaType("application", "vnd.yang.data+xml");
+ private static final MediaType MEDIA_TYPE_DRAFT02 = new MediaType("application", "yang.data+xml");
@BeforeClass
public static void init() throws FileNotFoundException {
public void testBadFormatXmlToCompositeNodeProvider() throws UnsupportedEncodingException, URISyntaxException {
String uri = createUri("/operations/", "ietf-interfaces:interfaces/interface/eth0");
- Response response = target(uri).request(MediaTypes.API + RestconfService.XML).post(
+ Response response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).post(
Entity.entity("<SimpleNode/>", MEDIA_TYPE));
assertEquals(400, response.getStatus());
- response = target(uri).request(MediaTypes.API + RestconfService.XML).post(
+ response = target(uri).request(Draft01.MediaTypes.DATA + RestconfService.XML).post(
Entity.entity("<SimpleNode>", MEDIA_TYPE));
assertEquals(400, response.getStatus());
}
when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
- Response response = target(uri).request(MediaTypes.API+RestconfService.XML).get();
+ Response response = target(uri).request(Draft01.MediaTypes.DATA+RestconfService.XML).get();
assertEquals(404, response.getStatus());
}
when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
- Response response = target(uri).request(MediaTypes.API+RestconfService.XML).get();
+ Response response = target(uri).request(Draft01.MediaTypes.DATA+RestconfService.XML).get();
assertEquals(400, response.getStatus());
}
public void testRpcResultCommitedToStatusCodes() throws UnsupportedEncodingException {
InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
- Entity<String> entity = Entity.entity(xml, MEDIA_TYPE);
+ Entity<String> entity = Entity.entity(xml, MEDIA_TYPE_DRAFT02);
RpcResult<TransactionStatus> rpcResult = DummyRpcResult.builder().result(TransactionStatus.COMMITED).build();
Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
when(brokerFacade.commitOperationalDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
- Response response = target(uri).request(MEDIA_TYPE).put(entity);
- assertEquals(200, response.getStatus());
- response = target(uri).request(MEDIA_TYPE).post(entity);
+ Response response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
assertEquals(204, response.getStatus());
+ response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
+ assertEquals(200, response.getStatus());
uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0");
- response = target(uri).request(MEDIA_TYPE).put(entity);
- assertEquals(200, response.getStatus());
- response = target(uri).request(MEDIA_TYPE).post(entity);
+ response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
assertEquals(204, response.getStatus());
+ response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
+ assertEquals(200, response.getStatus());
uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
response = target(uri).request(MEDIA_TYPE).put(entity);
- assertEquals(200, response.getStatus());
- response = target(uri).request(MEDIA_TYPE).post(entity);
assertEquals(204, response.getStatus());
+ response = target(uri).request(MEDIA_TYPE).post(entity);
+ assertEquals(200, response.getStatus());
}
@Test
public void testRpcResultOtherToStatusCodes() throws UnsupportedEncodingException {
InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
String xml = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
- Entity<String> entity = Entity.entity(xml, MEDIA_TYPE);
+ Entity<String> entity = Entity.entity(xml, MEDIA_TYPE_DRAFT02);
RpcResult<TransactionStatus> rpcResult = DummyRpcResult.builder().result(TransactionStatus.FAILED).build();
Future<RpcResult<TransactionStatus>> dummyFuture = DummyFuture.builder().rpcResult(rpcResult).build();
when(brokerFacade.commitOperationalDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(dummyFuture);
String uri = createUri("/config/", "ietf-interfaces:interfaces/interface/eth0");
- Response response = target(uri).request(MEDIA_TYPE).put(entity);
+ Response response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
assertEquals(500, response.getStatus());
- response = target(uri).request(MEDIA_TYPE).post(entity);
+ response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
assertEquals(500, response.getStatus());
uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0");
- response = target(uri).request(MEDIA_TYPE).put(entity);
+ response = target(uri).request(MEDIA_TYPE_DRAFT02).put(entity);
assertEquals(500, response.getStatus());
- response = target(uri).request(MEDIA_TYPE).post(entity);
+ response = target(uri).request(MEDIA_TYPE_DRAFT02).post(entity);
assertEquals(500, response.getStatus());
uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");