export async function handleQuickSightResourceCreation()

in source/lambda/solution-helper/create-quicksight.ts [56:238]


export async function handleQuickSightResourceCreation(event: ICreateQuickSightRequest): Promise<string> {
  const resourceProperties = event.ResourceProperties;
  const machineInformationId = `${resourceProperties.StackName}-MachineInformation`;
  const machineConfigInformationId = `${resourceProperties.StackName}-MachineConfigInformation`;
  const athenaId = `${resourceProperties.StackName}-Athena`;
  const dataSetName = `${resourceProperties.StackName}-DataSet`;
  const analysisName = `${resourceProperties.StackName}-Analysis`;
  const dashboardName = `${resourceProperties.StackName}-Dashboard`;

  const uploadSettings = {
    ContainsHeader: true,
    Delimiter: ',',
    Format: 'CSV',
    TextQualifier: 'SINGLE_QUOTE'
  };

  const quickSightHelper = new QuickSightHelper({
    awsAccountId: resourceProperties.AccountId,
    quickSightPrincipalArn: resourceProperties.PrincipalArn
  });

  switch (event.RequestType) {
    case 'Update':
      await deleteAllQuickSightResources(resourceProperties.StackName, dataSetName, analysisName, dashboardName, quickSightHelper);
      // fall through to create data sources and a data set
    case 'Create':
      try {
        // Creates QuickSight data sources
        const { machineInformationDataSource, machineConfigInformationDataSource, athenaDataSource } = await createAllDataSources(resourceProperties, quickSightHelper);

        // Creates a QuickSight data set
        const dataSet = await quickSightHelper.createDataSet({
          name: dataSetName,
          importMode: QuickSightDataSetImportMode.SPICE,
          physicalTableMap: {
            [machineInformationId]: {
              S3Source: {
                DataSourceArn: machineInformationDataSource.Arn,
                InputColumns: [
                  { Name: 'id', Type: 'STRING' },
                  { Name: 'machine_name', Type: 'STRING' },
                  { Name: 'location', Type: 'STRING' },
                  { Name: 'line', Type: 'STRING' }
                ],
                UploadSettings: uploadSettings
              }
            },
            [machineConfigInformationId]: {
              S3Source: {
                DataSourceArn: machineConfigInformationDataSource.Arn,
                InputColumns: [
                  { Name: 'id', Type: 'STRING' },
                  { Name: 'status_tag', Type: 'STRING' },
                  { Name: 'down_value', Type: 'STRING' }
                ],
                UploadSettings: uploadSettings
              }
            },
            [athenaId]: {
              CustomSql: {
                DataSourceArn: athenaDataSource.Arn,
                Name: athenaId,
                SqlQuery: SQL_QUERY.replace('{DATABASE}', resourceProperties.GlueDatabaseName).replace('{TABLE}', resourceProperties.GlueTableName),
                Columns: [
                  { Name: 'id', Type: 'STRING' },
                  { Name: 'tag', Type: 'STRING' },
                  { Name: 'value', Type: 'STRING' },
                  { Name: 'quality', Type: 'STRING' },
                  { Name: 'timestamp', Type: 'DATETIME' },
                  { Name: 'duration_seconds', Type: 'DECIMAL' },
                  { Name: 'duration_minutes', Type: 'DECIMAL' },
                  { Name: 'duration_hours', Type: 'DECIMAL' }
                ]
              }
            }
          },
          logicalTableMap: {
            [athenaId]: {
              Alias: 'Athena',
              Source: { PhysicalTableId: athenaId }
            },
            [machineInformationId]: {
              Alias: 'MachineInformation',
              DataTransforms: [{
                RenameColumnOperation: { ColumnName: 'id', NewColumnName: 'id[MachineInformation]' }
              }],
              Source: { PhysicalTableId: machineInformationId }
            },
            [machineConfigInformationId]: {
              Alias: 'MachineConfigInformation',
              DataTransforms: [{
                RenameColumnOperation: { ColumnName: 'id', NewColumnName: 'id[MachineConfigInformation]' }
              }],
              Source: { PhysicalTableId: machineConfigInformationId }
            },
            JoinMachineConfigInformation: {
              Alias: 'JoinMachineConfigInformation',
              Source: {
                JoinInstruction: {
                  LeftOperand: athenaId,
                  RightOperand: machineConfigInformationId,
                  Type: 'INNER',
                  OnClause: '{id} = {id[MachineConfigInformation]} and {tag} = {status_tag} and {value} = {down_value}'
                }
              }
            },
            JoinMachineInformation: {
              Alias: 'JoinAthenaAndMachineInformation',
              DataTransforms: [{
                ProjectOperation: {
                  ProjectedColumns: [
                    'id',
                    'tag',
                    'value',
                    'quality',
                    'timestamp',
                    'duration_seconds',
                    'duration_minutes',
                    'duration_hours',
                    'machine_name',
                    'location',
                    'line'
                  ]
                }
              }],
              Source: {
                JoinInstruction: {
                  LeftOperand: 'JoinMachineConfigInformation',
                  RightOperand: machineInformationId,
                  Type: 'INNER',
                  OnClause: '{id} = {id[MachineInformation]}'
                }
              }
            }
          }
        });

        // Creates a QuickSight analysis
        await quickSightHelper.createAnalysis({
          name: analysisName,
          sourceEntity: {
            SourceTemplate: {
              Arn: resourceProperties.QuickSightTemplate,
              DataSetReferences: [{
                DataSetArn: dataSet.Arn,
                DataSetPlaceholder: 'downtime-dataset'
              }]
            }
          }
        });

        // Creates a QuickSight dashboard
        await quickSightHelper.createDashboard({
          name: dashboardName,
          sourceEntity: {
            SourceTemplate: {
              Arn: resourceProperties.QuickSightTemplate,
              DataSetReferences: [{
                DataSetArn: dataSet.Arn,
                DataSetPlaceholder: 'downtime-dataset'
              }]
            }
          }
        });
      } catch (error) {
        // If any error happens, try to rollback everything, but in this time, it just passes when rollback fails.
        console.error(error);

        try {
          console.error('Rolling back all QuickSight resources');
          await deleteAllQuickSightResources(resourceProperties.StackName, dataSetName, analysisName, dashboardName, quickSightHelper);
        } catch (rollbackError) {
          console.error('Error occurred while rolling back the QuickSight resources', rollbackError);
        }

        throw error;
      }

      return `${event.RequestType} completed OK`;
    default:
      return `No action needed for ${event.RequestType}`;
  }
}