Merge branch 'master' into METAMODEL-1153 Conflicts: core/src/main/java/org/apache/metamodel/membrane/app/CachedDataSourceRegistryWrapper.java core/src/main/java/org/apache/metamodel/membrane/app/DataSourceRegistry.java core/src/main/java/org/apache/metamodel/membrane/app/InMemoryDataSourceRegistry.java core/src/main/java/org/apache/metamodel/membrane/app/registry/file/FileBasedDataSourceRegistry.java core/src/main/java/org/apache/metamodel/membrane/controllers/DataSourceController.java core/src/main/resources/swagger.yaml
Project: http://git-wip-us.apache.org/repos/asf/metamodel-membrane/repo Commit: http://git-wip-us.apache.org/repos/asf/metamodel-membrane/commit/516a0539 Tree: http://git-wip-us.apache.org/repos/asf/metamodel-membrane/tree/516a0539 Diff: http://git-wip-us.apache.org/repos/asf/metamodel-membrane/diff/516a0539 Branch: refs/heads/master Commit: 516a05397e409dca9e655d08d363a56614835210 Parents: 8e8a90c 364686d Author: Kasper Sørensen <i.am.kasper.soren...@gmail.com> Authored: Thu Sep 7 21:08:23 2017 -0700 Committer: Kasper Sørensen <i.am.kasper.soren...@gmail.com> Committed: Thu Sep 7 21:08:23 2017 -0700 ---------------------------------------------------------------------- .dockerignore | 18 ++ .travis.yml | 14 +- Dockerfile | 29 +++ core/pom.xml | 12 ++ .../app/CachedDataSourceRegistryWrapper.java | 20 +- .../membrane/app/DataSourceRegistry.java | 36 +++- .../app/InMemoryDataSourceRegistry.java | 4 + .../exceptions/InvalidDataSourceException.java | 30 +++ .../file/FileBasedDataSourceRegistry.java | 4 + .../controllers/DataSourceController.java | 51 +++-- .../membrane/controllers/RestErrorHandler.java | 16 ++ .../model/RestDataSourceDefinition.java | 4 + core/src/main/resources/swagger.yaml | 12 +- .../controllers/DataSourceControllerTest.java | 93 +++++++++ .../TenantInteractionScenarioTest.java | 10 +- docker-compose.yml | 20 +- pom.xml | 87 +++++++- postman-tests/Membrane.postman_collection.json | 202 ++++++++++++++++++ postman-tests/README.md | 20 ++ .../docker-toolbox.postman_environment.json | 16 ++ .../localhost.postman_environment.json | 16 ++ postman-tests/pom.xml | 204 +++++++++++++++++++ undertow/Dockerfile | 26 --- 23 files changed, 875 insertions(+), 69 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/516a0539/core/src/main/java/org/apache/metamodel/membrane/app/CachedDataSourceRegistryWrapper.java ---------------------------------------------------------------------- diff --cc core/src/main/java/org/apache/metamodel/membrane/app/CachedDataSourceRegistryWrapper.java index 96c9e80,86aac22..b7b5b1e --- a/core/src/main/java/org/apache/metamodel/membrane/app/CachedDataSourceRegistryWrapper.java +++ b/core/src/main/java/org/apache/metamodel/membrane/app/CachedDataSourceRegistryWrapper.java @@@ -108,8 -107,8 +107,13 @@@ public class CachedDataSourceRegistryWr } @Override + public void removeDataSource(String dataSourceName) throws NoSuchDataSourceException { + delegate.removeDataSource(dataSourceName); + loadingCache.invalidate(dataSourceName); + } ++ ++ @Override + public DataContext openDataContext(DataContextProperties properties) { + return delegate.openDataContext(properties); + } - } http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/516a0539/core/src/main/java/org/apache/metamodel/membrane/app/DataSourceRegistry.java ---------------------------------------------------------------------- diff --cc core/src/main/java/org/apache/metamodel/membrane/app/DataSourceRegistry.java index 53ba51d,fcf1ec3..1c5db17 --- 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,13 -34,43 +34,45 @@@ 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; + public void removeDataSource(String dataSourceName) throws NoSuchDataSourceException; + + /** + * 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; http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/516a0539/core/src/main/java/org/apache/metamodel/membrane/app/InMemoryDataSourceRegistry.java ---------------------------------------------------------------------- diff --cc core/src/main/java/org/apache/metamodel/membrane/app/InMemoryDataSourceRegistry.java index 573dfd7,cd71ec4..338ed86 --- a/core/src/main/java/org/apache/metamodel/membrane/app/InMemoryDataSourceRegistry.java +++ b/core/src/main/java/org/apache/metamodel/membrane/app/InMemoryDataSourceRegistry.java @@@ -63,11 -63,8 +63,15 @@@ public class InMemoryDataSourceRegistr } @Override + public void removeDataSource(String dataSourceName) throws NoSuchDataSourceException { + if (!dataSources.containsKey(dataSourceName)) { + throw new NoSuchDataSourceException(dataSourceName); + } + dataSources.remove(dataSourceName); + } + + 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/516a0539/core/src/main/java/org/apache/metamodel/membrane/app/registry/file/FileBasedDataSourceRegistry.java ---------------------------------------------------------------------- diff --cc core/src/main/java/org/apache/metamodel/membrane/app/registry/file/FileBasedDataSourceRegistry.java index ba1506c,7d49c6d..1a7759d --- 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 @@@ -120,19 -120,8 +120,23 @@@ public class FileBasedDataSourceRegistr } @Override + public void removeDataSource(String dataSourceName) throws NoSuchDataSourceException { + if (Strings.isNullOrEmpty(dataSourceName)) { + throw new IllegalArgumentException("DataSource name cannot be null or empty"); + } + final File file = getDataSourceFile(dataSourceName); + if (!file.exists()) { + throw new NoSuchDataSourceException(dataSourceName); + } + + final boolean deleted = file.delete(); + if (!deleted) { + throw new UncheckedIOException(new IOException("Unable to delete file: " + file)); + } + } + + 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/516a0539/core/src/main/java/org/apache/metamodel/membrane/controllers/DataSourceController.java ---------------------------------------------------------------------- diff --cc core/src/main/java/org/apache/metamodel/membrane/controllers/DataSourceController.java index ef1fe67,4f9fd55..1efcfed --- a/core/src/main/java/org/apache/metamodel/membrane/controllers/DataSourceController.java +++ b/core/src/main/java/org/apache/metamodel/membrane/controllers/DataSourceController.java @@@ -33,8 -33,8 +33,9 @@@ import org.apache.metamodel.factory.Dat 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.DeleteDatasourceResponse; import org.apache.metamodel.membrane.swagger.model.GetDatasourceResponse; import org.apache.metamodel.membrane.swagger.model.GetDatasourceResponseSchemas; import org.slf4j.Logger; @@@ -78,12 -75,21 +76,23 @@@ public class DataSourceController final DataContextProperties properties = new DataContextPropertiesImpl(map); - final String dataSourceIdentifier = 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); ++ final String dataSourceIdentifier = dataSourceRegistry.registerDataSource(dataSourceId, properties); - return get(tenantId, dataContextIdentifier); + logger.info("Created data source: {}/{}", tenantId, dataSourceIdentifier); + + return get(tenantId, dataSourceIdentifier); } @RequestMapping(method = RequestMethod.GET) http://git-wip-us.apache.org/repos/asf/metamodel-membrane/blob/516a0539/core/src/main/resources/swagger.yaml ---------------------------------------------------------------------- diff --cc core/src/main/resources/swagger.yaml index e15b60e,fa17ebf..37b64f8 --- a/core/src/main/resources/swagger.yaml +++ b/core/src/main/resources/swagger.yaml @@@ -116,14 -122,8 +122,16 @@@ paths description: Datasource created schema: $ref: "#/definitions/getDatasourceResponse" + delete: + responses: + 200: + description: Datasource deleted + schema: + $ref: "#/definitions/deleteDatasourceResponse" + 404: + description: Datasource not found + 400: + description: Datasource validation failed schema: $ref: "#/definitions/error" /{tenant}/{datasource}/q: