Skip to content

Commit

Permalink
fix: use dynamic imports for plugins construction
Browse files Browse the repository at this point in the history
  • Loading branch information
crystall-bitquill committed Jun 17, 2024
1 parent df1de6c commit 7c16643
Show file tree
Hide file tree
Showing 22 changed files with 313 additions and 93 deletions.
8 changes: 0 additions & 8 deletions common/lib/authentication/aws_secrets_manager_plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ import {
} from "@aws-sdk/client-secrets-manager";
import { logger } from "../../logutils";
import { AbstractConnectionPlugin } from "../abstract_connection_plugin";
import { ConnectionPlugin } from "../connection_plugin";
import { HostInfo } from "../host_info";
import { ConnectionPluginFactory } from "../plugin_factory";
import { PluginService } from "../plugin_service";
import { AwsWrapperError } from "../utils/errors";
import { Messages } from "../utils/messages";
Expand Down Expand Up @@ -175,9 +173,3 @@ export class Secret {
this.password = password;
}
}

export class AwsSecretsManagerPluginFactory implements ConnectionPluginFactory {
getInstance(pluginService: PluginService, properties: Map<string, any>): ConnectionPlugin {
return new AwsSecretsManagerPlugin(pluginService, new Map(properties));
}
}
34 changes: 34 additions & 0 deletions common/lib/authentication/aws_secrets_manager_plugin_factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
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.
*/

import { ConnectionPluginFactory } from "../plugin_factory";
import { PluginService } from "../plugin_service";
import { ConnectionPlugin } from "../connection_plugin";
import { AwsWrapperError } from "../utils/errors";
import { Messages } from "../utils/messages";
import { logger } from "../../logutils";

export class AwsSecretsManagerPluginFactory implements ConnectionPluginFactory {
async getInstance(pluginService: PluginService, properties: Map<string, any>): Promise<ConnectionPlugin> {
try {
const awsSecretsManagerPlugin = await import("./aws_secrets_manager_plugin");
return new awsSecretsManagerPlugin.AwsSecretsManagerPlugin(pluginService, new Map(properties));
} catch (error: any) {
logger.error(error);
throw new AwsWrapperError(Messages.get("ConnectionPluginChainBuilder.errorImportingPlugin", "AwsSecretsManagerPlugin"));
}
}
}
8 changes: 0 additions & 8 deletions common/lib/authentication/iam_authentication_plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
limitations under the License.
*/

import { ConnectionPlugin } from "../connection_plugin";
import { ConnectionPluginFactory } from "../plugin_factory";
import { PluginService } from "../plugin_service";
import { RdsUtils } from "../utils/rds_utils";
import { Messages } from "../utils/messages";
Expand Down Expand Up @@ -119,9 +117,3 @@ export class IamAuthenticationPlugin extends AbstractConnectionPlugin {
this.tokenCache.clear();
}
}

export class IamAuthenticationPluginFactory implements ConnectionPluginFactory {
getInstance(pluginService: PluginService, properties: object): ConnectionPlugin {
return new IamAuthenticationPlugin(pluginService);
}
}
34 changes: 34 additions & 0 deletions common/lib/authentication/iam_authentication_plugin_factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
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.
*/

import { ConnectionPluginFactory } from "../plugin_factory";
import { PluginService } from "../plugin_service";
import { ConnectionPlugin } from "../connection_plugin";
import { AwsWrapperError } from "../utils/errors";
import { Messages } from "../utils/messages";
import { logger } from "../../logutils";

export class IamAuthenticationPluginFactory implements ConnectionPluginFactory {
async getInstance(pluginService: PluginService, properties: object): Promise<ConnectionPlugin> {
try {
const iamAuthenticationPlugin = await import("./iam_authentication_plugin");
return new iamAuthenticationPlugin.IamAuthenticationPlugin(pluginService);
} catch (error: any) {
logger.error(error);
throw new AwsWrapperError(Messages.get("ConnectionPluginChainBuilder.errorImportingPlugin", "IamAuthenticationPlugin"));
}
}
}
5 changes: 5 additions & 0 deletions common/lib/aws_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ export abstract class AwsClient extends EventEmitter {
this.pluginService.setCurrentHostInfo(new HostInfo(host, port));
}

private async setup() {
await this.pluginManager.init();
}

