AWSTemplateFormatVersion: "2010-09-09"
Description: Amazon IVS with Datazoom Analytics Datastore and Visualization Resources

Parameters:
  CFNDatabaseName:
    Type: String
    Default: cfn-datazoom-ivs-analytics
  CFNTableName1:
    Type: String
    Default: ivs-player-events

Resources:
  MyIVSChannel:
    Type: AWS::IVS::Channel
    Properties:
      Authorized: false
      LatencyMode: "LOW"
      Name: "my-ivs-channel-3"
      RecordingConfigurationArn: ""
      Type: "STANDARD"

  KinesisBucket:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: "ivs-datazoom-kinesis-firehose-bucket-1"

  AthenaGrafanaBucket:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: "grafana-athena-query-results-ivs-datazoom-1"

  CFNDatabaseEvents:
    Type: AWS::Glue::Database
    Properties:
      CatalogId: !Ref AWS::AccountId
      DatabaseInput:
        Name: !Ref CFNDatabaseName
        Description: Database to hold IVS player event data

  CFNTableEvents:
    Type: AWS::Glue::Table
    Properties:
      CatalogId: !Ref AWS::AccountId
      DatabaseName: !Ref CFNDatabaseName
      TableInput:
        Name: !Ref CFNTableName1
        Description: Define the first few columns of the flights table
        TableType: EXTERNAL_TABLE
        Parameters: { "classification": "parquet" }
        StorageDescriptor:
          OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
          Columns:
            - Name: configuration_id
              Type: string
              Comment: ""
            - Name: connector_config_id
              Type: string
              Comment: ""
            - Name: connector_list
              Type: string
              Comment: ""
            - Name: customer_code
              Type: string
              Comment: ""
            - Name: dz_connector_id
              Type: string
              Comment: ""
            - Name: dzmessagetype
              Type: string
              Comment: ""
            - Name: event_id
              Type: string
              Comment: ""
            - Name: ad
              Type: struct<ad_blocker:boolean,ad_break_id:string,ad_click_url:string,ad_creative_id:string,ad_duration_sec:int,ad_id:string,ad_partner:string,ad_position:string,ad_session_id:string,ad_skipped:boolean,ad_system:string,ad_time_offset_sec:float,advertiser_name:string,cpm:float,cpmCurrency:string,cpmMatch:boolean,creative_name:string,deal_id:string,gam_advertiser_name:string,gam_request_type:string,gam_brand:string,gam_industry:string,price:float,quantity:int,revenueType:string,skip_time_offset_sec:float,wrapper_creative_ids:string,wrapper_systems:string,wrapper_id:string>
              Comment: ""
            - Name: attempt
              Type: struct<global_count:int,local_count:int,last_failure_message:string,success:boolean,terminal:boolean,status_code:int>
              Comment: ""
            - Name: cdn
              Type: struct<host:string,cdn:string,cache_hit:boolean,http_status:string,content_type:string>
              Comment: ""
            - Name: cmcd
              Type: struct<sid:string,nor:string,d:int,dl:int,mtp:int,cid:string,ot:string,pr:int,rid:string,st:string,tb:int,bl:int,rtp:int,br:int,bs:boolean,sf:string,v:float,su:boolean,nrr:string>
              Comment: ""
            - Name: device
              Type: struct<ad_tracking_opt_out:boolean,advertising_id:string,browser_height:int,browser_name:string,browser_version:string,browser_width:int,cookies_enabled:boolean,device_id:string,device_mfg:string,device_name:string,device_type:string,orientation:string,os_name:string,os_version:string>
              Comment: ""
            - Name: egress
              Type: struct<data_size:int,dz_internal:boolean,timestamp:bigint>
              Comment: ""
            - Name: event
              Type: struct<type:string,timestamp:timestamp,attributes:struct<abs_shift:string,error_code:string,error_msg:string,inner_error:string,milestone_percent:float,seek_start_point_ms:int,seek_end_point_ms:int,startup_duration_content_ms:int,startup_duration_total_ms:int,qualified_view_sec:int,heartbeat_count:int>,metrics:struct<bandwidth_kbps:int,buffer_duration_ads_ms:int,buffer_duration_content_ms:int,buffer_duration_ms:int,buffer_fill_percent:float,buffer_length_ms:int,bytes_served:int,content_session_start_ts_ms:bigint,current_audio_track:string,current_subtitles:string,engagement_duration_ads_ms:int,engagement_duration_content_ms:int,engagement_duration_ms:int,event_count:int,num_ad_plays:int,num_content_plays:int,num_errors_ads:int,num_errors_content:int,num_errors:int,num_requests_content:int,playback_duration_ads_ms:int,playback_duration_content_ms:int,playback_duration_ms:int,playback_duration_promo_ms:int,playback_rate:float,player_state:string,player_viewable_percent:float,player_viewable:boolean,playhead_position_sec:float,rendition_height:int,rendition_name:string,rendition_audio_bitrate_kbps:int,rendition_video_bitrate_kbps:int,rendition_width:int,round_trip_time_mu:int,stall_count_ads:int,stall_count_content:int,stall_count:int,stall_duration_ads_ms:int,stall_duration_content_ms:int,stall_duration_ms:int,time_since_last_ad_break_start_ms:int,time_since_last_ad_completed_ms:int,time_since_last_buffer_start_ad_ms:int,time_since_last_buffer_start_content_ms:int,time_since_last_buffer_start_ms:int,time_since_last_heartbeat_ms:int,time_since_last_milestone_ad_ms:int,time_since_last_milestone_content_ms:int,time_since_last_pause_ms:int,time_since_last_rendition_change_ms:int,time_since_last_request_ad_ms:int,time_since_last_seek_start_ms:int,time_since_last_stall_start_ad_ms:int,time_since_last_stall_start_content_ms:int,time_since_last_stall_start_ms:int,time_since_last_started_ad_ms:int,time_since_request_content_ms:int,time_since_started_content_ms:int,time_taken_mu:int,time_to_first_byte_mu:int,pause_duration_ms:int,pause_duration_ads_ms:int,pause_duration_content_ms:int,volume_level_percent:float>>
              Comment: ""
            - Name: geo_location
              Type: struct<city:string,country_code:string,country:string,latitude:float,longitude:float,postal_code:string,region_code:string,region:string,district:string,continent:string,continent_code:string,timezone_offset:float,timezone_name:string>
              Comment: ""
            - Name: network
              Type: struct<asn:string,asn_org:string,isp:string,network_type:string,mobile_connection:boolean>
              Comment: ""
            - Name: ops_metadata
              Type: struct<client_ts_ms:bigint,collector:string,collector_platform:string,configuration_name:string,connector:string,connector_config_name:string,customer:string,duplicate:boolean,enriched:boolean,msg_send_client_ts_ms:bigint,server_ts_offset_ms:int,enrichment_types:string>
              Comment: ""
            - Name: page
              Type: struct<dz_sdk_version:string,page_title:string,page_url:string,referrer_url:string,site_domain:string,referrer:string>
              Comment: ""
            - Name: player
              Type: struct<autostart:boolean,casting:boolean,controls:boolean,default_muted:boolean,default_playback_rate:float,fullscreen:boolean,loop:boolean,muted:boolean,player_name:string,player_version:string,preload:boolean,ready_state:string,streaming_protocol:string,streaming_type:string,subtitles:boolean>
              Comment: ""
            - Name: sampling
              Type: struct<in_sample:boolean,connector_sampling_rate:int>
              Comment: ""
            - Name: user_details
              Type: struct<app_session_id:string,app_session_start_ts_ms:bigint,app_session_end_ts_ms:bigint,content_session_id:string,client_ip:string,user_agent:string>
              Comment: ""
            - Name: video
              Type: struct<asset_id:string,description:string,duration_sec:float,frame_rate:float,media_type:string,player_height:int,player_width:int,source:string,title:string>
              Comment: ""
          InputFormat: org.apache.hadoop.mapred.TextInputFormat
          Location: s3://grafana-athena-query-results-ivs-datazoom-1
          SerdeInfo:
            SerializationLibrary: org.openx.data.jsonserde.JsonSerDe
    DependsOn:
      - CFNDatabaseEvents
      - AthenaGrafanaBucket

  AmazonGrafanaWorkspaceIAMRole:
    Type: "AWS::IAM::Role"
    Properties:
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/service-role/AmazonGrafanaAthenaAccess"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - grafana.amazonaws.com
            Action:
              - "sts:AssumeRole"

  AmazonS3IAMRole:
    Type: AWS::IAM::Role
    Properties:
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/AmazonS3FullAccess"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - firehose.amazonaws.com
            Action:
              - "sts:AssumeRole"

  AmazonGlueIAMRole:
    Type: AWS::IAM::Role
    Properties:
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/AWSGlueConsoleFullAccess"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - firehose.amazonaws.com
            Action:
              - "sts:AssumeRole"

  AmazonGrafanaWorkspace:
    Type: "AWS::Grafana::Workspace"
    Properties:
      AccountAccessType: CURRENT_ACCOUNT
      Name: AmazonGrafanaWorkspace
      Description: Amazon Grafana Workspace
      AuthenticationProviders:
        - AWS_SSO
      DataSources:
        - ATHENA
      PermissionType: SERVICE_MANAGED
      RoleArn: !GetAtt
        - AmazonGrafanaWorkspaceIAMRole
        - Arn

  KinesisDeliveryStream:
    Type: AWS::KinesisFirehose::DeliveryStream
    Properties:
      DeliveryStreamType: DirectPut
      ExtendedS3DestinationConfiguration:
        BucketARN: !GetAtt
          - KinesisBucket
          - Arn
        RoleARN: !GetAtt
          - AmazonS3IAMRole
          - Arn
        DataFormatConversionConfiguration:
          SchemaConfiguration:
            DatabaseName: !Ref CFNDatabaseEvents
            RoleARN: !GetAtt
              - AmazonGlueIAMRole
              - Arn
            TableName: !Ref CFNTableEvents
          InputFormatConfiguration:
            Deserializer:
              OpenXJsonSerDe: {}
          OutputFormatConfiguration:
            Serializer:
              ParquetSerDe: {}
    DependsOn:
      - AmazonS3IAMRole
      - AmazonGlueIAMRole
      - KinesisBucket
      - CFNDatabaseEvents
      - CFNTableEvents

Outputs:
  WorkspaceEndpoint:
    Value: !GetAtt
      - AmazonGrafanaWorkspace
      - Endpoint
  WorkspaceStatus:
    Value: !GetAtt
      - AmazonGrafanaWorkspace
      - Status
  WorkspaceId:
    Value: !Ref AmazonGrafanaWorkspace
  GrafanaVersion:
    Value: !GetAtt
      - AmazonGrafanaWorkspace
      - GrafanaVersion
