Repository: metamodel-membrane Updated Branches: refs/heads/master 65ab98cb4 -> 364686d8f
METAMODEL-1158: Added handling for data sources that don't validate Project: http://git-wip-us.apache.org/repos/asf/metamodel-membrane/repo Commit: http://git-wip-us.apache.org/repos/asf/metamodel-membrane/commit/364686d8 Tree: http://git-wip-us.apache.org/repos/asf/metamodel-membrane/tree/364686d8 Diff: http://git-wip-us.apache.org/repos/asf/metamodel-membrane/diff/364686d8 Branch: refs/heads/master Commit: 364686d8f8ded7961789b163a6943e227f262830 Parents: 65ab98c Author: Kasper Sørensen <i.am.kasper.soren...@gmail.com> Authored: Wed Aug 23 22:39:31 2017 -0700 Committer: Kasper Sørensen <i.am.kasper.soren...@gmail.com> Committed: Wed Aug 23 22:49:09 2017 -0700 ---------------------------------------------------------------------- .../app/CachedDataSourceRegistryWrapper.java | 20 +++-- .../membrane/app/DataSourceRegistry.java | 39 +++++++- .../app/InMemoryDataSourceRegistry.java | 5 ++ .../exceptions/InvalidDataSourceException.java | 30 +++++++ .../file/FileBasedDataSourceRegistry.java | 9 +- .../controllers/DataSourceController.java | 55 +++++++++--- .../membrane/controllers/RestErrorHandler.java | 16 ++++ .../model/RestDataSourceDefinition.java | 4 + core/src/main/resources/swagger.yaml | 14 ++- .../controllers/DataSourceControllerTest.java | 93 ++++++++++++++++++++ .../TenantInteractionScenarioTest.java | 4 +- 11 files changed, 259 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/364686d8/core/src/main/java/org/apache/metamodel/membrane/app/CachedDataSourceRegistryWrapper.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/app/CachedDataSourceRegistryWrapper.java b/core/src/main/java/org/apache/metamodel/membrane/app/CachedDataSourceRegistryWrapper.java index 77fbb77..86aac22 100644 --- a/core/src/main/java/org/apache/metamodel/membrane/app/CachedDataSourceRegistryWrapper.java +++ b/core/src/main/java/org/apache/metamodel/membrane/app/CachedDataSourceRegistryWrapper.java @@ -36,14 +36,13 @@ import com.google.common.cache.RemovalNotification; import com.google.common.util.concurrent.UncheckedExecutionException; /** - * A wrapper that adds a cache around a {@link DataSourceRegistry} in order to - * prevent re-connecting all the time to the same data source. + * A wrapper that adds a cache around a {@link DataSourceRegistry} in order to prevent re-connecting all the time to the + * same data source. */ public class CachedDataSourceRegistryWrapper implements DataSourceRegistry { /** - * The default timeout (in seconds) before the cache evicts and closes the - * created {@link DataContext}s. + * The default timeout (in seconds) before the cache evicts and closes the created {@link DataContext}s. */ public static final int DEFAULT_TIMEOUT_SECONDS = 60; @@ -57,8 +56,8 @@ public class CachedDataSourceRegistryWrapper implements DataSourceRegistry { public CachedDataSourceRegistryWrapper(final DataSourceRegistry delegate, final long cacheTimeout, final TimeUnit cacheTimeoutUnit) { this.delegate = delegate; - this.loadingCache = CacheBuilder.newBuilder().expireAfterAccess(cacheTimeout, cacheTimeoutUnit).removalListener( - createRemovalListener()).build(createCacheLoader()); + this.loadingCache = CacheBuilder.newBuilder().expireAfterAccess(cacheTimeout, cacheTimeoutUnit) + .removalListener(createRemovalListener()).build(createCacheLoader()); } private RemovalListener<String, DataContext> createRemovalListener() { @@ -102,9 +101,14 @@ public class CachedDataSourceRegistryWrapper implements DataSourceRegistry { if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } - throw new MetaModelException("Unexpected error happened while getting DataContext '" + dataSourceName - + "' from cache", e); + throw new MetaModelException( + "Unexpected error happened while getting DataContext '" + dataSourceName + "' from cache", e); } } + @Override + public DataContext openDataContext(DataContextProperties properties) { + return delegate.openDataContext(properties); + } + } http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/364686d8/core/src/main/java/org/apache/metamodel/membrane/app/DataSourceRegistry.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/app/DataSourceRegistry.java b/core/src/main/java/org/apache/metamodel/membrane/app/DataSourceRegistry.java index b4678c0..fcf1ec3 100644 --- a/core/src/main/java/org/apache/metamodel/membrane/app/DataSourceRegistry.java +++ b/core/src/main/java/org/apache/metamodel/membrane/app/DataSourceRegistry.java @@ -34,15 +34,48 @@ public interface DataSourceRegistry { public List<String> getDataSourceNames(); - public String registerDataSource(String dataSourceName, DataContextProperties dataContextProperties) throws DataSourceAlreadyExistException; + /** + * + * @param dataSourceName + * @param dataContextProperties + * @return the identifier/name for the data source. + * @throws DataSourceAlreadyExistException + */ + public String registerDataSource(String dataSourceName, DataContextProperties dataContextProperties) + throws DataSourceAlreadyExistException; + /** + * Opens a {@link DataContext} that exists in the registry. + * + * @param dataSourceName + * @return + * @throws NoSuchDataSourceException + */ public DataContext openDataContext(String dataSourceName) throws NoSuchDataSourceException; - public default UpdateableDataContext openDataContextForUpdate(String dataSourceName) { + /** + * Opens a {@link DataContext} based on a set of {@link DataContextProperties}. This allows you to instantiate a + * data source without necesarily having registered it (yet). + * + * @param properties + * @return + */ + public DataContext openDataContext(DataContextProperties properties); + + /** + * Opens a {@link UpdateableDataContext} that exists in the registry. + * + * @param dataSourceName + * @return + * @throws DataSourceNotUpdateableException + */ + public default UpdateableDataContext openDataContextForUpdate(String dataSourceName) + throws DataSourceNotUpdateableException { final DataContext dataContext = openDataContext(dataSourceName); if (dataContext instanceof UpdateableDataContext) { return (UpdateableDataContext) dataContext; } throw new DataSourceNotUpdateableException(dataSourceName); - }; + } + } http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/364686d8/core/src/main/java/org/apache/metamodel/membrane/app/InMemoryDataSourceRegistry.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/app/InMemoryDataSourceRegistry.java b/core/src/main/java/org/apache/metamodel/membrane/app/InMemoryDataSourceRegistry.java index 1272cee..cd71ec4 100644 --- a/core/src/main/java/org/apache/metamodel/membrane/app/InMemoryDataSourceRegistry.java +++ b/core/src/main/java/org/apache/metamodel/membrane/app/InMemoryDataSourceRegistry.java @@ -62,4 +62,9 @@ public class InMemoryDataSourceRegistry implements DataSourceRegistry { return supplier.get(); } + @Override + public DataContext openDataContext(DataContextProperties properties) { + final DataContextSupplier supplier = new DataContextSupplier(null, properties); + return supplier.get(); + } } http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/364686d8/core/src/main/java/org/apache/metamodel/membrane/app/exceptions/InvalidDataSourceException.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/app/exceptions/InvalidDataSourceException.java b/core/src/main/java/org/apache/metamodel/membrane/app/exceptions/InvalidDataSourceException.java new file mode 100644 index 0000000..4cdfffb --- /dev/null +++ b/core/src/main/java/org/apache/metamodel/membrane/app/exceptions/InvalidDataSourceException.java @@ -0,0 +1,30 @@ +/** + * 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.app.exceptions; + +import org.apache.metamodel.MetaModelException; + +public class InvalidDataSourceException extends MetaModelException { + + private static final long serialVersionUID = 1L; + + public InvalidDataSourceException(Exception cause) { + super(cause.getClass().getSimpleName() + (cause.getMessage() == null ? "" : ": " + cause.getMessage())); + } +} http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/364686d8/core/src/main/java/org/apache/metamodel/membrane/app/registry/file/FileBasedDataSourceRegistry.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/app/registry/file/FileBasedDataSourceRegistry.java b/core/src/main/java/org/apache/metamodel/membrane/app/registry/file/FileBasedDataSourceRegistry.java index 74d1d3a..7d49c6d 100644 --- a/core/src/main/java/org/apache/metamodel/membrane/app/registry/file/FileBasedDataSourceRegistry.java +++ b/core/src/main/java/org/apache/metamodel/membrane/app/registry/file/FileBasedDataSourceRegistry.java @@ -114,9 +114,14 @@ public class FileBasedDataSourceRegistry implements DataSourceRegistry { throw new UncheckedIOException(e); } - final DataContextSupplier supplier = new DataContextSupplier(dataSourceName, dataSource - .toDataContextProperties()); + final DataContextSupplier supplier = + new DataContextSupplier(dataSourceName, dataSource.toDataContextProperties()); return supplier.get(); } + @Override + public DataContext openDataContext(DataContextProperties properties) { + final DataContextSupplier supplier = new DataContextSupplier(null, properties); + return supplier.get(); + } } http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/364686d8/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 7540cf5..4f9fd55 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 @@ -30,17 +30,22 @@ import org.apache.metamodel.DataContext; import org.apache.metamodel.UpdateableDataContext; import org.apache.metamodel.factory.DataContextProperties; import org.apache.metamodel.factory.DataContextPropertiesImpl; +import org.apache.metamodel.membrane.app.DataSourceRegistry; import org.apache.metamodel.membrane.app.TenantContext; import org.apache.metamodel.membrane.app.TenantRegistry; +import org.apache.metamodel.membrane.app.exceptions.InvalidDataSourceException; import org.apache.metamodel.membrane.controllers.model.RestDataSourceDefinition; import org.apache.metamodel.membrane.swagger.model.GetDatasourceResponse; import org.apache.metamodel.membrane.swagger.model.GetDatasourceResponseSchemas; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; 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.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @@ -48,6 +53,8 @@ import org.springframework.web.bind.annotation.RestController; @RequestMapping(value = "/{tenant}/{datasource}", produces = MediaType.APPLICATION_JSON_VALUE) public class DataSourceController { + private static final Logger logger = LoggerFactory.getLogger(DataSourceController.class); + private final TenantRegistry tenantRegistry; @Autowired @@ -59,16 +66,28 @@ public class DataSourceController { @ResponseBody public GetDatasourceResponse put(@PathVariable("tenant") String tenantId, @PathVariable("datasource") String dataSourceId, - @Valid @RequestBody RestDataSourceDefinition dataContextDefinition) { + @RequestParam(value = "validate", required = false) Boolean validate, + @Valid @RequestBody RestDataSourceDefinition dataSourceDefinition) { final Map<String, Object> map = new HashMap<>(); - map.putAll(dataContextDefinition.getProperties()); - map.put(DataContextPropertiesImpl.PROPERTY_DATA_CONTEXT_TYPE, dataContextDefinition.getType()); + map.putAll(dataSourceDefinition.getProperties()); + map.put(DataContextPropertiesImpl.PROPERTY_DATA_CONTEXT_TYPE, dataSourceDefinition.getType()); final DataContextProperties properties = new DataContextPropertiesImpl(map); - final String dataContextIdentifier = tenantRegistry.getTenantContext(tenantId).getDataSourceRegistry() - .registerDataSource(dataSourceId, properties); + final DataSourceRegistry dataSourceRegistry = tenantRegistry.getTenantContext(tenantId).getDataSourceRegistry(); + if (validate != null && validate.booleanValue()) { + // validate the data source by opening it and ensuring that a basic call such as getDefaultSchema() works. + try { + final DataContext dataContext = dataSourceRegistry.openDataContext(properties); + dataContext.getDefaultSchema(); + } catch (Exception e) { + logger.warn("Failed validation for PUT datasource '{}/{}'", tenantId, dataSourceId, e); + throw new InvalidDataSourceException(e); + } + } + + final String dataContextIdentifier = dataSourceRegistry.registerDataSource(dataSourceId, properties); return get(tenantId, dataContextIdentifier); } @@ -78,23 +97,33 @@ public class DataSourceController { public GetDatasourceResponse get(@PathVariable("tenant") String tenantId, @PathVariable("datasource") String dataSourceName) { final TenantContext tenantContext = tenantRegistry.getTenantContext(tenantId); - final DataContext dataContext = tenantContext.getDataSourceRegistry().openDataContext(dataSourceName); final String tenantName = tenantContext.getTenantName(); final UriBuilder uriBuilder = UriBuilder.fromPath("/{tenant}/{dataContext}/s/{schema}"); - final List<GetDatasourceResponseSchemas> schemaLinks = dataContext.getSchemaNames().stream().map(s -> { - final String uri = uriBuilder.build(tenantName, dataSourceName, s).toString(); - return new GetDatasourceResponseSchemas().name(s).uri(uri); - }).collect(Collectors.toList()); + List<GetDatasourceResponseSchemas> schemaLinks; + Boolean updateable; + try { + final DataContext dataContext = tenantContext.getDataSourceRegistry().openDataContext(dataSourceName); + updateable = dataContext instanceof UpdateableDataContext; + schemaLinks = dataContext.getSchemaNames().stream().map(s -> { + final String uri = uriBuilder.build(tenantName, dataSourceName, s).toString(); + return new GetDatasourceResponseSchemas().name(s).uri(uri); + }).collect(Collectors.toList()); + } catch (Exception e) { + logger.warn("Failed to open for GET datasource '{}/{}'. No schemas will be listed.", tenantId, + dataSourceName, e); + updateable = null; + schemaLinks = null; + } 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.updateable(updateable); + 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/364686d8/core/src/main/java/org/apache/metamodel/membrane/controllers/RestErrorHandler.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/controllers/RestErrorHandler.java b/core/src/main/java/org/apache/metamodel/membrane/controllers/RestErrorHandler.java index 5d79f56..1b5ec4d 100644 --- a/core/src/main/java/org/apache/metamodel/membrane/controllers/RestErrorHandler.java +++ b/core/src/main/java/org/apache/metamodel/membrane/controllers/RestErrorHandler.java @@ -26,6 +26,7 @@ import java.util.Map; import org.apache.metamodel.membrane.app.exceptions.AbstractIdentifierNamingException; import org.apache.metamodel.membrane.app.exceptions.DataSourceAlreadyExistException; import org.apache.metamodel.membrane.app.exceptions.DataSourceNotUpdateableException; +import org.apache.metamodel.membrane.app.exceptions.InvalidDataSourceException; import org.apache.metamodel.membrane.app.exceptions.NoSuchColumnException; import org.apache.metamodel.membrane.app.exceptions.NoSuchDataSourceException; import org.apache.metamodel.membrane.app.exceptions.NoSuchSchemaException; @@ -129,6 +130,21 @@ public class RestErrorHandler { return new RestErrorResponse(HttpStatus.BAD_REQUEST.value(), "DataSource not updateable: " + ex .getDataSourceName()); } + + /** + * DataSource invalid exception handler method - mapped to + * BAD_REQUEST. + * + * @param ex + * @return + */ + @ExceptionHandler(InvalidDataSourceException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ResponseBody + public RestErrorResponse processDataSourceNotUpdateable(InvalidDataSourceException ex) { + return new RestErrorResponse(HttpStatus.BAD_REQUEST.value(), "DataSource invalid: " + ex + .getMessage()); + } /** * Query parsing exception - mapped to BAD_REQUEST. http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/364686d8/core/src/main/java/org/apache/metamodel/membrane/controllers/model/RestDataSourceDefinition.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/metamodel/membrane/controllers/model/RestDataSourceDefinition.java b/core/src/main/java/org/apache/metamodel/membrane/controllers/model/RestDataSourceDefinition.java index eae3dc6..b3ac4ec 100644 --- a/core/src/main/java/org/apache/metamodel/membrane/controllers/model/RestDataSourceDefinition.java +++ b/core/src/main/java/org/apache/metamodel/membrane/controllers/model/RestDataSourceDefinition.java @@ -59,6 +59,10 @@ public class RestDataSourceDefinition implements DataSourceDefinition { public String getType() { return type; } + + public void setType(String type) { + this.type = type; + } @JsonAnyGetter @Override http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/364686d8/core/src/main/resources/swagger.yaml ---------------------------------------------------------------------- diff --git a/core/src/main/resources/swagger.yaml b/core/src/main/resources/swagger.yaml index 1423ee7..fa17ebf 100644 --- a/core/src/main/resources/swagger.yaml +++ b/core/src/main/resources/swagger.yaml @@ -105,17 +105,27 @@ paths: $ref: "#/definitions/error" put: parameters: + - name: validate + in: query + description: Whether or not to validate the datasource properties and reject creating the datasource if it cannot be created. + required: false + type: boolean + default: false - name: inputData in: body 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: - $ref: "#/definitions/putDatasourceResponse" + $ref: "#/definitions/putDatasourceRequest" responses: 200: description: Datasource created schema: $ref: "#/definitions/getDatasourceResponse" + 400: + description: Datasource validation failed + schema: + $ref: "#/definitions/error" /{tenant}/{datasource}/q: parameters: - name: tenant @@ -499,7 +509,7 @@ definitions: description: An array of generated keys for the records, if any items: type: object - putDatasourceResponse: + putDatasourceRequest: type: object properties: type: http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/364686d8/core/src/test/java/org/apache/metamodel/membrane/controllers/DataSourceControllerTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/metamodel/membrane/controllers/DataSourceControllerTest.java b/core/src/test/java/org/apache/metamodel/membrane/controllers/DataSourceControllerTest.java new file mode 100644 index 0000000..2a7e240 --- /dev/null +++ b/core/src/test/java/org/apache/metamodel/membrane/controllers/DataSourceControllerTest.java @@ -0,0 +1,93 @@ +/** + * 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; + +import static org.junit.Assert.assertEquals; + +import org.apache.metamodel.membrane.app.InMemoryTenantRegistry; +import org.apache.metamodel.membrane.app.TenantRegistry; +import org.apache.metamodel.membrane.app.exceptions.InvalidDataSourceException; +import org.apache.metamodel.membrane.controllers.model.RestDataSourceDefinition; +import org.apache.metamodel.membrane.swagger.model.GetDatasourceResponse; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class DataSourceControllerTest { + + private final TenantRegistry tenantRegistry = new InMemoryTenantRegistry(); + private final DataSourceController dataSourceController = new DataSourceController(tenantRegistry); + + @Rule + public TestName name = new TestName(); + + @Test + public void testPutWithoutValidation() throws Exception { + final String tenant = name.getMethodName(); + tenantRegistry.createTenantContext(tenant); + + final RestDataSourceDefinition dataSourceDefinition = new RestDataSourceDefinition(); + dataSourceDefinition.setType("foo bar"); + dataSourceDefinition.set("hello", "world"); + + final GetDatasourceResponse resp = dataSourceController.put(tenant, "ds1", false, dataSourceDefinition); + assertEquals("ds1", resp.getName()); + assertEquals(null, resp.getSchemas()); + assertEquals(null, resp.getUpdateable()); + } + + @Test + public void testPutWithValidationFailing() throws Exception { + final String tenant = name.getMethodName(); + tenantRegistry.createTenantContext(tenant); + + final RestDataSourceDefinition dataSourceDefinition = new RestDataSourceDefinition(); + dataSourceDefinition.setType("foo bar"); + dataSourceDefinition.set("hello", "world"); + + try { + dataSourceController.put(tenant, "ds1", true, dataSourceDefinition); + Assert.fail("exception expected"); + } catch (InvalidDataSourceException e) { + assertEquals("UnsupportedDataContextPropertiesException", e.getMessage()); + } + } + + @Test + public void testPutWithValidationPassing() throws Exception { + final String tenant = name.getMethodName(); + tenantRegistry.createTenantContext(tenant); + + final RestDataSourceDefinition dataSourceDefinition = new RestDataSourceDefinition(); + dataSourceDefinition.setType("pojo"); + + final GetDatasourceResponse resp = dataSourceController.put(tenant, "ds1", true, dataSourceDefinition); + + final ObjectMapper objectMapper = new ObjectMapper(); + + assertEquals( + "[{'name':'information_schema','uri':'/testPutWithValidationPassing/ds1/s/information_schema'}," + + "{'name':'Schema','uri':'/testPutWithValidationPassing/ds1/s/Schema'}]", + objectMapper.writeValueAsString(resp.getSchemas()).replace('\"', '\'')); + } + +} http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/364686d8/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 8a56934..3e0575d 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 @@ -48,14 +48,14 @@ public class TenantInteractionScenarioTest { final TenantRegistry tenantRegistry = new InMemoryTenantRegistry(); final TenantController tenantController = new TenantController(tenantRegistry); - final DataSourceController dataContextController = new DataSourceController(tenantRegistry); + final DataSourceController dataSourceController = new DataSourceController(tenantRegistry); final SchemaController schemaController = new SchemaController(tenantRegistry); final TableController tableController = new TableController(tenantRegistry); final ColumnController columnController = new ColumnController(tenantRegistry); final QueryController queryController = new QueryController(tenantRegistry); final TableDataController tableDataController = new TableDataController(tenantRegistry); - mockMvc = MockMvcBuilders.standaloneSetup(tenantController, dataContextController, schemaController, + mockMvc = MockMvcBuilders.standaloneSetup(tenantController, dataSourceController, schemaController, tableController, columnController, queryController, tableDataController).setMessageConverters( messageConverter).build(); }