Skip to content

Commit

Permalink
Merge pull request #984 from jhockett/update-tpi-references
Browse files Browse the repository at this point in the history
  • Loading branch information
phani-srikar authored Dec 6, 2022
2 parents 19b0693 + 6d8736f commit f6998c7
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 220 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
import { stateManager, getGraphQLTransformerOpenSearchProductionDocLink, ApiCategoryFacade } from 'amplify-cli-core';
const getParamMock = jest.fn();

import { $TSContext, stateManager, getGraphQLTransformerOpenSearchProductionDocLink, ApiCategoryFacade } from 'amplify-cli-core';
import { printer } from 'amplify-prompts';
import { searchablePushChecks } from '../../graphql-transformer/api-utils';

jest.mock('amplify-cli-core');
jest.mock('amplify-prompts');

jest.mock('@aws-amplify/amplify-environment-parameters', () => ({
ensureEnvParamManager: jest.fn().mockResolvedValue({
instance: {
getResourceParamManager: jest.fn().mockReturnValue({
getParam: getParamMock,
}),
},
}),
}));

const printerMock = printer as jest.Mocked<typeof printer>;
const stateManagerMock = stateManager as jest.Mocked<typeof stateManager>;
const getTransformerVersionMock = ApiCategoryFacade.getTransformerVersion as jest.MockedFunction<typeof ApiCategoryFacade.getTransformerVersion>
const getTransformerVersionMock = ApiCategoryFacade
.getTransformerVersion as jest.MockedFunction<typeof ApiCategoryFacade.getTransformerVersion>;
const getGraphQLTransformerOpenSearchProductionDocLinkMock = getGraphQLTransformerOpenSearchProductionDocLink as jest.MockedFunction<
typeof getGraphQLTransformerOpenSearchProductionDocLink
>;
Expand All @@ -21,171 +34,84 @@ describe('graphql schema checks', () => {
amplify: {
getEnvInfo: jest.fn(),
},
};
} as unknown as $TSContext;

const printerWarning = 'Your instance type for OpenSearch is t2.small.elasticsearch, you may experience performance issues or data loss.'
+ ' Consider reconfiguring with the instructions here mockDocsLink';

beforeEach(() => {
jest.clearAllMocks();
});

it('should warn users if they use not recommended open search instance without overrides', async () => {
stateManagerMock.getTeamProviderInfo.mockReturnValue({});
contextMock.amplify.getEnvInfo.mockReturnValue({ envName: 'test' });
stateManagerMock.getLocalEnvInfo.mockReturnValue({ envName: 'test' });
getParamMock.mockReturnValueOnce(undefined);
const map = { Post: ['model', 'searchable'] };
await searchablePushChecks(contextMock, map, 'test_api_name');
expect(printerMock.warn).lastCalledWith(
'Your instance type for OpenSearch is t2.small.elasticsearch, you may experience performance issues or data loss. Consider reconfiguring with the instructions here mockDocsLink',
);
expect(printerMock.warn).lastCalledWith(printerWarning);
});

it('should warn users if they use not recommended open search instance with overrides', async () => {
stateManagerMock.getTeamProviderInfo.mockReturnValue({
test: {
categories: {
api: {
test_api_name: {
OpenSearchInstanceType: 't2.small.elasticsearch',
},
},
},
},
});
contextMock.amplify.getEnvInfo.mockReturnValue({ envName: 'test' });
getParamMock.mockReturnValueOnce('t2.small.elasticsearch');
stateManagerMock.getLocalEnvInfo.mockReturnValue({ envName: 'test' });
const map = { Post: ['model', 'searchable'] };
await searchablePushChecks(contextMock, map, 'test_api_name');
expect(printerMock.warn).lastCalledWith(
'Your instance type for OpenSearch is t2.small.elasticsearch, you may experience performance issues or data loss. Consider reconfiguring with the instructions here mockDocsLink',
);
expect(printerMock.warn).lastCalledWith(printerWarning);
});

