diff --git a/legend-engine-config/legend-engine-connection-integration-tests/pom.xml b/legend-engine-config/legend-engine-connection-integration-tests/pom.xml index 6953e8a064b..06744106c48 100644 --- a/legend-engine-config/legend-engine-connection-integration-tests/pom.xml +++ b/legend-engine-config/legend-engine-connection-integration-tests/pom.xml @@ -74,26 +74,7 @@ - - - - - - - - - - - - - - - - junit - junit - test - org.junit.jupiter junit-jupiter-api diff --git a/legend-engine-config/legend-engine-connection-integration-tests/src/test/java/org/finos/legend/engine/connection/test/AbstractConnectionFactoryTest.java b/legend-engine-config/legend-engine-connection-integration-tests/src/test/java/org/finos/legend/engine/connection/test/AbstractConnectionFactoryTest.java index 880898bb024..a72de8a4250 100644 --- a/legend-engine-config/legend-engine-connection-integration-tests/src/test/java/org/finos/legend/engine/connection/test/AbstractConnectionFactoryTest.java +++ b/legend-engine-config/legend-engine-connection-integration-tests/src/test/java/org/finos/legend/engine/connection/test/AbstractConnectionFactoryTest.java @@ -20,9 +20,10 @@ import org.finos.legend.connection.Authenticator; import org.finos.legend.connection.ConnectionFactory; import org.finos.legend.connection.DatabaseType; -import org.finos.legend.connection.EnvironmentConfiguration; import org.finos.legend.connection.IdentityFactory; import org.finos.legend.connection.IdentitySpecification; +import org.finos.legend.connection.InstrumentedStoreInstanceProvider; +import org.finos.legend.connection.LegendEnvironment; import org.finos.legend.connection.RelationalDatabaseStoreSupport; import org.finos.legend.connection.StoreInstance; import org.finos.legend.connection.impl.KerberosCredentialExtractor; @@ -41,8 +42,9 @@ public abstract class AbstractConnectionFactoryTest { protected static final String TEST_STORE_INSTANCE_NAME = "test-store"; - protected EnvironmentConfiguration environmentConfiguration; + protected LegendEnvironment environment; protected IdentityFactory identityFactory; + protected InstrumentedStoreInstanceProvider storeInstanceProvider; protected ConnectionFactory connectionFactory; @BeforeEach @@ -50,7 +52,7 @@ public void initialize() { this.setup(); - EnvironmentConfiguration.Builder environmentConfigurationBuilder = new EnvironmentConfiguration.Builder() + LegendEnvironment.Builder environmentBuilder = new LegendEnvironment.Builder() .withVaults( new SystemPropertiesCredentialVault(), new EnvironmentCredentialVault() @@ -82,15 +84,16 @@ public void initialize() CredentialVault credentialVault = this.getCredentialVault(); if (credentialVault != null) { - environmentConfigurationBuilder.withVault(credentialVault); + environmentBuilder.withVault(credentialVault); } - this.environmentConfiguration = environmentConfigurationBuilder.build(); + this.environment = environmentBuilder.build(); - this.identityFactory = new IdentityFactory.Builder(environmentConfiguration) + this.identityFactory = new IdentityFactory.Builder(this.environment) .build(); - this.connectionFactory = new ConnectionFactory.Builder(environmentConfiguration) + this.storeInstanceProvider = new InstrumentedStoreInstanceProvider(); + this.connectionFactory = new ConnectionFactory.Builder(this.environment, this.storeInstanceProvider) .withCredentialBuilders( new KerberosCredentialExtractor(), new UserPasswordCredentialBuilder(), @@ -129,12 +132,12 @@ public CredentialVault getCredentialVault() @Test public void runTest() throws Exception { - this.connectionFactory.injectStoreInstance(this.getStoreInstance()); + this.storeInstanceProvider.injectStoreInstance(this.getStoreInstance()); Identity identity = this.getIdentity(); AuthenticationConfiguration authenticationConfiguration = this.getAuthenticationConfiguration(); Authenticator authenticator = this.connectionFactory.getAuthenticator(identity, TEST_STORE_INSTANCE_NAME, authenticationConfiguration); - T connection = this.connectionFactory.getConnection(authenticator); + T connection = this.connectionFactory.getConnection(identity, authenticator); this.runTestWithConnection(connection); System.out.println("Successfully established and checked connection!"); diff --git a/legend-engine-config/legend-engine-connection-integration-tests/src/test/java/org/finos/legend/engine/connection/test/TestPostgresConnection.java b/legend-engine-config/legend-engine-connection-integration-tests/src/test/java/org/finos/legend/engine/connection/test/TestPostgresConnection.java index 1f92986d3e6..eef783ac898 100644 --- a/legend-engine-config/legend-engine-connection-integration-tests/src/test/java/org/finos/legend/engine/connection/test/TestPostgresConnection.java +++ b/legend-engine-config/legend-engine-connection-integration-tests/src/test/java/org/finos/legend/engine/connection/test/TestPostgresConnection.java @@ -30,7 +30,7 @@ import java.sql.Statement; import java.util.Properties; -import static org.junit.Assume.assumeTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; public class TestPostgresConnection { @@ -48,7 +48,7 @@ public void setup() } catch (Exception e) { - assumeTrue("Can't start PostgreSQLContainer", false); + assumeTrue(false, "Can't start PostgreSQLContainer"); } } @@ -77,7 +77,7 @@ public StoreInstance getStoreInstance() this.postgresContainer.getPort(), this.postgresContainer.getDatabaseName() ); - return new StoreInstance.Builder(this.environmentConfiguration) + return new StoreInstance.Builder(this.environment) .withIdentifier(TEST_STORE_INSTANCE_NAME) .withStoreSupportIdentifier("Postgres") .withAuthenticationMechanisms( diff --git a/legend-engine-config/legend-engine-connection-integration-tests/src/test/java/org/finos/legend/engine/connection/test/TestSnowflakeConnection.java b/legend-engine-config/legend-engine-connection-integration-tests/src/test/java/org/finos/legend/engine/connection/test/TestSnowflakeConnection.java index 2d522ff96d8..c95604ba9c6 100644 --- a/legend-engine-config/legend-engine-connection-integration-tests/src/test/java/org/finos/legend/engine/connection/test/TestSnowflakeConnection.java +++ b/legend-engine-config/legend-engine-connection-integration-tests/src/test/java/org/finos/legend/engine/connection/test/TestSnowflakeConnection.java @@ -29,14 +29,14 @@ import java.sql.Statement; import java.util.Properties; -import static org.junit.Assume.assumeTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; public class TestSnowflakeConnection { public static class WithKeyPair extends AbstractConnectionFactoryTest { - private static final String TEST_SNOWFLAKE_PK = "TEST_SNOWFLAKE_PK"; - private static final String TEST_SNOWFLAKE_PK_PASSPHRASE = "TEST_SNOWFLAKE_PK_PASSPHRASE"; + private static final String CONNECTION_INTEGRATION_TEST__SNOWFLAKE_PK = "CONNECTION_INTEGRATION_TEST__SNOWFLAKE_PK"; + private static final String CONNECTION_INTEGRATION_TEST__SNOWFLAKE_PK_PASSPHRASE = "CONNECTION_INTEGRATION_TEST__SNOWFLAKE_PK_PASSPHRASE"; private String snowflakePrivateKey; private String snowflakePassPhrase; @@ -45,12 +45,12 @@ public void setup() { try { - this.snowflakePrivateKey = this.environmentConfiguration.lookupVaultSecret(new EnvironmentCredentialVaultSecret(TEST_SNOWFLAKE_PK), null); - this.snowflakePassPhrase = this.environmentConfiguration.lookupVaultSecret(new EnvironmentCredentialVaultSecret(TEST_SNOWFLAKE_PK_PASSPHRASE), null); + this.snowflakePrivateKey = this.environment.lookupVaultSecret(new EnvironmentCredentialVaultSecret(CONNECTION_INTEGRATION_TEST__SNOWFLAKE_PK), null); + this.snowflakePassPhrase = this.environment.lookupVaultSecret(new EnvironmentCredentialVaultSecret(CONNECTION_INTEGRATION_TEST__SNOWFLAKE_PK_PASSPHRASE), null); } catch (Exception e) { - assumeTrue("Can't retrieve Snowflake test instance key-pair info (TEST_SNOWFLAKE_PK, TEST_SNOWFLAKE_PK_PASSPHRASE)", false); + assumeTrue(false, String.format("Can't retrieve Snowflake connection key-pair info (%s, %s environment variables are expected)", CONNECTION_INTEGRATION_TEST__SNOWFLAKE_PK, CONNECTION_INTEGRATION_TEST__SNOWFLAKE_PK_PASSPHRASE)); } } @@ -79,7 +79,7 @@ public StoreInstance getStoreInstance() connectionSpecification.region = "us-east-2"; connectionSpecification.cloudType = "aws"; connectionSpecification.role = "SUMMIT_DEV"; - return new StoreInstance.Builder(this.environmentConfiguration) + return new StoreInstance.Builder(this.environment) .withIdentifier(TEST_STORE_INSTANCE_NAME) .withStoreSupportIdentifier("Snowflake") .withAuthenticationMechanisms( diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/AuthenticationMechanismLoader.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/AuthenticationMechanismLoader.java deleted file mode 100644 index 377d2aa4656..00000000000 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/AuthenticationMechanismLoader.java +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2023 Goldman Sachs -// -// Licensed 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.finos.legend.connection; - -import org.finos.legend.connection.protocol.AuthenticationMechanism; - -import java.util.List; - -public interface AuthenticationMechanismLoader -{ - List getMechanisms(); -} diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/AuthenticationMechanismProvider.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/AuthenticationMechanismProvider.java deleted file mode 100644 index d9ad6a7195e..00000000000 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/AuthenticationMechanismProvider.java +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2023 Goldman Sachs -// -// Licensed 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.finos.legend.connection; - -import org.finos.legend.connection.protocol.AuthenticationMechanism; - -import java.util.List; - -public interface AuthenticationMechanismProvider -{ - List getLoaders(); -} diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/Authenticator.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/Authenticator.java index 85120be4ab4..71b949b1b80 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/Authenticator.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/Authenticator.java @@ -14,6 +14,8 @@ package org.finos.legend.connection; +import org.eclipse.collections.api.factory.Lists; +import org.eclipse.collections.api.list.ImmutableList; import org.finos.legend.connection.protocol.AuthenticationConfiguration; import org.finos.legend.engine.shared.core.identity.Credential; import org.finos.legend.engine.shared.core.identity.Identity; @@ -23,31 +25,28 @@ public class Authenticator { - private final Identity identity; private final StoreInstance storeInstance; private final AuthenticationConfiguration authenticationConfiguration; private final Class sourceCredentialType; - - private final List credentialBuilders; + private final ImmutableList credentialBuilders; private final ConnectionBuilder connectionBuilder; - public Authenticator(Identity identity, StoreInstance storeInstance, AuthenticationConfiguration authenticationConfiguration, Class sourceCredentialType, List credentialBuilders, ConnectionBuilder connectionBuilder) + public Authenticator(StoreInstance storeInstance, AuthenticationConfiguration authenticationConfiguration, Class sourceCredentialType, List credentialBuilders, ConnectionBuilder connectionBuilder) { - this.identity = identity; this.storeInstance = storeInstance; this.authenticationConfiguration = authenticationConfiguration; this.sourceCredentialType = sourceCredentialType; - this.credentialBuilders = credentialBuilders; + this.credentialBuilders = Lists.immutable.withAll(credentialBuilders); this.connectionBuilder = connectionBuilder; } - public Credential makeCredential(EnvironmentConfiguration configuration) throws Exception + public Credential makeCredential(Identity identity, LegendEnvironment environment) throws Exception { Credential credential = null; // no need to resolve the source credential if the flow starts with generic `Credential` node if (!this.sourceCredentialType.equals(Credential.class)) { - Optional credentialOptional = this.identity.getCredential((Class) this.sourceCredentialType); + Optional credentialOptional = identity.getCredential((Class) this.sourceCredentialType); if (!credentialOptional.isPresent()) { throw new RuntimeException(String.format("Can't resolve source credential of type '%s' from the specified identity", this.sourceCredentialType.getSimpleName())); @@ -59,7 +58,7 @@ public Credential makeCredential(EnvironmentConfiguration configuration) throws } for (CredentialBuilder credentialBuilder : this.credentialBuilders) { - credential = credentialBuilder.makeCredential(this.identity, this.authenticationConfiguration, credential, configuration); + credential = credentialBuilder.makeCredential(identity, this.authenticationConfiguration, credential, environment); } return credential; } @@ -79,7 +78,7 @@ public Class getSourceCredentialType() return sourceCredentialType; } - public List getCredentialBuilders() + public ImmutableList getCredentialBuilders() { return credentialBuilders; } diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/ConnectionBuilder.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/ConnectionBuilder.java index 2119dd37648..276c9d7a8af 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/ConnectionBuilder.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/ConnectionBuilder.java @@ -21,9 +21,9 @@ import java.lang.reflect.Type; import java.util.Objects; -public abstract class ConnectionBuilder +public abstract class ConnectionBuilder { - public abstract T getConnection(CRED credential, SPEC connectionSpecification, StoreInstance storeInstance) throws Exception; + public abstract CONNECTION getConnection(StoreInstance storeInstance, CRED credential) throws Exception; public Class getCredentialType() { @@ -42,6 +42,11 @@ private Type[] actualTypeArguments() return parameterizedType.getActualTypeArguments(); } + protected SPEC getCompatibleConnectionSpecification(StoreInstance storeInstance) + { + return (SPEC) storeInstance.getConnectionSpecification(this.getConnectionSpecificationType()); + } + public static class Key { private final Class connectionSpecificationType; diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/ConnectionFactory.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/ConnectionFactory.java index 4f9a88dde27..c90f266b041 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/ConnectionFactory.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/ConnectionFactory.java @@ -15,7 +15,6 @@ package org.finos.legend.connection; import org.eclipse.collections.api.factory.Lists; -import org.eclipse.collections.impl.utility.ListIterate; import org.finos.legend.connection.protocol.AuthenticationConfiguration; import org.finos.legend.connection.protocol.AuthenticationMechanism; import org.finos.legend.connection.protocol.ConnectionSpecification; @@ -39,14 +38,15 @@ public class ConnectionFactory { - private final EnvironmentConfiguration environmentConfiguration; + private final LegendEnvironment environment; + private final StoreInstanceProvider storeInstanceProvider; private final Map credentialBuildersIndex = new LinkedHashMap<>(); private final Map connectionBuildersIndex = new LinkedHashMap<>(); - private final Map storeInstancesIndex; - private ConnectionFactory(EnvironmentConfiguration environmentConfiguration, List credentialBuilders, List connectionBuilders, Map storeInstancesIndex) + private ConnectionFactory(LegendEnvironment environment, StoreInstanceProvider storeInstanceProvider, List credentialBuilders, List connectionBuilders) { - this.environmentConfiguration = environmentConfiguration; + this.environment = environment; + this.storeInstanceProvider = storeInstanceProvider; for (ConnectionBuilder builder : connectionBuilders) { this.connectionBuildersIndex.put(new ConnectionBuilder.Key(builder.getConnectionSpecificationType(), builder.getCredentialType()), builder); @@ -55,35 +55,16 @@ private ConnectionFactory(EnvironmentConfiguration environmentConfiguration, Lis { this.credentialBuildersIndex.put(new CredentialBuilder.Key(builder.getAuthenticationConfigurationType(), builder.getInputCredentialType(), builder.getOutputCredentialType()), builder); } - this.storeInstancesIndex = storeInstancesIndex; - } - - /** - * This method is meant for testing. - * The recommended usage is to include all the store instances during initialization - */ - public void injectStoreInstance(StoreInstance storeInstance) - { - if (this.storeInstancesIndex.containsKey(storeInstance.getIdentifier())) - { - throw new RuntimeException(String.format("Can't register store instance: found multiple store instances with identifier '%s'", storeInstance.getIdentifier())); - } - this.storeInstancesIndex.put(storeInstance.getIdentifier(), storeInstance); - } - - private StoreInstance findStoreInstance(String identifier) - { - return Objects.requireNonNull(this.storeInstancesIndex.get(identifier), String.format("Can't find store instance with identifier '%s'", identifier)); } public Authenticator getAuthenticator(Identity identity, String storeInstanceIdentifier, AuthenticationConfiguration authenticationConfiguration) { - return this.getAuthenticator(identity, this.findStoreInstance(storeInstanceIdentifier), authenticationConfiguration); + return this.getAuthenticator(identity, this.storeInstanceProvider.lookup(storeInstanceIdentifier), authenticationConfiguration); } public Authenticator getAuthenticator(Identity identity, StoreInstance storeInstance, AuthenticationConfiguration authenticationConfiguration) { - AuthenticationMechanism authenticationMechanism = environmentConfiguration.findAuthenticationMechanismForConfiguration(authenticationConfiguration); + AuthenticationMechanism authenticationMechanism = environment.findAuthenticationMechanismForConfiguration(authenticationConfiguration); String authenticationMechanismLabel = authenticationMechanism != null ? ("authentication mechanism '" + authenticationMechanism.getLabel() + "'") : ("authentication mechanism with configuration '" + authenticationConfiguration.getClass().getSimpleName() + "'"); if (!storeInstance.getAuthenticationConfigurationTypes().contains(authenticationConfiguration.getClass())) { @@ -103,24 +84,24 @@ public Authenticator getAuthenticator(Identity identity, StoreInstance storeInst storeInstance.getConnectionSpecification().getClass().getSimpleName()) ); } - return new Authenticator(identity, storeInstance, authenticationConfiguration, result.sourceCredentialType, result.flow, connectionBuildersIndex.get(new ConnectionBuilder.Key(storeInstance.getConnectionSpecification().getClass(), result.targetCredentialType))); + return new Authenticator(storeInstance, authenticationConfiguration, result.sourceCredentialType, result.flow, connectionBuildersIndex.get(new ConnectionBuilder.Key(storeInstance.getConnectionSpecification().getClass(), result.targetCredentialType))); } public Authenticator getAuthenticator(Identity identity, String storeInstanceIdentifier) { - return this.getAuthenticator(identity, this.findStoreInstance(storeInstanceIdentifier)); + return this.getAuthenticator(identity, this.storeInstanceProvider.lookup(storeInstanceIdentifier)); } public Authenticator getAuthenticator(Identity identity, StoreInstance storeInstance) { - List authenticationConfigurations = ListIterate.collect(storeInstance.getAuthenticationMechanisms(), AuthenticationMechanism::generateConfiguration).select(Objects::nonNull); + List authenticationConfigurations = storeInstance.getAuthenticationMechanisms().toList().collect(AuthenticationMechanism::generateConfiguration).select(Objects::nonNull); Authenticator authenticator = null; for (AuthenticationConfiguration authenticationConfiguration : authenticationConfigurations) { AuthenticationFlowResolver.ResolutionResult result = AuthenticationFlowResolver.run(this.credentialBuildersIndex, this.connectionBuildersIndex, identity, authenticationConfiguration, storeInstance.getConnectionSpecification()); if (result != null) { - authenticator = new Authenticator(identity, storeInstance, authenticationConfiguration, result.sourceCredentialType, result.flow, connectionBuildersIndex.get(new ConnectionBuilder.Key(storeInstance.getConnectionSpecification().getClass(), result.targetCredentialType))); + authenticator = new Authenticator(storeInstance, authenticationConfiguration, result.sourceCredentialType, result.flow, connectionBuildersIndex.get(new ConnectionBuilder.Key(storeInstance.getConnectionSpecification().getClass(), result.targetCredentialType))); break; } } @@ -128,7 +109,7 @@ public Authenticator getAuthenticator(Identity identity, StoreInstance storeInst { throw new RuntimeException(String.format("Can't get authenticator: no authentication flow for store '%s' can be resolved for the specified identity using auto-generated authentication configuration. Try specifying an authentication mechanism by providing a configuration of one of the following types:\n%s", storeInstance.getIdentifier(), - ListIterate.select(storeInstance.getAuthenticationMechanisms(), mechanism -> mechanism.generateConfiguration() == null).collect(mechanism -> "- " + mechanism.getAuthenticationConfigurationType().getSimpleName() + " (mechanism: " + mechanism.getLabel() + ")").makeString("\n") + storeInstance.getAuthenticationMechanisms().select(mechanism -> mechanism.generateConfiguration() == null).collect(mechanism -> "- " + mechanism.getAuthenticationConfigurationType().getSimpleName() + " (mechanism: " + mechanism.getLabel() + ")").makeString("\n") )); } return authenticator; @@ -177,7 +158,7 @@ private AuthenticationFlowResolver(Map .filter(builder -> builder.getAuthenticationConfigurationType().equals(authenticationConfiguration.getClass())) .forEach(builder -> { - if (!(builder instanceof CredentialExtractor)) + if (!(builder.getInputCredentialType().equals(builder.getOutputCredentialType()))) { this.processEdge(new FlowNode(builder.getInputCredentialType()), new FlowNode(builder.getOutputCredentialType())); } @@ -362,131 +343,92 @@ public ResolutionResult(List flow, Class T getConnection(Identity identity, StoreInstance storeInstance, AuthenticationConfiguration authenticationConfiguration) throws Exception { - return this.getConnection(this.getAuthenticator(identity, storeInstance, authenticationConfiguration)); + return this.getConnection(identity, this.getAuthenticator(identity, storeInstance, authenticationConfiguration)); } public T getConnection(Identity identity, String storeInstanceIdentifier, AuthenticationConfiguration authenticationConfiguration) throws Exception { - return this.getConnection(this.getAuthenticator(identity, storeInstanceIdentifier, authenticationConfiguration)); + return this.getConnection(identity, this.getAuthenticator(identity, storeInstanceIdentifier, authenticationConfiguration)); } public T getConnection(Identity identity, StoreInstance storeInstance) throws Exception { - return this.getConnection(this.getAuthenticator(identity, storeInstance)); + return this.getConnection(identity, this.getAuthenticator(identity, storeInstance)); } public T getConnection(Identity identity, String storeInstanceIdentifier) throws Exception { - return this.getConnection(this.getAuthenticator(identity, storeInstanceIdentifier)); + return this.getConnection(identity, this.getAuthenticator(identity, storeInstanceIdentifier)); } - public T getConnection(Authenticator authenticator) throws Exception + public T getConnection(Identity identity, Authenticator authenticator) throws Exception { - Credential credential = authenticator.makeCredential(this.environmentConfiguration); + Credential credential = authenticator.makeCredential(identity, this.environment); ConnectionBuilder flow = (ConnectionBuilder) authenticator.getConnectionBuilder(); - return flow.getConnection(credential, authenticator.getStoreInstance().getConnectionSpecification(), authenticator.getStoreInstance()); + return flow.getConnection(authenticator.getStoreInstance(), credential); } public static class Builder { - private final EnvironmentConfiguration environmentConfiguration; - private CredentialBuilderProvider credentialBuilderProvider; - private ConnectionBuilderProvider connectionBuilderProvider; - private final List> credentialBuilders = Lists.mutable.empty(); - private final List> connectionBuilders = Lists.mutable.empty(); - private final Map storeInstancesIndex = new HashMap<>(); - - public Builder(EnvironmentConfiguration environmentConfiguration) - { - this.environmentConfiguration = environmentConfiguration; - } + private final LegendEnvironment environment; + private final StoreInstanceProvider storeInstanceProvider; + private final List credentialBuilders = Lists.mutable.empty(); + private final List connectionBuilders = Lists.mutable.empty(); - public Builder withCredentialBuilderProvider(CredentialBuilderProvider provider) + public Builder(LegendEnvironment environment, StoreInstanceProvider storeInstanceProvider) { - this.credentialBuilderProvider = provider; - return this; - } - - public Builder withConnectionBuilderProvider(ConnectionBuilderProvider provider) - { - this.connectionBuilderProvider = provider; - return this; + this.environment = environment; + this.storeInstanceProvider = storeInstanceProvider; } - public Builder withCredentialBuilders(List> credentialBuilders) + public Builder withCredentialBuilders(List credentialBuilders) { this.credentialBuilders.addAll(credentialBuilders); return this; } - public Builder withCredentialBuilders(CredentialBuilder... credentialBuilders) + public Builder withCredentialBuilders(CredentialBuilder... credentialBuilders) { this.credentialBuilders.addAll(Lists.mutable.with(credentialBuilders)); return this; } - public Builder withCredentialBuilder(CredentialBuilder credentialBuilder) + public Builder withCredentialBuilder(CredentialBuilder credentialBuilder) { this.credentialBuilders.add(credentialBuilder); return this; } - public Builder withConnectionBuilders(List> connectionBuilders) + public Builder withConnectionBuilders(List connectionBuilders) { this.connectionBuilders.addAll(connectionBuilders); return this; } - public Builder withConnectionBuilders(ConnectionBuilder... connectionBuilders) + public Builder withConnectionBuilders(ConnectionBuilder... connectionBuilders) { this.connectionBuilders.addAll(Lists.mutable.with(connectionBuilders)); return this; } - public Builder withConnectionBuilder(ConnectionBuilder connectionBuilder) + public Builder withConnectionBuilder(ConnectionBuilder connectionBuilder) { this.connectionBuilders.add(connectionBuilder); return this; } - public Builder withStoreInstances(List storeInstances) - { - storeInstances.forEach(this::registerStoreInstance); - return this; - } - - public Builder withStoreInstance(StoreInstance storeInstance) - { - this.registerStoreInstance(storeInstance); - return this; - } - - private void registerStoreInstance(StoreInstance storeInstance) - { - if (this.storeInstancesIndex.containsKey(storeInstance.getIdentifier())) - { - throw new RuntimeException(String.format("Can't register store instance: found multiple store instances with identifier '%s'", storeInstance.getIdentifier())); - } - this.storeInstancesIndex.put(storeInstance.getIdentifier(), storeInstance); - } - public ConnectionFactory build() { - List credentialBuilders = this.credentialBuilderProvider != null ? this.credentialBuilderProvider.getBuilders() : Lists.mutable.empty(); - credentialBuilders.addAll(this.credentialBuilders); - List connectionBuilders = this.connectionBuilderProvider != null ? this.connectionBuilderProvider.getBuilders() : Lists.mutable.empty(); - connectionBuilders.addAll(this.connectionBuilders); - for (ConnectionManager connectionManager : ServiceLoader.load(ConnectionManager.class)) { connectionManager.initialize(); } return new ConnectionFactory( - this.environmentConfiguration, - credentialBuilders, - connectionBuilders, - this.storeInstancesIndex + this.environment, + this.storeInstanceProvider, + this.credentialBuilders, + this.connectionBuilders ); } } diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/CredentialBuilder.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/CredentialBuilder.java index 59239f8d311..0f4726abfd7 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/CredentialBuilder.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/CredentialBuilder.java @@ -22,9 +22,9 @@ import java.lang.reflect.Type; import java.util.Objects; -public abstract class CredentialBuilder +public abstract class CredentialBuilder { - public abstract OUTPUT_CRED makeCredential(Identity identity, SPEC spec, INPUT_CRED cred, EnvironmentConfiguration configuration) throws Exception; + public abstract OUTPUT_CRED makeCredential(Identity identity, CONFIG config, INPUT_CRED cred, LegendEnvironment environment) throws Exception; public Class getAuthenticationConfigurationType() { diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/CredentialExtractor.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/CredentialExtractor.java deleted file mode 100644 index d21f9ea5e5f..00000000000 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/CredentialExtractor.java +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2023 Goldman Sachs -// -// Licensed 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.finos.legend.connection; - -import org.finos.legend.connection.protocol.AuthenticationConfiguration; -import org.finos.legend.engine.shared.core.identity.Credential; -import org.finos.legend.engine.shared.core.identity.Identity; - -import java.util.Optional; - -public abstract class CredentialExtractor extends CredentialBuilder -{ - - @Override - public Class getOutputCredentialType() - { - return (Class) actualTypeArguments()[1]; - } - - @Override - public CRED makeCredential(Identity identity, SPEC spec, CRED cred, EnvironmentConfiguration configuration) throws Exception - { - Optional credentialOptional = identity.getCredential((Class) this.getOutputCredentialType()); - if (!credentialOptional.isPresent()) - { - throw new RuntimeException(String.format("Can't extract credential of type '%s' from the specified identity", this.getOutputCredentialType().getSimpleName())); - } - return credentialOptional.get(); - } -} diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/DefaultAuthenticationMechanismLoader.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/DefaultAuthenticationMechanismLoader.java deleted file mode 100644 index d099129b9b5..00000000000 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/DefaultAuthenticationMechanismLoader.java +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2023 Goldman Sachs -// -// Licensed 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.finos.legend.connection; - -import org.eclipse.collections.api.factory.Lists; -import org.finos.legend.connection.protocol.AuthenticationMechanism; -import org.finos.legend.connection.protocol.AuthenticationMechanismType; - -import java.util.List; - -public class DefaultAuthenticationMechanismLoader implements AuthenticationMechanismLoader -{ - @Override - public List getMechanisms() - { - return Lists.mutable.with(AuthenticationMechanismType.values()); - } -} diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/DefaultAuthenticationMechanismProvider.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/DefaultAuthenticationMechanismProvider.java deleted file mode 100644 index cc19a7b9174..00000000000 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/DefaultAuthenticationMechanismProvider.java +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2023 Goldman Sachs -// -// Licensed 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.finos.legend.connection; - -import org.eclipse.collections.api.factory.Lists; - -import java.util.List; -import java.util.ServiceLoader; - -public class DefaultAuthenticationMechanismProvider implements AuthenticationMechanismProvider -{ - @Override - public List getLoaders() - { - return Lists.mutable.withAll(ServiceLoader.load(AuthenticationMechanismLoader.class)); - } -} diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/DefaultConnectionBuilderProvider.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/DefaultConnectionBuilderProvider.java deleted file mode 100644 index e52a422658e..00000000000 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/DefaultConnectionBuilderProvider.java +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2023 Goldman Sachs -// -// Licensed 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.finos.legend.connection; - -import org.eclipse.collections.api.factory.Lists; - -import java.util.List; -import java.util.ServiceLoader; - -public class DefaultConnectionBuilderProvider implements ConnectionBuilderProvider -{ - @Override - public List getBuilders() - { - return Lists.mutable.withAll(ServiceLoader.load(ConnectionBuilder.class)); - } -} diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/DefaultCredentialBuilderProvider.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/DefaultCredentialBuilderProvider.java deleted file mode 100644 index 1d2bc6f769f..00000000000 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/DefaultCredentialBuilderProvider.java +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2023 Goldman Sachs -// -// Licensed 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.finos.legend.connection; - -import org.eclipse.collections.api.factory.Lists; - -import java.util.List; -import java.util.ServiceLoader; - -public class DefaultCredentialBuilderProvider implements CredentialBuilderProvider -{ - @Override - public List getBuilders() - { - return Lists.mutable.withAll(ServiceLoader.load(CredentialBuilder.class)); - } -} diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/DefaultStoreInstanceProvider.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/DefaultStoreInstanceProvider.java new file mode 100644 index 00000000000..4a914100c38 --- /dev/null +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/DefaultStoreInstanceProvider.java @@ -0,0 +1,89 @@ +// Copyright 2023 Goldman Sachs +// +// Licensed 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.finos.legend.connection; + +import org.eclipse.collections.api.factory.Lists; +import org.eclipse.collections.api.factory.Maps; +import org.eclipse.collections.api.map.ImmutableMap; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.ServiceLoader; + +public class DefaultStoreInstanceProvider implements StoreInstanceProvider +{ + private final ImmutableMap storeInstancesIndex; + + private DefaultStoreInstanceProvider(Map storeInstancesIndex) + { + + this.storeInstancesIndex = Maps.immutable.withAll(storeInstancesIndex); + } + + @Override + public StoreInstance lookup(String identifier) + { + return Objects.requireNonNull(this.storeInstancesIndex.get(identifier), String.format("Can't find store instance with identifier '%s'", identifier)); + } + + public static class Builder + { + private final Map storeInstancesIndex = new HashMap<>(); + + public Builder() + { + + } + + public Builder withStoreInstances(List storeInstances) + { + storeInstances.forEach(this::registerStoreInstance); + return this; + } + + public Builder withStoreInstances(StoreInstance... storeInstances) + { + Lists.mutable.with(storeInstances).forEach(this::registerStoreInstance); + return this; + } + + public Builder withStoreInstance(StoreInstance storeInstance) + { + this.registerStoreInstance(storeInstance); + return this; + } + + private void registerStoreInstance(StoreInstance storeInstance) + { + if (this.storeInstancesIndex.containsKey(storeInstance.getIdentifier())) + { + throw new RuntimeException(String.format("Can't register store instance: found multiple store instances with identifier '%s'", storeInstance.getIdentifier())); + } + this.storeInstancesIndex.put(storeInstance.getIdentifier(), storeInstance); + } + + public DefaultStoreInstanceProvider build() + { + for (ConnectionManager connectionManager : ServiceLoader.load(ConnectionManager.class)) + { + connectionManager.initialize(); + } + + return new DefaultStoreInstanceProvider(this.storeInstancesIndex); + } + } +} diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/IdentityFactory.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/IdentityFactory.java index 917f3996657..206f5e61162 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/IdentityFactory.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/IdentityFactory.java @@ -23,11 +23,11 @@ public class IdentityFactory { - private final EnvironmentConfiguration environmentConfiguration; + private final LegendEnvironment environment; - private IdentityFactory(EnvironmentConfiguration environmentConfiguration) + private IdentityFactory(LegendEnvironment environment) { - this.environmentConfiguration = environmentConfiguration; + this.environment = environment; } // TODO: @akphi - this clones the logic from IdentityFactoryProvider, we should @@ -46,16 +46,16 @@ public Identity createIdentity(IdentitySpecification identitySpecification) public static class Builder { - private final EnvironmentConfiguration environmentConfiguration; + private final LegendEnvironment environment; - public Builder(EnvironmentConfiguration environmentConfiguration) + public Builder(LegendEnvironment environment) { - this.environmentConfiguration = environmentConfiguration; + this.environment = environment; } public IdentityFactory build() { - return new IdentityFactory(this.environmentConfiguration); + return new IdentityFactory(this.environment); } } } diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/InstrumentedLegendEnvironment.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/InstrumentedLegendEnvironment.java new file mode 100644 index 00000000000..4cb67543747 --- /dev/null +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/InstrumentedLegendEnvironment.java @@ -0,0 +1,64 @@ +// Copyright 2023 Goldman Sachs +// +// Licensed 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.finos.legend.connection; + +import org.eclipse.collections.api.list.MutableList; +import org.eclipse.collections.api.map.MutableMap; +import org.finos.legend.authentication.vault.CredentialVault; +import org.finos.legend.connection.protocol.AuthenticationMechanism; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.authentication.vault.CredentialVaultSecret; + +import java.util.List; +import java.util.Map; + +/** + * This is the instrumented version of {@link LegendEnvironment} which is used for testing. + */ +public class InstrumentedLegendEnvironment extends LegendEnvironment +{ + protected final MutableList vaults; + protected final MutableMap, CredentialVault> vaultsIndex; + protected final MutableMap storeSupportsIndex; + + protected final MutableMap authenticationMechanismsIndex; + + protected InstrumentedLegendEnvironment(List vaults, Map storeSupportsIndex, Map authenticationMechanismsIndex) + { + super(vaults, storeSupportsIndex, authenticationMechanismsIndex); + this.vaults = super.vaults.toList(); + this.vaultsIndex = super.vaultsIndex.toMap(); + this.storeSupportsIndex = super.storeSupportsIndex.toMap(); + this.authenticationMechanismsIndex = super.authenticationMechanismsIndex.toMap(); + } + + public void injectVault(CredentialVault vault) + { + if (this.vaultsIndex.containsKey(vault.getSecretType())) + { + throw new RuntimeException(String.format("Can't register credential vault: found multiple vaults with secret type '%s'", vault.getSecretType().getSimpleName())); + } + this.vaultsIndex.put(vault.getSecretType(), vault); + this.vaults.add(vault); + } + + public void injectStoreSupport(StoreSupport storeSupport) + { + if (this.storeSupportsIndex.containsKey(storeSupport.getIdentifier())) + { + throw new RuntimeException(String.format("Can't register store support: found multiple store supports with identifier '%s'", storeSupport.getIdentifier())); + } + this.storeSupportsIndex.put(storeSupport.getIdentifier(), storeSupport); + } +} diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/InstrumentedStoreInstanceProvider.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/InstrumentedStoreInstanceProvider.java new file mode 100644 index 00000000000..19314be985d --- /dev/null +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/InstrumentedStoreInstanceProvider.java @@ -0,0 +1,43 @@ +// Copyright 2023 Goldman Sachs +// +// Licensed 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.finos.legend.connection; + +import org.eclipse.collections.api.factory.Maps; + +import java.util.Map; +import java.util.Objects; + +/** + * This is the instrumented version of {@link StoreInstanceProvider} which is used for testing. + */ +public class InstrumentedStoreInstanceProvider implements StoreInstanceProvider +{ + private final Map storeInstancesIndex = Maps.mutable.empty(); + + public void injectStoreInstance(StoreInstance storeInstance) + { + if (this.storeInstancesIndex.containsKey(storeInstance.getIdentifier())) + { + throw new RuntimeException(String.format("Can't register store instance: found multiple store instances with identifier '%s'", storeInstance.getIdentifier())); + } + this.storeInstancesIndex.put(storeInstance.getIdentifier(), storeInstance); + } + + @Override + public StoreInstance lookup(String identifier) + { + return Objects.requireNonNull(this.storeInstancesIndex.get(identifier), String.format("Can't find store instance with identifier '%s'", identifier)); + } +} diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/EnvironmentConfiguration.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/LegendEnvironment.java similarity index 69% rename from legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/EnvironmentConfiguration.java rename to legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/LegendEnvironment.java index c43c983f909..ed3ac3d345d 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/EnvironmentConfiguration.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/LegendEnvironment.java @@ -15,6 +15,9 @@ package org.finos.legend.connection; import org.eclipse.collections.api.factory.Lists; +import org.eclipse.collections.api.list.ImmutableList; +import org.eclipse.collections.api.map.ImmutableMap; +import org.eclipse.collections.api.map.MutableMap; import org.eclipse.collections.impl.factory.Maps; import org.eclipse.collections.impl.utility.ListIterate; import org.finos.legend.authentication.vault.CredentialVault; @@ -31,41 +34,28 @@ import java.util.Set; /** - * This is meant to the place we package common configs, such as vaults, - * that can be passed to various parts of engine, authentication, connection factory, etc. + * This is the runtime instance of configuration for Legend Engine, the place we package common configs, + * such as vaults, that can be passed to various parts of engine, authentication, connection factory, etc. */ -public class EnvironmentConfiguration +public class LegendEnvironment { - private final List vaults; - private final Map, CredentialVault> vaultsIndex; - private final Map storeSupportsIndex; + protected final ImmutableList vaults; + protected final ImmutableMap, CredentialVault> vaultsIndex; + protected final ImmutableMap storeSupportsIndex; - private final Map authenticationMechanismsIndex; + protected final ImmutableMap authenticationMechanismsIndex; - private EnvironmentConfiguration(List vaults, Map storeSupportsIndex, Map authenticationMechanismsIndex) + protected LegendEnvironment(List vaults, Map storeSupportsIndex, Map authenticationMechanismsIndex) { - this.vaults = Lists.mutable.withAll(vaults); - this.vaultsIndex = Maps.mutable.empty(); + this.vaults = Lists.immutable.withAll(vaults); + MutableMap, CredentialVault> vaultsIndex = Maps.mutable.empty(); for (CredentialVault vault : vaults) { vaultsIndex.put(vault.getSecretType(), vault); } - this.storeSupportsIndex = storeSupportsIndex; - this.authenticationMechanismsIndex = authenticationMechanismsIndex; - } - - /** - * This method is meant for testing. - * The recommended usage is to include all the vaults during initialization - */ - public void injectVault(CredentialVault vault) - { - if (this.vaultsIndex.containsKey(vault.getSecretType())) - { - throw new RuntimeException(String.format("Can't register credential vault: found multiple vaults with secret type '%s'", vault.getSecretType().getSimpleName())); - } - this.vaultsIndex.put(vault.getSecretType(), vault); - this.vaults.add(vault); + this.vaultsIndex = vaultsIndex.toImmutable(); + this.storeSupportsIndex = Maps.immutable.withAll(storeSupportsIndex); + this.authenticationMechanismsIndex = Maps.immutable.withAll(authenticationMechanismsIndex); } public String lookupVaultSecret(CredentialVaultSecret credentialVaultSecret, Identity identity) throws Exception @@ -79,19 +69,6 @@ public String lookupVaultSecret(CredentialVaultSecret credentialVaultSecret, Ide return vault.lookupSecret(credentialVaultSecret, identity); } - /** - * This method is meant for testing. - * The recommended usage is to include all the store supports during initialization - */ - public void injectStoreSupport(StoreSupport storeSupport) - { - if (this.storeSupportsIndex.containsKey(storeSupport.getIdentifier())) - { - throw new RuntimeException(String.format("Can't register store support: found multiple store supports with identifier '%s'", storeSupport.getIdentifier())); - } - this.storeSupportsIndex.put(storeSupport.getIdentifier(), storeSupport); - } - public StoreSupport findStoreSupport(String identifier) { return Objects.requireNonNull(this.storeSupportsIndex.get(identifier), String.format("Can't find store support with identifier '%s'", identifier)); @@ -106,7 +83,6 @@ public static class Builder { private final List vaults = Lists.mutable.empty(); private final Map storeSupportsIndex = new LinkedHashMap<>(); - private AuthenticationMechanismProvider authenticationMechanismProvider; private final Set authenticationMechanisms = new LinkedHashSet<>(); public Builder() @@ -159,12 +135,6 @@ private void registerStoreSupport(StoreSupport storeSupport) this.storeSupportsIndex.put(storeSupport.getIdentifier(), storeSupport); } - public Builder withAuthenticationMechanismProvider(AuthenticationMechanismProvider authenticationMechanismProvider) - { - this.authenticationMechanismProvider = authenticationMechanismProvider; - return this; - } - public Builder withAuthenticationMechanisms(List authenticationMechanisms) { this.authenticationMechanisms.addAll(authenticationMechanisms); @@ -184,12 +154,10 @@ public Builder withAuthenticationMechanism(AuthenticationMechanism authenticatio return this; } - public EnvironmentConfiguration build() + public LegendEnvironment build() { - List authenticationMechanisms = this.authenticationMechanismProvider != null ? ListIterate.flatCollect(this.authenticationMechanismProvider.getLoaders(), AuthenticationMechanismLoader::getMechanisms) : Lists.mutable.empty(); - authenticationMechanisms.addAll(this.authenticationMechanisms); Map authenticationMechanismsIndex = new LinkedHashMap<>(); - authenticationMechanisms.forEach(mechanism -> + this.authenticationMechanisms.forEach(mechanism -> { String key = mechanism.getAuthenticationConfigurationType().getSimpleName(); if (authenticationMechanismsIndex.containsKey(key)) @@ -212,7 +180,7 @@ public EnvironmentConfiguration build() authenticationMechanismsIndex.put(key, mechanism); }); - return new EnvironmentConfiguration(this.vaults, this.storeSupportsIndex, authenticationMechanismsIndex); + return new LegendEnvironment(this.vaults, this.storeSupportsIndex, authenticationMechanismsIndex); } } } diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/StoreInstance.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/StoreInstance.java index af25e716a92..cd409d5d996 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/StoreInstance.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/StoreInstance.java @@ -15,6 +15,7 @@ package org.finos.legend.connection; import org.eclipse.collections.api.factory.Lists; +import org.eclipse.collections.api.list.ImmutableList; import org.eclipse.collections.api.list.MutableList; import org.eclipse.collections.impl.utility.ListIterate; import org.finos.legend.connection.protocol.AuthenticationConfiguration; @@ -27,20 +28,23 @@ import java.util.Objects; import java.util.Set; +/** + * A StoreInstance represents a named instance of a Store. + */ public class StoreInstance { private final String identifier; private final StoreSupport storeSupport; - private final List authenticationMechanisms; - private final List> authenticationConfigurationTypes; + private final ImmutableList authenticationMechanisms; + private final ImmutableList> authenticationConfigurationTypes; private final ConnectionSpecification connectionSpecification; private StoreInstance(String identifier, StoreSupport storeSupport, List authenticationMechanisms, ConnectionSpecification connectionSpecification) { this.identifier = identifier; this.storeSupport = storeSupport; - this.authenticationMechanisms = authenticationMechanisms; - this.authenticationConfigurationTypes = ListIterate.collect(authenticationMechanisms, AuthenticationMechanism::getAuthenticationConfigurationType); + this.authenticationMechanisms = Lists.immutable.withAll(authenticationMechanisms); + this.authenticationConfigurationTypes = Lists.immutable.withAll(ListIterate.collect(authenticationMechanisms, AuthenticationMechanism::getAuthenticationConfigurationType)); this.connectionSpecification = connectionSpecification; } @@ -54,12 +58,12 @@ public StoreSupport getStoreSupport() return storeSupport; } - public List getAuthenticationMechanisms() + public ImmutableList getAuthenticationMechanisms() { return authenticationMechanisms; } - public List> getAuthenticationConfigurationTypes() + public ImmutableList> getAuthenticationConfigurationTypes() { return authenticationConfigurationTypes; } @@ -69,17 +73,26 @@ public ConnectionSpecification getConnectionSpecification() return connectionSpecification; } + public T getConnectionSpecification(Class clazz) + { + if (!this.connectionSpecification.getClass().equals(clazz)) + { + throw new RuntimeException(String.format("Can't get connection specification of type '%s' for store '%s'", clazz.getSimpleName(), this.identifier)); + } + return (T) this.connectionSpecification; + } + public static class Builder { - private final EnvironmentConfiguration environmentConfiguration; + private final LegendEnvironment environment; private String identifier; private String storeSupportIdentifier; private final Set authenticationMechanisms = new LinkedHashSet<>(); private ConnectionSpecification connectionSpecification; - public Builder(EnvironmentConfiguration environmentConfiguration) + public Builder(LegendEnvironment environment) { - this.environmentConfiguration = environmentConfiguration; + this.environment = environment; } public Builder withIdentifier(String identifier) @@ -120,7 +133,7 @@ public Builder withConnectionSpecification(ConnectionSpecification connectionSpe public StoreInstance build() { - StoreSupport storeSupport = this.environmentConfiguration.findStoreSupport(Objects.requireNonNull(this.storeSupportIdentifier, "Store instance store support identifier is required")); + StoreSupport storeSupport = this.environment.findStoreSupport(Objects.requireNonNull(this.storeSupportIdentifier, "Store instance store support identifier is required")); MutableList unsupportedAuthenticationMechanisms = ListIterate.select(new ArrayList<>(this.authenticationMechanisms), mechanism -> !storeSupport.getAuthenticationMechanisms().contains(mechanism)); if (!unsupportedAuthenticationMechanisms.isEmpty()) { @@ -130,7 +143,7 @@ public StoreInstance build() Objects.requireNonNull(this.identifier, "Store instance identifier is required"), storeSupport, // NOTE: if no mechanism is specified, it means the store instance supports all mechanisms - this.authenticationMechanisms.isEmpty() ? storeSupport.getAuthenticationMechanisms() : new ArrayList<>(this.authenticationMechanisms), + this.authenticationMechanisms.isEmpty() ? storeSupport.getAuthenticationMechanisms().toList() : new ArrayList<>(this.authenticationMechanisms), Objects.requireNonNull(this.connectionSpecification, "Store instance connection specification is required") ); } diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/CredentialBuilderProvider.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/StoreInstanceProvider.java similarity index 85% rename from legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/CredentialBuilderProvider.java rename to legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/StoreInstanceProvider.java index 51700704cb6..8b83db33c91 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/CredentialBuilderProvider.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/StoreInstanceProvider.java @@ -14,9 +14,7 @@ package org.finos.legend.connection; -import java.util.List; - -public interface CredentialBuilderProvider +public interface StoreInstanceProvider { - List getBuilders(); + StoreInstance lookup(String identifier); } diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/StoreSupport.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/StoreSupport.java index 982c6049507..89518bc4dde 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/StoreSupport.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/StoreSupport.java @@ -26,17 +26,21 @@ import java.util.Objects; import java.util.Set; +/** + * A StoreSupport describes the capabilities supported by a Store. + * For now, it describes the authentication mechanisms. + */ public class StoreSupport { private final String identifier; - private final List authenticationMechanisms; - private final List> authenticationConfigurationTypes; + private final ImmutableList authenticationMechanisms; + private final ImmutableList> authenticationConfigurationTypes; protected StoreSupport(String identifier, List authenticationMechanisms) { this.identifier = identifier; - this.authenticationMechanisms = authenticationMechanisms; - this.authenticationConfigurationTypes = ListIterate.collect(authenticationMechanisms, AuthenticationMechanism::getAuthenticationConfigurationType); + this.authenticationMechanisms = Lists.immutable.withAll(authenticationMechanisms); + this.authenticationConfigurationTypes = Lists.immutable.withAll(ListIterate.collect(authenticationMechanisms, AuthenticationMechanism::getAuthenticationConfigurationType)); } public String getIdentifier() @@ -44,7 +48,7 @@ public String getIdentifier() return identifier; } - public List getAuthenticationMechanisms() + public ImmutableList getAuthenticationMechanisms() { return authenticationMechanisms; } diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/impl/KerberosCredentialExtractor.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/impl/KerberosCredentialExtractor.java index 22499b65ad8..a36c3add1cc 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/impl/KerberosCredentialExtractor.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/impl/KerberosCredentialExtractor.java @@ -14,9 +14,23 @@ package org.finos.legend.connection.impl; -import org.finos.legend.connection.CredentialExtractor; +import org.finos.legend.connection.CredentialBuilder; +import org.finos.legend.connection.LegendEnvironment; +import org.finos.legend.engine.shared.core.identity.Identity; import org.finos.legend.engine.shared.core.identity.credential.LegendKerberosCredential; -public class KerberosCredentialExtractor extends CredentialExtractor +import java.util.Optional; + +public class KerberosCredentialExtractor extends CredentialBuilder { + @Override + public LegendKerberosCredential makeCredential(Identity identity, KerberosAuthenticationConfiguration authenticationConfiguration, LegendKerberosCredential credential, LegendEnvironment environment) throws Exception + { + Optional credentialOptional = identity.getCredential(LegendKerberosCredential.class); + if (!credentialOptional.isPresent()) + { + throw new RuntimeException(String.format("Can't extract credential of type '%s' from the specified identity", LegendKerberosCredential.class.getSimpleName())); + } + return credentialOptional.get(); + } } diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/impl/KeyPairCredentialBuilder.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/impl/KeyPairCredentialBuilder.java index da47ee7def9..46cc4ddc880 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/impl/KeyPairCredentialBuilder.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/impl/KeyPairCredentialBuilder.java @@ -25,7 +25,7 @@ import org.eclipse.collections.api.RichIterable; import org.eclipse.collections.impl.factory.Strings; import org.finos.legend.connection.CredentialBuilder; -import org.finos.legend.connection.EnvironmentConfiguration; +import org.finos.legend.connection.LegendEnvironment; import org.finos.legend.engine.shared.core.identity.Credential; import org.finos.legend.engine.shared.core.identity.Identity; import org.finos.legend.engine.shared.core.identity.credential.PrivateKeyCredential; @@ -42,10 +42,10 @@ public class KeyPairCredentialBuilder extends CredentialBuilder { @Override - public PrivateKeyCredential makeCredential(Identity identity, EncryptedPrivateKeyPairAuthenticationConfiguration authenticationConfiguration, Credential credential, EnvironmentConfiguration environmentConfiguration) throws Exception + public PrivateKeyCredential makeCredential(Identity identity, EncryptedPrivateKeyPairAuthenticationConfiguration authenticationConfiguration, Credential credential, LegendEnvironment environment) throws Exception { - String encryptedPrivateKey = environmentConfiguration.lookupVaultSecret(authenticationConfiguration.privateKey, identity); - String passphrase = environmentConfiguration.lookupVaultSecret(authenticationConfiguration.passphrase, identity); + String encryptedPrivateKey = environment.lookupVaultSecret(authenticationConfiguration.privateKey, identity); + String passphrase = environment.lookupVaultSecret(authenticationConfiguration.passphrase, identity); PrivateKey privateKey = this.getDecryptedPrivateKey(encryptedPrivateKey, passphrase); return new PrivateKeyCredential(authenticationConfiguration.userName, privateKey); } diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/impl/UserPasswordCredentialBuilder.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/impl/UserPasswordCredentialBuilder.java index 7739c6ca171..7cec18bd446 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/impl/UserPasswordCredentialBuilder.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/impl/UserPasswordCredentialBuilder.java @@ -15,7 +15,7 @@ package org.finos.legend.connection.impl; import org.finos.legend.connection.CredentialBuilder; -import org.finos.legend.connection.EnvironmentConfiguration; +import org.finos.legend.connection.LegendEnvironment; import org.finos.legend.engine.shared.core.identity.Credential; import org.finos.legend.engine.shared.core.identity.Identity; import org.finos.legend.engine.shared.core.identity.credential.PlaintextUserPasswordCredential; @@ -23,10 +23,10 @@ public class UserPasswordCredentialBuilder extends CredentialBuilder { @Override - public PlaintextUserPasswordCredential makeCredential(Identity identity, UserPasswordAuthenticationConfiguration authenticationConfiguration, Credential credential, EnvironmentConfiguration environmentConfiguration) throws Exception + public PlaintextUserPasswordCredential makeCredential(Identity identity, UserPasswordAuthenticationConfiguration authenticationConfiguration, Credential credential, LegendEnvironment environment) throws Exception { - String password = environmentConfiguration.lookupVaultSecret(authenticationConfiguration.password, identity); + String password = environment.lookupVaultSecret(authenticationConfiguration.password, identity); return new PlaintextUserPasswordCredential(authenticationConfiguration.username, password); } } diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/protocol/AuthenticationMechanism.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/protocol/AuthenticationMechanism.java index 284ac36c7f3..70f75d1f4fd 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/protocol/AuthenticationMechanism.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/java/org/finos/legend/connection/protocol/AuthenticationMechanism.java @@ -14,8 +14,6 @@ package org.finos.legend.connection.protocol; -import java.util.List; - public interface AuthenticationMechanism { String getLabel(); diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/resources/META-INF/services/org.finos.legend.connection.AuthenticationMechanismLoader b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/resources/META-INF/services/org.finos.legend.connection.AuthenticationMechanismLoader deleted file mode 100644 index f77e7b4a4ab..00000000000 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/resources/META-INF/services/org.finos.legend.connection.AuthenticationMechanismLoader +++ /dev/null @@ -1 +0,0 @@ -org.finos.legend.connection.DefaultAuthenticationMechanismLoader diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/resources/META-INF/services/org.finos.legend.connection.CredentialBuilder b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/resources/META-INF/services/org.finos.legend.connection.CredentialBuilder deleted file mode 100644 index 032f2e6497f..00000000000 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/main/resources/META-INF/services/org.finos.legend.connection.CredentialBuilder +++ /dev/null @@ -1,2 +0,0 @@ -org.finos.legend.connection.impl.UserPasswordCredentialBuilder -org.finos.legend.connection.impl.KerberosCredentialExtractor diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/test/java/org/finos/legend/connection/ConnectionFactoryTest.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/test/java/org/finos/legend/connection/ConnectionFactoryTest.java index d6bc8dbf398..6bf0b357a69 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/test/java/org/finos/legend/connection/ConnectionFactoryTest.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/test/java/org/finos/legend/connection/ConnectionFactoryTest.java @@ -24,38 +24,10 @@ import org.junit.Test; import java.util.List; +import java.util.Optional; public class ConnectionFactoryTest { - @Test - public void testStoreInstanceManagement() - { - TestEnv env = TestEnv.create(); - StoreInstance storeInstance = new StoreInstance.Builder(env.environmentConfiguration) - .withIdentifier("test-store") - .withStoreSupportIdentifier("test") - .withConnectionSpecification(new TestConnectionSpecification()) - .build(); - env.connectionFactory.injectStoreInstance(storeInstance); - - // failure - Exception exception; - - // error: store already registered - exception = Assert.assertThrows(RuntimeException.class, () -> - { - env.connectionFactory.injectStoreInstance(storeInstance); - }); - Assert.assertEquals("Can't register store instance: found multiple store instances with identifier 'test-store'", exception.getMessage()); - - // error: store not found - exception = Assert.assertThrows(RuntimeException.class, () -> - { - env.connectionFactory.getAuthenticator(new Identity("test"), "unknown"); - }); - Assert.assertEquals("Can't find store instance with identifier 'unknown'", exception.getMessage()); - } - @Test public void testGetConnection_WithFailures() throws Exception { @@ -75,28 +47,28 @@ public void testGetConnection_WithFailures() throws Exception Identity identity = new Identity("test"); // success - env.connectionFactory.getConnection(env.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_X())); + env.connectionFactory.getConnection(identity, env.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_X())); Exception exception; // error: store not found exception = Assert.assertThrows(RuntimeException.class, () -> { - env.connectionFactory.getConnection(env.connectionFactory.getAuthenticator(identity, "unknown", new AuthenticationConfiguration_X())); + env.connectionFactory.getConnection(identity, env.connectionFactory.getAuthenticator(identity, "unknown", new AuthenticationConfiguration_X())); }); Assert.assertEquals("Can't find store instance with identifier 'unknown'", exception.getMessage()); // error: unsupported authentication mechanism exception = Assert.assertThrows(RuntimeException.class, () -> { - env.connectionFactory.getConnection(env.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_Z())); + env.connectionFactory.getConnection(identity, env.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_Z())); }); Assert.assertEquals("Can't get authenticator: authentication mechanism 'Z' is not supported by store 'test'. Supported mechanism(s):\n- X (config: AuthenticationConfiguration_X)\n- Y (config: AuthenticationConfiguration_Y)", exception.getMessage()); // error: unresolvable authentication flow exception = Assert.assertThrows(RuntimeException.class, () -> { - env.connectionFactory.getConnection(env.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_Y())); + env.connectionFactory.getConnection(identity, env.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_Y())); }); Assert.assertEquals("Can't get authenticator: no authentication flow for store 'test' can be resolved for the specified identity using authentication mechanism 'Y' (authentication configuration: AuthenticationConfiguration_Y, connection specification: TestConnectionSpecification)", exception.getMessage()); @@ -114,14 +86,14 @@ public void testGetConnection_WithFailures() throws Exception // error: unsupported authentication mechanism exception = Assert.assertThrows(RuntimeException.class, () -> { - env2.connectionFactory.getConnection(env2.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_Z())); + env2.connectionFactory.getConnection(identity, env2.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_Z())); }); Assert.assertEquals("Can't get authenticator: authentication mechanism with configuration 'AuthenticationConfiguration_Z' is not supported by store 'test'. Supported mechanism(s):\n- X (config: AuthenticationConfiguration_X)\n- Y (config: AuthenticationConfiguration_Y)", exception.getMessage()); // error: unresolvable authentication flow exception = Assert.assertThrows(RuntimeException.class, () -> { - env2.connectionFactory.getConnection(env2.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_Y())); + env2.connectionFactory.getConnection(identity, env2.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_Y())); }); Assert.assertEquals("Can't get authenticator: no authentication flow for store 'test' can be resolved for the specified identity using authentication mechanism with configuration 'AuthenticationConfiguration_Y' (authentication configuration: AuthenticationConfiguration_Y, connection specification: TestConnectionSpecification)", exception.getMessage()); } @@ -149,7 +121,7 @@ public void testGetConnection_WithSimpleFlow() throws Exception Identity identity = new Identity("test"); Authenticator authenticator = env.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_X()); - assertAuthenticator(env.connectionFactory, authenticator, Credential.class, Lists.mutable.with( + assertAuthenticator(identity, env.connectionFactory, authenticator, Credential.class, Lists.mutable.with( "Credential->Credential_A [AuthenticationConfiguration_X]" ), ConnectionBuilder_A.class); } @@ -177,7 +149,7 @@ public void testGetConnection_WithSpecificBuilderOrder() throws Exception Identity identity = new Identity("test"); Authenticator authenticator = env.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_X()); - assertAuthenticator(env.connectionFactory, authenticator, Credential.class, Lists.mutable.with( + assertAuthenticator(identity, env.connectionFactory, authenticator, Credential.class, Lists.mutable.with( "Credential->Credential_B [AuthenticationConfiguration_X]" ), ConnectionBuilder_B.class); } @@ -204,7 +176,7 @@ public void testGetConnection_WithChainFlow() throws Exception Identity identity = new Identity("test"); Authenticator authenticator = env.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_X()); - assertAuthenticator(env.connectionFactory, authenticator, Credential.class, Lists.mutable.with( + assertAuthenticator(identity, env.connectionFactory, authenticator, Credential.class, Lists.mutable.with( "Credential->Credential_A [AuthenticationConfiguration_X]", "Credential_A->Credential_B [AuthenticationConfiguration_X]", "Credential_B->Credential_C [AuthenticationConfiguration_X]" @@ -233,7 +205,7 @@ public void testGetConnection_WithShortestFlowResolved() throws Exception Identity identity = new Identity("test", new Credential_B()); Authenticator authenticator = env.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_X()); - assertAuthenticator(env.connectionFactory, authenticator, Credential_B.class, Lists.mutable.with( + assertAuthenticator(identity, env.connectionFactory, authenticator, Credential_B.class, Lists.mutable.with( "Credential_B->Credential_C [AuthenticationConfiguration_X]" ), ConnectionBuilder_C.class); } @@ -263,7 +235,7 @@ public void testGetConnection_WithNoAuthConfigProvided() throws Exception // success Authenticator authenticator = env.connectionFactory.getAuthenticator(identity, "test"); - assertAuthenticator(env.connectionFactory, authenticator, Credential_A.class, Lists.mutable.with( + assertAuthenticator(identity, env.connectionFactory, authenticator, Credential_A.class, Lists.mutable.with( "Credential_A->Credential_B [AuthenticationConfiguration_Y]" ), ConnectionBuilder_B.class); @@ -295,7 +267,7 @@ public void testGetConnection_WithCredentialExtractor() throws Exception Identity identity = new Identity("test", new Credential_A()); Authenticator authenticator = env.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_X()); - assertAuthenticator(env.connectionFactory, authenticator, Credential_A.class, Lists.mutable.with( + assertAuthenticator(identity, env.connectionFactory, authenticator, Credential_A.class, Lists.mutable.with( "Credential_A->Credential_A [AuthenticationConfiguration_X]" ), ConnectionBuilder_A.class); @@ -313,7 +285,7 @@ public void testGetConnection_WithCredentialExtractor() throws Exception ).newStore("test", Lists.mutable.empty()); authenticator = env2.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_X()); - assertAuthenticator(env2.connectionFactory, authenticator, Credential_A.class, Lists.mutable.with( + assertAuthenticator(identity, env2.connectionFactory, authenticator, Credential_A.class, Lists.mutable.with( "Credential_A->Credential_A [AuthenticationConfiguration_X]" ), ConnectionBuilder_A.class); } @@ -340,35 +312,36 @@ public void testGetConnection_WithoutCredentialExtractor() throws Exception Identity identity = new Identity("test", new Credential_A()); Exception exception = Assert.assertThrows(RuntimeException.class, () -> { - env.connectionFactory.getConnection(env.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_X())); + env.connectionFactory.getConnection(identity, env.connectionFactory.getAuthenticator(identity, "test", new AuthenticationConfiguration_X())); }); Assert.assertEquals("Can't get authenticator: no authentication flow for store 'test' can be resolved for the specified identity using authentication mechanism 'X' (authentication configuration: AuthenticationConfiguration_X, connection specification: TestConnectionSpecification)", exception.getMessage()); } - private void assertAuthenticator(ConnectionFactory connectionFactory, Authenticator authenticator, Class sourceCredentialType, List credentialBuilders, Class connectionBuilderType) throws Exception + private void assertAuthenticator(Identity identity, ConnectionFactory connectionFactory, Authenticator authenticator, Class sourceCredentialType, List credentialBuilders, Class connectionBuilderType) throws Exception { Assert.assertEquals(sourceCredentialType, authenticator.getSourceCredentialType()); Assert.assertEquals(connectionBuilderType, authenticator.getConnectionBuilder().getClass()); Assert.assertArrayEquals(credentialBuilders.toArray(), authenticator.getCredentialBuilders().stream().map(builder -> String.format("%s->%s [%s]", builder.getInputCredentialType().getSimpleName(), builder.getOutputCredentialType().getSimpleName(), builder.getAuthenticationConfigurationType().getSimpleName())).toArray()); - connectionFactory.getConnection(authenticator); + connectionFactory.getConnection(identity, authenticator); } private static class TestEnv { - final EnvironmentConfiguration environmentConfiguration; + final LegendEnvironment environment; + final InstrumentedStoreInstanceProvider storeInstanceProvider; final ConnectionFactory connectionFactory; - private TestEnv(List> credentialBuilders, List> connectionBuilders, List authenticationMechanisms, List supportedAuthenticationMechanisms) + private TestEnv(List credentialBuilders, List connectionBuilders, List authenticationMechanisms, List supportedAuthenticationMechanisms) { - this.environmentConfiguration = new EnvironmentConfiguration.Builder() + this.environment = new LegendEnvironment.Builder() .withStoreSupport(new StoreSupport.Builder() .withIdentifier("test") .withAuthenticationMechanisms(supportedAuthenticationMechanisms) .build()) .withAuthenticationMechanisms(authenticationMechanisms) .build(); - - this.connectionFactory = new ConnectionFactory.Builder(environmentConfiguration) + this.storeInstanceProvider = new InstrumentedStoreInstanceProvider(); + this.connectionFactory = new ConnectionFactory.Builder(this.environment, this.storeInstanceProvider) .withCredentialBuilders(credentialBuilders) .withConnectionBuilders(connectionBuilders) .build(); @@ -376,7 +349,7 @@ private TestEnv(List> credentialBuilders, List authenticationMechanisms) { - this.connectionFactory.injectStoreInstance(new StoreInstance.Builder(environmentConfiguration) + this.storeInstanceProvider.injectStoreInstance(new StoreInstance.Builder(this.environment) .withIdentifier(identifier) .withStoreSupportIdentifier("test") .withAuthenticationMechanisms(authenticationMechanisms) @@ -390,12 +363,12 @@ static TestEnv create() return new TestEnv(Lists.mutable.empty(), Lists.mutable.empty(), Lists.mutable.empty(), Lists.mutable.empty()); } - static TestEnv create(List> credentialBuilders, List> connectionBuilders, List authenticationMechanisms, List supportedAuthenticationMechanisms) + static TestEnv create(List credentialBuilders, List connectionBuilders, List authenticationMechanisms, List supportedAuthenticationMechanisms) { return new TestEnv(credentialBuilders, connectionBuilders, authenticationMechanisms, supportedAuthenticationMechanisms); } - static TestEnv create(List> credentialBuilders, List> connectionBuilders, List supportedAuthenticationMechanisms) + static TestEnv create(List credentialBuilders, List connectionBuilders, List supportedAuthenticationMechanisms) { return new TestEnv(credentialBuilders, connectionBuilders, Lists.mutable.with( TestAuthenticationMechanismType.X, @@ -476,7 +449,7 @@ public String getLabel() private static class CredentialBuilder_A_to_A__withX extends CredentialBuilder { @Override - public Credential_A makeCredential(Identity identity, AuthenticationConfiguration_X authenticationConfiguration, Credential_A credential, EnvironmentConfiguration configuration) throws Exception + public Credential_A makeCredential(Identity identity, AuthenticationConfiguration_X authenticationConfiguration, Credential_A credential, LegendEnvironment environment) throws Exception { return new Credential_A(); } @@ -485,7 +458,7 @@ public Credential_A makeCredential(Identity identity, AuthenticationConfiguratio private static class CredentialBuilder_A_to_B__withX extends CredentialBuilder { @Override - public Credential_B makeCredential(Identity identity, AuthenticationConfiguration_X authenticationConfiguration, Credential_A credential, EnvironmentConfiguration configuration) throws Exception + public Credential_B makeCredential(Identity identity, AuthenticationConfiguration_X authenticationConfiguration, Credential_A credential, LegendEnvironment environment) throws Exception { return new Credential_B(); } @@ -494,7 +467,7 @@ public Credential_B makeCredential(Identity identity, AuthenticationConfiguratio private static class CredentialBuilder_B_to_C__withX extends CredentialBuilder { @Override - public Credential_C makeCredential(Identity identity, AuthenticationConfiguration_X authenticationConfiguration, Credential_B credential, EnvironmentConfiguration configuration) throws Exception + public Credential_C makeCredential(Identity identity, AuthenticationConfiguration_X authenticationConfiguration, Credential_B credential, LegendEnvironment environment) throws Exception { return new Credential_C(); } @@ -503,7 +476,7 @@ public Credential_C makeCredential(Identity identity, AuthenticationConfiguratio private static class CredentialBuilder_Any_to_A__withX extends CredentialBuilder { @Override - public Credential_A makeCredential(Identity identity, AuthenticationConfiguration_X authenticationConfiguration, Credential credential, EnvironmentConfiguration configuration) throws Exception + public Credential_A makeCredential(Identity identity, AuthenticationConfiguration_X authenticationConfiguration, Credential credential, LegendEnvironment environment) throws Exception { return new Credential_A(); } @@ -512,7 +485,7 @@ public Credential_A makeCredential(Identity identity, AuthenticationConfiguratio private static class CredentialBuilder_A_to_B__withY extends CredentialBuilder { @Override - public Credential_B makeCredential(Identity identity, AuthenticationConfiguration_Y authenticationConfiguration, Credential_A credential, EnvironmentConfiguration configuration) throws Exception + public Credential_B makeCredential(Identity identity, AuthenticationConfiguration_Y authenticationConfiguration, Credential_A credential, LegendEnvironment environment) throws Exception { return new Credential_B(); } @@ -521,14 +494,25 @@ public Credential_B makeCredential(Identity identity, AuthenticationConfiguratio private static class CredentialBuilder_Any_to_B__withX extends CredentialBuilder { @Override - public Credential_B makeCredential(Identity identity, AuthenticationConfiguration_X authenticationConfigurationX, Credential credential, EnvironmentConfiguration configuration) throws Exception + public Credential_B makeCredential(Identity identity, AuthenticationConfiguration_X authenticationConfigurationX, Credential credential, LegendEnvironment environment) throws Exception { return new Credential_B(); } } - private static class CredentialExtractor_A__withX extends CredentialExtractor + private static class CredentialExtractor_A__withX extends CredentialBuilder { + @Override + public Credential_A makeCredential(Identity identity, AuthenticationConfiguration_X authenticationConfiguration, Credential_A credential, LegendEnvironment environment) throws Exception + { + + Optional credentialOptional = identity.getCredential(Credential_A.class); + if (!credentialOptional.isPresent()) + { + throw new RuntimeException(""); + } + return credentialOptional.get(); + } } // -------------------------- Connection ------------------------------- @@ -540,7 +524,7 @@ private static class TestConnectionSpecification extends ConnectionSpecification private static class ConnectionBuilder_A extends ConnectionBuilder { @Override - public Object getConnection(Credential_A credential, TestConnectionSpecification connectionSpecification, StoreInstance storeInstance) throws Exception + public Object getConnection(StoreInstance storeInstance, Credential_A credential) throws Exception { return null; } @@ -549,7 +533,7 @@ public Object getConnection(Credential_A credential, TestConnectionSpecification private static class ConnectionBuilder_B extends ConnectionBuilder { @Override - public Object getConnection(Credential_B credential, TestConnectionSpecification connectionSpecification, StoreInstance storeInstance) throws Exception + public Object getConnection(StoreInstance storeInstance, Credential_B credential) throws Exception { return null; } @@ -558,7 +542,7 @@ public Object getConnection(Credential_B credential, TestConnectionSpecification private static class ConnectionBuilder_C extends ConnectionBuilder { @Override - public Object getConnection(Credential_C credential, TestConnectionSpecification connectionSpecification, StoreInstance storeInstance) throws Exception + public Object getConnection(StoreInstance storeInstance, Credential_C credential) throws Exception { return null; } diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/test/java/org/finos/legend/connection/EnvironmentConfigurationTest.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/test/java/org/finos/legend/connection/LegendEnvironmentTest.java similarity index 96% rename from legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/test/java/org/finos/legend/connection/EnvironmentConfigurationTest.java rename to legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/test/java/org/finos/legend/connection/LegendEnvironmentTest.java index b06d773479a..2ff1f49db9c 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/test/java/org/finos/legend/connection/EnvironmentConfigurationTest.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/test/java/org/finos/legend/connection/LegendEnvironmentTest.java @@ -20,13 +20,13 @@ import org.junit.Assert; import org.junit.Test; -public class EnvironmentConfigurationTest +public class LegendEnvironmentTest { @Test public void testValidateBuilder() { // success - new EnvironmentConfiguration.Builder() + new LegendEnvironment.Builder() .withAuthenticationMechanisms(Lists.mutable.of( TestAuthenticationMechanismType.X, TestAuthenticationMechanismType.Y @@ -37,7 +37,7 @@ public void testValidateBuilder() // failure: found invalid mechanism exception = Assert.assertThrows(RuntimeException.class, () -> { - new EnvironmentConfiguration.Builder() + new LegendEnvironment.Builder() .withAuthenticationMechanisms(Lists.mutable.of( TestAuthenticationMechanismType.X, TestAuthenticationMechanismType.Y, @@ -49,7 +49,7 @@ public void testValidateBuilder() // failure: found conflicting mechanisms exception = Assert.assertThrows(RuntimeException.class, () -> { - new EnvironmentConfiguration.Builder() + new LegendEnvironment.Builder() .withAuthenticationMechanisms(Lists.mutable.of( TestAuthenticationMechanismType.X, TestAuthenticationMechanismType.Y, diff --git a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/test/java/org/finos/legend/connection/StoreSupportTest.java b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/test/java/org/finos/legend/connection/StoreSupportTest.java index 18a13ab84a7..d82b88c99c8 100644 --- a/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/test/java/org/finos/legend/connection/StoreSupportTest.java +++ b/legend-engine-xts-authentication/legend-engine-xt-authentication-connection-factory/src/test/java/org/finos/legend/connection/StoreSupportTest.java @@ -43,7 +43,7 @@ public void testValidateStoreSupportBuilder() @Test public void testValidateStoreInstanceBuilder() { - EnvironmentConfiguration environmentConfiguration = new EnvironmentConfiguration.Builder() + LegendEnvironment environment = new LegendEnvironment.Builder() .withStoreSupport(new StoreSupport.Builder() .withIdentifier("test") .withAuthenticationMechanisms( @@ -54,7 +54,7 @@ public void testValidateStoreInstanceBuilder() .build(); // success - StoreInstance testStore = new StoreInstance.Builder(environmentConfiguration) + StoreInstance testStore = new StoreInstance.Builder(environment) .withIdentifier("test-store") .withStoreSupportIdentifier("test") .withAuthenticationMechanisms(AuthenticationMechanismType.USER_PASSWORD) @@ -63,7 +63,7 @@ public void testValidateStoreInstanceBuilder() Assert.assertArrayEquals(new AuthenticationMechanism[]{AuthenticationMechanismType.USER_PASSWORD}, testStore.getAuthenticationMechanisms().toArray()); // make sure if no auth mechanisms is specified, all mechanisms will be supported - StoreInstance testStore2 = new StoreInstance.Builder(environmentConfiguration) + StoreInstance testStore2 = new StoreInstance.Builder(environment) .withIdentifier("test-store") .withStoreSupportIdentifier("test") .withConnectionSpecification(new TestConnectionSpecification()) @@ -75,7 +75,7 @@ public void testValidateStoreInstanceBuilder() exception = Assert.assertThrows(RuntimeException.class, () -> { - new StoreInstance.Builder(environmentConfiguration) + new StoreInstance.Builder(environment) .withIdentifier("test-store") .withStoreSupportIdentifier("test") .build(); @@ -84,7 +84,7 @@ public void testValidateStoreInstanceBuilder() exception = Assert.assertThrows(RuntimeException.class, () -> { - new StoreInstance.Builder(environmentConfiguration) + new StoreInstance.Builder(environment) .withIdentifier("test-store") .withStoreSupportIdentifier("test") .withAuthenticationMechanisms(AuthenticationMechanismType.API_KEY) @@ -97,4 +97,43 @@ public void testValidateStoreInstanceBuilder() private static class TestConnectionSpecification extends ConnectionSpecification { } + + @Test + public void testStoreInstanceManagement() + { + LegendEnvironment environment = new LegendEnvironment.Builder() + .withStoreSupport(new StoreSupport.Builder() + .withIdentifier("test") + .withAuthenticationMechanisms( + AuthenticationMechanismType.USER_PASSWORD, + AuthenticationMechanismType.KERBEROS + ) + .build()) + .build(); + + StoreInstance storeInstance = new StoreInstance.Builder(environment) + .withIdentifier("test-store") + .withStoreSupportIdentifier("test") + .withConnectionSpecification(new TestConnectionSpecification()) + .build(); + + StoreInstanceProvider storeInstanceProvider = new DefaultStoreInstanceProvider.Builder().withStoreInstance(storeInstance).build(); + + // failure + Exception exception; + + // error: store already registered + exception = Assert.assertThrows(RuntimeException.class, () -> + { + new DefaultStoreInstanceProvider.Builder().withStoreInstances(storeInstance, storeInstance).build(); + }); + Assert.assertEquals("Can't register store instance: found multiple store instances with identifier 'test-store'", exception.getMessage()); + + // error: store not found + exception = Assert.assertThrows(RuntimeException.class, () -> + { + storeInstanceProvider.lookup("unknown"); + }); + Assert.assertEquals("Can't find store instance with identifier 'unknown'", exception.getMessage()); + } } diff --git a/legend-engine-xts-data-push/legend-engine-xt-data-push-server/src/main/java/org/finos/legend/engine/datapush/server/ConnectionFactoryBundle.java b/legend-engine-xts-data-push/legend-engine-xt-data-push-server/src/main/java/org/finos/legend/engine/datapush/server/ConnectionFactoryBundle.java index 51bbcec8268..77c70b13c14 100644 --- a/legend-engine-xts-data-push/legend-engine-xt-data-push-server/src/main/java/org/finos/legend/engine/datapush/server/ConnectionFactoryBundle.java +++ b/legend-engine-xts-data-push/legend-engine-xt-data-push-server/src/main/java/org/finos/legend/engine/datapush/server/ConnectionFactoryBundle.java @@ -23,12 +23,11 @@ import org.finos.legend.authentication.vault.impl.SystemPropertiesCredentialVault; import org.finos.legend.connection.ConnectionFactory; import org.finos.legend.connection.DatabaseType; -import org.finos.legend.connection.DefaultAuthenticationMechanismProvider; -import org.finos.legend.connection.DefaultConnectionBuilderProvider; -import org.finos.legend.connection.DefaultCredentialBuilderProvider; -import org.finos.legend.connection.EnvironmentConfiguration; +import org.finos.legend.connection.DefaultStoreInstanceProvider; +import org.finos.legend.connection.LegendEnvironment; import org.finos.legend.connection.IdentityFactory; import org.finos.legend.connection.RelationalDatabaseStoreSupport; +import org.finos.legend.connection.StoreInstanceProvider; import org.finos.legend.connection.protocol.AuthenticationMechanismType; import java.util.List; @@ -36,8 +35,9 @@ public class ConnectionFactoryBundle implements ConfiguredBundle { - private static EnvironmentConfiguration environmentConfiguration; + private static LegendEnvironment environment; private static IdentityFactory identityFactory; + private static StoreInstanceProvider storeInstanceProvider; private static ConnectionFactory connectionFactory; private final List credentialVaults; private final Function configSupplier; @@ -56,7 +56,7 @@ public void initialize(Bootstrap bootstrap) @Override public void run(C configuration, Environment environment) { - environmentConfiguration = new EnvironmentConfiguration.Builder() + ConnectionFactoryBundle.environment = new LegendEnvironment.Builder() // TODO: @akphi - add a property credential vault and load its content up from the config // .withVault(propertiesFileCredentialVault) .withVault(new SystemPropertiesCredentialVault()) @@ -68,27 +68,28 @@ public void run(C configuration, Environment environment) .withAuthenticationMechanisms( AuthenticationMechanismType.USER_PASSWORD ).build()) - .withAuthenticationMechanismProvider(new DefaultAuthenticationMechanismProvider()) // can also use service loader .build(); - identityFactory = new IdentityFactory.Builder(environmentConfiguration) + identityFactory = new IdentityFactory.Builder(ConnectionFactoryBundle.environment) .build(); - connectionFactory = new ConnectionFactory.Builder(environmentConfiguration) - .withCredentialBuilderProvider(new DefaultCredentialBuilderProvider()) // can also use service loader - .withConnectionBuilderProvider(new DefaultConnectionBuilderProvider()) // can also use service loader + storeInstanceProvider = new DefaultStoreInstanceProvider.Builder().build(); + + connectionFactory = new ConnectionFactory.Builder(ConnectionFactoryBundle.environment, storeInstanceProvider) +// .withCredentialBuilderProvider(new DefaultCredentialBuilderProvider()) // can also use service loader +// .withConnectionBuilderProvider(new DefaultConnectionBuilderProvider()) // can also use service loader .build(); // TODO: register store instances } - public static EnvironmentConfiguration getEnvironmentConfiguration() + public static LegendEnvironment getEnvironment() { - if (environmentConfiguration == null) + if (environment == null) { throw new IllegalStateException("Environment configuration has not been set!"); } - return environmentConfiguration; + return environment; } public static IdentityFactory getIdentityFactory() diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-connection/src/main/java/org/finos/legend/connection/jdbc/JDBCConnectionManager.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-connection/src/main/java/org/finos/legend/connection/jdbc/JDBCConnectionManager.java index 12a48d2611f..9ee1c8cac2f 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-connection/src/main/java/org/finos/legend/connection/jdbc/JDBCConnectionManager.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-connection/src/main/java/org/finos/legend/connection/jdbc/JDBCConnectionManager.java @@ -27,7 +27,7 @@ * We probably need to have a mechanism to control the connection pool * We cloned DatabaseManager from relational executor, we should consider if we can eventually unify these 2 */ -public class JDBCConnectionManager implements ConnectionManager +public final class JDBCConnectionManager implements ConnectionManager { private static final ConcurrentHashMap driversByName = ConcurrentHashMap.newMap(); private static final AtomicBoolean isInitialized = new AtomicBoolean(); diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-connection/src/main/java/org/finos/legend/connection/jdbc/StaticJDBCConnectionBuilder.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-connection/src/main/java/org/finos/legend/connection/jdbc/StaticJDBCConnectionBuilder.java index c5068467bef..0dce38fbbdd 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-connection/src/main/java/org/finos/legend/connection/jdbc/StaticJDBCConnectionBuilder.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-connection/src/main/java/org/finos/legend/connection/jdbc/StaticJDBCConnectionBuilder.java @@ -29,9 +29,10 @@ public class StaticJDBCConnectionBuilder { public static class WithPlaintextUsernamePassword extends ConnectionBuilder { - public Connection getConnection(PlaintextUserPasswordCredential credential, StaticJDBCConnectionSpecification connectionSpecification, StoreInstance storeInstance) throws Exception + public Connection getConnection(StoreInstance storeInstance, PlaintextUserPasswordCredential credential) throws Exception { StoreSupport storeSupport = storeInstance.getStoreSupport(); + StaticJDBCConnectionSpecification connectionSpecification = this.getCompatibleConnectionSpecification(storeInstance); if (!(storeSupport instanceof RelationalDatabaseStoreSupport)) { throw new RuntimeException("Can't get connection: only support relational databases"); diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-connection/src/main/java/org/finos/legend/connection/jdbc/StaticJDBCConnectionSpecification.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-connection/src/main/java/org/finos/legend/connection/jdbc/StaticJDBCConnectionSpecification.java index ca531113137..0ce55adfa6e 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-connection/src/main/java/org/finos/legend/connection/jdbc/StaticJDBCConnectionSpecification.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-connection/src/main/java/org/finos/legend/connection/jdbc/StaticJDBCConnectionSpecification.java @@ -15,14 +15,12 @@ package org.finos.legend.connection.jdbc; import org.finos.legend.connection.protocol.ConnectionSpecification; -import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.connection.DatabaseType; public class StaticJDBCConnectionSpecification extends ConnectionSpecification { public String host; public int port; public String databaseName; - public DatabaseType databaseType; public StaticJDBCConnectionSpecification(String host, int port, String databaseName) { diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-snowflake/legend-engine-xt-relationalStore-snowflake-connection/src/main/java/org/finos/legend/connection/impl/SnowflakeConnectionBuilder.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-snowflake/legend-engine-xt-relationalStore-snowflake-connection/src/main/java/org/finos/legend/connection/impl/SnowflakeConnectionBuilder.java index 655c9a1f11c..6972dbf9321 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-snowflake/legend-engine-xt-relationalStore-snowflake-connection/src/main/java/org/finos/legend/connection/impl/SnowflakeConnectionBuilder.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-snowflake/legend-engine-xt-relationalStore-snowflake-connection/src/main/java/org/finos/legend/connection/impl/SnowflakeConnectionBuilder.java @@ -21,6 +21,7 @@ import org.finos.legend.connection.StoreSupport; import org.finos.legend.connection.jdbc.JDBCConnectionManager; import org.finos.legend.connection.jdbc.driver.JDBCConnectionDriver; +import org.finos.legend.connection.protocol.ConnectionSpecification; import org.finos.legend.connection.protocol.SnowflakeConnectionSpecification; import org.finos.legend.engine.shared.core.identity.credential.PrivateKeyCredential; @@ -36,8 +37,9 @@ public class SnowflakeConnectionBuilder public static class WithKeyPair extends ConnectionBuilder { @Override - public Connection getConnection(PrivateKeyCredential credential, SnowflakeConnectionSpecification connectionSpecification, StoreInstance storeInstance) throws Exception + public Connection getConnection(StoreInstance storeInstance, PrivateKeyCredential credential) throws Exception { + SnowflakeConnectionSpecification connectionSpecification = this.getCompatibleConnectionSpecification(storeInstance); StoreSupport storeSupport = storeInstance.getStoreSupport(); if (!(storeSupport instanceof RelationalDatabaseStoreSupport) || !DatabaseType.SNOWFLAKE.equals(((RelationalDatabaseStoreSupport) storeSupport).getDatabase())) { diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-snowflake/legend-engine-xt-relationalStore-snowflake-connection/src/main/resources/META-INF/services/org.finos.legend.connection.ConnectionBuilder b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-snowflake/legend-engine-xt-relationalStore-snowflake-connection/src/main/resources/META-INF/services/org.finos.legend.connection.ConnectionBuilder deleted file mode 100644 index 69a94fc1226..00000000000 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-snowflake/legend-engine-xt-relationalStore-snowflake-connection/src/main/resources/META-INF/services/org.finos.legend.connection.ConnectionBuilder +++ /dev/null @@ -1 +0,0 @@ -org.finos.legend.connection.impl.SnowflakeConnectionBuilder$WithKeyPair