Repository: metamodel-membrane Updated Branches: refs/heads/master d5419cb34 -> d9bde2a90
METAMODEL-1147: Created controller models with swagger-codegen Project: http://git-wip-us.apache.org/repos/asf/metamodel-membrane/repo Commit: http://git-wip-us.apache.org/repos/asf/metamodel-membrane/commit/609cc85b Tree: http://git-wip-us.apache.org/repos/asf/metamodel-membrane/tree/609cc85b Diff: http://git-wip-us.apache.org/repos/asf/metamodel-membrane/diff/609cc85b Branch: refs/heads/master Commit: 609cc85b1ebb01104f0e5af38b33d44737b97ba1 Parents: d5419cb Author: Kasper Sørensen <i.am.kasper.soren...@gmail.com> Authored: Mon Jul 31 21:47:36 2017 -0700 Committer: Kasper Sørensen <i.am.kasper.soren...@gmail.com> Committed: Mon Jul 31 21:58:29 2017 -0700 ---------------------------------------------------------------------- .gitignore | 1 + CHANGES.md | 1 + core/pom.xml | 5 + .../membrane/controllers/ColumnController.java | 44 +- .../controllers/DataSourceController.java | 33 +- .../membrane/controllers/QueryController.java | 33 +- .../controllers/RootInformationController.java | 40 +- .../membrane/controllers/SchemaController.java | 27 +- .../membrane/controllers/TableController.java | 32 +- .../controllers/TableDataController.java | 25 +- .../membrane/controllers/TenantController.java | 51 ++- .../membrane/controllers/model/RestLink.java | 59 --- core/src/main/resources/swagger.yaml | 455 +++++++++++-------- .../TenantInteractionScenarioTest.java | 14 +- pom.xml | 1 + swagger-codegen/pom.xml | 122 +++++ 16 files changed, 543 insertions(+), 400 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/.gitignore ---------------------------------------------------------------------- diff --git a/.gitignore b/.gitignore index eb25b83..e1befa5 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ target/ *.ipr *.iws .vscode/ +.DS_Store http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/CHANGES.md ---------------------------------------------------------------------- diff --git a/CHANGES.md b/CHANGES.md index 9610fa8..6a0a894 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,4 @@ ### Apache MetaModel Membrane 0.1 [work in progress] +* [METAMODEL-1147] - Implemented Swagger codegen to build model classes from swagger file. * Established project source control, structure and build. http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/core/pom.xml ---------------------------------------------------------------------- diff --git a/core/pom.xml b/core/pom.xml index 7042a08..c46c699 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -30,6 +30,11 @@ under the License. <dependencies> <dependency> + <groupId>org.apache.metamodel.membrane</groupId> + <artifactId>Membrane-swagger-model</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> <groupId>org.apache.metamodel</groupId> <artifactId>MetaModel-spring</artifactId> </dependency> http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/core/src/main/java/org/apache/metamodel/membrane/controllers/ColumnController.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/controllers/ColumnController.java b/core/src/main/java/org/apache/metamodel/membrane/controllers/ColumnController.java index 6e99371..5e51a39 100644 --- a/core/src/main/java/org/apache/metamodel/membrane/controllers/ColumnController.java +++ b/core/src/main/java/org/apache/metamodel/membrane/controllers/ColumnController.java @@ -18,13 +18,12 @@ */ package org.apache.metamodel.membrane.controllers; -import java.util.LinkedHashMap; -import java.util.Map; - import org.apache.metamodel.DataContext; import org.apache.metamodel.membrane.app.DataContextTraverser; import org.apache.metamodel.membrane.app.TenantContext; import org.apache.metamodel.membrane.app.TenantRegistry; +import org.apache.metamodel.membrane.swagger.model.GetColumnResponse; +import org.apache.metamodel.membrane.swagger.model.GetColumnResponseMetadata; import org.apache.metamodel.schema.Column; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; @@ -48,7 +47,7 @@ public class ColumnController { @RequestMapping(method = RequestMethod.GET) @ResponseBody - public Map<String, Object> get(@PathVariable("tenant") String tenantId, + public GetColumnResponse get(@PathVariable("tenant") String tenantId, @PathVariable("dataContext") String dataSourceName, @PathVariable("schema") String schemaId, @PathVariable("table") String tableId, @PathVariable("column") String columnId) { final TenantContext tenantContext = tenantRegistry.getTenantContext(tenantId); @@ -62,25 +61,24 @@ public class ColumnController { final String tableName = column.getTable().getName(); final String schemaName = column.getTable().getSchema().getName(); - final Map<String, Object> metadata = new LinkedHashMap<>(); - metadata.put("number", column.getColumnNumber()); - metadata.put("size", column.getColumnSize()); - metadata.put("nullable", column.isNullable()); - metadata.put("primary-key", column.isPrimaryKey()); - metadata.put("indexed", column.isIndexed()); - metadata.put("column-type", column.getType() == null ? null : column.getType().getName()); - metadata.put("native-type", column.getNativeType()); - metadata.put("remarks", column.getRemarks()); - - final Map<String, Object> map = new LinkedHashMap<>(); - map.put("type", "column"); - map.put("name", column.getName()); - map.put("table", tableName); - map.put("schema", schemaName); - map.put("datasource", dataSourceName); - map.put("tenant", tenantName); - map.put("metadata", metadata); + final GetColumnResponseMetadata metadata = new GetColumnResponseMetadata(); + metadata.number(column.getColumnNumber()); + metadata.size(column.getColumnSize()); + metadata.nullable(column.isNullable()); + metadata.primaryKey(column.isPrimaryKey()); + metadata.indexed(column.isIndexed()); + metadata.columnType(column.getType() == null ? null : column.getType().getName()); + metadata.nativeType(column.getNativeType()); + metadata.remarks(column.getRemarks()); - return map; + final GetColumnResponse response = new GetColumnResponse(); + response.type("column"); + response.name(column.getName()); + response.table(tableName); + response.schema(schemaName); + response.datasource(dataSourceName); + response.tenant(tenantName); + response.metadata(metadata); + return response ; } } http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/core/src/main/java/org/apache/metamodel/membrane/controllers/DataSourceController.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/controllers/DataSourceController.java b/core/src/main/java/org/apache/metamodel/membrane/controllers/DataSourceController.java index c9df027..309893e 100644 --- a/core/src/main/java/org/apache/metamodel/membrane/controllers/DataSourceController.java +++ b/core/src/main/java/org/apache/metamodel/membrane/controllers/DataSourceController.java @@ -20,7 +20,6 @@ package org.apache.metamodel.membrane.controllers; import java.util.Arrays; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -35,7 +34,8 @@ import org.apache.metamodel.factory.DataContextPropertiesImpl; import org.apache.metamodel.membrane.app.TenantContext; import org.apache.metamodel.membrane.app.TenantRegistry; import org.apache.metamodel.membrane.controllers.model.RestDataSourceDefinition; -import org.apache.metamodel.membrane.controllers.model.RestLink; +import org.apache.metamodel.membrane.swagger.model.GetDatasourceResponse; +import org.apache.metamodel.membrane.swagger.model.GetDatasourceResponseSchemas; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PathVariable; @@ -58,7 +58,7 @@ public class DataSourceController { @RequestMapping(method = RequestMethod.PUT) @ResponseBody - public Map<String, Object> put(@PathVariable("tenant") String tenantId, + public GetDatasourceResponse put(@PathVariable("tenant") String tenantId, @PathVariable("datasource") String dataSourceId, @Valid @RequestBody RestDataSourceDefinition dataContextDefinition) { @@ -81,7 +81,7 @@ public class DataSourceController { @RequestMapping(method = RequestMethod.GET) @ResponseBody - public Map<String, Object> get(@PathVariable("tenant") String tenantId, + public GetDatasourceResponse get(@PathVariable("tenant") String tenantId, @PathVariable("datasource") String dataSourceName) { final TenantContext tenantContext = tenantRegistry.getTenantContext(tenantId); final DataContext dataContext = tenantContext.getDataSourceRegistry().openDataContext(dataSourceName); @@ -89,16 +89,19 @@ public class DataSourceController { final String tenantName = tenantContext.getTenantName(); final UriBuilder uriBuilder = UriBuilder.fromPath("/{tenant}/{dataContext}/s/{schema}"); - final List<RestLink> schemaLinks = Arrays.stream(dataContext.getSchemaNames()).map(s -> new RestLink(s, - uriBuilder.build(tenantName, dataSourceName, s))).collect(Collectors.toList()); - - final Map<String, Object> map = new LinkedHashMap<>(); - map.put("type", "datasource"); - map.put("name", dataSourceName); - map.put("tenant", tenantName); - map.put("updateable", dataContext instanceof UpdateableDataContext); - map.put("query_uri", UriBuilder.fromPath("/{tenant}/{dataContext}/query").build(tenantName, dataSourceName)); - map.put("schemas", schemaLinks); - return map; + final List<GetDatasourceResponseSchemas> schemaLinks = Arrays.stream(dataContext.getSchemaNames()).map(s -> { + final String uri = uriBuilder.build(tenantName, dataSourceName, s).toString(); + return new GetDatasourceResponseSchemas().name(s).uri(uri); + }).collect(Collectors.toList()); + + final GetDatasourceResponse resp = new GetDatasourceResponse(); + resp.type("datasource"); + resp.name(dataSourceName); + resp.tenant(tenantName); + resp.updateable(dataContext instanceof UpdateableDataContext); + resp.queryUri(UriBuilder.fromPath("/{tenant}/{dataContext}/query").build(tenantName, dataSourceName) + .toString()); + resp.schemas(schemaLinks); + return resp; } } http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/core/src/main/java/org/apache/metamodel/membrane/controllers/QueryController.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/controllers/QueryController.java b/core/src/main/java/org/apache/metamodel/membrane/controllers/QueryController.java index 1cd6ed6..7cf90b5 100644 --- a/core/src/main/java/org/apache/metamodel/membrane/controllers/QueryController.java +++ b/core/src/main/java/org/apache/metamodel/membrane/controllers/QueryController.java @@ -18,15 +18,16 @@ */ package org.apache.metamodel.membrane.controllers; +import java.util.ArrayList; import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.Map; +import java.util.List; import java.util.stream.Collectors; import org.apache.metamodel.DataContext; import org.apache.metamodel.data.DataSet; import org.apache.metamodel.membrane.app.TenantContext; import org.apache.metamodel.membrane.app.TenantRegistry; +import org.apache.metamodel.membrane.swagger.model.QueryResponse; import org.apache.metamodel.query.Query; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; @@ -51,7 +52,7 @@ public class QueryController { @RequestMapping(method = RequestMethod.GET) @ResponseBody - public Map<String, Object> get(@PathVariable("tenant") String tenantId, + public QueryResponse get(@PathVariable("tenant") String tenantId, @PathVariable("dataContext") String dataSourceName, @RequestParam(value = "sql", required = true) String queryString, @RequestParam(value = "offset", required = false) Integer offset, @@ -60,11 +61,11 @@ public class QueryController { final DataContext dataContext = tenantContext.getDataSourceRegistry().openDataContext(dataSourceName); final Query query = dataContext.parseQuery(queryString); - + return executeQuery(dataContext, query, offset, limit); } - public static Map<String, Object> executeQuery(DataContext dataContext, Query query, Integer offset, Integer limit) { + public static QueryResponse executeQuery(DataContext dataContext, Query query, Integer offset, Integer limit) { if (offset != null) { query.setFirstRow(offset); @@ -73,13 +74,21 @@ public class QueryController { query.setMaxRows(limit); } - final DataSet dataSet = dataContext.executeQuery(query); + final List<String> headers; + final List<List<Object>> data = new ArrayList<>(); + + try (final DataSet dataSet = dataContext.executeQuery(query)) { + headers = Arrays.stream(dataSet.getSelectItems()).map((si) -> si.toString()).collect(Collectors.toList()); + while (dataSet.next()) { + final Object[] values = dataSet.getRow().getValues(); + data.add(Arrays.asList(values)); + } + } - final Map<String, Object> map = new LinkedHashMap<>(); - map.put("type", "dataset"); - map.put("header", Arrays.stream(dataSet.getSelectItems()).map((si) -> si.toString()).collect(Collectors - .toList())); - map.put("data", dataSet.toObjectArrays()); - return map; + final QueryResponse resp = new QueryResponse(); + resp.type("dataset"); + resp.headers(headers); + resp.data(data); + return resp; } } http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/core/src/main/java/org/apache/metamodel/membrane/controllers/RootInformationController.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/controllers/RootInformationController.java b/core/src/main/java/org/apache/metamodel/membrane/controllers/RootInformationController.java index 0a624aa..49fad5d 100644 --- a/core/src/main/java/org/apache/metamodel/membrane/controllers/RootInformationController.java +++ b/core/src/main/java/org/apache/metamodel/membrane/controllers/RootInformationController.java @@ -23,12 +23,13 @@ import java.net.InetAddress; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; -import java.util.LinkedHashMap; -import java.util.Map; import java.util.Properties; import javax.servlet.ServletContext; +import org.apache.metamodel.membrane.swagger.model.HelloResponse; +import org.apache.metamodel.membrane.swagger.model.HelloResponseOpenapi; +import org.apache.metamodel.membrane.swagger.model.HelloResponseServertime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -48,35 +49,34 @@ public class RootInformationController { @RequestMapping(method = RequestMethod.GET, value = "/", produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody - public Map<String, Object> index() { - final Map<String, Object> map = new LinkedHashMap<>(); - map.put("ping", "pong!"); - map.put("application", "Apache MetaModel Membrane"); - map.put("version", getVersion()); - map.put("server-time", getServerTime()); + public HelloResponse index() { + final HelloResponse resp = new HelloResponse(); + resp.ping("pong!"); + resp.application("Apache MetaModel Membrane"); + resp.version(getVersion()); + resp.serverTime(getServerTime()); try { - map.put("canonical-hostname", InetAddress.getLocalHost().getCanonicalHostName()); + resp.canonicalHostname(InetAddress.getLocalHost().getCanonicalHostName()); } catch (Exception e) { logger.info("Failed to get canonical-hostname", e); } - map.put("open-api", getOpenApi()); - return map; + resp.openApi(getOpenApi()); + return resp; } - private Map<String, Object> getOpenApi() { - final Map<String, Object> map = new LinkedHashMap<>(); - map.put("spec", servletContext.getContextPath() + "/swagger.json"); - return map; + private HelloResponseOpenapi getOpenApi() { + final String swaggerUri = servletContext.getContextPath() + "/swagger.json"; + return new HelloResponseOpenapi().spec(swaggerUri); } - private Map<String, Object> getServerTime() { + private HelloResponseServertime getServerTime() { final ZonedDateTime now = ZonedDateTime.now(); final String dateFormatted = now.format(DateTimeFormatter.ISO_INSTANT); - final Map<String, Object> map = new LinkedHashMap<>(); - map.put("timestamp", new Date().getTime()); - map.put("iso8601", dateFormatted); - return map; + final HelloResponseServertime serverTime = new HelloResponseServertime(); + serverTime.timestamp(new Date().getTime()); + serverTime.iso8601(dateFormatted); + return serverTime; } /** http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/core/src/main/java/org/apache/metamodel/membrane/controllers/SchemaController.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/controllers/SchemaController.java b/core/src/main/java/org/apache/metamodel/membrane/controllers/SchemaController.java index 0332138..0fdf49b 100644 --- a/core/src/main/java/org/apache/metamodel/membrane/controllers/SchemaController.java +++ b/core/src/main/java/org/apache/metamodel/membrane/controllers/SchemaController.java @@ -19,9 +19,7 @@ package org.apache.metamodel.membrane.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; @@ -30,7 +28,8 @@ import org.apache.metamodel.DataContext; import org.apache.metamodel.membrane.app.DataContextTraverser; import org.apache.metamodel.membrane.app.TenantContext; import org.apache.metamodel.membrane.app.TenantRegistry; -import org.apache.metamodel.membrane.controllers.model.RestLink; +import org.apache.metamodel.membrane.swagger.model.GetSchemaResponse; +import org.apache.metamodel.membrane.swagger.model.GetSchemaResponseTables; import org.apache.metamodel.schema.Schema; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; @@ -54,7 +53,7 @@ public class SchemaController { @RequestMapping(method = RequestMethod.GET) @ResponseBody - public Map<String, Object> get(@PathVariable("tenant") String tenantId, + public GetSchemaResponse get(@PathVariable("tenant") String tenantId, @PathVariable("dataContext") String dataSourceName, @PathVariable("schema") String schemaId) { final TenantContext tenantContext = tenantRegistry.getTenantContext(tenantId); final DataContext dataContext = tenantContext.getDataSourceRegistry().openDataContext(dataSourceName); @@ -66,15 +65,17 @@ public class SchemaController { final UriBuilder uriBuilder = UriBuilder.fromPath("/{tenant}/{dataContext}/s/{schema}/t/{table}"); final String schemaName = schema.getName(); - final List<RestLink> tableLinks = Arrays.stream(schema.getTableNames()).map(t -> new RestLink(String.valueOf(t), - uriBuilder.build(tenantName, dataSourceName, schemaName, t))).collect(Collectors.toList()); + final List<GetSchemaResponseTables> tableLinks = Arrays.stream(schema.getTableNames()).map(t -> { + final String uri = uriBuilder.build(tenantName, dataSourceName, schemaName, t).toString(); + return new GetSchemaResponseTables().name(String.valueOf(t)).uri(uri); + }).collect(Collectors.toList()); - final Map<String, Object> map = new LinkedHashMap<>(); - map.put("type", "schema"); - map.put("name", schemaName); - map.put("datasource", dataSourceName); - map.put("tenant", tenantName); - map.put("tables", tableLinks); - return map; + final GetSchemaResponse resp = new GetSchemaResponse(); + resp.type("schema"); + resp.name(schemaName); + resp.datasource(dataSourceName); + resp.tenant(tenantName); + resp.tables(tableLinks); + return resp; } } http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/core/src/main/java/org/apache/metamodel/membrane/controllers/TableController.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/controllers/TableController.java b/core/src/main/java/org/apache/metamodel/membrane/controllers/TableController.java index 82f568d..f43f598 100644 --- a/core/src/main/java/org/apache/metamodel/membrane/controllers/TableController.java +++ b/core/src/main/java/org/apache/metamodel/membrane/controllers/TableController.java @@ -19,9 +19,7 @@ package org.apache.metamodel.membrane.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; @@ -30,7 +28,8 @@ import org.apache.metamodel.DataContext; import org.apache.metamodel.membrane.app.DataContextTraverser; import org.apache.metamodel.membrane.app.TenantContext; import org.apache.metamodel.membrane.app.TenantRegistry; -import org.apache.metamodel.membrane.controllers.model.RestLink; +import org.apache.metamodel.membrane.swagger.model.GetTableResponse; +import org.apache.metamodel.membrane.swagger.model.GetTableResponseColumns; import org.apache.metamodel.schema.Table; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; @@ -54,12 +53,12 @@ public class TableController { @RequestMapping(method = RequestMethod.GET) @ResponseBody - public Map<String, Object> get(@PathVariable("tenant") String tenantId, + public GetTableResponse get(@PathVariable("tenant") String tenantId, @PathVariable("dataContext") String dataSourceName, @PathVariable("schema") String schemaId, @PathVariable("table") String tableId) { final TenantContext tenantContext = tenantRegistry.getTenantContext(tenantId); final DataContext dataContext = tenantContext.getDataSourceRegistry().openDataContext(dataSourceName); - + final DataContextTraverser traverser = new DataContextTraverser(dataContext); final Table table = traverser.getTable(schemaId, tableId); @@ -69,17 +68,18 @@ public class TableController { final String tableName = table.getName(); final String schemaName = table.getSchema().getName(); - final List<RestLink> columnsLinks = Arrays.stream(table.getColumnNames()).map(c -> new RestLink(String.valueOf( - c), uriBuilder.build(tenantName, dataSourceName, schemaName, tableName, c))).collect(Collectors - .toList()); + final List<GetTableResponseColumns> columnsLinks = Arrays.stream(table.getColumnNames()).map(c -> { + final String uri = uriBuilder.build(tenantName, dataSourceName, schemaName, tableName, c).toString(); + return new GetTableResponseColumns().name(c).uri(uri); + }).collect(Collectors.toList()); - final Map<String, Object> map = new LinkedHashMap<>(); - map.put("type", "table"); - map.put("name", tableName); - map.put("schema", schemaName); - map.put("datasource", dataSourceName); - map.put("tenant", tenantName); - map.put("columns", columnsLinks); - return map; + final GetTableResponse resp = new GetTableResponse(); + resp.type("table"); + resp.name(tableName); + resp.schema(schemaName); + resp.datasource(dataSourceName); + resp.tenant(tenantName); + resp.columns(columnsLinks); + return resp; } } http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/core/src/main/java/org/apache/metamodel/membrane/controllers/TableDataController.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/controllers/TableDataController.java b/core/src/main/java/org/apache/metamodel/membrane/controllers/TableDataController.java index e906556..91d2588 100644 --- a/core/src/main/java/org/apache/metamodel/membrane/controllers/TableDataController.java +++ b/core/src/main/java/org/apache/metamodel/membrane/controllers/TableDataController.java @@ -18,7 +18,7 @@ */ package org.apache.metamodel.membrane.controllers; -import java.util.LinkedHashMap; +import java.math.BigDecimal; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -32,6 +32,8 @@ import org.apache.metamodel.insert.RowInsertionBuilder; import org.apache.metamodel.membrane.app.DataContextTraverser; import org.apache.metamodel.membrane.app.TenantContext; import org.apache.metamodel.membrane.app.TenantRegistry; +import org.apache.metamodel.membrane.swagger.model.InsertionResponse; +import org.apache.metamodel.membrane.swagger.model.QueryResponse; import org.apache.metamodel.query.Query; import org.apache.metamodel.schema.Table; import org.springframework.beans.factory.annotation.Autowired; @@ -44,6 +46,8 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; +import com.google.common.collect.Lists; + @RestController @RequestMapping(value = { "/{tenant}/{dataContext}/schemas/{schema}/tables/{table}/data", "/{tenant}/{dataContext}/s/{schema}/t/{table}/d" }, produces = MediaType.APPLICATION_JSON_VALUE) @@ -58,13 +62,13 @@ public class TableDataController { @RequestMapping(method = RequestMethod.GET) @ResponseBody - public Map<String, Object> get(@PathVariable("tenant") String tenantId, + public QueryResponse get(@PathVariable("tenant") String tenantId, @PathVariable("dataContext") String dataSourceName, @PathVariable("schema") String schemaId, @PathVariable("table") String tableId, @RequestParam(value = "offset", required = false) Integer offset, @RequestParam(value = "limit", required = false) Integer limit) { final TenantContext tenantContext = tenantRegistry.getTenantContext(tenantId); final DataContext dataContext = tenantContext.getDataSourceRegistry().openDataContext(dataSourceName); - + final DataContextTraverser traverser = new DataContextTraverser(dataContext); final Table table = traverser.getTable(schemaId, tableId); @@ -76,12 +80,13 @@ public class TableDataController { @RequestMapping(method = RequestMethod.POST) @ResponseBody - public Map<String, Object> post(@PathVariable("tenant") String tenantId, + public InsertionResponse post(@PathVariable("tenant") String tenantId, @PathVariable("dataContext") String dataSourceName, @PathVariable("schema") String schemaId, @PathVariable("table") String tableId, @RequestBody final List<Map<String, Object>> inputRecords) { final TenantContext tenantContext = tenantRegistry.getTenantContext(tenantId); - final UpdateableDataContext dataContext = tenantContext.getDataSourceRegistry().openDataContextForUpdate(dataSourceName); + final UpdateableDataContext dataContext = tenantContext.getDataSourceRegistry().openDataContextForUpdate( + dataSourceName); final DataContextTraverser traverser = new DataContextTraverser(dataContext); @@ -100,14 +105,16 @@ public class TableDataController { } }); - final Map<String, Object> response = new LinkedHashMap<>(); - response.put("status", "ok"); + final InsertionResponse response = new InsertionResponse(); + response.status("ok"); if (result.getInsertedRows().isPresent()) { - response.put("inserted-rows", result.getInsertedRows().get()); + final Integer insertedRecords = result.getInsertedRows().get(); + response.insertedRows(new BigDecimal(insertedRecords)); } if (result.getGeneratedKeys().isPresent()) { - response.put("generated-keys", result.getGeneratedKeys().get()); + final Iterable<Object> keys = result.getGeneratedKeys().get(); + response.generatedKeys(Lists.newArrayList(keys)); } return response; http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/core/src/main/java/org/apache/metamodel/membrane/controllers/TenantController.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/controllers/TenantController.java b/core/src/main/java/org/apache/metamodel/membrane/controllers/TenantController.java index c4af271..76197a1 100644 --- a/core/src/main/java/org/apache/metamodel/membrane/controllers/TenantController.java +++ b/core/src/main/java/org/apache/metamodel/membrane/controllers/TenantController.java @@ -18,16 +18,17 @@ */ package org.apache.metamodel.membrane.controllers; -import java.util.LinkedHashMap; +import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; import javax.ws.rs.core.UriBuilder; import org.apache.metamodel.membrane.app.TenantContext; import org.apache.metamodel.membrane.app.TenantRegistry; -import org.apache.metamodel.membrane.controllers.model.RestLink; +import org.apache.metamodel.membrane.swagger.model.DeleteTenantResponse; +import org.apache.metamodel.membrane.swagger.model.GetTenantResponse; +import org.apache.metamodel.membrane.swagger.model.GetTenantResponseDatasources; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PathVariable; @@ -49,46 +50,48 @@ public class TenantController { @RequestMapping(method = RequestMethod.GET) @ResponseBody - public Map<String, Object> getTenant(@PathVariable("tenant") String tenantName) { + public GetTenantResponse getTenant(@PathVariable("tenant") String tenantName) { final TenantContext tenantContext = tenantRegistry.getTenantContext(tenantName); final String tenantNameNormalized = tenantContext.getTenantName(); final UriBuilder uriBuilder = UriBuilder.fromPath("/{tenant}/{datasource}"); final List<String> dataContextIdentifiers = tenantContext.getDataSourceRegistry().getDataSourceNames(); - final List<RestLink> dataSourceLinks = dataContextIdentifiers.stream().map(s -> new RestLink(s, uriBuilder - .build(tenantNameNormalized, s))).collect(Collectors.toList()); - - final Map<String, Object> map = new LinkedHashMap<>(); - map.put("type", "tenant"); - map.put("name", tenantNameNormalized); - map.put("datasources", dataSourceLinks); - return map; + final List<GetTenantResponseDatasources> dataSourceLinks = dataContextIdentifiers.stream().map(s -> { + final String uri = uriBuilder.build(tenantNameNormalized, s).toString(); + return new GetTenantResponseDatasources().name(s).uri(uri); + }).collect(Collectors.toList()); + + final GetTenantResponse resp = new GetTenantResponse(); + resp.type("tenant"); + resp.name(tenantNameNormalized); + resp.datasources(dataSourceLinks); + return resp; } @RequestMapping(method = RequestMethod.PUT) @ResponseBody - public Map<String, Object> putTenant(@PathVariable("tenant") String tenantName) { + public GetTenantResponse putTenant(@PathVariable("tenant") String tenantName) { final TenantContext tenantContext = tenantRegistry.createTenantContext(tenantName); final String tenantIdentifier = tenantContext.getTenantName(); - final Map<String, Object> map = new LinkedHashMap<>(); - map.put("type", "tenant"); - map.put("name", tenantIdentifier); - - return map; + final GetTenantResponse resp = new GetTenantResponse(); + resp.type("tenant"); + resp.name(tenantIdentifier); + resp.datasources(Collections.emptyList()); + return resp; } @RequestMapping(method = RequestMethod.DELETE) @ResponseBody - public Map<String, Object> deleteTenant(@PathVariable("tenant") String tenantName) { + public DeleteTenantResponse deleteTenant(@PathVariable("tenant") String tenantName) { tenantRegistry.deleteTenantContext(tenantName); - final Map<String, Object> map = new LinkedHashMap<>(); - map.put("type", "tenant"); - map.put("name", tenantName); - map.put("deleted", true); + final DeleteTenantResponse resp = new DeleteTenantResponse(); + resp.type("tenant"); + resp.name(tenantName); + resp.deleted(true); - return map; + return resp; } } http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/core/src/main/java/org/apache/metamodel/membrane/controllers/model/RestLink.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/controllers/model/RestLink.java b/core/src/main/java/org/apache/metamodel/membrane/controllers/model/RestLink.java deleted file mode 100644 index cde135c..0000000 --- a/core/src/main/java/org/apache/metamodel/membrane/controllers/model/RestLink.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.membrane.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(final String name, final URI uri) { - this(); - this.name = name; - this.uri = uri; - } - - public String getName() { - return name; - } - - public void setName(final String name) { - this.name = name; - } - - public URI getUri() { - return uri; - } - - public void setUri(final URI uri) { - this.uri = uri; - } -} http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/core/src/main/resources/swagger.yaml ---------------------------------------------------------------------- diff --git a/core/src/main/resources/swagger.yaml b/core/src/main/resources/swagger.yaml index dc5ef93..0666728 100644 --- a/core/src/main/resources/swagger.yaml +++ b/core/src/main/resources/swagger.yaml @@ -38,30 +38,7 @@ paths: 200: description: The system is operational schema: - type: object - properties: - ping: - type: string - description: Should return 'pong!' when the system is operational - application: - type: string - description: The name of the application running (Apache MetaModel Membrane) - version: - type: string - description: The version of the application running - server-time: - type: object - properties: - timestamp: - type: integer - format: int64 - description: The server-time in timestamp format (millis since 1st of January 1970) - iso8601: - type: string - description: The server-time in ISO-8601 format - canonical-hostname: - type: string - description: The canonical hostname of the server + $ref: "#/definitions/helloResponse" /{tenant}: parameters: - name: tenant @@ -75,13 +52,7 @@ paths: 200: description: Tenant created schema: - properties: - type: - type: string - description: The type of entity (tenant) - name: - type: string - description: The tenant name/identifier + $ref: "#/definitions/putTenantResponse" 409: description: Tenant already exist schema: @@ -97,26 +68,7 @@ paths: 200: description: Tenant found schema: - type: object - properties: - type: - type: string - description: The type of entity (tenant) - name: - type: string - description: The tenant name/identifier - datasources: - type: array - items: - type: object - properties: - name: - type: string - description: The name of the datasource - uri: - type: string - format: uri - description: A link to the datasource information + $ref: "#/definitions/getTenantResponse" delete: summary: Delete tenant description: Deletes a tenant from the system @@ -124,14 +76,7 @@ paths: 200: description: Tenant deleted schema: - type: object - properties: - type: - type: string - description: The type of entity (tenant) - name: - type: string - description: The tenant name/identifier + ref: "#/definitions/deleteTenantResponse" 404: description: Tenant not found schema: @@ -153,37 +98,7 @@ paths: 200: description: Datasource found schema: - type: object - properties: - type: - type: string - description: The type of entity (datasource) - name: - type: string - description: The datasource name - tenant: - type: string - description: The tenant name - updateable: - type: boolean - description: Is this datasource updateable? - query_uri: - type: string - description: A link to the query endpoint for this datasource - format: uri - schemas: - type: array - description: The schemas of this datasource - items: - type: object - properties: - name: - type: string - description: The schema name - uri: - type: string - description: A link to the schema information - format: uri + $ref: "#/definitions/getDatasourceResponse" 404: description: Datasource not found schema: @@ -195,10 +110,12 @@ paths: description: The definition of the datasource using properties. The same properties as normally applied in MetaModel factories (e.g. 'type', 'resource', 'url', 'driver-class' ,'hostname', 'port', 'catalog', 'database', 'username', 'port', 'table-defs') are used here. required: true schema: - type: object + $ref: "#/definitions/putDatasourceResponse" responses: 200: description: Datasource created + schema: + $ref: "#/definitions/getDatasourceResponse" /{tenant}/{datasource}/q: parameters: - name: tenant @@ -268,30 +185,7 @@ paths: 200: description: Schema found schema: - type: object - properties: - type: - type: string - description: The type of entity (schema) - name: - type: string - description: The schema name - datasource: - type: string - description: The datasource name - tables: - type: array - description: The names of the schema's tables - items: - type: object - properties: - name: - type: string - description: The table name - uri: - type: string - description: A link to the table information - format: uri + $ref: "#/definitions/getSchemaResponse" 404: description: Schema not found schema: @@ -323,36 +217,7 @@ paths: 200: description: Table found schema: - type: object - properties: - type: - type: string - description: The type of entity (table) - name: - type: string - description: The table name - schema: - type: string - description: The schema name - datasource: - type: string - description: The datasource name - tenant: - type: string - description: The tenant name - columns: - type: array - description: The names of the table's columns - items: - type: object - properties: - name: - type: string - description: The column name - uri: - type: string - description: A link to the column information - format: uri + $ref: "#/definitions/getTableResponse" 404: description: Table not found schema: @@ -406,14 +271,12 @@ paths: description: The data to insert required: true schema: - type: array - items: - description: A record to insert where each key is expected to match a column name and each value is the value to put. - type: object + $ref: "#/definitions/insertionRequest" responses: 200: description: Data inserted - #TODO + schema: + $ref: "#/definitions/insertionResponse" 404: description: Table not found schema: @@ -451,54 +314,7 @@ paths: 200: description: Query executed schema: - type: object - properties: - type: - type: string - description: The type of entity (column) - name: - type: string - description: The column name - table: - type: string - description: The table name - schema: - type: string - description: The schema name - datasource: - type: string - description: The datasource name - tenant: - type: string - description: The tenant name - metadata: - type: object - description: Metadata about the column - properties: - number: - type: integer - description: The column number (0-based) - size: - type: integer - description: The column size - nullable: - type: boolean - description: Is the column nullable? - primary-key: - type: boolean - description: Is the column a primary key? - indexed: - type: boolean - description: Is the column indexed? - column-type: - type: string - description: The column type (as interpreted/adapted by Apache MetaModel) - native-type: - type: string - description: The native column type (as defined by the datasource itself) - remarks: - type: string - description: Any remarks on the column + $ref: "#/definitions/getColumnResponse" 404: description: Column not found schema: @@ -523,6 +339,249 @@ definitions: type: array items: type: object + helloResponse: + type: object + properties: + ping: + type: string + description: Should return 'pong!' when the system is operational + application: + type: string + description: The name of the application running (Apache MetaModel Membrane) + version: + type: string + description: The version of the application running + server-time: + type: object + properties: + timestamp: + type: integer + format: int64 + description: The server-time in timestamp format (millis since 1st of January 1970) + iso8601: + type: string + description: The server-time in ISO-8601 format + canonical-hostname: + type: string + description: The canonical hostname of the server + open-api: + type: object + properties: + spec: + type: string + format: uri + description: Href for the Open API (fka. Swagger) specification that describes the service. + getTenantResponse: + type: object + properties: + type: + type: string + description: The type of entity (tenant) + name: + type: string + description: The tenant name/identifier + datasources: + type: array + items: + type: object + properties: + name: + type: string + description: The name of the datasource + uri: + type: string + format: uri + description: A link to the datasource information + putTenantResponse: + type: object + properties: + type: + type: string + description: The type of entity (tenant) + name: + type: string + description: The tenant name/identifier + deleteTenantResponse: + type: object + properties: + type: + type: string + description: The type of entity (tenant) + name: + type: string + description: The tenant name/identifier + deleted: + type: boolean + description: A confirmation boolean to indicate that the deletion is effectuated. + insertionRequest: + type: array + items: + description: A record to insert where each key is expected to match a column name and each value is the value to put. + type: object + insertionResponse: + description: Represents the result of inserting records to a table + type: object + properties: + status: + type: string + description: A confirmation 'ok' that the insertion went well. + inserted-rows: + type: number + format: int32 + description: The amount of inserted records + generated-keys: + type: array + description: An array of generated keys for the records, if any + items: + type: object + putDatasourceResponse: + type: object + properties: + type: + type: string + description: DataContext type (e.g. 'jdbc', 'csv' etc.) + additionalProperties: + type: string + getDatasourceResponse: + type: object + properties: + type: + type: string + description: The type of entity (datasource) + name: + type: string + description: The datasource name + tenant: + type: string + description: The tenant name + updateable: + type: boolean + description: Is this datasource updateable? + query_uri: + type: string + description: A link to the query endpoint for this datasource + format: uri + schemas: + type: array + description: The schemas of this datasource + items: + type: object + properties: + name: + type: string + description: The schema name + uri: + type: string + description: A link to the schema information + format: uri + getSchemaResponse: + type: object + properties: + type: + type: string + description: The type of entity (schema) + name: + type: string + description: The schema name + datasource: + type: string + description: The datasource name + tenant: + type: string + description: The tenant name + tables: + type: array + description: The names of the schema's tables + items: + type: object + properties: + name: + type: string + description: The table name + uri: + type: string + description: A link to the table information + format: uri + getTableResponse: + type: object + properties: + type: + type: string + description: The type of entity (table) + name: + type: string + description: The table name + schema: + type: string + description: The schema name + datasource: + type: string + description: The datasource name + tenant: + type: string + description: The tenant name + columns: + type: array + description: The names of the table's columns + items: + type: object + properties: + name: + type: string + description: The column name + uri: + type: string + description: A link to the column information + format: uri + getColumnResponse: + type: object + properties: + type: + type: string + description: The type of entity (column) + name: + type: string + description: The column name + table: + type: string + description: The table name + schema: + type: string + description: The schema name + datasource: + type: string + description: The datasource name + tenant: + type: string + description: The tenant name + metadata: + type: object + description: Metadata about the column + properties: + number: + type: integer + description: The column number (0-based) + size: + type: integer + description: The column size + nullable: + type: boolean + description: Is the column nullable? + primary-key: + type: boolean + description: Is the column a primary key? + indexed: + type: boolean + description: Is the column indexed? + column-type: + type: string + description: The column type (as interpreted/adapted by Apache MetaModel) + native-type: + type: string + description: The native column type (as defined by the datasource itself) + remarks: + type: string + description: Any remarks on the column error: description: Elaborates the error that occurred type: object http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/core/src/test/java/org/apache/metamodel/membrane/controllers/TenantInteractionScenarioTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/metamodel/membrane/controllers/TenantInteractionScenarioTest.java b/core/src/test/java/org/apache/metamodel/membrane/controllers/TenantInteractionScenarioTest.java index 4c01e53..59dfbb0 100644 --- a/core/src/test/java/org/apache/metamodel/membrane/controllers/TenantInteractionScenarioTest.java +++ b/core/src/test/java/org/apache/metamodel/membrane/controllers/TenantInteractionScenarioTest.java @@ -19,19 +19,11 @@ package org.apache.metamodel.membrane.controllers; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; import java.util.Map; import org.apache.metamodel.membrane.app.InMemoryTenantRegistry; import org.apache.metamodel.membrane.app.TenantRegistry; -import org.apache.metamodel.membrane.controllers.ColumnController; -import org.apache.metamodel.membrane.controllers.DataSourceController; -import org.apache.metamodel.membrane.controllers.QueryController; -import org.apache.metamodel.membrane.controllers.SchemaController; -import org.apache.metamodel.membrane.controllers.TableController; -import org.apache.metamodel.membrane.controllers.TableDataController; -import org.apache.metamodel.membrane.controllers.TenantController; import org.junit.Before; import org.junit.Test; import org.springframework.http.MediaType; @@ -73,7 +65,7 @@ public class TenantInteractionScenarioTest { final Map<?, ?> map = new ObjectMapper().readValue(content, Map.class); assertEquals("tenant", map.get("type")); assertEquals("tenant1", map.get("name")); - assertNull(map.get("datasources")); + assertEquals("[]", map.get("datasources").toString()); } // create datasource @@ -157,7 +149,7 @@ public class TenantInteractionScenarioTest { final String content = result.getResponse().getContentAsString(); final Map<?, ?> map = new ObjectMapper().readValue(content, Map.class); assertEquals("dataset", map.get("type")); - assertEquals("[columns.name, columns.table]", map.get("header").toString()); + assertEquals("[columns.name, columns.table]", map.get("headers").toString()); assertEquals("[[bar, foo], [baz, foo], [greeting, hello_world], [who, hello_world]]", map.get("data") .toString()); } @@ -194,7 +186,7 @@ public class TenantInteractionScenarioTest { final String content = result.getResponse().getContentAsString(); final Map<?, ?> map = new ObjectMapper().readValue(content, Map.class); assertEquals("dataset", map.get("type")); - assertEquals("[hello_world.greeting, hello_world.who AS who_is_it]", map.get("header").toString()); + assertEquals("[hello_world.greeting, hello_world.who AS who_is_it]", map.get("headers").toString()); assertEquals("[[Howdy, MetaModel], [Hi, Apache]]", map.get("data") .toString()); } http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index ebac406..46d967b 100644 --- a/pom.xml +++ b/pom.xml @@ -43,6 +43,7 @@ under the License. <inceptionYear>2017</inceptionYear> <packaging>pom</packaging> <modules> + <module>swagger-codegen</module> <module>core</module> <module>war</module> <module>undertow</module> http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/609cc85b/swagger-codegen/pom.xml ---------------------------------------------------------------------- diff --git a/swagger-codegen/pom.xml b/swagger-codegen/pom.xml new file mode 100644 index 0000000..5f50f49 --- /dev/null +++ b/swagger-codegen/pom.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- +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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <groupId>org.apache.metamodel.membrane</groupId> + <artifactId>Membrane-parent</artifactId> + <version>0.1-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>Membrane-swagger-model</artifactId> + <packaging>jar</packaging> + + <properties> + <swagger.version>2.2.3</swagger.version> + <jersey-version>2.22.2</jersey-version> + </properties> + + <build> + <plugins> + <plugin> + <groupId>io.swagger</groupId> + <artifactId>swagger-codegen-maven-plugin</artifactId> + <version>${swagger.version}</version> + <executions> + <execution> + <goals> + <goal>generate</goal> + </goals> + <configuration> + <groupId>${project.groupId}</groupId> + <artifactId>Membrane-swagger-model</artifactId> + <inputSpec>${project.basedir}/../core/src/main/resources/swagger.yaml</inputSpec> + <language>java</language> + <modelPackage>org.apache.metamodel.membrane.swagger.model</modelPackage> + <apiPackage>org.apache.metamodel.membrane.swagger.api</apiPackage> + <invokerPackage>org.apache.metamodel.membrane.swagger.invoker</invokerPackage> + <library>jersey2</library> + <configOptions> + <sourceFolder>src/gen/java/main</sourceFolder> + <dateLibrary>java8</dateLibrary> + </configOptions> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>io.swagger</groupId> + <artifactId>swagger-annotations</artifactId> + <version>1.5.16</version> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-annotations</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.datatype</groupId> + <artifactId>jackson-datatype-jsr310</artifactId> + <version>${jackson.version}</version> + </dependency> + <!-- + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-validator</artifactId> + </dependency> + --> + + <!-- Client-side dependencies that swagger-codegen requires for client-stubs, + but we don't need them on the server side --> + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-client</artifactId> + <version>${jersey-version}</version> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.glassfish.jersey.media</groupId> + <artifactId>jersey-media-json-jackson</artifactId> + <version>${jersey-version}</version> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.glassfish.jersey.media</groupId> + <artifactId>jersey-media-multipart</artifactId> + <version>${jersey-version}</version> + <optional>true</optional> + </dependency> + + <!-- Base64 encoding that works in both JVM and Android --> + <dependency> + <groupId>com.brsanthu</groupId> + <artifactId>migbase64</artifactId> + <version>2.2</version> + <optional>true</optional> + </dependency> + </dependencies> +</project>