it('should warn users if they use not recommended elastic search instance with overrides', async () => {
stateManagerMock.getTeamProviderInfo.mockReturnValue({
test: {
categories: {
api: {
test_api_name: {
ElasticSearchInstanceType: 't2.small.elasticsearch',
},
},
},
},
});
contextMock.amplify.getEnvInfo.mockReturnValue({ envName: 'test' });
getParamMock.mockReturnValueOnce('t2.small.elasticsearch');
stateManagerMock.getLocalEnvInfo.mockReturnValue({ envName: 'test' });
const map = { Post: ['model', 'searchable'] };
await searchablePushChecks(contextMock, map, 'test_api_name');
expect(printerMock.warn).lastCalledWith(
'Your instance type for OpenSearch is t2.small.elasticsearch, you may experience performance issues or data loss. Consider reconfiguring with the instructions here mockDocsLink',
);
expect(printerMock.warn).lastCalledWith(printerWarning);
});

it('should NOT warn users if they use recommended open search instance', async () => {
stateManagerMock.getTeamProviderInfo.mockReturnValue({
test: {
categories: {
api: {
test_api_name: {
OpenSearchInstanceType: 't2.medium.elasticsearch',
},
},
},
},
});
contextMock.amplify.getEnvInfo.mockReturnValue({ envName: 'test' });
getParamMock.mockReturnValueOnce('t2.medium.elasticsearch');
stateManagerMock.getLocalEnvInfo.mockReturnValue({ envName: 'test' });
const map = { Post: ['model', 'searchable'] };
await searchablePushChecks(contextMock, map, 'test_api_name');
expect(printerMock.warn).not.toBeCalled();
});

it('should NOT warn users if they use recommended elastic search instance', async () => {
stateManagerMock.getTeamProviderInfo.mockReturnValue({
test: {
categories: {
api: {
test_api_name: {
ElasticSearchInstanceType: 't2.medium.elasticsearch',
},
},
},
},
});
contextMock.amplify.getEnvInfo.mockReturnValue({ envName: 'test' });
getParamMock.mockReturnValueOnce('t2.medium.elasticsearch');
stateManagerMock.getLocalEnvInfo.mockReturnValue({ envName: 'test' });
const map = { Post: ['model', 'searchable'] };
await searchablePushChecks(contextMock, map, 'test_api_name');
expect(printerMock.warn).not.toBeCalled();
});

it('should NOT warn users if they use recommended open search instance on the environment', async () => {
stateManagerMock.getTeamProviderInfo.mockReturnValue({
dev: {
categories: {
api: {
test_api_name: {
OpenSearchInstanceType: 't2.small.elasticsearch',
},
},
},
},
prod: {
categories: {
api: {
test_api_name: {
OpenSearchInstanceType: 't2.medium.elasticsearch',
},
},
},
},
});
contextMock.amplify.getEnvInfo.mockReturnValue({ envName: 'prod' });
getParamMock.mockReturnValueOnce('t2.medium.elasticsearch');
stateManagerMock.getLocalEnvInfo.mockReturnValue({ envName: 'prod' });
const map = { Post: ['model', 'searchable'] };
await searchablePushChecks(contextMock, map, 'test_api_name');
expect(printerMock.warn).not.toBeCalled();
});

it('should NOT warn users if they use recommended elastic search instance on the environment', async () => {
stateManagerMock.getTeamProviderInfo.mockReturnValue({
dev: {
categories: {
api: {
test_api_name: {
ElasticSearchInstanceType: 't2.small.elasticsearch',
},
},
},
},
prod: {
categories: {
api: {
test_api_name: {
ElasticSearchInstanceType: 't2.medium.elasticsearch',
},
},
},
},
});
contextMock.amplify.getEnvInfo.mockReturnValue({ envName: 'prod' });
getParamMock.mockReturnValueOnce('t2.medium.elasticsearch');
stateManagerMock.getLocalEnvInfo.mockReturnValue({ envName: 'prod' });
const map = { Post: ['model', 'searchable'] };
await searchablePushChecks(contextMock, map, 'test_api_name');
expect(printerMock.warn).not.toBeCalled();
});

it('should NOT warn users if they do NOT use searchable', async () => {
stateManagerMock.getTeamProviderInfo.mockReturnValue({});
contextMock.amplify.getEnvInfo.mockReturnValue({ envName: 'test' });
getParamMock.mockReturnValueOnce(undefined);
stateManagerMock.getLocalEnvInfo.mockReturnValue({ envName: 'test' });
const map = { Post: ['model'] };
await searchablePushChecks(contextMock, map, 'test_api_name');
expect(printerMock.warn).not.toBeCalled();
});