protected async internalConnect() {
await this.setup();
const hostListProvider: HostListProvider = this.pluginService
.getDialect()
.getHostListProvider(this.properties, this.properties.get("host"), this.pluginService);
Expand Down
28 changes: 14 additions & 14 deletions common/lib/connection_plugin_chain_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@
limitations under the License.
*/

import { IamAuthenticationPluginFactory } from "./authentication/iam_authentication_plugin";
import { FailoverPluginFactory } from "./plugins/failover/failover_plugin";
import { PluginService } from "./plugin_service";
import { ConnectionPlugin } from "./connection_plugin";
import { WrapperProperties } from "./wrapper_property";
import { AwsWrapperError } from "./utils/errors";
import { Messages } from "./utils/messages";
import { DefaultPlugin } from "./plugins/default_plugin";
import { ExecuteTimePluginFactory } from "./plugins/execute_time_plugin";
import { ConnectTimePluginFactory } from "./plugins/connect_time_plugin";
import { AwsSecretsManagerPluginFactory } from "./authentication/aws_secrets_manager_plugin";
import { ConnectionProvider } from "./connection_provider";
import { ReadWriteSplittingPluginFactory } from "./plugins/read_write_splitting";
import { StaleDnsPluginFactory } from "./plugins/stale_dns/stale_dns_plugin";
import { FederatedAuthPluginFactory } from "./plugins/federated_auth/federated_auth_plugin";
import { DefaultPlugin } from "./plugins/default_plugin";
import { IamAuthenticationPluginFactory } from "./authentication/iam_authentication_plugin_factory";
import { ExecuteTimePluginFactory } from "./plugins/execute_time_plugin_factory";
import { ConnectTimePluginFactory } from "./plugins/connect_time_plugin_factory";
import { AwsSecretsManagerPluginFactory } from "./authentication/aws_secrets_manager_plugin_factory";
import { FailoverPluginFactory } from "./plugins/failover/failover_plugin_factory";
import { StaleDnsPluginFactory } from "./plugins/stale_dns/stale_dns_plugin_factory";
import { FederatedAuthPluginFactory } from "./plugins/federated_auth/federated_auth_plugin_factory";
import { ReadWriteSplittingPluginFactory } from "./plugins/read_write_splitting_plugin_factory";

export class PluginFactoryInfo {}

Expand All @@ -49,12 +49,12 @@ export class ConnectionPluginChainBuilder {
["federatedAuth", FederatedAuthPluginFactory]
]);

getPlugins(
async getPlugins(
pluginService: PluginService,
props: Map<string, any>,
defaultConnProvider: ConnectionProvider,
effectiveConnProvider: ConnectionProvider | null
): ConnectionPlugin[] {
): Promise<ConnectionPlugin[]> {
const plugins: ConnectionPlugin[] = [];
let pluginCodes: string = props.get(WrapperProperties.PLUGINS.name);
if (pluginCodes == null) {
Expand All @@ -76,10 +76,10 @@ export class ConnectionPluginChainBuilder {
}
});

pluginFactories.forEach((factory) => {
for (const factory of pluginFactories) {
const factoryObj = new factory();
plugins.push(factoryObj.getInstance(pluginService, props));
});
plugins.push(await factoryObj.getInstance(pluginService, props));
}
}

plugins.push(new DefaultPlugin(pluginService, defaultConnProvider, effectiveConnProvider));
Expand Down
2 changes: 1 addition & 1 deletion common/lib/plugin_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ import { PluginService } from "./plugin_service";
import { ConnectionPlugin } from "./connection_plugin";

