You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metamodel.apache.org by ka...@apache.org on 2016/06/14 05:20:48 UTC

[04/11] metamodel git commit: Added DataContextController. Removed half-baked error handling for now.

Added DataContextController. Removed half-baked error handling for now.

Project: http://git-wip-us.apache.org/repos/asf/metamodel/repo
Commit: http://git-wip-us.apache.org/repos/asf/metamodel/commit/972ea4b1
Tree: http://git-wip-us.apache.org/repos/asf/metamodel/tree/972ea4b1
Diff: http://git-wip-us.apache.org/repos/asf/metamodel/diff/972ea4b1

Branch: refs/heads/feature/5.x/swagger-docs
Commit: 972ea4b1549db94ab595956a043e86fa80dfceed
Parents: fabd1b9
Author: Kasper S�rensen <i....@gmail.com>
Authored: Sun Jun 5 23:00:03 2016 -0700
Committer: Kasper S�rensen <i....@gmail.com>
Committed: Sun Jun 5 23:36:42 2016 -0700

----------------------------------------------------------------------
 .../service/app/DataContextDefinition.java      | 24 ++++++
 .../service/app/DataContextRegistry.java        |  2 +
 .../app/InMemoryDataContextRegistry.java        | 17 ++++
 .../controllers/DataContextController.java      | 87 ++++++++++++++++++++
 .../service/controllers/SchemaController.java   | 76 +++++++++++++++++
 .../service/controllers/TableController.java    | 84 +++++++++++++++++++
 .../service/controllers/TenantController.java   | 77 ++++++++---------
 .../service/controllers/model/Link.java         | 59 -------------
 .../model/RestDataContextDefinition.java        | 33 ++++++++
 .../service/controllers/model/RestLink.java     | 60 ++++++++++++++
 .../RootInformationControllerTest.java          |  2 +-
 11 files changed, 417 insertions(+), 104 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/metamodel/blob/972ea4b1/service-webapp/src/main/java/org/apache/metamodel/service/app/DataContextDefinition.java