it('should warn users if they use not recommended open search instance with overrides', async () => {
stateManagerMock.getTeamProviderInfo.mockReturnValue({
test: {
categories: {},
},
});
contextMock.amplify.getEnvInfo.mockReturnValue({ envName: 'test' });
getParamMock.mockReturnValueOnce(undefined);
stateManagerMock.getLocalEnvInfo.mockReturnValue({ envName: 'test' });
const map = { Post: ['model', 'searchable'] };
await searchablePushChecks(contextMock, map, 'test_api_name');
expect(printerMock.warn).lastCalledWith(
'Your instance type for OpenSearch is t2.small.elasticsearch, you may experience performance issues or data loss. Consider reconfiguring with the instructions here mockDocsLink',
);
expect(printerMock.warn).lastCalledWith(printerWarning);
});
});
44 changes: 22 additions & 22 deletions packages/amplify-category-api/src/graphql-transformer/api-utils.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { stateManager, getGraphQLTransformerOpenSearchProductionDocLink, ApiCategoryFacade } from "amplify-cli-core";
import { printer } from "amplify-prompts";
import { ResourceConstants } from "graphql-transformer-common";
import _ from "lodash";
import { ensureEnvParamManager } from '@aws-amplify/amplify-environment-parameters';
import {
$TSContext, $TSObject, AmplifyCategories, ApiCategoryFacade, getGraphQLTransformerOpenSearchProductionDocLink,
} from 'amplify-cli-core';
import { printer } from 'amplify-prompts';
import { ResourceConstants } from 'graphql-transformer-common';

export async function searchablePushChecks(context, map, apiName): Promise<void> {
const searchableModelTypes = Object.keys(map).filter(type => map[type].includes('searchable') && map[type].includes('model'));
if (searchableModelTypes.length) {
const currEnv = context.amplify.getEnvInfo().envName;
const teamProviderInfo = stateManager.getTeamProviderInfo();
const getInstanceType = (instanceTypeParam: string) => _.get(teamProviderInfo, [currEnv, 'categories', 'api', apiName, instanceTypeParam]);
const instanceType =
getInstanceType(ResourceConstants.PARAMETERS.OpenSearchInstanceType) ??
getInstanceType(ResourceConstants.PARAMETERS.ElasticsearchInstanceType) ??
't2.small.elasticsearch';
if (instanceType === 't2.small.elasticsearch' || instanceType === 't3.small.elasticsearch') {
const version = await ApiCategoryFacade.getTransformerVersion(context);
const docLink = getGraphQLTransformerOpenSearchProductionDocLink(version);
printer.warn(
`Your instance type for OpenSearch is ${instanceType}, you may experience performance issues or data loss. Consider reconfiguring with the instructions here ${docLink}`,
);
}
export async function searchablePushChecks(context: $TSContext, map: $TSObject, apiName: string): Promise<void> {
const searchableModelTypes = Object.keys(map).filter((type) => map[type].includes('searchable') && map[type].includes('model'));
if (searchableModelTypes.length) {
const apiParameterManager = (await ensureEnvParamManager()).instance.getResourceParamManager(AmplifyCategories.API, apiName);
const getInstanceType = (instanceTypeParam: string) => apiParameterManager.getParam(instanceTypeParam);
const instanceType = getInstanceType(ResourceConstants.PARAMETERS.OpenSearchInstanceType)
?? getInstanceType(ResourceConstants.PARAMETERS.ElasticsearchInstanceType)
?? 't2.small.elasticsearch';
if (instanceType === 't2.small.elasticsearch' || instanceType === 't3.small.elasticsearch') {
const version = await ApiCategoryFacade.getTransformerVersion(context);
const docLink = getGraphQLTransformerOpenSearchProductionDocLink(version);
printer.warn(
`Your instance type for OpenSearch is ${instanceType}, you may experience performance issues or data loss. Consider reconfiguring with the instructions here ${docLink}`,
);
}
}
}
}
49 changes: 14 additions & 35 deletions packages/amplify-category-api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
pathManager,
stateManager,
} from 'amplify-cli-core';
import { ensureEnvParamManager } from '@aws-amplify/amplify-environment-parameters';
import { printer } from 'amplify-prompts';
import { validateAddApiRequest, validateUpdateApiRequest } from 'amplify-util-headless-input';
import * as fs from 'fs-extra';
Expand Down Expand Up @@ -43,7 +44,6 @@ export * from './graphql-transformer';
export * from './force-updates';

