diff --git a/src/main/java/it/inaf/oats/vospace/ListNodeController.java b/src/main/java/it/inaf/oats/vospace/ListNodeController.java index 2a7ce2cdb2b7ad273676eabe7661d19c506a026f..e35793314cbb9cd049420c2aefccabbc812efe98 100644 --- a/src/main/java/it/inaf/oats/vospace/ListNodeController.java +++ b/src/main/java/it/inaf/oats/vospace/ListNodeController.java @@ -1,5 +1,6 @@ package it.inaf.oats.vospace; +import it.inaf.oats.vospace.exception.NodeNotFoundException; import org.springframework.web.bind.annotation.RestController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -21,6 +22,7 @@ public class ListNodeController extends BaseNodeController { produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_XML_VALUE}) public ResponseEntity<Node> listNode(HttpServletRequest request) { String path = getPath(); - return ResponseEntity.ok(nodeDAO.listNode(path)); + return ResponseEntity.ok(nodeDAO.listNode(path) + .orElseThrow(() -> new NodeNotFoundException(path))); } } diff --git a/src/main/java/it/inaf/oats/vospace/exception/ErrorController.java b/src/main/java/it/inaf/oats/vospace/exception/ErrorController.java new file mode 100644 index 0000000000000000000000000000000000000000..5e4143e9a543b830075e642e2d51f751b573c7a3 --- /dev/null +++ b/src/main/java/it/inaf/oats/vospace/exception/ErrorController.java @@ -0,0 +1,33 @@ +package it.inaf.oats.vospace.exception; + +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController; +import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("${server.error.path:${error.path:/error}}") +public class ErrorController extends AbstractErrorController { + + @Autowired + public ErrorController(ErrorAttributes errorAttributes) { + super(errorAttributes); + } + + @RequestMapping(produces = MediaType.TEXT_XML_VALUE) + public void errorText(HttpServletRequest request, HttpServletResponse response) throws Exception { + Map<String, Object> errors = super.getErrorAttributes(request, true); + response.setContentType("text/plain;charset=UTF-8"); + response.getOutputStream().print((String) errors.get("message")); + } + + @Override + public String getErrorPath() { + return null; + } +} diff --git a/src/main/java/it/inaf/oats/vospace/exception/NodeNotFoundException.java b/src/main/java/it/inaf/oats/vospace/exception/NodeNotFoundException.java new file mode 100644 index 0000000000000000000000000000000000000000..b14f4c2a791b2caea3786f43e3fc75d5a889296e --- /dev/null +++ b/src/main/java/it/inaf/oats/vospace/exception/NodeNotFoundException.java @@ -0,0 +1,12 @@ +package it.inaf.oats.vospace.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(value = HttpStatus.NOT_FOUND) +public class NodeNotFoundException extends VoSpaceException { + + public NodeNotFoundException(String path) { + super("NodeNotFound: " + path); + } +} diff --git a/src/main/java/it/inaf/oats/vospace/exception/VoSpaceException.java b/src/main/java/it/inaf/oats/vospace/exception/VoSpaceException.java new file mode 100644 index 0000000000000000000000000000000000000000..7aa48be8ba38533fd88fcbecf771fdd0738d093e --- /dev/null +++ b/src/main/java/it/inaf/oats/vospace/exception/VoSpaceException.java @@ -0,0 +1,8 @@ +package it.inaf.oats.vospace.exception; + +public class VoSpaceException extends RuntimeException { + + public VoSpaceException(String message) { + super(message); + } +} diff --git a/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java b/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java index 3f9a2b374558612f46e686ce84b7034191d84828..a0eb6521267a124883a70706948a25faf77c8019 100644 --- a/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java +++ b/src/main/java/it/inaf/oats/vospace/persistence/NodeDAO.java @@ -5,6 +5,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; +import java.util.Optional; import javax.sql.DataSource; import net.ivoa.xml.vospace.v2.ContainerNode; import net.ivoa.xml.vospace.v2.DataNode; @@ -43,7 +44,7 @@ public class NodeDAO { return myNode; } - public Node listNode(String path) { + public Optional<Node> listNode(String path) { String sql = "SELECT os.vos_path, n.node_id, type, async_trans, owner_id, group_read, group_write, is_public, content_length, created_on, last_modified from node n\n" + "JOIN node_vos_path os ON n.node_id = os.node_id\n" @@ -59,6 +60,10 @@ public class NodeDAO { return getNodeFromResultSet(row); }); + if(parentAndChildren.isEmpty()) { + return Optional.empty(); + } + // Query returns parent as first node Node node = parentAndChildren.get(0); @@ -70,7 +75,7 @@ public class NodeDAO { } } - return node; + return Optional.of(node); } private String getFirstLevelChildrenSelector(String path) { diff --git a/src/test/java/it/inaf/oats/vospace/ListNodeControllerTest.java b/src/test/java/it/inaf/oats/vospace/ListNodeControllerTest.java index f1aa0ba31a9989a0b7d7be670868d0156420902d..47988ca6b974c7c28c1c72e1ee9180b67c270d62 100644 --- a/src/test/java/it/inaf/oats/vospace/ListNodeControllerTest.java +++ b/src/test/java/it/inaf/oats/vospace/ListNodeControllerTest.java @@ -2,6 +2,7 @@ package it.inaf.oats.vospace; import static it.inaf.oats.vospace.VOSpaceXmlTestUtil.loadDocument; import it.inaf.oats.vospace.persistence.NodeDAO; +import java.util.Optional; import net.ivoa.xml.vospace.v2.ContainerNode; import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.Node; @@ -55,7 +56,7 @@ public class ListNodeControllerTest { @Test public void testNodeXml() throws Exception { - when(dao.listNode(eq("/mynode"))).thenReturn(getDataNode()); + when(dao.listNode(eq("/mynode"))).thenReturn(Optional.of(getDataNode())); String xml = mockMvc.perform(get("/nodes/mynode") .accept(MediaType.APPLICATION_XML)) @@ -70,11 +71,18 @@ public class ListNodeControllerTest { verify(dao, times(1)).listNode(eq("/mynode")); } - private Node getRootNode() { + @Test + public void testNodeNotFound() throws Exception { + mockMvc.perform(get("/nodes/mynode") + .accept(MediaType.APPLICATION_XML)) + .andExpect(status().isNotFound()); + } + + private Optional<Node> getRootNode() { ContainerNode root = new ContainerNode(); root.setUri(URI_PREFIX + "/"); root.getNodes().add(getDataNode()); - return root; + return Optional.of(root); } private Node getDataNode() { diff --git a/src/test/java/it/inaf/oats/vospace/persistence/NodeDAOTest.java b/src/test/java/it/inaf/oats/vospace/persistence/NodeDAOTest.java index d2bb275c5c01f7ead10a3244268fe30019694120..b0757235b8f8dad130246a5ba0f2b10ceb9e6a37 100644 --- a/src/test/java/it/inaf/oats/vospace/persistence/NodeDAOTest.java +++ b/src/test/java/it/inaf/oats/vospace/persistence/NodeDAOTest.java @@ -27,7 +27,7 @@ public class NodeDAOTest { @Test public void testListNode() { - ContainerNode root = (ContainerNode) dao.listNode("/"); + ContainerNode root = (ContainerNode) dao.listNode("/").get(); assertEquals(4, root.getNodes().size()); } }