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 extends Credential> sourceCredentialType;
-
- private final List credentialBuilders;
+ private final ImmutableList credentialBuilders;
private final ConnectionBuilder connectionBuilder;
- public Authenticator(Identity identity, StoreInstance storeInstance, AuthenticationConfiguration authenticationConfiguration, Class extends Credential> sourceCredentialType, List credentialBuilders, ConnectionBuilder connectionBuilder)
+ public Authenticator(StoreInstance storeInstance, AuthenticationConfiguration authenticationConfiguration, Class extends Credential> 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 extends Credential> 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 extends Credential> 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 extends ConnectionSpecification> 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 extends Credential
public 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 extends AuthenticationConfiguration> 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 extends Credential> getOutputCredentialType()
- {
- return (Class extends Credential>) 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 extends CredentialVaultSecret>> 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 extends CredentialVaultSecret>> vaultsIndex;
- private final Map storeSupportsIndex;
+ protected final ImmutableList vaults;
+ protected final ImmutableMap, CredentialVault extends CredentialVaultSecret>> 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 extends CredentialVaultSecret>> vaultsIndex = Maps.mutable.empty();
for (CredentialVault extends CredentialVaultSecret> 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 extends Credential> sourceCredentialType, List credentialBuilders, Class extends ConnectionBuilder> connectionBuilderType) throws Exception
+ private void assertAuthenticator(Identity identity, ConnectionFactory connectionFactory, Authenticator authenticator, Class extends Credential> sourceCredentialType, List credentialBuilders, Class extends ConnectionBuilder> 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