const category = AmplifyCategories.API;
const categories = 'categories';

/**
* Open the AppSync/API Gateway AWS console
Expand Down Expand Up @@ -102,12 +102,6 @@ export const initEnv = async (context: $TSContext): Promise<void> => {
const datasource = 'Aurora Serverless';
const service = 'service';
const rdsInit = 'rdsInit';
const rdsRegion = 'rdsRegion';
const rdsClusterIdentifier = 'rdsClusterIdentifier';
const rdsSecretStoreArn = 'rdsSecretStoreArn';
const rdsDatabaseName = 'rdsDatabaseName';

const { amplify } = context;

/**
* Check if we need to do the walkthrough, by looking to see if previous environments have
Expand Down Expand Up @@ -154,43 +148,28 @@ export const initEnv = async (context: $TSContext): Promise<void> => {
}

/**
* Check team provider info to ensure it hasn't already been created for current env
* Check environment parameter manager to ensure it hasn't already been created for current env
*/
const currentEnv = amplify.getEnvInfo().envName;
const teamProviderInfo = stateManager.getTeamProviderInfo();
const envParamManager = (await ensureEnvParamManager()).instance;
if (
teamProviderInfo[currentEnv][categories]
&& teamProviderInfo[currentEnv][categories][category]
&& teamProviderInfo[currentEnv][categories][category][resourceName]
&& teamProviderInfo[currentEnv][categories][category][resourceName]
&& teamProviderInfo[currentEnv][categories][category][resourceName][rdsRegion]
envParamManager.hasResourceParamManager(category, resourceName)
&& envParamManager.getResourceParamManager(category, resourceName).getParam('rdsRegion')
) {
return;
}

// execute the walkthrough
await providerController
.addDatasource(context, category, datasource)
.then(answers => {
/**
* Write the new answers to the team provider info
* Update environment parameter manager with answers
*/
if (!teamProviderInfo[currentEnv][categories]) {
teamProviderInfo[currentEnv][categories] = {};
}
if (!teamProviderInfo[currentEnv][categories][category]) {
teamProviderInfo[currentEnv][categories][category] = {};
}
if (!teamProviderInfo[currentEnv][categories][category][resourceName]) {
teamProviderInfo[currentEnv][categories][category][resourceName] = {};
}

teamProviderInfo[currentEnv][categories][category][resourceName][rdsRegion] = answers.region;
teamProviderInfo[currentEnv][categories][category][resourceName][rdsClusterIdentifier] = answers.dbClusterArn;
teamProviderInfo[currentEnv][categories][category][resourceName][rdsSecretStoreArn] = answers.secretStoreArn;
teamProviderInfo[currentEnv][categories][category][resourceName][rdsDatabaseName] = answers.databaseName;

stateManager.setTeamProviderInfo(undefined, teamProviderInfo);
envParamManager.getResourceParamManager(category, resourceName).setParams({
rdsRegion: answers.region,
rdsClusterIdentifier: answers.dbClusterArn,
rdsSecretStoreArn: answers.secretStoreArn,
rdsDatabaseName: answers.databaseName,
});
})
.then(() => {
context.amplify.executeProviderUtils(context, 'awscloudformation', 'compileSchema', { forceCompile: true });
Expand Down Expand Up @@ -245,7 +224,7 @@ export const executeAmplifyCommand = async (context: $TSContext): Promise<void>
commandPath = path.join(commandPath, category, context.input.command);
}

//TODO: This is a temporary suppression for CDK deprecation warnings, which should be removed after the migration is complete
// TODO: This is a temporary suppression for CDK deprecation warnings, which should be removed after the migration is complete
// Most of these warning messages are targetting searchable directive, which needs to migrate from elastic search to open search
// This is not diabled in debug mode
disableCDKDeprecationWarning();
Expand Down Expand Up @@ -372,4 +351,4 @@ const disableCDKDeprecationWarning = () => {
if (!isDebug) {
process.env.JSII_DEPRECATED = 'quiet';
}
}
};
1 change: 1 addition & 0 deletions packages/amplify-graphql-transformer-migrator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"lodash": "^4.17.21"
},
"peerDependencies": {
"@aws-amplify/amplify-environment-parameters": "^1.1.0",
"amplify-cli-core": "^3.0.0",
"amplify-prompts": "^2.0.1"
},
Expand Down
Loading

0 comments on commit f6998c7

Please sign in to comment.