export interface ConnectionPluginFactory {
getInstance(pluginService: PluginService, properties: object): ConnectionPlugin;
getInstance(pluginService: PluginService, properties: object): Promise<ConnectionPlugin>;
}
23 changes: 15 additions & 8 deletions common/lib/plugin_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,11 @@ export class PluginManager {
private static readonly NOTIFY_CONNECTION_CHANGED_METHOD: string = "notifyConnectionChanged";
private static readonly ACCEPTS_STRATEGY_METHOD: string = "acceptsStrategy";
private static readonly GET_HOST_INFO_BY_STRATEGY_METHOD: string = "getHostInfoByStrategy";
private readonly _plugins: ConnectionPlugin[] = [];
private readonly defaultConnProvider;
private readonly effectiveConnProvider;
private readonly props: Map<string, any>;
private _plugins: ConnectionPlugin[] = [];
private pluginServiceManagerContainer: PluginServiceManagerContainer;
private props: Map<string, any>;

constructor(
pluginServiceManagerContainer: PluginServiceManagerContainer,
Expand All @@ -83,16 +85,21 @@ export class PluginManager {
this.pluginServiceManagerContainer = pluginServiceManagerContainer;
this.pluginServiceManagerContainer.pluginManager = this;
this.props = props;
this.defaultConnProvider = defaultConnProvider;
this.effectiveConnProvider = effectiveConnProvider;

// TODO: proper parsing logic
}

async init() {
if (this.pluginServiceManagerContainer.pluginService != null) {
this._plugins = new ConnectionPluginChainBuilder().getPlugins(
this._plugins = await new ConnectionPluginChainBuilder().getPlugins(
this.pluginServiceManagerContainer.pluginService,
props,
defaultConnProvider,
effectiveConnProvider
this.props,
this.defaultConnProvider,
this.effectiveConnProvider
);
}

// TODO: proper parsing logic
}

execute<T>(hostInfo: HostInfo | null, props: Map<string, any>, methodName: string, methodFunc: () => Promise<T>, options: any): Promise<T> {
Expand Down
9 changes: 0 additions & 9 deletions common/lib/plugins/connect_time_plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ import { logger } from "../../logutils";
import { HostInfo } from "../host_info";
import { getTimeInNanos } from "../utils/utils";
import { Messages } from "../utils/messages";
import { ConnectionPluginFactory } from "../plugin_factory";
import { ConnectionPlugin } from "../connection_plugin";
import { PluginService } from "../plugin_service";

export class ConnectTimePlugin extends AbstractConnectionPlugin {
private static readonly subscribedMethods: Set<string> = new Set<string>(["connect", "forceConnect"]);
Expand Down Expand Up @@ -71,9 +68,3 @@ export class ConnectTimePlugin extends AbstractConnectionPlugin {
return ConnectTimePlugin.connectTime;
}
}

export class ConnectTimePluginFactory implements ConnectionPluginFactory {
getInstance(pluginService: PluginService, properties: Map<string, any>): ConnectionPlugin {
return new ConnectTimePlugin();
}
}
34 changes: 34 additions & 0 deletions common/lib/plugins/connect_time_plugin_factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
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.
*/

import { ConnectionPluginFactory } from "../plugin_factory";
import { PluginService } from "../plugin_service";
import { ConnectionPlugin } from "../connection_plugin";
import { AwsWrapperError } from "../utils/errors";
import { Messages } from "../utils/messages";
import { logger } from "../../logutils";

export class ConnectTimePluginFactory implements ConnectionPluginFactory {
async getInstance(pluginService: PluginService, properties: Map<string, any>): Promise<ConnectionPlugin> {
try {
const connectTimePlugin = await import("./connect_time_plugin");
return new connectTimePlugin.ConnectTimePlugin();
} catch (error: any) {
logger.error(error);
throw new AwsWrapperError(Messages.get("ConnectionPluginChainBuilder.errorImportingPlugin", "ConnectTimePlugin"));
}
}
}
9 changes: 0 additions & 9 deletions common/lib/plugins/execute_time_plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@

import { logger } from "../../logutils";
import { AbstractConnectionPlugin } from "../abstract_connection_plugin";
import { ConnectionPlugin } from "../connection_plugin";
import { ConnectionPluginFactory } from "../plugin_factory";
import { PluginService } from "../plugin_service";
import { Messages } from "../utils/messages";
import { getTimeInNanos } from "../utils/utils";

Expand Down Expand Up @@ -51,9 +48,3 @@ export class ExecuteTimePlugin extends AbstractConnectionPlugin {
return ExecuteTimePlugin.executeTime;
}
}

export class ExecuteTimePluginFactory implements ConnectionPluginFactory {
getInstance(pluginService: PluginService, properties: Map<string, any>): ConnectionPlugin {
return new ExecuteTimePlugin();
}
}
34 changes: 34 additions & 0 deletions common/lib/plugins/execute_time_plugin_factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
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.
*/

import { ConnectionPluginFactory } from "../plugin_factory";
import { PluginService } from "../plugin_service";
import { ConnectionPlugin } from "../connection_plugin";
import { AwsWrapperError } from "../utils/errors";
import { Messages } from "../utils/messages";
import { logger } from "../../logutils";

export class ExecuteTimePluginFactory implements ConnectionPluginFactory {
async getInstance(pluginService: PluginService, properties: Map<string, any>): Promise<ConnectionPlugin> {
try {
const executeTimePlugin = await import("./execute_time_plugin");
return new executeTimePlugin.ExecuteTimePlugin();
} catch (error: any) {
logger.error(error);
throw new AwsWrapperError(Messages.get("ConnectionPluginChainBuilder.errorImportingPlugin", "ExecuteTimePlugin"));
}
}
}
6 changes: 0 additions & 6 deletions common/lib/plugins/failover/failover_plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -530,9 +530,3 @@ export class FailoverPlugin extends AbstractConnectionPlugin {
return false;
}
}

export class FailoverPluginFactory implements ConnectionPluginFactory {
getInstance(pluginService: PluginService, properties: Map<string, any>): ConnectionPlugin {
return new FailoverPlugin(pluginService, properties, new RdsUtils());
}
}
35 changes: 35 additions & 0 deletions common/lib/plugins/failover/failover_plugin_factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
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.
*/

import { ConnectionPluginFactory } from "../../plugin_factory";
import { PluginService } from "../../plugin_service";
import { ConnectionPlugin } from "../../connection_plugin";
import { RdsUtils } from "../../utils/rds_utils";
import { logger } from "../../../logutils";
import { AwsWrapperError } from "../../utils/errors";
import { Messages } from "../../utils/messages";

export class FailoverPluginFactory implements ConnectionPluginFactory {
async getInstance(pluginService: PluginService, properties: Map<string, any>): Promise<ConnectionPlugin> {
try {
const failoverPlugin = await import("./failover_plugin");
return new failoverPlugin.FailoverPlugin(pluginService, properties, new RdsUtils());
} catch (error: any) {
logger.error(error);
throw new AwsWrapperError(Messages.get("ConnectionPluginChainBuilder.errorImportingPlugin", "FailoverPlugin"));
}
}
}
Loading

0 comments on commit 7c16643

Please sign in to comment.