----------------------------------------------------------------------
diff --git a/service-webapp/src/main/java/org/apache/metamodel/service/app/DataContextDefinition.java b/service-webapp/src/main/java/org/apache/metamodel/service/app/DataContextDefinition.java
new file mode 100644
index 0000000..955ff6c
--- /dev/null
+++ b/service-webapp/src/main/java/org/apache/metamodel/service/app/DataContextDefinition.java
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.metamodel.service.app;
+
+public interface DataContextDefinition {
+
+    // TODO
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/972ea4b1/service-webapp/src/main/java/org/apache/metamodel/service/app/DataContextRegistry.java
----------------------------------------------------------------------
diff --git a/service-webapp/src/main/java/org/apache/metamodel/service/app/DataContextRegistry.java b/service-webapp/src/main/java/org/apache/metamodel/service/app/DataContextRegistry.java
index dd18a04..d2a7526 100644
--- a/service-webapp/src/main/java/org/apache/metamodel/service/app/DataContextRegistry.java
+++ b/service-webapp/src/main/java/org/apache/metamodel/service/app/DataContextRegistry.java
@@ -29,5 +29,7 @@ public interface DataContextRegistry {
 
     public List<String> getDataContextIdentifiers();
 
+    public String registerDataContext(String dataContextIdentifier, DataContextDefinition dataContextDef) throws IllegalArgumentException;
+
     public DataContext openDataContext(String dataContextIdentifier) throws IllegalArgumentException;
 }

http://git-wip-us.apache.org/repos/asf/metamodel/blob/972ea4b1/service-webapp/src/main/java/org/apache/metamodel/service/app/InMemoryDataContextRegistry.java
----------------------------------------------------------------------
diff --git a/service-webapp/src/main/java/org/apache/metamodel/service/app/InMemoryDataContextRegistry.java b/service-webapp/src/main/java/org/apache/metamodel/service/app/InMemoryDataContextRegistry.java
index 89d835d..f9b6aa0 100644
--- a/service-webapp/src/main/java/org/apache/metamodel/service/app/InMemoryDataContextRegistry.java
+++ b/service-webapp/src/main/java/org/apache/metamodel/service/app/InMemoryDataContextRegistry.java
@@ -25,6 +25,7 @@ import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
 import org.apache.metamodel.DataContext;
+import org.apache.metamodel.pojo.PojoDataContext;
 
 public class InMemoryDataContextRegistry implements DataContextRegistry {
 
@@ -35,6 +36,22 @@ public class InMemoryDataContextRegistry implements DataContextRegistry {
     }
 
     @Override
+    public String registerDataContext(final String dataContextIdentifier, final DataContextDefinition dataContextDef)
+            throws IllegalArgumentException {
+        if (dataContextIdentifiers.containsKey(dataContextIdentifier)) {
+            throw new IllegalArgumentException("DataContext already exist: " + dataContextIdentifier);
+        }
+        dataContextIdentifiers.put(dataContextIdentifier, new Supplier<DataContext>() {
+            @Override
+            public DataContext get() {
+                // TODO: Do a proper transformation from definition to instance
+                return new PojoDataContext();
+            }
+        });
+        return dataContextIdentifier;
+    }
+
+    @Override
     public List<String> getDataContextIdentifiers() {
         return dataContextIdentifiers.keySet().stream().collect(Collectors.toList());
     }

http://git-wip-us.apache.org/repos/asf/metamodel/blob/972ea4b1/service-webapp/src/main/java/org/apache/metamodel/service/controllers/DataContextController.java
----------------------------------------------------------------------
diff --git a/service-webapp/src/main/java/org/apache/metamodel/service/controllers/DataContextController.java b/service-webapp/src/main/java/org/apache/metamodel/service/controllers/DataContextController.java
new file mode 100644
index 0000000..441c74b
--- /dev/null
+++ b/service-webapp/src/main/java/org/apache/metamodel/service/controllers/DataContextController.java
@@ -0,0 +1,87 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.metamodel.service.controllers;
+
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.validation.Valid;
+import javax.ws.rs.core.UriBuilder;
+
+import org.apache.metamodel.DataContext;
+import org.apache.metamodel.service.app.TenantContext;
+import org.apache.metamodel.service.app.TenantRegistry;
+import org.apache.metamodel.service.controllers.model.RestLink;
+import org.apache.metamodel.service.controllers.model.RestDataContextDefinition;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(value = "/{tenant}/{dataContext}", produces = MediaType.APPLICATION_JSON_VALUE)
+public class DataContextController {
+
+    private final TenantRegistry tenantRegistry;
+
+    @Autowired
+    public DataContextController(TenantRegistry tenantRegistry) {
+        this.tenantRegistry = tenantRegistry;
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    @ResponseBody
+    public Map<String, Object> put(@PathVariable("tenant") String tenantId,
+            @PathVariable("dataContext") String dataContextId,
+            @Valid @RequestBody RestDataContextDefinition dataContextDefinition) {
+        final String dataContextIdentifier = tenantRegistry.getTenantContext(tenantId).getDataContextRegistry()
+                .registerDataContext(dataContextId, dataContextDefinition);
+
+        return get(tenantId, dataContextIdentifier);
+    }
+
+    @RequestMapping(method = RequestMethod.GET)
+    @ResponseBody
+    public Map<String, Object> get(@PathVariable("tenant") String tenantId,
+            @PathVariable("dataContext") String dataContextId) {
+        final TenantContext tenantContext = tenantRegistry.getTenantContext(tenantId);
+        final DataContext dataContext = tenantContext.getDataContextRegistry().openDataContext(dataContextId);
+
+        final String tenantIdentifier = tenantContext.getTenantIdentifier();
+        final UriBuilder uriBuilder = UriBuilder.fromPath("/{tenant}/{dataContext}/schemas/{schema}");
+
+        final List<RestLink> schemaLinks = Arrays.stream(dataContext.getSchemaNames()).map(s -> new RestLink(s, uriBuilder
+                .build(tenantIdentifier, dataContextId, s))).collect(Collectors.toList());
+
+        final Map<String, Object> map = new LinkedHashMap<>();
+        map.put("type", "data-context");
+        map.put("name", dataContextId);
+        map.put("tenant", tenantIdentifier);
+        map.put("query", UriBuilder.fromPath("/{tenant}/{dataContext}/query").build(tenantIdentifier, dataContextId));
+        map.put("schemas", schemaLinks);
+        return map;
+    }
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/972ea4b1/service-webapp/src/main/java/org/apache/metamodel/service/controllers/SchemaController.java
----------------------------------------------------------------------
diff --git a/service-webapp/src/main/java/org/apache/metamodel/service/controllers/SchemaController.java b/service-webapp/src/main/java/org/apache/metamodel/service/controllers/SchemaController.java
new file mode 100644
index 0000000..9c18c3b
--- /dev/null
+++ b/service-webapp/src/main/java/org/apache/metamodel/service/controllers/SchemaController.java
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.metamodel.service.controllers;
+
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.ws.rs.core.UriBuilder;
+
+import org.apache.metamodel.DataContext;
+import org.apache.metamodel.schema.Schema;
+import org.apache.metamodel.service.app.TenantContext;
+import org.apache.metamodel.service.app.TenantRegistry;
+import org.apache.metamodel.service.controllers.model.RestLink;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(value = "/{tenant}/{dataContext}/schemas/{schema}", produces = MediaType.APPLICATION_JSON_VALUE)
+public class SchemaController {
+
+    private final TenantRegistry tenantRegistry;
+
+    @Autowired
+    public SchemaController(TenantRegistry tenantRegistry) {
+        this.tenantRegistry = tenantRegistry;
+    }
+
+    @RequestMapping(method = RequestMethod.GET)
+    @ResponseBody
+    public Map<String, Object> get(@PathVariable("tenant") String tenantId,
+            @PathVariable("dataContext") String dataContextId, @PathVariable("schema") String schemaId) {
+        final TenantContext tenantContext = tenantRegistry.getTenantContext(tenantId);
+        final DataContext dataContext = tenantContext.getDataContextRegistry().openDataContext(dataContextId);
+
+        final Schema schema = dataContext.getSchemaByName(schemaId);
+        final String tenantIdentifier = tenantContext.getTenantIdentifier();
+        final UriBuilder uriBuilder = UriBuilder.fromPath("/{tenant}/{dataContext}/schemas/{schema}/tables/{table}");
+
+        final String schemaName = schema.getName();
+        final List<RestLink> tableLinks = Arrays.stream(schema.getTableNames()).map(t -> new RestLink(String.valueOf(t),
+                uriBuilder.build(tenantIdentifier, dataContextId, schemaName, t))).collect(Collectors.toList());
+
+        final Map<String, Object> map = new LinkedHashMap<>();
+        map.put("type", "schema");
+        map.put("name", schemaName);
+        map.put("data-context", dataContextId);
+        map.put("tenant", tenantIdentifier);
+        map.put("tables", tableLinks);
+        return map;
+    }
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/972ea4b1/service-webapp/src/main/java/org/apache/metamodel/service/controllers/TableController.java
----------------------------------------------------------------------
diff --git a/service-webapp/src/main/java/org/apache/metamodel/service/controllers/TableController.java b/service-webapp/src/main/java/org/apache/metamodel/service/controllers/TableController.java
new file mode 100644
index 0000000..373c1db
--- /dev/null
+++ b/service-webapp/src/main/java/org/apache/metamodel/service/controllers/TableController.java
@@ -0,0 +1,84 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.metamodel.service.controllers;
+
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.ws.rs.core.UriBuilder;
+
+import org.apache.metamodel.DataContext;
+import org.apache.metamodel.schema.Schema;
+import org.apache.metamodel.schema.Table;
+import org.apache.metamodel.service.app.TenantContext;
+import org.apache.metamodel.service.app.TenantRegistry;
+import org.apache.metamodel.service.controllers.model.RestLink;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping(value = "/{tenant}/{dataContext}/schemas/{schema}/tables/{table}", produces = MediaType.APPLICATION_JSON_VALUE)
+public class TableController {
+
+    private final TenantRegistry tenantRegistry;
+
+    @Autowired
+    public TableController(TenantRegistry tenantRegistry) {
+        this.tenantRegistry = tenantRegistry;
+    }
+
+    @RequestMapping(method = RequestMethod.GET)
+    @ResponseBody
+    public Map<String, Object> get(@PathVariable("tenant") String tenantId,
+            @PathVariable("dataContext") String dataContextId, @PathVariable("schema") String schemaId,
+            @PathVariable("table") String tableId) {
+        final TenantContext tenantContext = tenantRegistry.getTenantContext(tenantId);
+        final DataContext dataContext = tenantContext.getDataContextRegistry().openDataContext(dataContextId);
+
+        final Schema schema = dataContext.getSchemaByName(schemaId);
+        final Table table = schema.getTableByName(tableId);
+
+        final String tenantIdentifier = tenantContext.getTenantIdentifier();
+        final UriBuilder uriBuilder = UriBuilder.fromPath(
+                "/{tenant}/{dataContext}/schemas/{schema}/tables/{table}/columns/{column}");
+
+        final String tableName = table.getName();
+        final String schemaName = schema.getName();
+        final List<RestLink> columnsLinks = Arrays.stream(table.getColumnNames()).map(c -> new RestLink(String.valueOf(c),
+                uriBuilder.build(tenantIdentifier, dataContextId, schemaName, tableName, c))).collect(Collectors
+                        .toList());
+
+        final Map<String, Object> map = new LinkedHashMap<>();
+        map.put("type", "table");
+        map.put("name", tableName);
+        map.put("schema", schemaName);
+        map.put("data-context", dataContextId);
+        map.put("tenant", tenantIdentifier);
+        map.put("columns", columnsLinks);
+        return map;
+    }
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/972ea4b1/service-webapp/src/main/java/org/apache/metamodel/service/controllers/TenantController.java
----------------------------------------------------------------------
diff --git a/service-webapp/src/main/java/org/apache/metamodel/service/controllers/TenantController.java b/service-webapp/src/main/java/org/apache/metamodel/service/controllers/TenantController.java
index afefb9e..48a0ed1 100644
--- a/service-webapp/src/main/java/org/apache/metamodel/service/controllers/TenantController.java
+++ b/service-webapp/src/main/java/org/apache/metamodel/service/controllers/TenantController.java
@@ -18,50 +18,67 @@
  */
 package org.apache.metamodel.service.controllers;
 
-import java.io.IOException;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
-import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.core.UriBuilder;
 
 import org.apache.metamodel.service.app.TenantContext;
 import org.apache.metamodel.service.app.TenantRegistry;
-import org.apache.metamodel.service.controllers.model.Link;
+import org.apache.metamodel.service.controllers.model.RestLink;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.client.HttpServerErrorException;
 
 @RestController
 @RequestMapping(value = "/{tenant}", produces = MediaType.APPLICATION_JSON_VALUE)
 public class TenantController {
 
+    private final TenantRegistry tenantRegistry;
+
     @Autowired
-    TenantRegistry tenantRegistry;
+    public TenantController(TenantRegistry tenantRegistry) {
+        this.tenantRegistry = tenantRegistry;
+    }
+
+    @RequestMapping(method = RequestMethod.GET)
+    @ResponseBody
+    public Map<String, Object> getTenant(@PathVariable("tenant") String tenantName) {
+        final TenantContext tenantContext = tenantRegistry.getTenantContext(tenantName);
+        if (tenantContext == null) {
+            throw new IllegalArgumentException("No such tenant: " + tenantName);
+        }
+
+        final String tenantIdentifier = tenantContext.getTenantIdentifier();
+
+        final UriBuilder uriBuilder = UriBuilder.fromPath("/{tenant}/{dataContext}");
+
+        final List<String> dataContextIdentifiers = tenantContext.getDataContextRegistry().getDataContextIdentifiers();
+        final List<RestLink> dataContextLinks = dataContextIdentifiers.stream().map(s -> new RestLink(s, uriBuilder.build(
+                tenantIdentifier, s))).collect(Collectors.toList());
+
+        final Map<String, Object> map = new LinkedHashMap<>();
+        map.put("type", "tenant");
+        map.put("name", tenantIdentifier);
+        map.put("data-contexts", dataContextLinks);
+        return map;
+    }
 
     @RequestMapping(method = RequestMethod.PUT)
     @ResponseBody
     public Map<String, Object> putTenant(@PathVariable("tenant") String tenantName) {
-        final TenantContext tenantContext;
-        try {
-            tenantContext = tenantRegistry.createTenantContext(tenantName);
-        } catch (IllegalArgumentException e) {
-            throw new HttpServerErrorException(HttpStatus.CONFLICT, e.getMessage());
-        }
+        final TenantContext tenantContext = tenantRegistry.createTenantContext(tenantName);
         final String tenantIdentifier = tenantContext.getTenantIdentifier();
 
         final Map<String, Object> map = new LinkedHashMap<>();
         map.put("type", "tenant");
-        map.put("id", tenantIdentifier);
+        map.put("name", tenantIdentifier);
 
         return map;
     }
@@ -72,42 +89,14 @@ public class TenantController {
         final boolean deleted = tenantRegistry.deleteTenantContext(tenantName);
 
         if (!deleted) {
-            throw new HttpServerErrorException(HttpStatus.NOT_FOUND, "No such tenant: " + tenantName);
+            throw new IllegalArgumentException("No such tenant: " + tenantName);
         }
 
         final Map<String, Object> map = new LinkedHashMap<>();
         map.put("type", "tenant");
-        map.put("id", tenantName);
+        map.put("name", tenantName);
         map.put("deleted", deleted);
 
         return map;
     }
-
-    @RequestMapping(method = RequestMethod.GET)
-    @ResponseBody
-    public Map<String, Object> getTenant(@PathVariable("tenant") String tenantName) {
-        final TenantContext tenantContext = tenantRegistry.getTenantContext(tenantName);
-        if (tenantContext == null) {
-            throw new HttpServerErrorException(HttpStatus.NOT_FOUND, "No such tenant: " + tenantName);
-        }
-
-        final String tenantIdentifier = tenantContext.getTenantIdentifier();
-
-        final UriBuilder uriBuilder = UriBuilder.fromPath("/{tenant}/{dataContext}");
-
-        final List<String> dataContextIdentifiers = tenantContext.getDataContextRegistry().getDataContextIdentifiers();
-        final List<Link> dataContextLinks = dataContextIdentifiers.stream().map(s -> new Link(s, uriBuilder.build(
-                tenantIdentifier, s))).collect(Collectors.toList());
-
-        final Map<String, Object> map = new LinkedHashMap<>();
-        map.put("type", "tenant");
-        map.put("id", tenantIdentifier);
-        map.put("data-contexts", dataContextLinks);
-        return map;
-    }
-
-    @ExceptionHandler(HttpServerErrorException.class)
-    public void handleException(HttpServerErrorException e, HttpServletResponse resp) throws IOException {
-        resp.sendError(e.getStatusCode().value(), e.getStatusText());
-    }
 }

http://git-wip-us.apache.org/repos/asf/metamodel/blob/972ea4b1/service-webapp/src/main/java/org/apache/metamodel/service/controllers/model/Link.java
----------------------------------------------------------------------
diff --git a/service-webapp/src/main/java/org/apache/metamodel/service/controllers/model/Link.java b/service-webapp/src/main/java/org/apache/metamodel/service/controllers/model/Link.java
deleted file mode 100644
index 4871553..0000000
--- a/service-webapp/src/main/java/org/apache/metamodel/service/controllers/model/Link.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.metamodel.service.controllers.model;
-
-import java.io.Serializable;
-import java.net.URI;
-
-/**
- * Represents a hyper-link to a service (typically provided in the REST
- * responses)
- */
-public class Link implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    private String name;
-    private URI uri;
-
-    public Link() {
-    }
-
-    public Link(String name, URI uri) {
-        this();
-        this.name = name;
-        this.uri = uri;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public URI getUri() {
-        return uri;
-    }
-
-    public void setUri(URI uri) {
-        this.uri = uri;
-    }
-}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/972ea4b1/service-webapp/src/main/java/org/apache/metamodel/service/controllers/model/RestDataContextDefinition.java
----------------------------------------------------------------------
diff --git a/service-webapp/src/main/java/org/apache/metamodel/service/controllers/model/RestDataContextDefinition.java b/service-webapp/src/main/java/org/apache/metamodel/service/controllers/model/RestDataContextDefinition.java
new file mode 100644
index 0000000..ba2002e
--- /dev/null
+++ b/service-webapp/src/main/java/org/apache/metamodel/service/controllers/model/RestDataContextDefinition.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.metamodel.service.controllers.model;
+
+import javax.validation.constraints.NotNull;
+
+import org.apache.metamodel.service.app.DataContextDefinition;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class RestDataContextDefinition implements DataContextDefinition {
+
+    @JsonProperty(value = "type", required = true)
+    @NotNull
+    public String type;
+
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/972ea4b1/service-webapp/src/main/java/org/apache/metamodel/service/controllers/model/RestLink.java
----------------------------------------------------------------------
diff --git a/service-webapp/src/main/java/org/apache/metamodel/service/controllers/model/RestLink.java b/service-webapp/src/main/java/org/apache/metamodel/service/controllers/model/RestLink.java
new file mode 100644
index 0000000..2830389
--- /dev/null
+++ b/service-webapp/src/main/java/org/apache/metamodel/service/controllers/model/RestLink.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.metamodel.service.controllers.model;
+
+import java.io.Serializable;
+import java.net.URI;
+
+/**
+ * Represents a hyper-link to a service (typically provided in the REST
+ * responses)
+ */
+public class RestLink implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String name;
+
+    private URI uri;
+
+    public RestLink() {
+    }
+
+    public RestLink(String name, URI uri) {
+        this();
+        this.name = name;
+        this.uri = uri;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public URI getUri() {
+        return uri;
+    }
+
+    public void setUri(URI uri) {
+        this.uri = uri;
+    }
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/972ea4b1/service-webapp/src/test/java/org/apache/metamodel/service/controllers/RootInformationControllerTest.java
----------------------------------------------------------------------
diff --git a/service-webapp/src/test/java/org/apache/metamodel/service/controllers/RootInformationControllerTest.java b/service-webapp/src/test/java/org/apache/metamodel/service/controllers/RootInformationControllerTest.java
index 58a5ca5..8e3dab3 100644
--- a/service-webapp/src/test/java/org/apache/metamodel/service/controllers/RootInformationControllerTest.java
+++ b/service-webapp/src/test/java/org/apache/metamodel/service/controllers/RootInformationControllerTest.java
@@ -47,7 +47,7 @@ public class RootInformationControllerTest {
     }
 
     @Test
-    public void testGenericMessageSuccess() throws Exception {
+    public void testGet() throws Exception {
         final MockHttpServletRequestBuilder request = MockMvcRequestBuilders.get("/").contentType(
                 MediaType.APPLICATION_JSON);