Response for PUT and POST operations 21/2921/1
authormsunal <msunal@cisco.com>
Wed, 20 Nov 2013 16:49:08 +0000 (17:49 +0100)
committermsunal <msunal@cisco.com>
Wed, 20 Nov 2013 16:51:19 +0000 (17:51 +0100)
- added response as is written in http://tools.ietf.org/html/draft-bierman-netconf-restconf-02#page-37
- tests

Change-Id: Ice0a698f08b7512ea7ee29c1a534bff068e3b6bd
Signed-off-by: Martin Sunal <msunal@cisco.com>
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyFuture.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyRpcResult.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java

index c36a79c5d901093ad3bf79d1a4a354ebcf161209..a22ea623975049cd3bd37c8af3103fecce4317e4 100644 (file)
@@ -15,10 +15,9 @@ 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.Response;
 
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
-import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 /**
@@ -57,7 +56,6 @@ public interface RestconfService extends RestconfServiceLegacy {
     @GET
     public Object getRoot();
 
-
     @GET
     @Path("/modules")
     @Produces({API+JSON,API+XML})
@@ -68,23 +66,20 @@ public interface RestconfService extends RestconfServiceLegacy {
     @Produces({Draft02.MediaTypes.API+JSON,Draft02.MediaTypes.API+XML,API+JSON,API+XML})
     public StructuredData invokeRpc(@PathParam("identifier") String identifier, CompositeNode payload);
     
-    
     @GET
     @Path("/config/{identifier:.+}")
     @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML})
     public StructuredData readConfigurationData(@PathParam("identifier") String identifier);
-
-    
     
     @PUT
     @Path("/config/{identifier:.+}")
     @Produces({API+JSON,API+XML})
-    public RpcResult<TransactionStatus> createConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
+    public Response createConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
 
     @POST
     @Path("/config/{identifier:.+}")
     @Produces({API+JSON,API+XML})
-    public RpcResult<TransactionStatus> updateConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
+    public Response updateConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
 
     @GET
     @Path("/operational/{identifier:.+}")
@@ -94,12 +89,11 @@ public interface RestconfService extends RestconfServiceLegacy {
     @PUT
     @Path("/operational/{identifier:.+}")
     @Produces({API+JSON,API+XML})
-    public RpcResult<TransactionStatus> createOperationalData(@PathParam("identifier") String identifier, CompositeNode payload);
+    public Response createOperationalData(@PathParam("identifier") String identifier, CompositeNode payload);
 
     @POST
     @Path("/operational/{identifier:.+}")
     @Produces({API+JSON,API+XML})
-    public RpcResult<TransactionStatus> updateOperationalData(@PathParam("identifier") String identifier, CompositeNode payload);
+    public Response updateOperationalData(@PathParam("identifier") String identifier, CompositeNode payload);
 
-    
 }
index 6683fd1835942f2af4bd23d42dc16220f3bb6872..242e7f3150d4b775ce56d957ae62ba947a080eba 100644 (file)
@@ -8,10 +8,9 @@ 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.Response;
 
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
-import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 public interface RestconfServiceLegacy {
@@ -35,12 +34,12 @@ public interface RestconfServiceLegacy {
     @PUT
     @Path("/datastore/{identifier:.+}")
     @Produces({API+JSON,API+XML})
-    public RpcResult<TransactionStatus> createConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
+    public Response createConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
 
     @Deprecated
     @POST
     @Path("/datastore/{identifier:.+}")
     @Produces({API+JSON,API+XML})
-    public RpcResult<TransactionStatus> updateConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
+    public Response updateConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
 
 }
index a41a48287df87f887dd37c12b0fd88f4539f7597..d9ac53589fa5415bcba3e59467576fcbb98d069e 100644 (file)
@@ -1,10 +1,12 @@
 package org.opendaylight.controller.sal.restconf.impl
 
 import java.util.List
+import javax.ws.rs.core.Response
 import org.opendaylight.controller.sal.rest.api.RestconfService
 import org.opendaylight.yangtools.yang.data.api.CompositeNode
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus
 
 class RestconfImpl implements RestconfService {
     
@@ -48,13 +50,21 @@ class RestconfImpl implements RestconfService {
     override createConfigurationData(String identifier, CompositeNode payload) {
         val identifierWithSchemaNode = identifier.toInstanceIdentifier
         val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
-        return broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
+        val status = broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
+        switch status.result {
+            case TransactionStatus.COMMITED: Response.status(Response.Status.OK).build
+            default: Response.status(Response.Status.INTERNAL_SERVER_ERROR).build
+        }
     }
 
     override updateConfigurationData(String identifier, CompositeNode payload) {
         val identifierWithSchemaNode = identifier.toInstanceIdentifier
         val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
-        return broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
+        val status = broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
+        switch status.result {
+            case TransactionStatus.COMMITED: Response.status(Response.Status.NO_CONTENT).build
+            default: Response.status(Response.Status.INTERNAL_SERVER_ERROR).build
+        }
     }
 
     override invokeRpc(String identifier, CompositeNode payload) {
@@ -88,13 +98,21 @@ class RestconfImpl implements RestconfService {
     override createOperationalData(String identifier, CompositeNode payload) {
         val identifierWithSchemaNode = identifier.toInstanceIdentifier
         val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
-        return broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
+        val status = broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
+        switch status.result {
+            case TransactionStatus.COMMITED: Response.status(Response.Status.OK).build
+            default: Response.status(Response.Status.INTERNAL_SERVER_ERROR).build
+        }
     }
     
     override updateOperationalData(String identifier, CompositeNode payload) {
         val identifierWithSchemaNode = identifier.toInstanceIdentifier
         val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
-        return broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
+        val status = broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
+        switch status.result {
+            case TransactionStatus.COMMITED: Response.status(Response.Status.NO_CONTENT).build
+            default: Response.status(Response.Status.INTERNAL_SERVER_ERROR).build
+        }
     }
     
     private def CompositeNode resolveNodeNamespaceBySchema(CompositeNode node, DataSchemaNode schema) {
index a32a3479bada1b7a5b63d5c8f39e7c86731dc12f..251b212513c80f617740bb6562f1159f43aa6b24 100644 (file)
@@ -6,30 +6,85 @@ import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
 public class DummyFuture implements Future<RpcResult<TransactionStatus>> {
+    
+    private final boolean cancel;
+    private final boolean isCancelled;
+    private final boolean isDone;
+    private final RpcResult<TransactionStatus> result;
+    
+    public DummyFuture() {
+        cancel = false;
+        isCancelled = false;
+        isDone = false;
+        result = null;
+    }
+    
+    private DummyFuture(Builder builder) {
+        cancel = builder.cancel;
+        isCancelled = builder.isCancelled;
+        isDone = builder.isDone;
+        result = builder.result;
+    }
+    
+    public static Builder builder() {
+        return new DummyFuture.Builder();
+    }
 
     @Override
     public boolean cancel(boolean mayInterruptIfRunning) {
-        return false;
+        return cancel;
     }
 
     @Override
     public boolean isCancelled() {
-        return false;
+        return isCancelled;
     }
 
     @Override
     public boolean isDone() {
-        return false;
+        return isDone;
     }
 
     @Override
     public RpcResult<TransactionStatus> get() throws InterruptedException, ExecutionException {
-        return null;
+        return result;
     }
 
     @Override
     public RpcResult<TransactionStatus> get(long timeout, TimeUnit unit) throws InterruptedException,
             ExecutionException, TimeoutException {
-        return null;
+        return result;
+    }
+    
+    public static class Builder {
+        
+        private boolean cancel;
+        private boolean isCancelled;
+        private boolean isDone;
+        private RpcResult<TransactionStatus> result;
+
+        public Builder cancel(boolean cancel) {
+            this.cancel = cancel;
+            return this;
+        }
+        
+        public Builder isCancelled(boolean isCancelled) {
+            this.isCancelled = isCancelled;
+            return this;
+        }
+        
+        public Builder isDone(boolean isDone) {
+            this.isDone = isDone;
+            return this;
+        }
+        
+        public Builder rpcResult(RpcResult<TransactionStatus> result) {
+            this.result = result;
+            return this;
+        }
+        
+        public Future<RpcResult<TransactionStatus>> build() {
+            return new DummyFuture(this);
+        }
     }
 }
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyRpcResult.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/DummyRpcResult.java
new file mode 100644 (file)
index 0000000..5ab4f99
--- /dev/null
@@ -0,0 +1,72 @@
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+public class DummyRpcResult implements RpcResult<TransactionStatus> {
+    
+    private final boolean isSuccessful;
+    private final TransactionStatus result;
+    private final Collection<RpcError> errors;
+    
+    public DummyRpcResult() {
+        isSuccessful = false;
+        result = null;
+        errors = null;
+    }
+    
+    private DummyRpcResult(Builder builder) {
+        isSuccessful = builder.isSuccessful;
+        result = builder.result;
+        errors = builder.errors;
+    }
+    
+    public static Builder builder() {
+        return new DummyRpcResult.Builder();
+    }
+
+    @Override
+    public boolean isSuccessful() {
+        return isSuccessful;
+    }
+
+    @Override
+    public TransactionStatus getResult() {
+        return result;
+    }
+
+    @Override
+    public Collection<RpcError> getErrors() {
+        return errors;
+    }
+    
+    public static class Builder {
+        private boolean isSuccessful;
+        private TransactionStatus result;
+        private Collection<RpcError> errors;
+        
+        public Builder isSuccessful(boolean isSuccessful) {
+            this.isSuccessful = isSuccessful;
+            return this;
+        }
+        
+        public Builder result(TransactionStatus result) {
+            this.result = result;
+            return this;
+        }
+        
+        public Builder errors(Collection<RpcError> errors) {
+            this.errors = errors;
+            return this;
+        }
+        
+        public RpcResult<TransactionStatus> build() {
+            return new DummyRpcResult(this);
+        }
+        
+    }
+
+}
index 3d06e4a759985f1eb938576b7bac10e9be9b8aae..1d8d7495f9dfabae21bdddb737401032af34724b 100644 (file)
@@ -10,16 +10,22 @@ import java.io.*;
 import java.net.*;
 import java.sql.Date;
 import java.util.*;
+import java.util.concurrent.Future;
 
 import javax.ws.rs.WebApplicationException;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.transform.*;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToJsonProvider;
 import org.opendaylight.controller.sal.restconf.impl.*;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.*;
 import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
 import org.opendaylight.yangtools.yang.model.api.*;
@@ -27,6 +33,9 @@ import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 import org.slf4j.*;
 import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.google.common.base.Preconditions;
 
 final class TestUtils {
 
@@ -90,8 +99,20 @@ final class TestUtils {
         }
         return (CompositeNode) dataTree;
     }
+    
+    public static Document loadDocumentFrom(InputStream inputStream) {
+        try {
+            DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
+            DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
+            return docBuilder.parse(inputStream);
+        } catch (SAXException | IOException | ParserConfigurationException e) {
+            logger.error("Error during loading Document from XML", e);
+            return null;
+        }
+    }
 
     public static String getDocumentInPrintableForm(Document doc) {
+        Preconditions.checkNotNull(doc);
         try {
             ByteArrayOutputStream out = new ByteArrayOutputStream();
             TransformerFactory tf = TransformerFactory.newInstance();
@@ -272,9 +293,10 @@ final class TestUtils {
         ControllerContext controllerContext = mock(ControllerContext.class);
         BrokerFacade broker = mock(BrokerFacade.class);
 
+        RpcResult<TransactionStatus> rpcResult = DummyRpcResult.builder().result(TransactionStatus.COMMITED).build();
+        Future<RpcResult<TransactionStatus>> future = DummyFuture.builder().rpcResult(rpcResult).build();
         when(controllerContext.toInstanceIdentifier(any(String.class))).thenReturn(instIdAndSchema);
-        when(broker.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(
-                new DummyFuture());
+        when(broker.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(future);
 
         restconf.setControllerContext(controllerContext);
         restconf.setBroker(broker);
index baf226712ffbb255550948c3c5f36160d4c30262..7b63c5fd9422e5bb3abd0060be1ba57dc9643389 100644 (file)
@@ -1,22 +1,19 @@
 package org.opendaylight.controller.sal.restconf.impl.test;
 
-import static org.mockito.Mockito.*;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 import java.io.FileNotFoundException;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URLEncoder;
-import java.util.Collection;
 import java.util.List;
 import java.util.Set;
-import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
 
@@ -24,11 +21,7 @@ import javax.ws.rs.client.Entity;
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
 
-import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
 import org.glassfish.jersey.test.TestProperties;
@@ -43,15 +36,11 @@ 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.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
 
 import com.google.common.base.Charsets;
 
@@ -60,15 +49,11 @@ public class XmlProvidersTest extends JerseyTest {
     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");
 
     @BeforeClass
-    public static void init() {
-        Set<Module> allModules = null;
-        try {
-            allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs").getPath());
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
-        }
+    public static void init() throws FileNotFoundException {
+        Set<Module> allModules = TestUtils.loadModules(RestconfImplTest.class.getResource("/full-versions/yangs").getPath());
         SchemaContext schemaContext = TestUtils.loadSchemaContext(allModules);
         controllerContext = ControllerContext.getInstance();
         controllerContext.setSchemas(schemaContext);
@@ -87,96 +72,100 @@ public class XmlProvidersTest extends JerseyTest {
     }
 
     @Test
-    public void testStructuredDataToXmlProvider() throws FileNotFoundException {
-        URI uri = null;
-        try {
-            uri = new URI("/datastore/" + URLEncoder.encode("ietf-interfaces:interfaces/interface/eth0", Charsets.US_ASCII.name()).toString());
-        } catch (UnsupportedEncodingException | URISyntaxException e) {
-            e.printStackTrace();
-        }
+    public void testStructuredDataToXmlProvider() throws FileNotFoundException, UnsupportedEncodingException {
+        String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
         
         InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
         CompositeNode loadedCompositeNode = TestUtils.loadCompositeNode(xmlStream);
         when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(loadedCompositeNode);
         
-        Response response = target(uri.toASCIIString()).request(MediaTypes.API+RestconfService.XML).get();
+        Response response = target(uri).request(MEDIA_TYPE).get();
         assertEquals(200, response.getStatus());
     }
 
     @Test
-    public void testXmlToCompositeNodeProvider() throws ParserConfigurationException, SAXException, IOException {
-        URI uri = null;
-        try {
-            uri = new URI("/config/" + URLEncoder.encode("ietf-interfaces:interfaces/interface/eth0", Charsets.US_ASCII.name()).toString());
-        } catch (UnsupportedEncodingException | URISyntaxException e) {
-            e.printStackTrace();
-        }
-        InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
-        final CompositeNode loadedCompositeNode = TestUtils.loadCompositeNode(xmlStream);
-        when(brokerFacade.commitConfigurationDataPut(any(InstanceIdentifier.class), any(CompositeNode.class))).thenReturn(new Future<RpcResult<TransactionStatus>>() {
-            @Override
-            public boolean cancel(boolean mayInterruptIfRunning) {
-                return false;
-            }
-            @Override
-            public boolean isCancelled() {
-                return false;
-            }
-            @Override
-            public boolean isDone() {
-                return false;
-            }
-            @Override
-            public RpcResult<TransactionStatus> get() throws InterruptedException, ExecutionException {
-                return null;
-            }
-            @Override
-            public RpcResult<TransactionStatus> get(long timeout, TimeUnit unit) throws InterruptedException,
-                    ExecutionException, TimeoutException {
-                return null;
-            }
-        });
+    public void testBadFormatXmlToCompositeNodeProvider() throws UnsupportedEncodingException, URISyntaxException {
+        String uri = createUri("/operations/", "ietf-interfaces:interfaces/interface/eth0");
         
-        DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
-        DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
-        xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
-        Document doc = docBuilder.parse(xmlStream);
+        Response response = target(uri).request(MediaTypes.API + RestconfService.XML).post(
+                Entity.entity("<SimpleNode/>", MEDIA_TYPE));
+        assertEquals(400, response.getStatus());
         
-        Response response = target(uri.toASCIIString()).request(MediaTypes.API+RestconfService.XML).post(Entity.entity(TestUtils.getDocumentInPrintableForm(doc), new MediaType("application","vnd.yang.api+xml")));
-        assertEquals(204, response.getStatus());
+        response = target(uri).request(MediaTypes.API + RestconfService.XML).post(
+                Entity.entity("<SimpleNode>", MEDIA_TYPE));
+        assertEquals(400, response.getStatus());
     }
     
     @Test
-    public void testXmlToCompositeNodeProviderExceptions() {
-        URI uri = null;
-        try {
-            uri = new URI("/operations/" + URLEncoder.encode("ietf-interfaces:interfaces/interface/eth0", Charsets.US_ASCII.name()).toString());
-        } catch (UnsupportedEncodingException | URISyntaxException e) {
-            e.printStackTrace();
-        }
+    public void testXmlToCompositeNode404NotFound() throws UnsupportedEncodingException, URISyntaxException {
+        String uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
         
-        Response response = target(uri.toASCIIString()).request(MediaTypes.API + RestconfService.XML).post(
-                Entity.entity("<SimpleNode/>", new MediaType("application", "vnd.yang.api+xml")));
-        assertEquals(400, response.getStatus());
+        when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
         
-        response = target(uri.toASCIIString()).request(MediaTypes.API + RestconfService.XML).post(
-                Entity.entity("<SimpleNode>", new MediaType("application", "vnd.yang.api+xml")));
-        assertEquals(400, response.getStatus());
+        Response response = target(uri).request(MediaTypes.API+RestconfService.XML).get();
+        assertEquals(404, response.getStatus());
     }
     
     @Test
-    public void testXmlToCompositeNode404NotFound() {
-        URI uri = null;
-        try {
-            uri = new URI("/datastore/" + URLEncoder.encode("ietf-interfaces:interfaces/interface/eth0", Charsets.US_ASCII.name()).toString());
-        } catch (UnsupportedEncodingException | URISyntaxException e) {
-            e.printStackTrace();
-        }
+    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);
+        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);
         
-        when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
+        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);
+        assertEquals(204, response.getStatus());
         
-        Response response = target(uri.toASCIIString()).request(MediaTypes.API+RestconfService.XML).get();
-        assertEquals(404, 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);
+        assertEquals(204, 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());
+    }
+    
+    @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);
+        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);
+        assertEquals(500, response.getStatus());
+        response = target(uri).request(MEDIA_TYPE).post(entity);
+        assertEquals(500, response.getStatus());
+        
+        uri = createUri("/operational/", "ietf-interfaces:interfaces/interface/eth0");
+        response = target(uri).request(MEDIA_TYPE).put(entity);
+        assertEquals(500, response.getStatus());
+        response = target(uri).request(MEDIA_TYPE).post(entity);
+        assertEquals(500, response.getStatus());
+        
+        uri = createUri("/datastore/", "ietf-interfaces:interfaces/interface/eth0");
+        response = target(uri).request(MEDIA_TYPE).put(entity);
+        assertEquals(500, response.getStatus());
+        response = target(uri).request(MEDIA_TYPE).post(entity);
+        assertEquals(500, response.getStatus());
+    }
+    
+    private String createUri(String prefix, String encodedPart) throws UnsupportedEncodingException {
+        return URI.create(prefix + URLEncoder.encode(encodedPart, Charsets.US_ASCII.name()).toString()).toASCIIString();
     }
 
     @Override