From 51e0dbeb61a04ba9674802ad74771ec25048f834 Mon Sep 17 00:00:00 2001 From: Sajeer N Date: Wed, 17 Jul 2019 17:03:07 +0530 Subject: [PATCH 01/86] Multiple auth mechanism support has been added for providers --- installer/core/providers/aws/__init__.py | 18 ++- .../core/providers/aws/boto3/__init__.py | 35 ++++++ .../core/providers/aws/boto3/aws_lambda.py | 21 ++-- installer/core/providers/aws/boto3/batch.py | 53 +++----- .../providers/aws/boto3/cloudwatch_event.py | 39 +++--- .../providers/aws/boto3/cloudwatch_log.py | 21 ++-- installer/core/providers/aws/boto3/ecr.py | 21 ++-- installer/core/providers/aws/boto3/ecs.py | 79 +++++------- installer/core/providers/aws/boto3/elb.py | 51 +++----- installer/core/providers/aws/boto3/es.py | 21 ++-- installer/core/providers/aws/boto3/iam.py | 115 +++++++++--------- installer/core/providers/aws/boto3/rds.py | 45 +++---- .../core/providers/aws/boto3/redshift.py | 37 ++---- installer/core/providers/aws/boto3/s3.py | 14 +++ installer/core/providers/aws/boto3/sts.py | 30 +++-- installer/core/providers/aws/boto3/vpc.py | 37 ++---- installer/core/providers/aws/destroy.py | 2 + installer/core/providers/aws/input.py | 84 ++++++++++--- installer/core/providers/aws/install.py | 3 +- installer/core/providers/aws/validate.py | 83 ++++++------- 20 files changed, 397 insertions(+), 412 deletions(-) create mode 100644 installer/core/providers/aws/boto3/s3.py diff --git a/installer/core/providers/aws/__init__.py b/installer/core/providers/aws/__init__.py index 5d5ffcde0..2939b1594 100644 --- a/installer/core/providers/aws/__init__.py +++ b/installer/core/providers/aws/__init__.py @@ -7,6 +7,7 @@ import inspect import json import os +import uuid class BaseAction(MsgMixin): @@ -52,13 +53,20 @@ def files_count_in_output_status_dir(self): def _create_terraform_provider_file(self): """Terraform provider file is created as part of installation/destruction execution""" terraform_provider_file = get_terraform_provider_file() + + aws_provider = {'region': self.input.AWS_AUTH_CRED['aws_region']} + if self.input.AWS_AUTH_CRED['aws_auth_option'] == 1: + aws_provider['access_key'] = self.input.AWS_AUTH_CRED['aws_access_key'] + aws_provider['secret_key'] = self.input.AWS_AUTH_CRED['aws_secret_key'] + elif self.input.AWS_AUTH_CRED['aws_auth_option'] == 2: + aws_provider['assume_role'] = { + 'role_arn': self.input.AWS_AUTH_CRED['assume_role_arn'], + 'session_name': str(uuid.uuid4()) + } + provider_script = { 'provider': { - 'aws': { - 'access_key': self.input.aws_access_key, - 'secret_key': self.input.aws_secret_key, - 'region': self.input.aws_region - } + 'aws': aws_provider } } diff --git a/installer/core/providers/aws/boto3/__init__.py b/installer/core/providers/aws/boto3/__init__.py index e69de29bb..35cab8047 100644 --- a/installer/core/providers/aws/boto3/__init__.py +++ b/installer/core/providers/aws/boto3/__init__.py @@ -0,0 +1,35 @@ +import boto3 + + +def prepare_aws_client_with_given_cred(service_name, aws_auth_cred=None): + auth_data = {} + + if aws_auth_cred: + if aws_auth_cred['aws_auth_option'] == 1: + auth_data['aws_access_key_id'] = aws_auth_cred['aws_access_key'] + auth_data['aws_secret_access_key'] = aws_auth_cred['aws_secret_key'] + elif aws_auth_cred['aws_auth_option'] == 2: + auth_data['aws_access_key_id'] = aws_auth_cred['tmp_credentials']['AccessKeyId'] + auth_data['aws_secret_access_key'] = aws_auth_cred['tmp_credentials']['SecretAccessKey'] + auth_data['aws_session_token'] = aws_auth_cred['tmp_credentials']['SessionToken'] + + auth_data['region_name'] = aws_auth_cred['aws_region'] + + return boto3.client(service_name, **auth_data) + + +def prepare_aws_resource_with_given_cred(service_name, aws_auth_cred=None): + auth_data = {} + + if aws_auth_cred: + if aws_auth_cred['aws_auth_option'] == 1: + auth_data['aws_access_key_id'] = aws_auth_cred['aws_access_key'] + auth_data['aws_secret_access_key'] = aws_auth_cred['aws_secret_key'] + elif aws_auth_cred['aws_auth_option'] == 2: + auth_data['aws_access_key_id'] = aws_auth_cred['tmp_credentials']['AccessKeyId'] + auth_data['aws_secret_access_key'] = aws_auth_cred['tmp_credentials']['SecretAccessKey'] + auth_data['aws_session_token'] = aws_auth_cred['tmp_credentials']['SessionToken'] + + auth_data['region_name'] = aws_auth_cred['aws_region'] + + return boto3.resource(service_name, **auth_data) diff --git a/installer/core/providers/aws/boto3/aws_lambda.py b/installer/core/providers/aws/boto3/aws_lambda.py index e8fa321f3..373334743 100644 --- a/installer/core/providers/aws/boto3/aws_lambda.py +++ b/installer/core/providers/aws/boto3/aws_lambda.py @@ -1,39 +1,32 @@ +from core.providers.aws.boto3 import prepare_aws_client_with_given_cred import boto3 -def get_lambda_client(access_key, secret_key, region): +def get_lambda_client(aws_auth_cred): """ Returns the client object for AWS Lambda Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: obj: Lambda Client Obj """ - return boto3.client( - "lambda", - region_name=region, - aws_access_key_id=access_key, - aws_secret_access_key=secret_key) + return prepare_aws_client_with_given_cred("lambda", aws_auth_cred) -def check_function_exists(function_name, access_key, secret_key, region): +def check_function_exists(function_name, aws_auth_cred): """ Checks the passed lambda function exists or not Args: function_name (str): AWS Lambda function name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: boolean: True if Lambda exists else False """ - client = get_lambda_client(access_key, secret_key, region) + client = get_lambda_client(aws_auth_cred) try: response = client.get_function(FunctionName=function_name) return True if response['Configuration'] else False diff --git a/installer/core/providers/aws/boto3/batch.py b/installer/core/providers/aws/boto3/batch.py index 3f668b5d9..81a32d9e6 100644 --- a/installer/core/providers/aws/boto3/batch.py +++ b/installer/core/providers/aws/boto3/batch.py @@ -1,39 +1,32 @@ +from core.providers.aws.boto3 import prepare_aws_client_with_given_cred import boto3 -def get_batch_client(access_key, secret_key, region): +def get_batch_client(aws_auth_cred): """ Returns the client object for AWS Batch Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: obj: AWS Batch Client Obj """ - return boto3.client( - 'batch', - region_name=region, - aws_access_key_id=access_key, - aws_secret_access_key=secret_key) + return prepare_aws_client_with_given_cred('batch', aws_auth_cred) -def get_compute_environments(compute_envs, access_key, secret_key, region): +def get_compute_environments(compute_envs, aws_auth_cred): """ Returns AWS Batch compute envs list with all details Args: compute_envs (list): List of compute env names - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: envs (list): List of all Batch compute envs with all details """ - client = get_batch_client(access_key, secret_key, region) + client = get_batch_client(aws_auth_cred) response = client.describe_compute_environments( computeEnvironments=compute_envs @@ -42,34 +35,30 @@ def get_compute_environments(compute_envs, access_key, secret_key, region): return response['computeEnvironments'] -def check_compute_env_exists(compute_env, access_key, secret_key, region): +def check_compute_env_exists(compute_env, aws_auth_cred): """ Check whether the given compute env name already exists in AWS account Args: compute_env (str): Compute env name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - if len(get_compute_environments([compute_env], access_key, secret_key, region)): + if len(get_compute_environments([compute_env], aws_auth_cred)): return True else: return False -def get_job_definitions(job_def_name, access_key, secret_key, region): +def get_job_definitions(job_def_name, aws_auth_cred): """ Get all job definition versions with details Args: job_def_name (str): Job definiiton name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: jobDefinitions (list): List of all job definitions with details @@ -82,41 +71,37 @@ def get_job_definitions(job_def_name, access_key, secret_key, region): return response['jobDefinitions'] -def check_job_definition_exists(job_def_name, access_key, secret_key, region): +def check_job_definition_exists(job_def_name, aws_auth_cred): """ Check whether the given job definiiton exists in AWS Batch Args: job_def_name (str): Job definiiton name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if it already exists else False """ - client = get_batch_client(access_key, secret_key, region) + client = get_batch_client(aws_auth_cred) try: - job_definitions = get_job_definitions(job_def_name, access_key, secret_key, region) + job_definitions = get_job_definitions(job_def_name, aws_auth_cred) return True if len(job_definitions) else False except: return False -def check_job_queue_exists(job_queue_name, access_key, secret_key, region): +def check_job_queue_exists(job_queue_name, aws_auth_cred): """ Check whether the given job queue exists in AWS Batch Args: job_queue_name (str): Job Queue name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if it already exists else False """ - client = get_batch_client(access_key, secret_key, region) + client = get_batch_client(aws_auth_cred) try: response = client.describe_job_queues( jobQueues=[job_queue_name], diff --git a/installer/core/providers/aws/boto3/cloudwatch_event.py b/installer/core/providers/aws/boto3/cloudwatch_event.py index a43fc5d3e..453793128 100644 --- a/installer/core/providers/aws/boto3/cloudwatch_event.py +++ b/installer/core/providers/aws/boto3/cloudwatch_event.py @@ -1,39 +1,32 @@ +from core.providers.aws.boto3 import prepare_aws_client_with_given_cred import boto3 -def get_event_client(access_key, secret_key, region): +def get_event_client(aws_auth_cred): """ Returns the client object for AWS Events Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: obj: AWS Cloudwatch Event Client Obj """ - return boto3.client( - "events", - region_name=region, - aws_access_key_id=access_key, - aws_secret_access_key=secret_key) + return prepare_aws_client_with_given_cred("events", aws_auth_cred) -def check_rule_exists(rule_name, access_key, secret_key, region): +def check_rule_exists(rule_name, aws_auth_cred): """ Check wheter the given cloudwatch rule already exists in AWS account Args: rule_name (str): Cloudwatch rule name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_event_client(access_key, secret_key, region) + client = get_event_client(aws_auth_cred) try: response = client.describe_rule(Name=rule_name) return True if response else False @@ -41,20 +34,18 @@ def check_rule_exists(rule_name, access_key, secret_key, region): return False -def get_targets_of_a_rule(rule_name, access_key, secret_key, region): +def get_targets_of_a_rule(rule_name, aws_auth_cred): """ Returns the targets of the given cloudwatch rule Args: rule_name (str): Cloudwatch rule name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: targets (list): List of all targets attached to a rule """ - client = get_event_client(access_key, secret_key, region) + client = get_event_client(aws_auth_cred) try: response = client.list_targets_by_rule( @@ -66,22 +57,20 @@ def get_targets_of_a_rule(rule_name, access_key, secret_key, region): return response['Targets'] -def remove_all_targets_of_a_rule(rule_name, access_key, secret_key, region): +def remove_all_targets_of_a_rule(rule_name, aws_auth_cred): """ Remove all targets of a rule Args: rule_name (str): Cloudwatch rule name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials """ - targets = get_targets_of_a_rule(rule_name, access_key, secret_key, region) + targets = get_targets_of_a_rule(rule_name, aws_auth_cred) target_ids = [item['Id'] for item in targets] if len(target_ids) > 0: - client = get_event_client(access_key, secret_key, region) + client = get_event_client(aws_auth_cred) client.remove_targets( Rule=rule_name, diff --git a/installer/core/providers/aws/boto3/cloudwatch_log.py b/installer/core/providers/aws/boto3/cloudwatch_log.py index 582ecd88f..775fd9504 100644 --- a/installer/core/providers/aws/boto3/cloudwatch_log.py +++ b/installer/core/providers/aws/boto3/cloudwatch_log.py @@ -1,39 +1,32 @@ +from core.providers.aws.boto3 import prepare_aws_client_with_given_cred import boto3 -def get_logs_client(access_key, secret_key, region): +def get_logs_client(aws_auth_cred): """ Returns the client object for AWS Cloudwatch Log Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: obj: AWS Cloudwatch Event Log Obj """ - return boto3.client( - "logs", - region_name=region, - aws_access_key_id=access_key, - aws_secret_access_key=secret_key) + return prepare_aws_client_with_given_cred("logs", aws_auth_cred) -def check_log_group_exists(log_group_name, access_key, secret_key, region): +def check_log_group_exists(log_group_name, aws_auth_cred): """ Check wheter the given cloudwatch log group already exists in AWS account Args: log_group_name (str): Cloudwatch log group name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_logs_client(access_key, secret_key, region) + client = get_logs_client(aws_auth_cred) try: response = client.describe_log_groups(logGroupNamePrefix=log_group_name) return True if len(response['logGroups']) else False diff --git a/installer/core/providers/aws/boto3/ecr.py b/installer/core/providers/aws/boto3/ecr.py index 50f31f4f6..8156d92ce 100644 --- a/installer/core/providers/aws/boto3/ecr.py +++ b/installer/core/providers/aws/boto3/ecr.py @@ -1,39 +1,32 @@ +from core.providers.aws.boto3 import prepare_aws_client_with_given_cred import boto3 -def get_ecr_client(access_key, secret_key, region): +def get_ecr_client(aws_auth_cred): """ Returns the client object for AWS ECR (Elastic COntainer Repository) Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: obj: AWS ECR Object """ - return boto3.client( - "ecr", - region_name=region, - aws_access_key_id=access_key, - aws_secret_access_key=secret_key) + return prepare_aws_client_with_given_cred("ecr", aws_auth_cred) -def check_ecr_exists(repo_name, access_key, secret_key, region): +def check_ecr_exists(repo_name, aws_auth_cred): """ Check wheter the given ECR already exists in AWS account Args: repo_name (str): Repository name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_ecr_client(access_key, secret_key, region) + client = get_ecr_client(aws_auth_cred) try: response = client.describe_repositories(repositoryNames=[repo_name]) return True if len(response['repositories']) else False diff --git a/installer/core/providers/aws/boto3/ecs.py b/installer/core/providers/aws/boto3/ecs.py index 49c4c6873..35f4fc283 100644 --- a/installer/core/providers/aws/boto3/ecs.py +++ b/installer/core/providers/aws/boto3/ecs.py @@ -1,36 +1,29 @@ +from core.providers.aws.boto3 import prepare_aws_client_with_given_cred import boto3 -def get_ecs_client(access_key, secret_key, region): +def get_ecs_client(aws_auth_cred): """ Returns the client object for AWS ECS Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: obj: AWS ECS Object """ - return boto3.client( - "ecs", - region_name=region, - aws_access_key_id=access_key, - aws_secret_access_key=secret_key) + return prepare_aws_client_with_given_cred("ecs", aws_auth_cred) -def deregister_task_definition(access_key, secret_key, region, task_definition): +def deregister_task_definition(task_definition, aws_auth_cred): """ Deregister all revisions of a given task definition from ECS Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region task_definition (str): Task definition name + aws_auth (dict): Dict containing AWS credentials """ - client = get_ecs_client(access_key, secret_key, region) + client = get_ecs_client(aws_auth_cred) # We need to get the list of all Active revisions of the given task definition # So we cannot use describe_task_definition which return the latest one only tasks_definitions = client.list_task_definitions(familyPrefix=task_definition) @@ -39,20 +32,18 @@ def deregister_task_definition(access_key, secret_key, region, task_definition): client.deregister_task_definition(taskDefinition=task_def) -def check_ecs_cluster_exists(cluster, access_key, secret_key, region): +def check_ecs_cluster_exists(cluster, aws_auth_cred): """ Check wheter the given ECS cluster already exists in AWS account Args: cluster (str): Repository name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_ecs_client(access_key, secret_key, region) + client = get_ecs_client(aws_auth_cred) try: response = client.describe_clusters(Names=[cluster]) return True if len(response['clusters']) else False @@ -60,20 +51,18 @@ def check_ecs_cluster_exists(cluster, access_key, secret_key, region): return False -def check_ecs_task_definition_exists(task_definition, access_key, secret_key, region): +def check_ecs_task_definition_exists(task_definition, aws_auth_cred): """ Check wheter the given ECS Task definition already exists in AWS account Args: task_definition (str): Task Definition Name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_ecs_client(access_key, secret_key, region) + client = get_ecs_client(aws_auth_cred) try: response = client.describe_task_definition(taskDefinition=task_definition) return True if response['taskDefinition'] else False @@ -81,20 +70,18 @@ def check_ecs_task_definition_exists(task_definition, access_key, secret_key, re return False -def check_ecs_service_exists(service_name, cluster, access_key, secret_key, region): +def check_ecs_service_exists(service_name, cluster, aws_auth_cred): """ Check wheter the given ECS CLuster service already exists in AWS account Args: service_name (str): ECS CLuster service name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_ecs_client(access_key, secret_key, region) + client = get_ecs_client(aws_auth_cred) try: response = client.describe_services(services=[service_name], cluster=cluster) return True if len(response['services']) else False @@ -102,20 +89,18 @@ def check_ecs_service_exists(service_name, cluster, access_key, secret_key, regi return False -def get_all_task_arns(cluster, access_key, secret_key, region): +def get_all_task_arns(cluster, aws_auth_cred): """ Get all task arns in a given cluster Args: cluster (str): Cluster name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: taskArns (list): List of all task arns """ - client = get_ecs_client(access_key, secret_key, region) + client = get_ecs_client(aws_auth_cred) try: response = client.list_tasks(cluster=cluster) @@ -125,37 +110,33 @@ def get_all_task_arns(cluster, access_key, secret_key, region): return response['taskArns'] -def stop_all_tasks_in_a_cluster(cluster, access_key, secret_key, region): +def stop_all_tasks_in_a_cluster(cluster, aws_auth_cred): """ Terminate all tasks in a given cluster Args: cluster (str): Cluster name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials """ - task_arns = get_all_task_arns(cluster, access_key, secret_key, region) + task_arns = get_all_task_arns(cluster, aws_auth_cred) - client = get_ecs_client(access_key, secret_key, region) + client = get_ecs_client(aws_auth_cred) for task_arn in task_arns: client.stop_task(task=task_arn, cluster=cluster) -def delete_cluster(cluster, access_key, secret_key, region): +def delete_cluster(cluster, aws_auth_cred): """ Delete a cluster from AWS ECS Args: cluster (str): Cluster name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: boolean: True if cluster get deleted else False """ - client = get_ecs_client(access_key, secret_key, region) + client = get_ecs_client(aws_auth_cred) try: client.delete_cluster(cluster=cluster) @@ -164,17 +145,15 @@ def delete_cluster(cluster, access_key, secret_key, region): return False -def delete_container_instances(cluster, access_key, secret_key, region): +def delete_container_instances(cluster, aws_auth_cred): """ Delete all contianer instances(Ec2) from a cluster Args: cluster (str): Cluster name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials """ - client = get_ecs_client(access_key, secret_key, region) + client = get_ecs_client(aws_auth_cred) container_arns = client.list_container_instances(cluster=cluster)['containerInstanceArns'] for container_arn in container_arns: try: diff --git a/installer/core/providers/aws/boto3/elb.py b/installer/core/providers/aws/boto3/elb.py index fdb39741f..49909bfce 100644 --- a/installer/core/providers/aws/boto3/elb.py +++ b/installer/core/providers/aws/boto3/elb.py @@ -1,39 +1,32 @@ +from core.providers.aws.boto3 import prepare_aws_client_with_given_cred import boto3 -def get_elbv2_client(access_key, secret_key, region): +def get_elbv2_client(aws_auth_cred): """ Returns the client object for AWS ELB Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: obj: AWS ELB Object """ - return boto3.client( - "elbv2", - region_name=region, - aws_access_key_id=access_key, - aws_secret_access_key=secret_key) + return prepare_aws_client_with_given_cred("elbv2", aws_auth_cred) -def get_alb(alb_name, access_key, secret_key, region): +def get_alb(alb_name, aws_auth_cred): """ Find and return loadbalancers of mentioned name Args: alb_name (str): Load balancer name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: alb (dict): Loadbalancer details """ - client = get_elbv2_client(access_key, secret_key, region) + client = get_elbv2_client(aws_auth_cred) try: response = client.describe_load_balancers(Names=[alb_name]) albs = response['LoadBalancers'] @@ -43,36 +36,32 @@ def get_alb(alb_name, access_key, secret_key, region): return None -def check_alb_exists(alb_name, access_key, secret_key, region): +def check_alb_exists(alb_name, aws_auth_cred): """ Check whether the given ALB already exists in the AWS Account Args: alb_name (str): Load balancer name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - return True if get_alb(alb_name, access_key, secret_key, region) else False + return True if get_alb(alb_name, aws_auth_cred) else False -def check_target_group_exists(tg_name, access_key, secret_key, region): +def check_target_group_exists(tg_name, aws_auth_cred): """ Check whether the given Target group already exists in the AWS Account Args: tg_name (str): Target group name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_elbv2_client(access_key, secret_key, region) + client = get_elbv2_client(aws_auth_cred) try: response = client.describe_target_groups(Names=[tg_name]) return True if len(response['TargetGroups']) else False @@ -80,23 +69,21 @@ def check_target_group_exists(tg_name, access_key, secret_key, region): return False -def delete_all_listeners_of_alb(alb_name, access_key, secret_key, region): +def delete_all_listeners_of_alb(alb_name, aws_auth_cred): """ Delete all listeners and target roups of a load balancers Args: alb_name (str): Load balancer name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - alb = get_alb(alb_name, access_key, secret_key, region) + alb = get_alb(alb_name, aws_auth_cred) if alb: - client = get_elbv2_client(access_key, secret_key, region) + client = get_elbv2_client(aws_auth_cred) listeners = client.describe_listeners(LoadBalancerArn=alb['LoadBalancerArn']) for listener in listeners['Listeners']: @@ -106,8 +93,8 @@ def delete_all_listeners_of_alb(alb_name, access_key, secret_key, region): raise Exception("Not able to remove listener: %s" % listener['ListenerArn']) -def delete_alltarget_groups(tg_names, access_key, secret_key, region): - client = get_elbv2_client(access_key, secret_key, region) +def delete_alltarget_groups(tg_names, aws_auth_cred): + client = get_elbv2_client(aws_auth_cred) try: target_groups = client.describe_target_groups(Names=tg_names) tgs = target_groups['TargetGroups'] diff --git a/installer/core/providers/aws/boto3/es.py b/installer/core/providers/aws/boto3/es.py index f77771d83..b30ac5b5d 100644 --- a/installer/core/providers/aws/boto3/es.py +++ b/installer/core/providers/aws/boto3/es.py @@ -1,39 +1,32 @@ +from core.providers.aws.boto3 import prepare_aws_client_with_given_cred import boto3 -def get_es_client(access_key, secret_key, region): +def get_es_client(aws_auth_cred): """ Returns the client object for AWS Elasticsearch Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: obj: AWS Elasticsearch Object """ - return boto3.client( - 'es', - region_name=region, - aws_access_key_id=access_key, - aws_secret_access_key=secret_key) + return prepare_aws_client_with_given_cred("es", aws_auth_cred) -def check_es_domain_exists(domain_name, access_key, secret_key, region): +def check_es_domain_exists(domain_name, aws_auth_cred): """ Check wheter the given ES Domain already exists in the AWS Account Args: domain_name (str): ES Domain name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_es_client(access_key, secret_key, region) + client = get_es_client(aws_auth_cred) try: response = client.describe_elasticsearch_domain( DomainName=domain_name diff --git a/installer/core/providers/aws/boto3/iam.py b/installer/core/providers/aws/boto3/iam.py index 4d63db1d8..62d7f60cb 100644 --- a/installer/core/providers/aws/boto3/iam.py +++ b/installer/core/providers/aws/boto3/iam.py @@ -1,99 +1,89 @@ +from core.providers.aws.boto3 import prepare_aws_client_with_given_cred +from core.providers.aws.boto3 import prepare_aws_resource_with_given_cred import boto3 -def get_iam_client(access_key, secret_key): +def get_iam_client(aws_auth_cred): """ Returns the client object for AWS IAM Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key + aws_auth_cred (dict): AWS Auth details with region information Returns: obj: AWS IAM Object """ - return boto3.client( - 'iam', - aws_access_key_id=access_key, - aws_secret_access_key=secret_key) + return prepare_aws_client_with_given_cred('iam', aws_auth_cred) -def get_iam_resource(access_key, secret_key): +def get_iam_resource(aws_auth_cred): """ Returns the Resource client object for AWS IAM Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key + aws_auth_cred (dict): AWS Auth details with region information Returns: obj: AWS IAM Resource Object """ - return boto3.resource( - 'iam', - aws_access_key_id=access_key, - aws_secret_access_key=secret_key) + return prepare_aws_resource_with_given_cred('iam', aws_auth_cred) -def get_user_name(access_key, secret_key): +def get_user_name(aws_auth_cred): """ Returns the username of the given user credentails Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key + aws_auth_cred (dict): AWS Auth details with region information Returns: user_name (str): AWS IAM User name """ - iam = get_iam_resource(access_key, secret_key) + iam = get_iam_resource(aws_auth_cred) user_name = iam.CurrentUser().user_name return user_name -def get_current_user(access_key, secret_key): +def get_current_user(aws_auth_cred): """ Returns the user detials of the given user credentails Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key + aws_auth_cred (dict): AWS Auth details with region information Returns: user (obj): AWS IAM User """ - iam = get_iam_resource(access_key, secret_key) + iam = get_iam_resource(aws_auth_cred) return iam.CurrentUser() -def get_aws_account_user(access_key, secret_key): +def get_aws_account_user(aws_auth_cred): """ Returns the user details of the current user Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key + aws_auth_cred (dict): AWS Auth details with region information Returns: obj: AWS IAM User """ - return get_iam_resource.CurrentUser(access_key, secret_key) + return get_iam_resource.CurrentUser() -def get_iam_user_policy_names(access_key, secret_key, user_name): +def get_iam_user_policy_names(user_name, aws_auth_cred): """ Returns the policy names of the current user has Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key + aws_auth_cred (dict): AWS Auth details with region information user_name (str): AWS user name Returns: policy_names (list): List of policy names the current user has """ - iam_client = get_iam_client(access_key, secret_key) + iam_client = get_iam_client(aws_auth_cred) attached_policies = iam_client.list_attached_user_policies(UserName=user_name)['AttachedPolicies'] attached_policy_names = [policy['PolicyName'] for policy in attached_policies] user_policy_names = iam_client.list_user_policies(UserName=user_name)['PolicyNames'] @@ -139,19 +129,18 @@ def get_group_policy_names(iam_client, groups): return policy_names -def get_user_group_policy_names(access_key, secret_key, user_name): +def get_user_group_policy_names(user_name, aws_auth_cred): """ Returns all group user policies of a user Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key + aws_auth_cred (dict): AWS Auth details with region information user_name (str): AWS user name Returns: policy_names (list): List of all goup policy names the current user has """ - iam_client = get_iam_client(access_key, secret_key) + iam_client = get_iam_client(aws_auth_cred) groups = iam_client.list_groups_for_user(UserName=user_name)['Groups'] group_managed_policy_names = get_group_managed_policy_names(iam_client, groups) group_policy_names = get_group_policy_names(iam_client, groups) @@ -159,33 +148,48 @@ def get_user_group_policy_names(access_key, secret_key, user_name): return group_managed_policy_names + group_policy_names -def get_all_policy_names(access_key, secret_key): +def get_all_policy_names(aws_auth_cred): """ Returns all group and user policies of a user Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key + aws_auth_cred (dict): AWS Auth details with region information Returns: policy_names (list): List of all goup policy names and user policy names the current user has """ - iam = get_iam_resource(access_key, secret_key) + iam = get_iam_resource(aws_auth_cred) user_name = iam.CurrentUser().user_name - user_policy_names = get_iam_user_policy_names(access_key, secret_key, user_name) - user_group_policy_names = get_user_group_policy_names(access_key, secret_key, user_name) + user_policy_names = get_iam_user_policy_names(user_name, aws_auth_cred) + user_group_policy_names = get_user_group_policy_names(user_name, aws_auth_cred) return user_policy_names + user_group_policy_names -def create_iam_service_linked_role(access_key, secret_key, service_name, desc): +def get_role_policy_names(role_name, aws_auth_cred): """ - Create AWS ES service linked role + Returns all policies under the given IAM role Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key + aws_auth_cred (dict): AWS Auth details with region information + role_name (str): Role name + + Returns: + policy_names (list): List of all goup policy names and user policy names the current user has + """ + iam_client = get_iam_client(aws_auth_cred) + attached_policies = iam_client.list_attached_role_policies(RoleName=role_name)['AttachedPolicies'] + + return [policy['PolicyName'] for policy in attached_policies] + + +def create_iam_service_linked_role(service_name, desc, aws_auth_cred): + """ + Create AWS RoleNameES service linked role + + Args: + aws_auth_cred (dict): AWS Auth details with region information service_name (str): Service name desc (str): Descsription @@ -193,7 +197,7 @@ def create_iam_service_linked_role(access_key, secret_key, service_name, desc): Set: True if created else false with error """ role_name = "AWSServiceRoleForAmazonElasticsearchService" - iam_client = get_iam_client(access_key, secret_key) + iam_client = get_iam_client(aws_auth_cred) try: iam_client.create_service_linked_role( AWSServiceName=service_name, @@ -204,19 +208,18 @@ def create_iam_service_linked_role(access_key, secret_key, service_name, desc): return False, str(e) -def check_role_exists(role_name, access_key, secret_key): +def check_role_exists(role_name, aws_auth_cred): """ Check wheter the given IAM role already exists in the AWS Account Args: role_name (str): Role name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key + aws_auth_cred (dict): AWS Auth details with region information Returns: Boolean: True if env exists else False """ - iam_client = get_iam_client(access_key, secret_key) + iam_client = get_iam_client(aws_auth_cred) try: role = iam_client.get_role(RoleName=role_name) return True if role else False @@ -224,19 +227,18 @@ def check_role_exists(role_name, access_key, secret_key): return False -def check_policy_exists(policy_name, access_key, secret_key, account_id): +def check_policy_exists(policy_name, account_id, aws_auth_cred): """ Check wheter the given IAM policy already exists in the AWS Account Args: policy_name (str): Policy name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key + aws_auth_cred (dict): AWS Auth details with region information Returns: Boolean: True if env exists else False """ - iam_client = get_iam_client(access_key, secret_key) + iam_client = get_iam_client(aws_auth_cred) policy_arn = "arn:aws:iam::%s:policy/%s" % (str(account_id), policy_name) try: @@ -246,19 +248,18 @@ def check_policy_exists(policy_name, access_key, secret_key, account_id): return False -def check_instance_profile_exists(instance_profile_name, access_key, secret_key): +def check_instance_profile_exists(instance_profile_name, aws_auth_cred): """ Check wheter the given IAM instance profile already exists in the AWS Account Args: instance_profile_name (str): Instance profile name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key + aws_auth_cred (dict): AWS Auth details with region information Returns: Boolean: True if env exists else False """ - iam_client = get_iam_client(access_key, secret_key) + iam_client = get_iam_client(aws_auth_cred) try: profile = iam_client.get_instance_profile(InstanceProfileName=instance_profile_name) return True if profile else False diff --git a/installer/core/providers/aws/boto3/rds.py b/installer/core/providers/aws/boto3/rds.py index f78e533f8..cfcd6bc14 100644 --- a/installer/core/providers/aws/boto3/rds.py +++ b/installer/core/providers/aws/boto3/rds.py @@ -1,39 +1,32 @@ +from core.providers.aws.boto3 import prepare_aws_client_with_given_cred import boto3 -def get_rds_client(access_key, secret_key, region): +def get_rds_client(aws_auth_cred): """ Returns the client object for AWS RDS Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: obj: AWS RDS Object """ - return boto3.client( - 'rds', - region_name=region, - aws_access_key_id=access_key, - aws_secret_access_key=secret_key) + return prepare_aws_client_with_given_cred("rds", aws_auth_cred) -def check_rds_instance_exists(instance_identifier, access_key, secret_key, region): +def check_rds_instance_exists(instance_identifier, aws_auth_cred): """ Check wheter the given RDS Instance already exists in the AWS Account Args: instance_identifier (str): RDS instance identifier - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_rds_client(access_key, secret_key, region) + client = get_rds_client(aws_auth_cred) try: response = client.describe_db_instances( DBInstanceIdentifier=instance_identifier @@ -43,20 +36,18 @@ def check_rds_instance_exists(instance_identifier, access_key, secret_key, regio return False -def check_rds_option_group_exists(name, access_key, secret_key, region): +def check_rds_option_group_exists(name, aws_auth_cred): """ Check wheter the given RDS Option Group already exists in the AWS Account Args: name (str): RDS Option Group name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_rds_client(access_key, secret_key, region) + client = get_rds_client(aws_auth_cred) try: response = client.describe_option_groups( OptionGroupName=name @@ -66,20 +57,18 @@ def check_rds_option_group_exists(name, access_key, secret_key, region): return False -def check_rds_parameter_group_exists(name, access_key, secret_key, region): +def check_rds_parameter_group_exists(name, aws_auth_cred): """ Check wheter the given RDS Parameter Group already exists in the AWS Account Args: name (str): RDS Parameter Group name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_rds_client(access_key, secret_key, region) + client = get_rds_client(aws_auth_cred) try: response = client.describe_db_parameter_groups( DBParameterGroupName=name @@ -89,20 +78,18 @@ def check_rds_parameter_group_exists(name, access_key, secret_key, region): return False -def check_rds_subnet_group_exists(name, access_key, secret_key, region): +def check_rds_subnet_group_exists(name, aws_auth_cred): """ Check wheter the given RDS SUbnet Group already exists in the AWS Account Args: name (str): RDS Subnet Group name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_rds_client(access_key, secret_key, region) + client = get_rds_client(aws_auth_cred) try: response = client.describe_db_subnet_groups( DBSubnetGroupName=name diff --git a/installer/core/providers/aws/boto3/redshift.py b/installer/core/providers/aws/boto3/redshift.py index df1e0bc02..9a074bb09 100644 --- a/installer/core/providers/aws/boto3/redshift.py +++ b/installer/core/providers/aws/boto3/redshift.py @@ -1,39 +1,32 @@ +from core.providers.aws.boto3 import prepare_aws_client_with_given_cred import boto3 -def get_redshift_client(access_key, secret_key, region): +def get_redshift_client(aws_auth_cred): """ Returns the client object for AWS Redshift Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: obj: AWS Redshift Object """ - return boto3.client( - 'redshift', - region_name=region, - aws_access_key_id=access_key, - aws_secret_access_key=secret_key) + return prepare_aws_client_with_given_cred("redshift", aws_auth_cred) -def check_redshift_cluster_exists(cluster_identifier, access_key, secret_key, region): +def check_redshift_cluster_exists(cluster_identifier, aws_auth_cred): """ Check wheter the given Redshift cluster already exists in the AWS Account Args: cluster_identifier (str): Redshift cluster identifier - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_redshift_client(access_key, secret_key, region) + client = get_redshift_client(aws_auth_cred) try: response = client.describe_clusters( ClusterIdentifier=cluster_identifier @@ -43,20 +36,18 @@ def check_redshift_cluster_exists(cluster_identifier, access_key, secret_key, re return False -def check_redshift_parameter_group_exists(name, access_key, secret_key, region): +def check_redshift_parameter_group_exists(name, aws_auth_cred): """ Check wheter the given Redshift Parameter Group already exists in the AWS Account Args: name (str): Redshift Parameter Group name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_redshift_client(access_key, secret_key, region) + client = get_redshift_client(aws_auth_cred) try: response = client.describe_cluster_parameter_groups( ParameterGroupName=name @@ -66,20 +57,18 @@ def check_redshift_parameter_group_exists(name, access_key, secret_key, region): return False -def check_redshift_subnet_group_exists(name, access_key, secret_key, region): +def check_redshift_subnet_group_exists(name, aws_auth_cred): """ Check wheter the given Redshift SUbnet Group already exists in the AWS Account Args: name (str): Redshift Subnet Group name - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_redshift_client(access_key, secret_key, region) + client = get_redshift_client(aws_auth_cred) try: response = client.describe_cluster_subnet_groups( ClusterSubnetGroupName=name diff --git a/installer/core/providers/aws/boto3/s3.py b/installer/core/providers/aws/boto3/s3.py new file mode 100644 index 000000000..6cad49ee7 --- /dev/null +++ b/installer/core/providers/aws/boto3/s3.py @@ -0,0 +1,14 @@ +from core.providers.aws.boto3 import prepare_aws_client_with_given_cred + + +def get_s3_client(aws_auth_cred): + """ + Returns the client object for AWS EC2 + + Args: + aws_auth (dict): Dict containing AWS credentials + + Returns: + obj: AWS EC2 Client Object + """ + return prepare_aws_client_with_given_cred('s3', aws_auth_cred) diff --git a/installer/core/providers/aws/boto3/sts.py b/installer/core/providers/aws/boto3/sts.py index e4ffdb83f..6df3ac397 100644 --- a/installer/core/providers/aws/boto3/sts.py +++ b/installer/core/providers/aws/boto3/sts.py @@ -1,32 +1,40 @@ +from core.providers.aws.boto3 import prepare_aws_client_with_given_cred import boto3 +import uuid -def get_sts_client(access_key, secret_key): +def get_sts_client(aws_auth_cred): """ Returns AWS sts client object Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key + aws_auth (dict): Dict containing AWS credentials Returns: obj: AWS Sts client Object """ - return boto3.client( - "sts", - aws_access_key_id=access_key, - aws_secret_access_key=secret_key) + return prepare_aws_client_with_given_cred('sts', aws_auth_cred) -def get_user_account_id(access_key, secret_key): +def generate_temp_credentials(assume_role_arn): + response = boto3.client( + 'sts' + ).assume_role( + RoleArn=assume_role_arn, + RoleSessionName=str(uuid.uuid4()) + ) + + return response['Credentials'] + + +def get_aws_caller_identity(aws_auth_cred): """ Returns AWS user account id from the given credentials Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key + aws_auth (dict): Dict containing AWS credentials Returns: account_id (str): AWS user account ID """ - return get_sts_client(access_key, secret_key).get_caller_identity().get('Account') + return get_sts_client(aws_auth_cred).get_caller_identity() diff --git a/installer/core/providers/aws/boto3/vpc.py b/installer/core/providers/aws/boto3/vpc.py index b06ed40cb..3c2df717b 100644 --- a/installer/core/providers/aws/boto3/vpc.py +++ b/installer/core/providers/aws/boto3/vpc.py @@ -1,57 +1,48 @@ +from core.providers.aws.boto3 import prepare_aws_client_with_given_cred import boto3 -def get_ec2_client(access_key, secret_key, region): +def get_ec2_client(aws_auth_cred): """ Returns the client object for AWS EC2 Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: obj: AWS EC2 Client Object """ - return boto3.client( - 'ec2', - region_name=region, - aws_access_key_id=access_key, - aws_secret_access_key=secret_key) + return prepare_aws_client_with_given_cred('ec2', aws_auth_cred) -def get_vpc_details(access_key, secret_key, region, vpc_ids): +def get_vpc_details(aws_auth_cred, vpc_ids): """ Find VPC details of all the ids passed to this method Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials vpc_ids (list): List of VOC Ids Returns: VPCS (list): List of all VPC objects """ - response = get_ec2_client(access_key, secret_key, region).describe_vpcs(VpcIds=vpc_ids) + response = get_ec2_client(aws_auth_cred).describe_vpcs(VpcIds=vpc_ids) return response["Vpcs"] -def get_vpc_subnets(access_key, secret_key, region, vpc_ids): +def get_vpc_subnets(aws_auth_cred, vpc_ids): """ Find all subnets under a VPC Args: - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials vpc_ids (list): List of VOC Ids Returns: Subnets (list): List of all subnets object """ - response = get_ec2_client(access_key, secret_key, region).describe_subnets(Filters=[ + response = get_ec2_client(aws_auth_cred).describe_subnets(Filters=[ { 'Name': 'vpc-id', 'Values': vpc_ids @@ -61,21 +52,19 @@ def get_vpc_subnets(access_key, secret_key, region, vpc_ids): return response['Subnets'] -def check_security_group_exists(group_name, vpc_id, access_key, secret_key, region): +def check_security_group_exists(group_name, vpc_id, aws_auth_cred): """ Check wheter the given security group already exists in the AWS Account Args: group_name (str): Security group name vpc_id (str): VPC id under which the group should be searched - access_key (str): AWS Access Key - secret_key (str): AWS Secret Key - region (str): AWS Region + aws_auth (dict): Dict containing AWS credentials Returns: Boolean: True if env exists else False """ - client = get_ec2_client(access_key, secret_key, region) + client = get_ec2_client(aws_auth_cred) try: response = client.describe_security_groups( Filters=[ diff --git a/installer/core/providers/aws/destroy.py b/installer/core/providers/aws/destroy.py index 8c161d783..629c918a6 100644 --- a/installer/core/providers/aws/destroy.py +++ b/installer/core/providers/aws/destroy.py @@ -140,6 +140,8 @@ def destroy_resources(self, resources, terraform_with_targets): self.executed_with_error = True self.exception = e + PyTerraform.save_terraform_output() + self.current_destroy_status = self.destroy_statuses.get('execution_finished') def show_progress_status(self, resources, terraform_with_targets): diff --git a/installer/core/providers/aws/input.py b/installer/core/providers/aws/input.py index d499aa3cb..e847d7d35 100644 --- a/installer/core/providers/aws/input.py +++ b/installer/core/providers/aws/input.py @@ -2,61 +2,105 @@ from core.config import Settings from core.mixins import MsgMixin from core import constants as K -from core.providers.aws.boto3.sts import get_user_account_id +from core.providers.aws.boto3.sts import get_aws_caller_identity +from core.providers.aws.boto3.sts import generate_temp_credentials +import uuid class SystemInput(MsgMixin, metaclass=ABCMeta): """Base input class for installation/destruction/status commands. This class reads required input from user for the process to start""" + AWS_AUTH_CRED = {} def read_input(self): """Read required inputs from user for the process to start""" self.show_step_heading(K.INPUT_READING_STARTED) - self.read_aws_access_key() - self.read_aws_secret_key() - self.read_aws_region() - self.load_aws_account_id() + + self.AWS_AUTH_CRED['aws_auth_option'] = self.read_aws_auth_mechanism() + + if self.AWS_AUTH_CRED['aws_auth_option'] == 1: + self.AWS_AUTH_CRED['aws_access_key'] = self.read_aws_access_key() + self.AWS_AUTH_CRED['aws_secret_key'] = self.read_aws_secret_key() + elif self.AWS_AUTH_CRED['aws_auth_option'] == 2: + self.AWS_AUTH_CRED['assume_role_arn'] = self.read_aws_assume_role_arn() + self.AWS_AUTH_CRED['tmp_credentials'] = generate_temp_credentials(self.AWS_AUTH_CRED['assume_role_arn']) + + self.AWS_AUTH_CRED['aws_region'] = self.read_aws_region() + + Settings.set('AWS_AUTH_CRED', self.AWS_AUTH_CRED) + + self.load_aws_account_details() self.show_step_finish(K.INPUT_READING_COMPLETED) + def read_aws_auth_mechanism(self): + while True: + self.show_inner_inline_message("\n\t%s" % K.AWS_AUTH_MECHANISM) + self.show_inner_inline_message("\n\t%s" % K.AWS_WITH_KEYS) + self.show_inner_inline_message("\n\t%s" % K.AWS_WITH_ASSUME_ROLE) + self.show_inner_inline_message("\n\t%s" % K.AWS_WITH_EC2_ROLE) + auth_mechanism = int(input("\n\t%s" % K.AWS_CHOOSE_AUTH_OPTION)) + if auth_mechanism in [1, 2, 3]: + break + + self.show_step_inner_warning(K.AWS_INCORRECT_MECHANISM) + + return auth_mechanism + def read_aws_access_key(self): """Read AWS access key from user if it is not already set in settings""" settings_access_key = getattr(Settings, 'AWS_ACCESS_KEY', None) if settings_access_key is None or settings_access_key == '': - self.aws_access_key = input("\n\t%s" % K.AWS_ACCESS_KEY_INPUT) - if len(self.aws_access_key) < 20: + aws_access_key = input("\n\t%s" % K.AWS_ACCESS_KEY_INPUT) + if len(aws_access_key) < 20: self.show_step_inner_error("\n\t" + K.INVALID_KEY) raise Exception(K.INVALID_KEY) - Settings.set('AWS_ACCESS_KEY', self.aws_access_key) else: - self.aws_access_key = settings_access_key + aws_access_key = settings_access_key + + return aws_access_key def read_aws_secret_key(self): """Read AWS secret key from user if it is not already set in settings""" settings_secret_key = getattr(Settings, 'AWS_SECRET_KEY', None) if settings_secret_key is None or settings_secret_key == '': - self.aws_secret_key = input("\n\t%s" % K.AWS_SECRET_KEY_INPUT) + aws_secret_key = input("\n\t%s" % K.AWS_SECRET_KEY_INPUT) - if len(self.aws_secret_key) < 25: + if len(aws_secret_key) < 25: self.show_step_inner_error("\n\t" + K.INVALID_KEY) raise Exception(K.INVALID_KEY) + else: + aws_secret_key = settings_secret_key - Settings.set('AWS_SECRET_KEY', self.aws_secret_key) + return aws_secret_key + + def read_aws_assume_role_arn(self): + """Read AWS secret key from user if it is not already set in settings""" + settings_assume_role_arn = getattr(Settings, 'AWS_ASSUME_ROLE_ARN', None) + if settings_assume_role_arn is None or settings_assume_role_arn == '': + assume_role_arn = input("\n\t%s" % K.AWS_ASSUME_ROLE_INPUT) else: - self.aws_secret_key = settings_secret_key + assume_role_arn = settings_assume_role_arn + + return assume_role_arn def read_aws_region(self): """Read AWS region from user if it is not already set in settings""" settings_region = getattr(Settings, 'AWS_REGION', None) if settings_region is None or settings_region == '': - self.aws_region = input("\n\t%s" % K.AWS_REGION_INPUT) - Settings.set('AWS_REGION', self.aws_region) + aws_region = input("\n\t%s" % K.AWS_REGION_INPUT) else: - self.aws_region = settings_region + aws_region = settings_region + + Settings.set('AWS_REGION', aws_region) + + return aws_region - def load_aws_account_id(self): + def load_aws_account_details(self): """Find AWS Account ID from the credentials given""" - aws_account_id = get_user_account_id(Settings.AWS_ACCESS_KEY, Settings.AWS_SECRET_KEY) - Settings.set('AWS_ACCOUNT_ID', aws_account_id) - self.aws_account_id = aws_account_id + caller_identity = get_aws_caller_identity(self.AWS_AUTH_CRED) + Settings.set('AWS_ACCOUNT_ID', caller_identity.get('Account')) + Settings.set('CALLER_ARN', caller_identity.get('Arn')) + self.AWS_ACCOUNT_ID = caller_identity.get('Account') + self.CALLER_ARN = caller_identity.get('Arn') class SystemInstallInput(SystemInput): diff --git a/installer/core/providers/aws/install.py b/installer/core/providers/aws/install.py index 38891f556..91c29179f 100644 --- a/installer/core/providers/aws/install.py +++ b/installer/core/providers/aws/install.py @@ -117,8 +117,7 @@ def _cleanup_installation_process(self, dry_run): """ py_terraform = PyTerraform() - if not dry_run: - self.terraform_outputs = py_terraform.save_terraform_output() + self.terraform_outputs = py_terraform.save_terraform_output() self._delete_terraform_provider_file() self.current_install_status = self.install_statuses.get('execution_finished') diff --git a/installer/core/providers/aws/validate.py b/installer/core/providers/aws/validate.py index 89c97ab4a..70358d024 100644 --- a/installer/core/providers/aws/validate.py +++ b/installer/core/providers/aws/validate.py @@ -31,9 +31,7 @@ def validate_vpc_and_cidr_blocks(self): cidr_blocks = Settings.VPC['CIDR_BLOCKS'] try: vpcs = vpc.get_vpc_details( - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, - Settings.AWS_REGION, + Settings.AWS_AUTH_CRED, vpc_ids ) except Exception as e: @@ -63,9 +61,7 @@ def validate_subnet_ids(self): subnet_ids = Settings.VPC['SUBNETS'] try: valid_subnets = vpc.get_vpc_subnets( - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, - Settings.AWS_REGION, + Settings.AWS_AUTH_CRED, vpc_ids ) except Exception as e: @@ -83,6 +79,22 @@ def validate_subnet_ids(self): return K.VALID + def validate_policies(self): + """ + Check required policies are present in in user or role + + Returns: + boolean: True if all policies are present else False + """ + aws_auth_option = Settings.AWS_AUTH_CRED['aws_auth_option'] + status = self.validate_user_policies() if aws_auth_option == 1 else self.validate_role_policies() + + if not status: + yes_or_no = input("\n\t%s: " % self._input_message_in_color(K.POLICY_YES_NO)) + status = True if yes_or_no.lower() == "yes" else False + + return status + def validate_user_policies(self): """ Check required policies are present in user policies or not. Required policies are kept in the settings AWS_POLICIES_REQUIRED @@ -90,70 +102,55 @@ def validate_user_policies(self): Returns: boolean: True if all policies are present else False """ - access_key, secret_key = Settings.AWS_ACCESS_KEY, Settings.AWS_SECRET_KEY - current_aws_user = iam.get_current_user(access_key, secret_key) + current_aws_user = iam.get_current_user(Settings.AWS_AUTH_CRED) user_name = current_aws_user.user_name if user_name: - # warning_message = "Policies (" + ", ".join(Settings.AWS_POLICIES_REQUIRED) + ") are required" - # self.show_step_inner_warning(warning_message) - - if self._check_user_policies(access_key, secret_key, user_name): - return True - - if self._check_group_policies(access_key, secret_key, user_name): + if self._check_user_policies(user_name) or self._check_group_policies(user_name): return True + elif "root" in current_aws_user.arn: + return True - yes_or_no = input("\n\t%s: " % self._input_message_in_color(K.POLICY_YES_NO)) + False - if yes_or_no.lower() == "yes": - return True + def validate_role_policies(self): + role_name = Settings.CALLER_ARN.split('/')[1] + role_policy_names = iam.get_role_policy_names(role_name, Settings.AWS_AUTH_CRED) - return False - elif "root" in current_aws_user.arn: - return True - else: - False + return self._check_required_policies_present(role_policy_names, K.CHECKING_ROLE_POLICY) - def _check_group_policies(self, access_key, secret_key, user_name): + def _check_group_policies(self, user_name): """ Check required policies are present in user-group policies or not. Required policies are kept in the settings AWS_POLICIES_REQUIRED Returns: boolean: True if all policies are present else False """ - group_policy_names = iam.get_user_group_policy_names(access_key, secret_key, user_name) - - if self._has_full_access_policies(group_policy_names): - self.show_step_inner_messaage(K.FULL_ACCESS_POLICY, K.PRESENT, None) - return True - - if set(Settings.AWS_POLICIES_REQUIRED).difference(set(group_policy_names)): - self.show_step_inner_messaage(K.CHECKING_GROUP_POLICY, K.NOT_PRESENT, self.error_message) - return False + group_policy_names = iam.get_user_group_policy_names(Settings.AWS_AUTH_CRED, user_name) - self.show_step_inner_messaage(K.CHECKING_GROUP_POLICY, K.PRESENT, self.error_message) + return self._check_required_policies_present(group_policy_names, K.CHECKING_GROUP_POLICY) - return True - - def _check_user_policies(self, access_key, secret_key, user_name): + def _check_user_policies(self, user_name): """ This method uses the above methods and validate required policies are present in combine User and Group policies Returns: boolean: True if all policies are present else False """ - user_policy_names = iam.get_iam_user_policy_names(access_key, secret_key, user_name) + user_policy_names = iam.get_iam_user_policy_names(Settings.AWS_AUTH_CRED, user_name) + + return self._check_required_policies_present(user_policy_names, K.CHECKING_USER_POLICY) - if self._has_full_access_policies(user_policy_names): + def _check_required_policies_present(self, policy_names, policy_type_msg): + if self._has_full_access_policies(policy_names): self.show_step_inner_messaage(K.FULL_ACCESS_POLICY, K.PRESENT, None) return True - if set(Settings.AWS_POLICIES_REQUIRED).difference(set(user_policy_names)): - self.show_step_inner_messaage(K.CHECKING_USER_POLICY, K.NOT_PRESENT, self.error_message) + if set(Settings.AWS_POLICIES_REQUIRED).difference(set(policy_names)): + self.show_step_inner_messaage(policy_type_msg, K.NOT_PRESENT, self.error_message) return False - self.show_step_inner_messaage(K.CHECKING_USER_POLICY, K.PRESENT, self.error_message) + self.show_step_inner_messaage(policy_type_msg, K.PRESENT, self.error_message) return True @@ -182,7 +179,7 @@ def validate(self): if status != K.VALID: return False - status = self.validate_user_policies() + status = self.validate_policies() return status From d70d317929913ece01bf5f8f9fcf33763349a22b Mon Sep 17 00:00:00 2001 From: Sajeer N Date: Thu, 18 Jul 2019 15:01:34 +0530 Subject: [PATCH 02/86] Terraform AWS resources creation credentials supplied based on user auth type --- installer/core/terraform/__init__.py | 7 +++++++ .../core/terraform/resources/aws/aws_lambda.py | 4 +--- installer/core/terraform/resources/aws/batch.py | 12 +++--------- .../core/terraform/resources/aws/cloudwatch.py | 8 ++------ installer/core/terraform/resources/aws/ecr.py | 4 +--- installer/core/terraform/resources/aws/ecs.py | 8 ++------ .../terraform/resources/aws/elasticsearch.py | 4 +--- installer/core/terraform/resources/aws/iam.py | 6 +++--- .../terraform/resources/aws/load_balancer.py | 8 ++------ installer/core/terraform/resources/aws/rds.py | 16 ++++------------ .../core/terraform/resources/aws/redshift.py | 12 +++--------- installer/core/terraform/resources/aws/vpc.py | 4 +--- 12 files changed, 30 insertions(+), 63 deletions(-) diff --git a/installer/core/terraform/__init__.py b/installer/core/terraform/__init__.py index 28be2a094..2e84fa3d8 100644 --- a/installer/core/terraform/__init__.py +++ b/installer/core/terraform/__init__.py @@ -8,6 +8,7 @@ from core.utils import exists_teraform_lock import inspect import json +import os class PyTerraform(): @@ -247,6 +248,12 @@ def save_terraform_output(cls): return output_dict + @classmethod + def delete_terraform_output_json_file(cls): + tf_output_file = get_terraform_latest_output_file() + if os.path.isfile(tf_output_file): + os.remove(tf_output_file) + @classmethod def load_terraform_output(cls): """ diff --git a/installer/core/terraform/resources/aws/aws_lambda.py b/installer/core/terraform/resources/aws/aws_lambda.py index b77f290b2..9d56b704c 100644 --- a/installer/core/terraform/resources/aws/aws_lambda.py +++ b/installer/core/terraform/resources/aws/aws_lambda.py @@ -44,9 +44,7 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = aws_lambda.check_function_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details diff --git a/installer/core/terraform/resources/aws/batch.py b/installer/core/terraform/resources/aws/batch.py index 673f53f7b..199033386 100644 --- a/installer/core/terraform/resources/aws/batch.py +++ b/installer/core/terraform/resources/aws/batch.py @@ -52,9 +52,7 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = batch.check_compute_env_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details @@ -99,9 +97,7 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = batch.check_job_definition_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details @@ -140,8 +136,6 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = batch.check_job_queue_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details diff --git a/installer/core/terraform/resources/aws/cloudwatch.py b/installer/core/terraform/resources/aws/cloudwatch.py index 7553543c2..914755c72 100644 --- a/installer/core/terraform/resources/aws/cloudwatch.py +++ b/installer/core/terraform/resources/aws/cloudwatch.py @@ -41,9 +41,7 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = cloudwatch_event.check_rule_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details @@ -93,9 +91,7 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = cloudwatch_log.check_log_group_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details diff --git a/installer/core/terraform/resources/aws/ecr.py b/installer/core/terraform/resources/aws/ecr.py index 866162ed5..cb7d29590 100644 --- a/installer/core/terraform/resources/aws/ecr.py +++ b/installer/core/terraform/resources/aws/ecr.py @@ -35,8 +35,6 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = ecr.check_ecr_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details diff --git a/installer/core/terraform/resources/aws/ecs.py b/installer/core/terraform/resources/aws/ecs.py index 3bc1c788a..403435b7d 100644 --- a/installer/core/terraform/resources/aws/ecs.py +++ b/installer/core/terraform/resources/aws/ecs.py @@ -36,9 +36,7 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = ecs.check_ecs_cluster_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details @@ -83,9 +81,7 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = ecs.check_ecs_task_definition_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details diff --git a/installer/core/terraform/resources/aws/elasticsearch.py b/installer/core/terraform/resources/aws/elasticsearch.py index ba4bf6dd9..d95305929 100644 --- a/installer/core/terraform/resources/aws/elasticsearch.py +++ b/installer/core/terraform/resources/aws/elasticsearch.py @@ -77,9 +77,7 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = es.check_es_domain_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details diff --git a/installer/core/terraform/resources/aws/iam.py b/installer/core/terraform/resources/aws/iam.py index 093e69cca..427054f5d 100644 --- a/installer/core/terraform/resources/aws/iam.py +++ b/installer/core/terraform/resources/aws/iam.py @@ -42,7 +42,7 @@ def check_exists_before(self, input, tf_outputs): exists = False if not self.resource_in_tf_output(tf_outputs): - exists = iam.check_role_exists(checked_details['value'], input.aws_access_key, input.aws_secret_key) + exists = iam.check_role_exists(checked_details['value'], input.AWS_AUTH_CRED) return exists, checked_details @@ -81,7 +81,7 @@ def check_exists_before(self, input, tf_outputs): checked_details = {'attr': "name", 'value': self.get_input_attr('name')} exists = False if not self.resource_in_tf_output(tf_outputs): - exists = iam.check_policy_exists(checked_details['value'], input.aws_access_key, input.aws_secret_key, input.aws_account_id) + exists = iam.check_policy_exists(checked_details['value'], input.AWS_ACCOUNT_ID, input.AWS_AUTH_CRED) return exists, checked_details @@ -130,7 +130,7 @@ def check_exists_before(self, input, tf_outputs): checked_details = {'attr': "name", 'value': self.get_input_attr('name')} exists = False if not self.resource_in_tf_output(tf_outputs): - exists = iam.check_instance_profile_exists(checked_details['value'], input.aws_access_key, input.aws_secret_key) + exists = iam.check_instance_profile_exists(checked_details['value'], input.AWS_AUTH_CRED) return exists, checked_details diff --git a/installer/core/terraform/resources/aws/load_balancer.py b/installer/core/terraform/resources/aws/load_balancer.py index 394e3ec26..a191a6c3d 100644 --- a/installer/core/terraform/resources/aws/load_balancer.py +++ b/installer/core/terraform/resources/aws/load_balancer.py @@ -39,9 +39,7 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = elb.check_alb_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details @@ -165,8 +163,6 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = elb.check_target_group_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details diff --git a/installer/core/terraform/resources/aws/rds.py b/installer/core/terraform/resources/aws/rds.py index 0fc48624f..6aa9ab5a2 100644 --- a/installer/core/terraform/resources/aws/rds.py +++ b/installer/core/terraform/resources/aws/rds.py @@ -52,9 +52,7 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = rds.check_rds_instance_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details @@ -97,9 +95,7 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = rds.check_rds_option_group_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details @@ -141,9 +137,7 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = rds.check_rds_parameter_group_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details @@ -185,8 +179,6 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = rds.check_rds_subnet_group_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details diff --git a/installer/core/terraform/resources/aws/redshift.py b/installer/core/terraform/resources/aws/redshift.py index c42547857..8f470bf0b 100644 --- a/installer/core/terraform/resources/aws/redshift.py +++ b/installer/core/terraform/resources/aws/redshift.py @@ -48,9 +48,7 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = redshift.check_redshift_cluster_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details @@ -92,9 +90,7 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = redshift.check_redshift_parameter_group_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details @@ -136,8 +132,6 @@ def check_exists_before(self, input, tf_outputs): if not self.resource_in_tf_output(tf_outputs): exists = redshift.check_redshift_subnet_group_exists( checked_details['value'], - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details diff --git a/installer/core/terraform/resources/aws/vpc.py b/installer/core/terraform/resources/aws/vpc.py index 30fcea718..b0d7a15b3 100644 --- a/installer/core/terraform/resources/aws/vpc.py +++ b/installer/core/terraform/resources/aws/vpc.py @@ -60,8 +60,6 @@ def check_exists_before(self, input, tf_outputs): exists = vpc.check_security_group_exists( checked_details['value'], self.get_input_attr('vpc_id'), - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) return exists, checked_details From 7ae623e25675c4e288667711251286f7cc446d62 Mon Sep 17 00:00:00 2001 From: Sajeer N Date: Fri, 19 Jul 2019 12:22:08 +0530 Subject: [PATCH 03/86] Framework is updated to handle multiple auth mechanism --- installer/core/commands/__init__.py | 18 +++++++----------- installer/core/constants.py | 9 +++++++++ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/installer/core/commands/__init__.py b/installer/core/commands/__init__.py index 06c5ec42c..74ee90d4d 100644 --- a/installer/core/commands/__init__.py +++ b/installer/core/commands/__init__.py @@ -39,7 +39,7 @@ def __init__(self, args): self.dry_run = True if any([x[1] for x in args if x[0] == "dry-run"]) else self.dry_run - def get_complete_resources(self, input_instance, need_instance=True): + def get_complete_resources(self, input_instance): """ This returns all the resources present in the common configurations @@ -47,23 +47,22 @@ def get_complete_resources(self, input_instance, need_instance=True): resources_to_process (list): List of all resources """ resource_keys_to_process = self.get_resource_keys_to_process(None, None) - resources_to_process = self.get_resources_from_the_keys(resource_keys_to_process, input_instance, need_instance) + resources_to_process = self.get_resources_from_the_keys(resource_keys_to_process, input_instance) return resources_to_process - def get_resources_to_process(self, input_instance, need_instance=True): + def get_resources_to_process(self, input_instance): """ This returns the resources to be processed currently. This can either be full resources or part of resources Args: input_instance (Input Obj): Input object - need_instance (boolean): True if object is required and if it is False then class is returned Returns: resources_to_process (list): List of resources """ resource_keys_to_process = self.get_resource_keys_to_process(self.resource_tags_list, self.category_field_name) - resources_to_process = self.get_resources_from_the_keys(resource_keys_to_process, input_instance, need_instance) + resources_to_process = self.get_resources_from_the_keys(resource_keys_to_process, input_instance) return resources_to_process @@ -79,11 +78,11 @@ def get_resources_with_given_tags(self, input_instance, tags_list): tagged_resources (list): List of resources """ tagged_resource_keys = self.get_resource_keys_to_process(tags_list, self.category_field_name) - tagged_resources = self.get_resources_from_the_keys(tagged_resource_keys, input_instance, True) + tagged_resources = self.get_resources_from_the_keys(tagged_resource_keys, input_instance) return tagged_resources - def get_resources_from_the_keys(self, resource_keys_to_process, input_instance, need_instance): + def get_resources_from_the_keys(self, resource_keys_to_process, input_instance): """ This returns the resources to be processed based on the key which is the filename @@ -105,10 +104,7 @@ def get_resources_from_the_keys(self, resource_keys_to_process, input_instance, for name, obj_class in inspect.getmembers(resource_module, inspect.isclass): if obj_class.__module__ == resource: # To collect Resource Classes defined only in the resource file if BaseTerraformResource in inspect.getmro(obj_class): - if need_instance: - resources_to_process.append(obj_class(input_instance)) # Create instance of that class - else: - resources_to_process.append(obj_class) + resources_to_process.append(obj_class(input_instance)) # Create instance of that class return resources_to_process diff --git a/installer/core/constants.py b/installer/core/constants.py index 76f70fdd4..5b4315444 100644 --- a/installer/core/constants.py +++ b/installer/core/constants.py @@ -26,9 +26,17 @@ INPUT_READING_STARTED = "Reading required inputs from user" INPUT_READING_COMPLETED = "Required inputs are available!!!" +AWS_AUTH_MECHANISM = "Select AWS authentication mechanism: " +AWS_WITH_KEYS = "1. with Access Key and Secret Key " +AWS_WITH_ASSUME_ROLE = "2. with an assumed role arn" +AWS_WITH_EC2_ROLE = "3. with role attached to the EC2 instance" +AWS_CHOOSE_AUTH_OPTION = "Type 1 or 2 or 3 to continue to create services in AWS: " +AWS_INCORRECT_MECHANISM = "Entered an incorrect value!!!" + AWS_ACCESS_KEY_INPUT = "Please enter AWS access key: " AWS_SECRET_KEY_INPUT = "Please enter AWS secret key: " AWS_REGION_INPUT = "Please enter region: " +AWS_ASSUME_ROLE_INPUT = "Enter IAM role to be assumed: " INVALID_KEY = "Entered invalid Key!!!" SETTINGS_CHECK_STARTED = "Checking settings and inputs" VPC_CHECK_STARTED = "Checking VPC and CIDR Blocks" @@ -41,6 +49,7 @@ CHECKING_GROUP_POLICY = "Checking group-attached policies" CHECKING_USER_POLICY = "Checking user-attached policies" +CHECKING_ROLE_POLICY = "Checkcing role policies" FULL_ACCESS_POLICY = "Administrator access policy" POLICY_YES_NO = "If you have added custom policies with all permissions, please type Yes or No" From 4f1b02839ce42e28e88026ed235bec841bd9ff5a Mon Sep 17 00:00:00 2001 From: Sajeer N Date: Fri, 19 Jul 2019 20:11:45 +0530 Subject: [PATCH 04/86] Custom commands and scripts files are modified to handle multiple aws auth mechanism --- installer/custom/commands/redeploy.py | 12 +--- installer/custom/commands/upgrade.py | 8 +-- installer/files/scripts/build_pacbot.py | 50 +++++-------- .../create_docker_image_and_push_to_ecr.py | 6 +- installer/files/scripts/utils.py | 71 ++++++++++++++----- 5 files changed, 79 insertions(+), 68 deletions(-) diff --git a/installer/custom/commands/redeploy.py b/installer/custom/commands/redeploy.py index 53d684f18..fe3882ce5 100644 --- a/installer/custom/commands/redeploy.py +++ b/installer/custom/commands/redeploy.py @@ -107,17 +107,13 @@ def run_pre_deployment_process(self, resources_to_process): if not self.dry_run: elb.delete_all_listeners_of_alb( ApplicationLoadBalancer.get_input_attr('name'), - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, - Settings.AWS_REGION) + Settings.AWS_AUTH_CRED) tg_resources = self._get_resources_of_a_given_class_type(resources_to_process, ALBTargetGroupResource) tg_names = [resource.get_input_attr('name') for resource in tg_resources] elb.delete_alltarget_groups( tg_names, - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, - Settings.AWS_REGION) + Settings.AWS_AUTH_CRED) def inactivate_required_services_for_redeploy(self, resources_to_process, dry_run): """ @@ -137,10 +133,8 @@ def inactivate_required_services_for_redeploy(self, resources_to_process, dry_ru if ECSTaskDefinitionResource in resource_base_classes: try: deregister_task_definition( - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, - Settings.AWS_REGION, resource.get_input_attr('family'), + Settings.AWS_AUTH_CRED, ) except: pass diff --git a/installer/custom/commands/upgrade.py b/installer/custom/commands/upgrade.py index e8e6025d3..fa6743122 100644 --- a/installer/custom/commands/upgrade.py +++ b/installer/custom/commands/upgrade.py @@ -63,17 +63,13 @@ def run_pre_deployment_process(self, resources_to_process): if not self.dry_run: elb.delete_all_listeners_of_alb( ApplicationLoadBalancer.get_input_attr('name'), - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, - Settings.AWS_REGION) + Settings.AWS_AUTH_CRED) tg_resources = self._get_resources_of_a_given_class_type(resources_to_process, ALBTargetGroupResource) tg_names = [resource.get_input_attr('name') for resource in tg_resources] elb.delete_alltarget_groups( tg_names, - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, - Settings.AWS_REGION) + Settings.AWS_AUTH_CRED) def upgrade_pacbot(self, input_instance): """ diff --git a/installer/files/scripts/build_pacbot.py b/installer/files/scripts/build_pacbot.py index 40c073798..609c1845c 100644 --- a/installer/files/scripts/build_pacbot.py +++ b/installer/files/scripts/build_pacbot.py @@ -1,4 +1,4 @@ -from utils import get_provider_credentials +from utils import get_provider_details, prepare_aws_client_with_given_aws_details, get_provider_details from datetime import datetime import os import subprocess @@ -22,37 +22,35 @@ class Buildpacbot(object): archive_type = "zip" # What type of archive is required issue_email_template = '' - def __init__(self, api_domain_url, upload_dir, log_dir, pacbot_code_dir): + def __init__(self, aws_details, api_domain_url, upload_dir, log_dir, pacbot_code_dir): self.api_domain_url = api_domain_url self.cwd = pacbot_code_dir self.codebase_root_dir = pacbot_code_dir self.debug_log = os.path.join(log_dir, "debug.log") self.maven_build_log = os.path.join(log_dir, "maven_build.log") self.upload_dir = upload_dir + self.s3_client = prepare_aws_client_with_given_aws_details('s3', aws_details) def _clean_up_all(self): os.chdir(self.cwd) - def build_api_and_ui_apps(self, aws_access_key, aws_secret_key, region, bucket, s3_key_prefix): - self.upload_ui_files_to_s3(aws_access_key, aws_secret_key, region, bucket) + def build_api_and_ui_apps(self, bucket, s3_key_prefix): + self.upload_ui_files_to_s3(bucket) print("Maven build started...\n") - self.build_jar_and_ui_from_code(aws_access_key, aws_secret_key, region, bucket, s3_key_prefix) + self.build_jar_and_ui_from_code(bucket, s3_key_prefix) - self.archive_ui_app_build(aws_access_key, aws_secret_key, region, bucket, s3_key_prefix) + self.archive_ui_app_build(bucket, s3_key_prefix) self.write_to_debug_log("Maven build completed!!!") print("Maven build completed!!!\n") self._clean_up_all() - def upload_ui_files_to_s3(self, aws_access_key, aws_secret_key, region, bucket): + def upload_ui_files_to_s3(self, bucket): """ Upload email template files to s3 from codebase Args: - aws_access_key (str): AWS access key - aws_secret_key (str): AWS secret key - region (str): AWS region bucket (str): S3 bucket name """ print("Uploading Email templates to S3...............\n") @@ -67,15 +65,14 @@ def upload_ui_files_to_s3(self, aws_access_key, aws_secret_key, region, bucket): if not files_to_upload: raise Exception("Email teamplate files are not found in %s" % str(local_folder_path)) - s3_client = s3 = boto3.client('s3', region_name=region, aws_access_key_id=aws_access_key, aws_secret_access_key=aws_secret_key) for file_name in files_to_upload: file_path = os.path.join(local_folder_path, file_name) extra_args = {'ACL': 'public-read'} # To make this public key = folder_to_upload + '/' + file_name - self.issue_email_template = '%s/%s/%s' % (s3_client.meta.endpoint_url, bucket, folder_to_upload) # To be added in config.ts + self.issue_email_template = '%s/%s/%s' % (self.s3_client.meta.endpoint_url, bucket, folder_to_upload) # To be added in config.ts - s3_client.upload_file(file_path, bucket, key, ExtraArgs=extra_args) + self.s3_client.upload_file(file_path, bucket, key, ExtraArgs=extra_args) self.write_to_debug_log("Email templates upload to S3 completed!!!") print("Email templates upload to S3 completed!!!\n") @@ -104,14 +101,11 @@ def run_bash_command(self, command, exec_dir): return stdout, stderr - def build_jar_and_ui_from_code(self, aws_access_key, aws_secret_key, region, bucket, s3_key_prefix): + def build_jar_and_ui_from_code(self, bucket, s3_key_prefix): """ Build jars and upload to S3 Args: - aws_access_key (str): AWS access key - aws_secret_key (str): AWS secret key - region (str): AWS region bucket (str): S3 bucket name s3_key_prefix (str): Under which folder this has be uploaded """ @@ -119,7 +113,7 @@ def build_jar_and_ui_from_code(self, aws_access_key, aws_secret_key, region, buc self._update_variables_in_ui_config(webapp_dir) self.build_api_job_jars(self.codebase_root_dir) self._replace_webapp_new_config_with_original(webapp_dir) - self.upload_jar_files(self.codebase_root_dir, aws_access_key, aws_secret_key, region, bucket, s3_key_prefix) + self.upload_jar_files(self.codebase_root_dir, bucket, s3_key_prefix) def build_api_job_jars(self, working_dir): print("Started building the jar...............\n") @@ -129,16 +123,11 @@ def build_api_job_jars(self, working_dir): stdout, stderr = self.run_bash_command(self.mvn_build_command, working_dir) self.write_to_debug_log("Build Completed...") - def upload_jar_files(self, working_dir, aws_access_key, aws_secret_key, region, bucket, s3_key_prefix): + def upload_jar_files(self, working_dir, bucket, s3_key_prefix): folders = [ os.path.join(working_dir, "dist", "api"), os.path.join(working_dir, "dist", "jobs"), ] - s3_client = s3 = boto3.client( - 's3', - region_name=region, - aws_access_key_id=aws_access_key, - aws_secret_access_key=aws_secret_key) for folder in folders: if os.path.exists(folder): @@ -147,7 +136,7 @@ def upload_jar_files(self, working_dir, aws_access_key, aws_secret_key, region, copy_file_from = os.path.join(folder, jarfile) s3_jar_file_key = str(os.path.join(s3_key_prefix, jarfile)) self.write_to_debug_log("JAR File: %s, Uploading to S3..." % s3_jar_file_key) - s3_client.upload_file(copy_file_from, bucket, s3_jar_file_key) + self.s3_client.upload_file(copy_file_from, bucket, s3_jar_file_key) self.write_to_debug_log("JAR File: %s, Uploaded to S3" % s3_jar_file_key) def _get_web_app_directory(self): @@ -183,8 +172,7 @@ def _replace_webapp_new_config_with_original(self, webapp_dir): shutil.copy2(original_config_file, config_file) os.remove(original_config_file) - def archive_ui_app_build(self, aws_access_key, aws_secret_key, region, bucket, s3_key_prefix): - s3_client = s3 = boto3.client('s3', region_name=region, aws_access_key_id=aws_access_key, aws_secret_access_key=aws_secret_key) + def archive_ui_app_build(self, bucket, s3_key_prefix): zip_file_name = self.upload_dir + "/dist" print("Started creating zip file...") @@ -193,7 +181,7 @@ def archive_ui_app_build(self, aws_access_key, aws_secret_key, region, bucket, s s3_zip_file_key = str(os.path.join(s3_key_prefix, "dist.zip")) self.write_to_debug_log("Zip File: %s, Uploading to S3..." % s3_zip_file_key) - s3_client.upload_file(zip_file_name + ".zip", bucket, s3_zip_file_key) + self.s3_client.upload_file(zip_file_name + ".zip", bucket, s3_zip_file_key) self.write_to_debug_log("Zip File: %s, Uploaded to S3" % s3_zip_file_key) os.remove(zip_file_name + ".zip") @@ -214,16 +202,14 @@ def write_to_debug_log(self, msg): provider_json_file = os.getenv('PROVIDER_FILE') s3_bucket = os.getenv('S3_BUCKET') s3_key_prefix = os.getenv('S3_KEY_PREFIX') - aws_access_key, aws_secret_key, region_name = get_provider_credentials("aws", provider_json_file) + aws_details = get_provider_details("aws", provider_json_file) Buildpacbot( + aws_details, api_domain_url, dist_files_upload_dir, log_dir, pacbot_code_dir).build_api_and_ui_apps( - aws_access_key, - aws_secret_key, - region_name, s3_bucket, s3_key_prefix ) diff --git a/installer/files/scripts/create_docker_image_and_push_to_ecr.py b/installer/files/scripts/create_docker_image_and_push_to_ecr.py index 0b9ac4603..bc77eb986 100644 --- a/installer/files/scripts/create_docker_image_and_push_to_ecr.py +++ b/installer/files/scripts/create_docker_image_and_push_to_ecr.py @@ -1,4 +1,4 @@ -from utils import get_provider_credentials, get_docker_push_aws_auth_config, build_docker_image, write_to_log_file +from utils import get_provider_details, get_docker_push_aws_auth_config, build_docker_image, write_to_log_file from utils import write_to_debug_log from docker import Client import os @@ -20,8 +20,8 @@ def build_and_push_docker_image(provider_json_file, ecr_repo, docker_file, docke """ write_to_debug_log(log_file, "Docker image creation and push to ecr repo: %s is started" % str(ecr_repo)) - aws_access_key, aws_secret_key, region_name = get_provider_credentials("aws", provider_json_file) - auth_config_payload = get_docker_push_aws_auth_config(aws_access_key, aws_secret_key, region_name, log_file) + aws_details = get_provider_details("aws", provider_json_file) + auth_config_payload = get_docker_push_aws_auth_config(aws_details, log_file) docker_client = build_docker_image(docker_file_dir, docker_file, ecr_repo, log_file) latest_tag = "latest" pushed = docker_client.push(ecr_repo, tag=latest_tag, auth_config=auth_config_payload) diff --git a/installer/files/scripts/utils.py b/installer/files/scripts/utils.py index 00fa75b4a..c5e71e8fe 100644 --- a/installer/files/scripts/utils.py +++ b/installer/files/scripts/utils.py @@ -3,9 +3,10 @@ import json import boto3 import base64 +import uuid -def get_provider_credentials(provider, provider_json_file): +def get_provider_details(provider, provider_json_file): """ From terraform provider file identify the credentials and return it @@ -14,39 +15,73 @@ def get_provider_credentials(provider, provider_json_file): provider_json_file (path): Json Provider file abs path Returns: - aws_access_key (str): AWS access key - aws_secret_key (str): AWS secret key - region_name (str): AWS region name + aws_details (dict): Terrafrom AWS provider details """ if provider == "aws": # TODO- write now we are supporting AWS only with open(provider_json_file, 'r') as jsonfile: - data = json.load(jsonfile) + aws_provider = json.load(jsonfile) - aws_access_key = data['provider']['aws']['access_key'] - aws_secret_key = data['provider']['aws']['secret_key'] - region_name = data['provider']['aws']['region'] + return aws_provider['provider']['aws'] - return aws_access_key, aws_secret_key, region_name +def generate_temp_credentials(assume_role_arn): + response = boto3.client( + 'sts' + ).assume_role( + RoleArn=assume_role_arn, + RoleSessionName=str(uuid.uuid4()) + ) -def get_docker_push_aws_auth_config(aws_access_key, aws_secret_key, region_name, log_file): + return response['Credentials'] + + +def prepare_aws_client_with_given_aws_details(service_name, aws_details): + auth_data = {} + + if 'access_key' in aws_details: + auth_data['aws_access_key_id'] = aws_details['access_key'] + auth_data['aws_secret_access_key'] = aws_details['secret_key'] + elif 'assume_role' in aws_details: + temp_cred = generate_temp_credentials(aws_details['assume_role']['role_arn']) + auth_data['aws_access_key_id'] = temp_cred['AccessKeyId'] + auth_data['aws_secret_access_key'] = temp_cred['SecretAccessKey'] + auth_data['aws_session_token'] = temp_cred['SessionToken'] + + auth_data['region_name'] = aws_details['region'] + + return boto3.client(service_name, **auth_data) + + +def prepare_aws_resource_with_given_aws_details(service_name, aws_details): + auth_data = {} + + if 'access_key' in aws_details: + auth_data['aws_access_key_id'] = aws_details['access_key'] + auth_data['aws_secret_access_key'] = aws_details['secret_key'] + elif 'assume_role' in aws_details: + temp_cred = generate_temp_credentials(aws_details['assume_role']['role_arn']) + auth_data['aws_access_key_id'] = temp_cred['AccessKeyId'] + auth_data['aws_secret_access_key'] = temp_cred['SecretAccessKey'] + auth_data['aws_session_token'] = temp_cred['SessionToken'] + + auth_data['region_name'] = aws_details['region'] + + return boto3.resource(service_name, **auth_data) + + +def get_docker_push_aws_auth_config(aws_details, log_file): """ Return AWS auth config for pushing docker image to ECR Args: - aws_access_key (str): AWS access key - aws_secret_key (str): AWS secret key - region_name (str): AWS region name + aws_details (dict): AWS details log_file (path): Log file path Returns: auth_config_payload (dict): AWS auth config """ - ecr = boto3.client( - 'ecr', - region_name=region_name, - aws_access_key_id=aws_access_key, - aws_secret_access_key=aws_secret_key) + ecr = prepare_aws_client_with_given_aws_details('ecr', aws_details) + write_to_log_file(log_file, " " * 10 + "Generating Auth token using boto3...") auth = ecr.get_authorization_token() From d4dd98d415035037b1dd1637b72379246a0d8802 Mon Sep 17 00:00:00 2001 From: Sajeer N Date: Mon, 22 Jul 2019 18:10:33 +0530 Subject: [PATCH 05/86] All Pacbot resources are updated to handle multiple auth mechanism --- installer/resources/batch/env.py | 8 +++---- installer/resources/batch/job.py | 6 ++--- installer/resources/batch/utils.py | 23 +++++-------------- installer/resources/datastore/db.py | 5 ++-- installer/resources/datastore/es.py | 5 ++-- .../resources/lambda_rule_engine/function.py | 8 ++----- installer/resources/pacbot_app/ecr.py | 5 ++-- .../resources/pacbot_app/upload_terraform.py | 7 ++---- 8 files changed, 21 insertions(+), 46 deletions(-) diff --git a/installer/resources/batch/env.py b/installer/resources/batch/env.py index 339634105..f81fe5815 100644 --- a/installer/resources/batch/env.py +++ b/installer/resources/batch/env.py @@ -29,7 +29,7 @@ class RuleEngineBatchJobEnv(BatchComputeEnvironmentResource): DEPENDS_ON = [BatchIAMRolePolicyAttach] # This is required otherwise policy would be dettached from Batchrole def pre_terraform_apply(self): - ec2_client = get_ec2_client(self.input.aws_access_key, self.input.aws_secret_key, self.input.aws_region) + ec2_client = get_ec2_client(self.input.AWS_AUTH_CRED) ec2_key_pair = self.get_input_attr('ec2_key_pair') try: key_obj = ec2_client.create_key_pair(KeyName=ec2_key_pair) @@ -41,9 +41,7 @@ def pre_terraform_apply(self): def check_batch_jobs_running(self): envs = get_compute_environments( [self.get_input_attr('compute_environment_name')], - self.input.aws_access_key, - self.input.aws_secret_key, - self.input.aws_region) + self.input.AWS_AUTH_CRED) if not len(envs): return @@ -59,7 +57,7 @@ def pre_generate_terraform(self): sys.exit() def post_terraform_destroy(self): - ec2_client = get_ec2_client(self.input.aws_access_key, self.input.aws_secret_key, self.input.aws_region) + ec2_client = get_ec2_client(self.input.AWS_AUTH_CRED) ec2_key_pair = self.get_input_attr('ec2_key_pair') try: key_obj = ec2_client.delete_key_pair(KeyName=ec2_key_pair) diff --git a/installer/resources/batch/job.py b/installer/resources/batch/job.py index 30c0731ec..86e4dae99 100644 --- a/installer/resources/batch/job.py +++ b/installer/resources/batch/job.py @@ -40,10 +40,8 @@ class SubmitAndRuleEngineJobDefinition(BatchJobDefinitionResource): def post_terraform_destroy(self): deregister_task_definition( - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, - Settings.AWS_REGION, - self.get_input_attr('name') + self.get_input_attr('name'), + Settings.AWS_AUTH_CRED ) def pre_terraform_destroy(self): diff --git a/installer/resources/batch/utils.py b/installer/resources/batch/utils.py index 3d980699c..2ff0e24a3 100644 --- a/installer/resources/batch/utils.py +++ b/installer/resources/batch/utils.py @@ -9,39 +9,28 @@ def remove_batch_job_related_resources(compute_env_name, job_definition_name): if ecs_cluster: ecs.stop_all_tasks_in_a_cluster( ecs_cluster, - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, - Settings.AWS_REGION) + Settings.AWS_AUTH_CRED) ecs.delete_container_instances( ecs_cluster, - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, - Settings.AWS_REGION) + Settings.AWS_AUTH_CRED) ecs.delete_cluster( ecs_cluster, - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, - Settings.AWS_REGION) + Settings.AWS_AUTH_CRED) def deregister_ecs_task_definition_of_batch_job(task_definition_name): ecs.deregister_task_definition( - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, - Settings.AWS_REGION, - task_definition_name + task_definition_name, + Settings.AWS_AUTH_CRED, ) def get_ecs_cluster_from_compute_env(compute_env_name): response = batch.get_compute_environments( [compute_env_name], - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, - Settings.AWS_REGION - ) + Settings.AWS_AUTH_CRED) if response: return response[0]['ecsClusterArn'] diff --git a/installer/resources/datastore/db.py b/installer/resources/datastore/db.py index e840b2b54..7049576a8 100644 --- a/installer/resources/datastore/db.py +++ b/installer/resources/datastore/db.py @@ -63,9 +63,8 @@ def render_output(self, outputs): def pre_terraform_apply(self): status, msg = create_iam_service_linked_role( - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, "rds.amazonaws.com", - Settings.RESOURCE_DESCRIPTION) + Settings.RESOURCE_DESCRIPTION, + Settings.AWS_AUTH_CRED) SysLog().write_debug_log("RDS IAM Service Linked role creation: Status:%s, Message: %s" % (str(status), msg)) diff --git a/installer/resources/datastore/es.py b/installer/resources/datastore/es.py index 75226a922..910eca8c6 100644 --- a/installer/resources/datastore/es.py +++ b/installer/resources/datastore/es.py @@ -63,10 +63,9 @@ def get_es_port(cls): def pre_terraform_apply(self): status, msg = create_iam_service_linked_role( - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, "es.amazonaws.com", - Settings.RESOURCE_DESCRIPTION) + Settings.RESOURCE_DESCRIPTION, + Settings.AWS_AUTH_CRED) SysLog().write_debug_log("ElasticSearch IAM Service Linked role creation: Status:%s, Message: %s" % (str(status), msg)) diff --git a/installer/resources/lambda_rule_engine/function.py b/installer/resources/lambda_rule_engine/function.py index e4c99f9e9..7d7912c88 100644 --- a/installer/resources/lambda_rule_engine/function.py +++ b/installer/resources/lambda_rule_engine/function.py @@ -69,9 +69,7 @@ def check_exists_before(self, input, tf_outputs): rule_name = rule['ruleId'] exists = cloudwatch_event.check_rule_exists( rule_name, - input.aws_access_key, - input.aws_secret_key, - input.aws_region) + input.AWS_AUTH_CRED) if exists: checked_details = {'attr': "name", 'value': rule_name} @@ -90,9 +88,7 @@ def pre_terraform_destroy(self): try: cloudwatch_event.remove_all_targets_of_a_rule( rule_name, - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, - Settings.AWS_REGION) + Settings.AWS_AUTH_CRED) except Exception as e: message = "\n\t ** Not able to remove targets from the rule: %s: Reason: %s **\n" % (rule_name, str(e)) print(MsgMixin.BERROR_ANSI + message + MsgMixin.RESET_ANSI) diff --git a/installer/resources/pacbot_app/ecr.py b/installer/resources/pacbot_app/ecr.py index 14ae3ed73..9d7c5992c 100644 --- a/installer/resources/pacbot_app/ecr.py +++ b/installer/resources/pacbot_app/ecr.py @@ -16,10 +16,9 @@ class APIEcrRepository(ECRRepository): def pre_terraform_apply(self): status, msg = create_iam_service_linked_role( - Settings.AWS_ACCESS_KEY, - Settings.AWS_SECRET_KEY, "ecs.amazonaws.com", - Settings.RESOURCE_DESCRIPTION) + Settings.RESOURCE_DESCRIPTION, + Settings.AWS_AUTH_CRED) SysLog().write_debug_log("ECS IAM Service Linked role creation: Status:%s, Message: %s" % (str(status), msg)) diff --git a/installer/resources/pacbot_app/upload_terraform.py b/installer/resources/pacbot_app/upload_terraform.py index b35df056b..e9698ebd7 100644 --- a/installer/resources/pacbot_app/upload_terraform.py +++ b/installer/resources/pacbot_app/upload_terraform.py @@ -2,6 +2,7 @@ from resources.s3.bucket import BucketStorage from core.config import Settings from core.log import SysLog +from core.providers.aws.boto3 import s3 import shutil import boto3 import os @@ -12,11 +13,7 @@ class UploadTrraform(NullResource): def post_terraform_apply(self): archive_type = "zip" - s3_client = boto3.client( - "s3", - region_name=Settings.AWS_REGION, - aws_access_key_id=Settings.AWS_ACCESS_KEY, - aws_secret_access_key=Settings.AWS_SECRET_KEY) + s3_client = s3.get_s3_client(Settings.AWS_AUTH_CRED) zip_file_name = Settings.RESOURCE_NAME_PREFIX + "-terraform-installer-backup" zip_file_abs_path = os.path.join(Settings.BASE_APP_DIR, zip_file_name) From f8072de7d6ee58916ad1d4e85e941eddeb65413d Mon Sep 17 00:00:00 2001 From: Sajeer N Date: Mon, 22 Jul 2019 18:36:56 +0530 Subject: [PATCH 06/86] Fix added for parameter position in passing args to functions --- installer/core/providers/aws/boto3/vpc.py | 4 ++-- installer/core/providers/aws/validate.py | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/installer/core/providers/aws/boto3/vpc.py b/installer/core/providers/aws/boto3/vpc.py index 3c2df717b..1cc47b86c 100644 --- a/installer/core/providers/aws/boto3/vpc.py +++ b/installer/core/providers/aws/boto3/vpc.py @@ -15,7 +15,7 @@ def get_ec2_client(aws_auth_cred): return prepare_aws_client_with_given_cred('ec2', aws_auth_cred) -def get_vpc_details(aws_auth_cred, vpc_ids): +def get_vpc_details(vpc_ids, aws_auth_cred): """ Find VPC details of all the ids passed to this method @@ -31,7 +31,7 @@ def get_vpc_details(aws_auth_cred, vpc_ids): return response["Vpcs"] -def get_vpc_subnets(aws_auth_cred, vpc_ids): +def get_vpc_subnets(vpc_ids, aws_auth_cred): """ Find all subnets under a VPC diff --git a/installer/core/providers/aws/validate.py b/installer/core/providers/aws/validate.py index 70358d024..d39835825 100644 --- a/installer/core/providers/aws/validate.py +++ b/installer/core/providers/aws/validate.py @@ -31,8 +31,8 @@ def validate_vpc_and_cidr_blocks(self): cidr_blocks = Settings.VPC['CIDR_BLOCKS'] try: vpcs = vpc.get_vpc_details( - Settings.AWS_AUTH_CRED, - vpc_ids + vpc_ids, + Settings.AWS_AUTH_CRED ) except Exception as e: self.error_message = str(e) + "\n\t" + K.CORRECT_VPC_MSG @@ -61,8 +61,8 @@ def validate_subnet_ids(self): subnet_ids = Settings.VPC['SUBNETS'] try: valid_subnets = vpc.get_vpc_subnets( - Settings.AWS_AUTH_CRED, - vpc_ids + vpc_ids, + Settings.AWS_AUTH_CRED ) except Exception as e: self.error_message = str(e) + "\n\t" + K.CORRECT_VPC_MSG @@ -126,7 +126,7 @@ def _check_group_policies(self, user_name): Returns: boolean: True if all policies are present else False """ - group_policy_names = iam.get_user_group_policy_names(Settings.AWS_AUTH_CRED, user_name) + group_policy_names = iam.get_user_group_policy_names(user_name, Settings.AWS_AUTH_CRED) return self._check_required_policies_present(group_policy_names, K.CHECKING_GROUP_POLICY) @@ -137,7 +137,7 @@ def _check_user_policies(self, user_name): Returns: boolean: True if all policies are present else False """ - user_policy_names = iam.get_iam_user_policy_names(Settings.AWS_AUTH_CRED, user_name) + user_policy_names = iam.get_iam_user_policy_names(user_name, Settings.AWS_AUTH_CRED) return self._check_required_policies_present(user_policy_names, K.CHECKING_USER_POLICY) From 851031728200167009b9aaddde1801ada40bb99a Mon Sep 17 00:00:00 2001 From: Sajeer N Date: Mon, 22 Jul 2019 18:47:19 +0530 Subject: [PATCH 07/86] Messages updated --- installer/core/constants.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/installer/core/constants.py b/installer/core/constants.py index 5b4315444..25e17e2bb 100644 --- a/installer/core/constants.py +++ b/installer/core/constants.py @@ -27,9 +27,9 @@ INPUT_READING_COMPLETED = "Required inputs are available!!!" AWS_AUTH_MECHANISM = "Select AWS authentication mechanism: " -AWS_WITH_KEYS = "1. with Access Key and Secret Key " -AWS_WITH_ASSUME_ROLE = "2. with an assumed role arn" -AWS_WITH_EC2_ROLE = "3. with role attached to the EC2 instance" +AWS_WITH_KEYS = "1. Using access key and secret key " +AWS_WITH_ASSUME_ROLE = "2. Assuming an IAM role" +AWS_WITH_EC2_ROLE = "3. Using IAM role attached to the this instance" AWS_CHOOSE_AUTH_OPTION = "Type 1 or 2 or 3 to continue to create services in AWS: " AWS_INCORRECT_MECHANISM = "Entered an incorrect value!!!" From 506b29c26aa392c6d5c5e2fc8df09d0c77d7c7f3 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Tue, 30 Jul 2019 17:59:56 +0530 Subject: [PATCH 08/86] Recommendation enricher changes --- installer/resources/pacbot_app/files/DB.sql | 11 + jobs/recommendation-enricher/pom.xml | 210 ++++++ .../cso/pacbot/recommendation/Main.java | 83 +++ .../cso/pacbot/recommendation/MainUtil.java | 45 ++ .../recommendation/dao/RDSDBManager.java | 109 +++ .../entity/RecommendationCollector.java | 258 +++++++ .../pacbot/recommendation/es/ESManager.java | 666 ++++++++++++++++++ .../exception/UnAuthorisedException.java | 41 ++ .../recommendation/util/ConfigUtil.java | 95 +++ .../pacbot/recommendation/util/Constants.java | 106 +++ .../recommendation/util/ErrorManageUtil.java | 80 +++ .../pacbot/recommendation/util/HttpUtil.java | 182 +++++ .../cso/pacbot/recommendation/util/Util.java | 218 ++++++ 13 files changed, 2104 insertions(+) create mode 100644 jobs/recommendation-enricher/pom.xml create mode 100644 jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/Main.java create mode 100644 jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/MainUtil.java create mode 100644 jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/dao/RDSDBManager.java create mode 100644 jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/entity/RecommendationCollector.java create mode 100644 jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/es/ESManager.java create mode 100644 jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/exception/UnAuthorisedException.java create mode 100644 jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/ConfigUtil.java create mode 100644 jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/Constants.java create mode 100644 jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/ErrorManageUtil.java create mode 100644 jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/HttpUtil.java create mode 100644 jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/Util.java diff --git a/installer/resources/pacbot_app/files/DB.sql b/installer/resources/pacbot_app/files/DB.sql index ab5bacea2..fbf2b11a9 100644 --- a/installer/resources/pacbot_app/files/DB.sql +++ b/installer/resources/pacbot_app/files/DB.sql @@ -877,6 +877,15 @@ CREATE TABLE IF NOT EXISTS pac_config_audit ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +CREATE TABLE IF NOT EXISTS `Recommendation_Mappings` ( + `checkId` varchar(20) COLLATE utf8_bin DEFAULT NULL, + `type` varchar(50) COLLATE utf8_bin DEFAULT NULL, + `resourceInfo` varchar(200) COLLATE utf8_bin DEFAULT NULL, + `_resourceId` varchar(200) COLLATE utf8_bin DEFAULT NULL, + `monthlySavingsField` varchar(200) COLLATE utf8_bin DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + + /*Insert task to necessary tables*/ INSERT IGNORE INTO `task`(`id`,`index`,`mappings`,`data`) values (1,'exceptions','{\"mappings\":{\"sticky_exceptions\":{\"properties\":{\"assetGroup\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"dataSource\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"exceptionName\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"exceptionReason\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"expiryDate\":{\"type\":\"date\"},\"targetTypes\":{\"properties\":{\"name\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"rules\":{\"properties\":{\"ruleId\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"ruleName\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}}}}}}}}}}',NULL),(2,'faqs','{\"mappings\":{\"widgetinfo\":{\"properties\":{\"widgetid\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"widgetname\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}}}},\"faqinfo\":{\"properties\":{\"answer\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"faqid\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"faqname\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"tag\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"widgetid\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}}}}}}','{\"index\": {\"_index\": \"faqs\", \"_type\": \"widgetinfo\", \"_id\": \"w1\"}}\r{\"widgetid\":\"w1\",\"widgetname\":\"compliance overview\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"widgetinfo\", \"_id\": \"w2\"}}\r{\"widgetid\":\"w2\",\"widgetname\":\"patching\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"widgetinfo\", \"_id\": \"w3\"}}\r{\"widgetid\":\"w3\",\"widgetname\":\"tagging\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"widgetinfo\", \"_id\": \"w4\"}}\r{\"widgetid\":\"w4\",\"widgetname\":\"vulnerabilities\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"widgetinfo\", \"_id\": \"w5\"}}\r{\"widgetid\":\"w5\",\"widgetname\":\"certificates\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w2q7\"}}\r{\"faqid\":\"q7\",\"faqname\":\"How is unpatched count calculated ?\",\"answer\":\"Total assets which does not have updated kernel version.\",\"widgetid\":\"w2\",\"tag\":\"patching\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w3q4\"}}\r{\"faqid\":\"q4\",\"faqname\":\"How is tagging compliance % calculated ?\",\"answer\":\"Tagging compliance is calculated by dividing total taggable assets by total tagged assets.\",\"widgetid\":\"w3\",\"tag\":\"tagging\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w1q1\"}}\r{\"faqid\":\"q1\",\"faqname\":\"What is shown in this graph?\",\"answer\":\"This multi ring donut represents the overall compliance percentage. Policies are grouped into categories like security, governance, cost optimization and tagging. Rings in the donut represents compliance percentage for each of those categories. The rolled up percentage value for a given category is calculated by doing a weighted average of compliance percentage values of individual policies in that category. Weights are assigned based on the importance of the policy. Overall rolled up number in the middle of the donut represents uber compliance percentage for the selected asset group. This value is calculated by doing a simple average of compliance percentage values of the four categories.\",\"widgetid\":\"w1\",\"tag\":\"over-all\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w4q5\"}}\r{\"faqid\":\"q5\",\"faqname\":\"How is vulnerabilities compliance % calculated ?\",\"answer\":\"Vulnerabilities compliance is calculated by dividing total vulnerable assets by total servers, if an asset is not scanned by qualys , then the asset is considered as vulnerable.\",\"widgetid\":\"w4\",\"tag\":\"vulnerabilities\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w5q3\"}}\r{\"faqid\":\"q3\",\"faqname\":\"How is certificates compliance % calculated ?\",\"answer\":\"Total non-expired certificates divided by total certificates\",\"widgetid\":\"w5\",\"tag\":\"certificates\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w3q8\"}}\r{\"faqid\":\"q8\",\"faqname\":\"How is untagged count calculated ?\",\"answer\":\"Total assets which is missing either application/environment tags or both tags.\",\"widgetid\":\"w3\",\"tag\":\"tagging\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w2q2\"}}\r{\"faqid\":\"q2\",\"faqname\":\"How is patching compliance % calculated ?\",\"answer\":\"Total patched resources divided by total running resources\",\"widgetid\":\"w2\",\"tag\":\"patching\"}'); @@ -1414,6 +1423,7 @@ INSERT IGNORE INTO pac_config_relation (application,parent) VALUES ('data-shippe INSERT IGNORE INTO pac_config_relation (application,parent) VALUES ('inventory','batch'); INSERT IGNORE INTO pac_config_relation (`application`,`parent`) VALUES ('rule','application'); INSERT IGNORE INTO pac_config_relation (application,parent) VALUES ('rule-engine','rule'); +INSERT IGNORE INTO pac_config_relation (application,parent) VALUES ('recommendation-enricher','batch'); INSERT IGNORE INTO pac_config_key_metadata (`cfkey`,`description`) VALUES ('admin.api-role','Description PlaceHolder'); INSERT IGNORE INTO pac_config_key_metadata (`cfkey`,`description`) VALUES ('admin.push.notification.pollinterval.milliseconds','description'); @@ -1946,6 +1956,7 @@ INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `pr + UPDATE `cf_RuleInstance` SET assetGroup = 'aws' WHERE ruleId='PacMan_AmazonRDSIdleDBInstancesRule_version-1_AmazonRDSIdleDBInstancesRule_rdsdb'; UPDATE `cf_RuleInstance` SET assetGroup = 'aws',ruleParams = '{"assetGroup":"aws","policyId":"PacMan_CheckInactiveIamUser_version-1","environmentVariables":[],"ruleUUID":"aws_iam_users_should_not_be_inactive_for_than_target_period","ruleType":"ManageRule","pac_ds":"aws","targetType":"iamuser","params":[{"encrypt":false,"value":"90","key":"pwdInactiveDuration"},{"encrypt":false,"value":"high","key":"severity"},{"encrypt":false,"value":"security","key":"ruleCategory"},{"encrypt":false,"value":"check-for-inactive-iam-users","key":"ruleKey"},{"encrypt":false,"value":"true","key":"threadsafe"}],"ruleId":"PacMan_CheckInactiveIamUser_version-1_CheckInactiveIamUser_iamuser","autofix":false,"alexaKeyword":"CheckInactiveIamUser","ruleRestUrl":""}' WHERE ruleId='PacMan_CheckInactiveIamUser_version-1_CheckInactiveIamUser_iamuser'; UPDATE `cf_RuleInstance` SET assetGroup = 'aws' WHERE ruleId='PacMan_EC2-RunInstance-iam-role-with-unapproved-access_version-1_ec2-runInstance-iam-role-with-unapproved-access_iamrole'; diff --git a/jobs/recommendation-enricher/pom.xml b/jobs/recommendation-enricher/pom.xml new file mode 100644 index 000000000..f9e7c5013 --- /dev/null +++ b/jobs/recommendation-enricher/pom.xml @@ -0,0 +1,210 @@ + + 4.0.0 + com.tmobile.cso.pacman + recommendation-enricher + 0.0.1-SNAPSHOT + + + 1.8 + + + + + + org.powermock + powermock-module-junit4 + 1.7.3 + test + + + org.powermock + powermock-api-mockito + 1.7.3 + test + + + org.springframework + spring-test + 4.0.5.RELEASE + test + + + com.amazonaws + aws-java-sdk-s3 + 1.11.490 + + + com.amazonaws + aws-java-sdk-sts + 1.11.490 + + + + com.tmobile.pacman + batch-commons + 1.0.0-SNAPSHOT + provided + + + com.amazonaws + aws-java-sdk-s3 + + + com.amazonaws + aws-java-sdk-rds + + + com.amazonaws + aws-java-sdk-events + + + com.amazonaws + aws-java-sdk-cloudwatch + + + com.amazonaws + aws-java-sdk-dynamodb + + + com.amazonaws + aws-java-sdk-cloudtrail + + + com.amazonaws + aws-java-sdk-core + + + com.amazonaws + + aws-java-sdk-elasticloadbalancingv2 + + + + com.amazonaws + aws-java-sdk-ec2 + + + com.amazonaws + aws-java-sdk-ses + + + com.amazonaws + aws-java-sdk-kms + + + com.amazonaws + aws-lambda-java-core + + + com.amazonaws + aws-java-sdk-iam + + + com.amazonaws + aws-java-sdk-config + + + com.amazonaws + aws-java-sdk-route53 + + + com.amazonaws + aws-java-sdk-sts + + + com.amazonaws + aws-java-sdk-api-gateway + + + com.amazonaws + aws-java-sdk-lambda + + + com.amazonaws + aws-java-sdk-guardduty + + + com.amazonaws + + aws-java-sdk-elasticloadbalancing + + + + + + org.apache.httpcomponents + httpclient + 4.5.3 + + + org.elasticsearch.client + rest + 5.3.0 + + + com.fasterxml.jackson.core + jackson-databind + 2.8.7 + + + mysql + mysql-connector-java + 5.1.17 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + 1.8 + 1.8 + + + + maven-assembly-plugin + + + build-a + + + + com.tmobile.pacman.commons.main.JobExecutor + + + + jar-with-dependencies + + recommendation-enricher + + package + + single + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.6.201602180812 + + + + prepare-agent + + + + report + test + + report + + + + + + + \ No newline at end of file diff --git a/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/Main.java b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/Main.java new file mode 100644 index 000000000..590ed192b --- /dev/null +++ b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/Main.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.cso.pacbot.recommendation; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tmobile.cso.pacbot.recommendation.entity.RecommendationCollector; +import com.tmobile.cso.pacbot.recommendation.util.Constants; +import com.tmobile.cso.pacbot.recommendation.util.ErrorManageUtil; +import com.tmobile.pacman.commons.jobs.PacmanJob; + + +/** + * The Class Main. + */ +@PacmanJob(methodToexecute = "shipData", jobName = "Recommendation-Enricher", desc = "", priority = 5) +public class Main implements Constants { + + + /** The Constant LOGGER. */ + private static final Logger LOGGER = LoggerFactory.getLogger(Main.class); + /** + * The main method. + * + * @param args + * the arguments + */ + public static void main(String[] args) { + Map params = new HashMap<>(); + Arrays.asList(args).stream().forEach(obj -> { + String[] paramArray = obj.split("[:]"); + params.put(paramArray[0], paramArray[1]); + }); + shipData(params); + System.exit(0); + } + + /** + * Ship data. + * + * @param params the params + * @return the map + */ + public static Map shipData(Map params) { + String jobName = System.getProperty("jobName"); + List> errorList = new ArrayList<>(); + try { + MainUtil.setup(params); + } catch (Exception e) { + Map errorMap = new HashMap<>(); + errorMap.put(ERROR, "Exception in setting up Job "); + errorMap.put(ERROR_TYPE, WARN); + errorMap.put(EXCEPTION, e.getMessage()); + errorList.add(errorMap); + return ErrorManageUtil.formErrorCode(jobName, errorList); + } + errorList.addAll(new RecommendationCollector().uploadRecommendationData()); + Map status = ErrorManageUtil.formErrorCode(jobName, errorList); + LOGGER.info("Job Return Status {} ",status); + return status; + } + +} diff --git a/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/MainUtil.java b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/MainUtil.java new file mode 100644 index 000000000..72c059087 --- /dev/null +++ b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/MainUtil.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.cso.pacbot.recommendation; + +import java.util.Map; + +import com.tmobile.cso.pacbot.recommendation.util.ConfigUtil; +import com.tmobile.cso.pacbot.recommendation.util.Constants; + + +/** + * The Class MainUtil. + */ +public class MainUtil { + + /** + * Setup. + * + * @param params the params + * @throws Exception the exception + */ + public static void setup(Map params) throws Exception { + + ConfigUtil.setConfigProperties(params.get(Constants.CONFIG_CREDS)); + + if( !(params==null || params.isEmpty())){ + params.forEach((k,v) -> System.setProperty(k, v)); + } + + } + +} diff --git a/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/dao/RDSDBManager.java b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/dao/RDSDBManager.java new file mode 100644 index 000000000..d92623513 --- /dev/null +++ b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/dao/RDSDBManager.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.cso.pacbot.recommendation.dao; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tmobile.cso.pacbot.recommendation.util.Constants; + +/** + * The Class RDSDBManager. + */ +public class RDSDBManager { + + /** The Constant dbURL. */ + private static final String DB_URL = System.getProperty(Constants.RDS_DB_URL); + + /** The Constant dbUserName. */ + private static final String DB_USER_NAME = System.getProperty(Constants.RDS_USER); + + /** The Constant dbPassword. */ + private static final String DB_PASSWORD = System.getProperty(Constants.RDS_PWD); + + /** The Constant LOGGER. */ + private static final Logger LOGGER = LoggerFactory.getLogger(RDSDBManager.class); + + /** + * Instantiates a new RDSDB manager. + */ + private RDSDBManager(){ + + } + + /** + * Gets the connection. + * + * @return the connection + * @throws ClassNotFoundException + * the class not found exception + * @throws SQLException + * the SQL exception + */ + private static Connection getConnection() throws ClassNotFoundException, SQLException { + Connection conn = null; + Class.forName("com.mysql.jdbc.Driver"); + Properties props = new Properties(); + + props.setProperty("user", DB_USER_NAME); + props.setProperty("password", DB_PASSWORD); + conn = DriverManager.getConnection(DB_URL, props); + + return conn; + } + + /** + * Execute query. + * + * @param query + * the query + * @return the list + */ + public static List> executeQuery(String query) { + List> results = new ArrayList<>(); + try( + Connection conn = getConnection(); + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(query);){ + ResultSetMetaData rsmd = rs.getMetaData(); + int columnCount = rsmd.getColumnCount(); + Map data; + while (rs.next()) { + data = new LinkedHashMap<>(); + for (int i = 1; i <= columnCount; i++) { + data.put(rsmd.getColumnName(i), rs.getString(i)); + } + results.add(data); + } + } catch (Exception ex) { + LOGGER.error("Error Executing Query",ex); + } + return results; + } + +} diff --git a/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/entity/RecommendationCollector.java b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/entity/RecommendationCollector.java new file mode 100644 index 000000000..c3d1207fa --- /dev/null +++ b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/entity/RecommendationCollector.java @@ -0,0 +1,258 @@ +package com.tmobile.cso.pacbot.recommendation.entity; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.amazonaws.util.StringUtils; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Strings; +import com.tmobile.cso.pacbot.recommendation.dao.RDSDBManager; +import com.tmobile.cso.pacbot.recommendation.es.ESManager; +import com.tmobile.cso.pacbot.recommendation.util.Constants; +import com.tmobile.cso.pacbot.recommendation.util.Util; + +/** + * The Class RecommendationCollector. + */ +public class RecommendationCollector implements Constants { + + /** The Constant log. */ + private static final Logger LOGGER = LoggerFactory.getLogger(RecommendationCollector.class); + + /** The Constant DATE_FORMAT. */ + private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZ"; + + /** The Constant CURR_DATE. */ + private static final String CURR_DATE = new SimpleDateFormat(DATE_FORMAT).format(new java.util.Date()); + + /** + * Upload recommendation data. + * + * @return the list + */ + public List> uploadRecommendationData() { + List> errorList = new ArrayList<>(); + + Map> recommendationMappings = RDSDBManager.executeQuery("select * FROM Recommendation_Mappings") + .stream().collect(Collectors.toMap(map -> (String) map.get("checkId"), map -> map)); + + List> resources = ESManager.getResourcesInfo("aws_checks", "checks_resources"); + Map> checks = ESManager.getChecksInfo("aws_checks","checks",Arrays.asList(Constants.CHECKNAME,Constants.CHECKID,Constants.ACCOUNTID,Constants.CHECKCATEGORY)); + + ObjectMapper mapper = new ObjectMapper(); + List errors = new ArrayList<>(); + Map> parentTypes = new HashMap<>(); + List> recommendationsWithResourceId = new ArrayList<>(); + List> recommendationsWithoutResourceId = new ArrayList<>(); + for(Map resource : resources) { + Map check = checks.get(resource.get(Constants.CHECKID)+"_"+resource.get(Constants.ACCOUNTID)); + Map resourceInfo = new HashMap<>(); + try { + resourceInfo = mapper.readValue(resource.get(Constants.RESOURCE_INFO), new TypeReference>() {}); + } catch (IOException e) { + LOGGER.error("Error in fetching resource info "+e); + } + + if(!resourceInfo.isEmpty()) { + Map recommendationMapping = recommendationMappings.get(resource.get(Constants.CHECKID)); + if(null !=recommendationMapping && !recommendationMapping.isEmpty()) { + formRecommendationsWithResourceId(recommendationsWithResourceId, recommendationMapping, check, + resourceInfo, resource, parentTypes); + } else { + formRecommendationsWithoutResourceId(recommendationsWithoutResourceId, check, resourceInfo, resource); + } + } + } + Map parentInfo = new HashMap<>(); + for(Entry> parentType :parentTypes.entrySet()) { + String query = "SELECT DISTINCT _resourceId FROM Recommendation_Mappings WHERE TYPE = '"+ parentType.getKey()+ "'"; + parentInfo.putAll(ESManager.getParentInfo(parentType.getKey(), parentType.getValue(),RDSDBManager.executeQuery(query).get(0).get("_resourceId"))); + } + uploadRecommendationsWithResourceIds(recommendationsWithResourceId, parentInfo, errors); + uploadRecommendationsWithoutResourceIds(recommendationsWithoutResourceId, errors); + + for(String parentType : parentTypes.keySet()) { + ESManager.deleteOldDocuments("aws_"+parentType, Constants.RECOMMENDATION, "_loaddate.keyword", CURR_DATE); + ESManager.updateLatestStatus("aws_"+parentType, Constants.RECOMMENDATION, "_loaddate.keyword", CURR_DATE); + } + ESManager.deleteOldDocuments(Constants.GLOBAL_RECOMMENDATIONS,Constants.RECOMMENDATION, Constants.LOAD_DATE,CURR_DATE); + ESManager.updateLatestStatus(Constants.GLOBAL_RECOMMENDATIONS,Constants.RECOMMENDATION, Constants.LOAD_DATE,CURR_DATE); + return errorList; + } + + /** + * Group resource id by type. + * + * @param parentTypes the parent types + * @param type the type + * @param resourceId the resource id + */ + private void groupResourceIdByType(Map> parentTypes, String type, String resourceId) { + if(parentTypes.containsKey(type)) { + if(!parentTypes.get(type).contains(resourceId)) { + parentTypes.get(type).add(resourceId); + } + } else { + List resourceIds = new ArrayList<>(); + resourceIds.add(resourceId); + parentTypes.put(type, resourceIds); + } + } + + /** + * Form recommendations with resource id. + * + * @param recommendationsWithResourceId the recommendations with resource id + * @param recommendationMapping the recommendation mapping + * @param check the check + * @param resourceInfo the resource info + * @param resource the resource + * @param parentTypes the parent types + */ + private void formRecommendationsWithResourceId(List> recommendationsWithResourceId,Map recommendationMapping, + Map check, Map resourceInfo,Map resource,Map> parentTypes) { + + Map recommendationObj = new HashMap<>(); + String type = recommendationMapping.get("type"); + resourceInfo.put(recommendationMapping.get("_resourceId"), resourceInfo.get(recommendationMapping.get("resourceInfo"))); + resourceInfo.remove(recommendationMapping.get("resourceInfo")); + try { + String resourceId = resourceInfo.get(recommendationMapping.get("_resourceId")).toString().split(" ")[0]; + recommendationObj.putAll(resource); + recommendationObj.remove(Constants.CHECKID); + recommendationObj.put(Constants.RESOURCE_INFO,resourceInfo); + recommendationObj.put("_resourceid", resourceId); + recommendationObj.put(Constants.LOAD_DATE,CURR_DATE); + recommendationObj.put("latest",false); + if(!Strings.isNullOrEmpty(recommendationMapping.get(Constants.MONTHLY_SAVINGS_FIELD)) && resourceInfo.containsKey(recommendationMapping.get(Constants.MONTHLY_SAVINGS_FIELD))) { + recommendationObj.put("monthlysavings", Double.valueOf(resourceInfo.get(recommendationMapping.get(Constants.MONTHLY_SAVINGS_FIELD)).toString().replace("-", "").replace("$", "").replace(",", ""))); + } + recommendationObj.put(Constants.RECOMMENDATION_ID,check.get(Constants.CHECKID)); + recommendationObj.put(Constants.RECOMMENDATION,check.get(Constants.CHECKNAME)); + recommendationObj.put("category",check.get(Constants.CHECKCATEGORY)); + recommendationObj.put(Constants.ACCOUNTID,check.get(Constants.ACCOUNTID)); + recommendationObj.put("type",type); + groupResourceIdByType(parentTypes, type, resourceId); + recommendationsWithResourceId.add(recommendationObj); + } catch(Exception e) { + LOGGER.error("Error in form recommendation info with resource id "+e); + } + } + + /** + * Form recommendations without resource id. + * + * @param recommendationsWithoutResourceId the recommendations without resource id + * @param check the check + * @param resourceInfo the resource info + * @param resource the resource + */ + private void formRecommendationsWithoutResourceId(List> recommendationsWithoutResourceId,Map check, + Map resourceInfo,Map resource) { + + Map recommendationObj = new HashMap<>(); + try { + recommendationObj.putAll(resource); + recommendationObj.remove(Constants.CHECKID); + recommendationObj.put(Constants.RESOURCE_INFO,resourceInfo); + recommendationObj.put(Constants.LOAD_DATE,CURR_DATE); + recommendationObj.put("latest",false); + recommendationObj.put(Constants.RECOMMENDATION_ID,check.get(Constants.CHECKID)); + recommendationObj.put(Constants.RECOMMENDATION,check.get(Constants.CHECKNAME)); + recommendationObj.put("category",check.get(Constants.CHECKCATEGORY)); + recommendationObj.put(Constants.ACCOUNTID,check.get(Constants.ACCOUNTID)); + recommendationsWithoutResourceId.add(recommendationObj); + } catch(Exception e) { + LOGGER.error("Error in form recommendation info without resource id "+e); + } + } + + /** + * Upload recommendations with resource ids. + * + * @param recommendationsWithResourceId the recommendations with resource id + * @param parentInfo the parent info + * @param errors the errors + */ + private void uploadRecommendationsWithResourceIds(List> recommendationsWithResourceId, Map parentInfo, List errors) { + + LOGGER.info("Started Uploading for recommendations with resource id {} ",recommendationsWithResourceId.size()); + String createTemplate = "{ \"index\" : { \"_index\" : \"%s\", \"_type\" : \"%s\", \"_id\" : \"%s\", \"_parent\" : \"%s\" } }%n"; + StringBuilder bulkRequest = new StringBuilder(); + int i=0; + for(Map recommendationObj : recommendationsWithResourceId) { + String type = recommendationObj.get("type").toString(); + String parentInfoId = recommendationObj.get("_resourceid")+"_"+recommendationObj.get(Constants.ACCOUNTID); + StringBuilder doc = new StringBuilder(ESManager.createESDoc(recommendationObj)); + if (doc != null) { + if(!StringUtils.isNullOrEmpty(parentInfo.get(parentInfoId))) { + ESManager.createType("aws_" + type, Constants.RECOMMENDATION, type); + bulkRequest.append(String.format(createTemplate,"aws_"+type,Constants.RECOMMENDATION,parentInfo.get(parentInfoId)+"_"+recommendationObj.get(Constants.RECOMMENDATION_ID)+"_"+Math.random(),parentInfo.get(parentInfoId))); + bulkRequest.append(doc + "\n"); + } + } + i++; + if (i % 100 == 0 || bulkRequest.toString().getBytes().length / (1024 * 1024) > 5) { + if (bulkRequest.length() > 0) { + LOGGER.info("Uploading {}", i); + ESManager.bulkUpload(errors,bulkRequest.toString()); + bulkRequest = new StringBuilder(); + } + } + } + if (bulkRequest.length() > 0) { + LOGGER.info("Uploading {}", i); + ESManager.bulkUpload(errors,bulkRequest.toString()); + } + LOGGER.info("Completed Uploading for recommendations with resource id"); + } + + /** + * Upload recommendations without resource ids. + * + * @param recommendationsWithoutResourceId the recommendations without resource id + * @param errors the errors + */ + private void uploadRecommendationsWithoutResourceIds(List> recommendationsWithoutResourceId, List errors) { + + LOGGER.info("Started Uploading for recommendations without resource id {} ",recommendationsWithoutResourceId.size()); + List> errorList = new ArrayList<>(); + String createTemplate = "{ \"index\" : { \"_index\" : \"%s\", \"_type\" : \"%s\", \"_id\" : \"%s\"} }%n"; + ESManager.createIndex(Constants.GLOBAL_RECOMMENDATIONS, errorList); + ESManager.createType(Constants.GLOBAL_RECOMMENDATIONS, Constants.RECOMMENDATION, errorList); + StringBuilder bulkRequest = new StringBuilder(); + int i=0; + for(Map recommendationObj : recommendationsWithoutResourceId) { + String id = recommendationObj.get(Constants.ACCOUNTID).toString()+recommendationObj.get(Constants.RECOMMENDATION_ID)+Math.random(); + StringBuilder doc = new StringBuilder(ESManager.createESDoc(recommendationObj)); + if (doc != null) { + bulkRequest.append(String.format(createTemplate,Constants.GLOBAL_RECOMMENDATIONS,Constants.RECOMMENDATION,Util.getUniqueID(id))); + bulkRequest.append(doc + "\n"); + } + i++; + if (i % 100 == 0 || bulkRequest.toString().getBytes().length / (1024 * 1024) > 5) { + if (bulkRequest.length() > 0) { + LOGGER.info("Uploading {}", i); + ESManager.bulkUpload(errors,bulkRequest.toString()); + bulkRequest = new StringBuilder(); + } + } + } + if (bulkRequest.length() > 0) { + LOGGER.info("Uploading {}", i); + ESManager.bulkUpload(errors,bulkRequest.toString()); + } + LOGGER.info("Completed Uploading for recommendations without resource id"); + } +} diff --git a/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/es/ESManager.java b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/es/ESManager.java new file mode 100644 index 000000000..41b9582ec --- /dev/null +++ b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/es/ESManager.java @@ -0,0 +1,666 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.cso.pacbot.recommendation.es; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.httpclient.HttpStatus; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.ParseException; +import org.apache.http.entity.ContentType; +import org.apache.http.nio.entity.NStringEntity; +import org.apache.http.util.EntityUtils; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Strings; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; +import com.tmobile.cso.pacbot.recommendation.util.Constants; +import com.tmobile.cso.pacbot.recommendation.util.Util; + +/** + * The Class ESManager. + */ +public class ESManager implements Constants { + + /** The es host key name. */ + private static final String ES_HOST_KEY_NAME = System.getProperty("elastic-search.host"); + + /** The es http port. */ + private static final Integer ES_HTTP_PORT = getESPort(); + + /** The rest client. */ + private static RestClient restClient; + + /** The log. */ + private static final Logger LOGGER = LoggerFactory.getLogger(ESManager.class); + + private static int THOUSAND_TWENTY_FOUR = 1024; + + /** + * Gets the ES port. + * + * @return the ES port + */ + private static int getESPort(){ + try{ + return Integer.parseInt(System.getProperty("elastic-search.port")); + }catch(Exception e){ + return 0; + } + } + /** + * Gets the rest client. + * + * @return the rest client + */ + private static RestClient getRestClient() { + if (restClient == null) + restClient = RestClient.builder(new HttpHost(ES_HOST_KEY_NAME, ES_HTTP_PORT)).build(); + return restClient; + + } + + /** + * Bulk upload. + * + * @param bulkRequest the bulk request + */ + private static void bulkUpload(StringBuilder bulkRequest) { + try { + Response resp = invokeAPI("POST", "/_bulk?refresh=true", bulkRequest.toString()); + String responseStr = EntityUtils.toString(resp.getEntity()); + if (responseStr.contains("\"errors\":true")) { + LOGGER.error(responseStr); + } + } catch (ParseException | IOException e) { + LOGGER.error("Error in uploading data", e); + } + } + + /** + * Refresh. + * + * @param index + * the index + */ + public static void refresh(String index) { + try { + Response refrehsResponse = invokeAPI("POST", index + "/" + "_refresh", null); + if (refrehsResponse != null && HttpStatus.SC_OK != refrehsResponse.getStatusLine().getStatusCode()) { + LOGGER.error("Refreshing index %s failed", index, refrehsResponse); + } + } catch (IOException e) { + LOGGER.error("Error in refresh ",e); + } + + } + + /** + * Method not used by the entity upload.But to append data to speific index + * + * @param index + * the index + * @param type + * the type + * @param docs + * the docs + * @param idKey + * the id key + * @param refresh + * the refresh + */ + public static void uploadData(String index, String type, List> docs, String idKey, + boolean refresh) { + String actionTemplate = "{ \"index\" : { \"_index\" : \"%s\", \"_type\" : \"%s\", \"_id\" : \"%s\"} }%n"; + String endpoint = "/_bulk"; + if (refresh) { + endpoint = endpoint + "?refresh=true"; + } + LOGGER.info("*********UPLOADING*** {}" , type); + if (null != docs && !docs.isEmpty()) { + StringBuilder bulkRequest = new StringBuilder(); + int i = 0; + for (Map doc : docs) { + String id = doc.get(idKey).toString(); + StringBuilder _doc = new StringBuilder(createESDoc(doc)); + + if (_doc != null) { + bulkRequest.append(String.format(actionTemplate, index, type, id)); + bulkRequest.append(_doc + "\n"); + } + i++; + if (i % 1000 == 0 || bulkRequest.toString().getBytes().length / (1024 * 1024) > 5) { + LOGGER.info("Uploaded {}" , i); + bulkUpload(endpoint, bulkRequest); + bulkRequest = new StringBuilder(); + } + } + if (bulkRequest.length() > 0) { + LOGGER.info("Uploaded {}" , i); + bulkUpload(endpoint, bulkRequest); + } + } + + } + + /** + * Bulk upload. + * + * @param endpoint the endpoint + * @param bulkRequest the bulk request + */ + private static void bulkUpload(String endpoint, StringBuilder bulkRequest) { + try { + Response resp = invokeAPI("POST", endpoint, bulkRequest.toString()); + String responseStr = EntityUtils.toString(resp.getEntity()); + if (responseStr.contains("\"errors\":true")) { + LOGGER.error(responseStr); + } + } catch (Exception e) { + LOGGER.error("Bulk upload failed",e); + + } + } + + public static void bulkUpload(List errors, String bulkRequest) { + try { + Response resp = invokeAPI("POST", "/_bulk?refresh=true", bulkRequest); + String responseStr = EntityUtils.toString(resp.getEntity()); + if (responseStr.contains("\"errors\":true")) { + LOGGER.error(responseStr); + errors.add(responseStr); + } + } catch (Exception e) { + LOGGER.error("Bulk upload failed",e); + errors.add(e.getMessage()); + } + } + + /** + * Update latest status. + * + * @param index + * the index + * @param type + * the type + * @param loaddate + * the loaddate + */ + public static void updateLatestStatus(String index, String type, String field, String value) { + String updateJson = "{\"script\":{\"inline\": \"ctx._source.latest=true\"},\"query\": {\"bool\": {\"must\": [{ \"match\": {\"latest\":false}}], \"must\": [{\"match\": {\"" + + field + "\":\"" + value + "\"}}]}}}"; + try { + invokeAPI("POST", index + "/" + type + "/" + "_update_by_query", updateJson); + } catch (IOException e) { + LOGGER.error("Error in updateLatestStatus",e); + } + } + + /** + * Creates the ES doc. + * + * @param doc + * the doc + * @return the string + */ + public static String createESDoc(Map doc) { + ObjectMapper objMapper = new ObjectMapper(); + String docJson = "{}"; + try { + docJson = objMapper.writeValueAsString(doc); + } catch (JsonProcessingException e) { + LOGGER.error("Error createESDoc",e); + } + return docJson; + } + + /** + * Invoke API. + * + * @param method the method + * @param endpoint the endpoint + * @param payLoad the pay load + * @return the response + * @throws IOException Signals that an I/O exception has occurred. + */ + public static Response invokeAPI(String method, String endpoint, String payLoad) throws IOException { + String uri = endpoint; + if (!uri.startsWith("/")) { + uri = "/" + uri; + } + HttpEntity entity = null; + if (payLoad != null) + entity = new NStringEntity(payLoad, ContentType.APPLICATION_JSON); + + return getRestClient().performRequest(method, uri, Collections.emptyMap(), entity); + } + + /** + * Index exists. + * + * @param indexName + * the index name + * @return true, if successful + */ + private static boolean indexExists(String indexName) { + + try { + Response response = invokeAPI("HEAD", indexName, null); + if (response != null) { + return response.getStatusLine().getStatusCode() == 200; + } + } catch (IOException e) { + LOGGER.error("Error indexExists",e); + } + return false; + } + + /** + * Type exists. + * + * @param indexName + * the index name + * @param type + * the type + * @return true, if successful + */ + private static boolean typeExists(String indexName, String type) { + try { + Response response = invokeAPI("HEAD", indexName + "/_mapping/" + type, null); + if (response != null) { + return response.getStatusLine().getStatusCode() == 200 ? true : false; + } + } catch (IOException e) { + LOGGER.error("Error in typeExists",e); + } + + return false; + } + + /** + * Gets the type count. + * + * @param indexName + * the index name + * @param type + * the type + * @return the type count + */ + private static int getTypeCount(String indexName, String type) { + try { + Response response = invokeAPI("GET", indexName + "/" + type + "/_count?filter_path=count", + "{\"query\":{ \"match\":{\"latest\":true}}}"); + String rspJson = EntityUtils.toString(response.getEntity()); + return new ObjectMapper().readTree(rspJson).at("/count").asInt(); + } catch (IOException e) { + LOGGER.error("Error in getTypeCount",e); + } + return 0; + } + + private static int getCount(String indexName, String type) { + try { + Response response = invokeAPI("GET", indexName + "/" + type + "/_count?filter_path=count", null); + String rspJson = EntityUtils.toString(response.getEntity()); + return new ObjectMapper().readTree(rspJson).at("/count").asInt(); + } catch (IOException e) { + LOGGER.error("Error in getTypeCount",e); + } + return 0; + } + + /** + * Gets the existing info. + * + * @param indexName + * the index name + * @param type + * the type + * @param filters + * the filters + * @return the existing info + */ + public static Map getParentInfo(String type, List resourceIds, String resourceIdKey) { + + Map results = new HashMap<>(); + String endPoint = "aws_"+ type + "/" + type + "/_search"; + ObjectMapper objMapper = new ObjectMapper(); + JsonParser parser = new JsonParser(); + try { + for (int index = 0; index <= (resourceIds.size() / THOUSAND_TWENTY_FOUR); index++) { + int from = index * THOUSAND_TWENTY_FOUR; + int to = from + THOUSAND_TWENTY_FOUR; + if (resourceIds.size() < to) { + to = resourceIds.size(); + } + StringBuilder requestBody = new StringBuilder("{\"size\":10000,\"_source\":[\"_docid\",\"accountid\",\"" + resourceIdKey + + "\"],\"query\":{\"bool\":{\"must\":[{\"terms\":{\"" + resourceIdKey + ".keyword\":"); + requestBody.append(objMapper.writeValueAsString(resourceIds.subList(from, to))); + requestBody.append("}},{\"match\":{\"latest\":\"true\"}}]}}}"); + String responseJson = EntityUtils.toString(invokeAPI("GET", endPoint, requestBody.toString()).getEntity()); + JsonObject responseDetailsjson = parser.parse(responseJson).getAsJsonObject(); + JsonArray hits = responseDetailsjson.get("hits").getAsJsonObject().get("hits").getAsJsonArray(); + for (JsonElement hit : hits) { + JsonObject source = hit.getAsJsonObject().get("_source").getAsJsonObject(); + if (source != null) { + Map doc = new Gson().fromJson(source, new TypeToken>() { + }.getType()); + results.put(doc.get(resourceIdKey)+"_"+doc.get("accountid"),doc.get("_docid")); + } + } + } + } catch (Exception e) { + LOGGER.error("Error in getParentInfo" ,e ); + } + return results; + } + + public static List> getResourcesInfo(String indexName, String type) { + int count = getCount(indexName, type); + int _count = count; + boolean scroll = false; + if (count > 10000) { + _count = 10000; + scroll = true; + } + + StringBuilder filter_path = new StringBuilder("&filter_path=_scroll_id,hits.hits._source"); + String endPoint = indexName + "/" + type + "/_search?scroll=1m" + filter_path.toString() + "&size=" + _count; + List> _data = new ArrayList<>(); + String scrollId = fetchDataAndScrollId(endPoint, _data, null); + + if (scroll) { + count -= 10000; + do { + endPoint = "/_search/scroll?scroll=1m&scroll_id=" + scrollId + filter_path.toString(); + scrollId = fetchDataAndScrollId(endPoint, _data, null); + count -= 10000; + if (count <= 0) + scroll = false; + } while (scroll); + } + return _data; + } + + public static Map> getChecksInfo(String indexName, String type, List filters) { + int count = getTypeCount(indexName, type); + int _count = count; + boolean scroll = false; + if (count > 10000) { + _count = 10000; + scroll = true; + } + + StringBuilder filter_path = new StringBuilder("&filter_path=_scroll_id,"); + for (String _filter : filters) { + filter_path.append("hits.hits._source." + _filter + ","); + } + filter_path.deleteCharAt(filter_path.length() - 1); + String endPoint = indexName + "/" + type + "/_search?scroll=1m" + filter_path.toString() + "&size=" + _count; + String payLoad = "{\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":\"true\"}}]}}}"; + Map> _data = new HashMap<>(); + String scrollId = fetchDataAndScrollId(endPoint, _data, payLoad); + + if (scroll) { + count -= 10000; + do { + endPoint = "/_search/scroll?scroll=1m&scroll_id=" + scrollId + filter_path.toString(); + scrollId = fetchDataAndScrollId(endPoint, _data, null); + count -= 10000; + if (count <= 0) + scroll = false; + } while (scroll); + } + return _data; + } + + /** + * Fetch data and scroll id. + * + * @param endPoint + * the end point + * @param _data + * the data + * @param keyField + * the key field + * @param payLoad + * the pay load + * @return the string + */ + private static String fetchDataAndScrollId(String endPoint, List> _data, String payLoad) { + try { + ObjectMapper objMapper = new ObjectMapper(); + Response response = invokeAPI("GET", endPoint, payLoad); + String responseJson = EntityUtils.toString(response.getEntity()); + JsonNode _info = objMapper.readTree(responseJson).at("/hits/hits"); + String scrollId = objMapper.readTree(responseJson).at("/_scroll_id").textValue(); + Iterator it = _info.elements(); + String doc; + Map docMap; + while (it.hasNext()) { + doc = it.next().fields().next().getValue().toString(); + docMap = objMapper.readValue(doc, new TypeReference>() { + }); + docMap.remove("discoverydate"); + docMap.remove("_loaddate"); + docMap.remove("id"); + _data.add(docMap); + } + return scrollId; + } catch (ParseException | IOException e) { + LOGGER.error("Error in fetchDataAndScrollId" ,e ); + } + return ""; + } + + private static String fetchDataAndScrollId(String endPoint, Map> _data, String payLoad) { + try { + ObjectMapper objMapper = new ObjectMapper(); + Response response = invokeAPI("GET", endPoint, payLoad); + String responseJson = EntityUtils.toString(response.getEntity()); + JsonNode _info = objMapper.readTree(responseJson).at("/hits/hits"); + String scrollId = objMapper.readTree(responseJson).at("/_scroll_id").textValue(); + Iterator it = _info.elements(); + String doc; + Map docMap; + while (it.hasNext()) { + doc = it.next().fields().next().getValue().toString(); + docMap = objMapper.readValue(doc, new TypeReference>() { + }); + _data.put(docMap.get("checkid")+"_"+docMap.get("accountid"), docMap); + } + return scrollId; + } catch (ParseException | IOException e) { + LOGGER.error("Error in fetchDataAndScrollId" ,e ); + } + return ""; + } + + /** + * Creates the index. + * + * @param indexName the index name + * @param errorList the error list + */ + public static void createIndex(String indexName, List> errorList) { + if (!indexExists(indexName)) { + String payLoad = "{\"settings\": { \"index.mapping.ignore_malformed\": true }}"; + try { + invokeAPI("PUT", indexName, payLoad); + } catch (IOException e) { + LOGGER.error("Error in createIndex" ,e ); + Map errorMap = new HashMap<>(); + errorMap.put(ERROR, "Error in createIndex "+indexName); + errorMap.put(ERROR_TYPE, WARN); + errorMap.put(EXCEPTION, e.getMessage()); + errorList.add(errorMap); + } + } + } + + /** + * Creates the type. + * + * @param indexName the index name + * @param typename the typename + * @param errorList the error list + */ + public static void createType(String indexName, String typename, List> errorList) { + if (!typeExists(indexName, typename)) { + String endPoint = indexName + "/_mapping/" + typename; + try { + invokeAPI("PUT", endPoint, "{ \"properties\":{}}"); + } catch (IOException e) { + LOGGER.error("Error in createType",e); + Map errorMap = new HashMap<>(); + errorMap.put(ERROR, "Error in createType "+typename); + errorMap.put(ERROR_TYPE, WARN); + errorMap.put(EXCEPTION, e.getMessage()); + errorList.add(errorMap); + } + } + } + + /** + * Creates the type. + * + * @param index the index + * @param type the type + * @param parent the parent + */ + public static void createType(String index, String type, String parent) { + if (!typeExists(index, type)) { + String endPoint = index + "/_mapping/" + type; + String payLoad = "{\"_parent\": { \"type\": \"" + parent + "\" } }"; + try { + invokeAPI("PUT", endPoint, payLoad); + } catch (IOException e) { + LOGGER.error("Error createType ", e); + } + } + } + + + /** + * added for uploading Child docs where parent id could be dervied from + * child. + * + * @param index the index + * @param type the type + * @param docs the docs + * @param parentKey the parent key + */ + public static void uploadData(String index, String type, List> docs, String[] parentKey) { + String actionTemplate = "{ \"index\" : { \"_index\" : \"%s\", \"_type\" : \"%s\", \"_parent\" : \"%s\" } }%n"; // added + // _parent + // node + + LOGGER.info("*********UPLOADING*** {}", type); + if (null != docs && !docs.isEmpty()) { + StringBuilder bulkRequest = new StringBuilder(); + int i = 0; + for (Map doc : docs) { + + StringBuilder _doc = new StringBuilder(new Gson().toJson(doc)); + String parent = Util.concatenate(doc, parentKey, "_"); + bulkRequest.append(String.format(actionTemplate, index, type, parent)); + bulkRequest.append(_doc + "\n"); + i++; + if (i % 1000 == 0 || bulkRequest.toString().getBytes().length / (1024 * 1024) > 5) { + bulkUpload(bulkRequest); + bulkRequest = new StringBuilder(); + } + } + if (bulkRequest.length() > 0) { + bulkUpload(bulkRequest); + } + } + } + + /** + * Delete old documents. + * + * @param index the index + * @param type the type + * @param field the field + * @param value the value + */ + public static void deleteOldDocuments(String index, String type, String field, String value) { + String deleteJson = "{\"query\": {\"bool\": {\"must_not\": [{ \"match\": {\"" + field + "\":\"" + value + + "\"}}]}}}"; + try { + invokeAPI("POST", index + "/" + type + "/" + "_delete_by_query", deleteJson); + } catch (IOException e) { + LOGGER.error("Error deleteOldDocuments ", e); + } + } + + /** + * Update load date. + * + * @param index the index + * @param type the type + * @param accountId the account id + * @param region the region + * @param loaddate the loaddate + * @param checkLatest the check latest + */ + public static long updateLoadDate(String index, String type, String accountId, String region, String loaddate,boolean checkLatest) { + LOGGER.info("Error records are handled for Account : {} Type : {} Region: {} ",accountId,type,region ); + StringBuilder updateJson = new StringBuilder("{\"script\":{\"inline\":\"ctx._source._loaddate= '"); + updateJson.append(loaddate).append("'\"},\"query\":{\"bool\":{\"must\":["); + updateJson.append("{\"match\":{\"accountid\":\""); + updateJson.append(accountId); + updateJson.append("\"}}"); + if(!Strings.isNullOrEmpty(region)) { + updateJson.append(",{\"match\":{\"region.keyword\":\""); + updateJson.append(region); + updateJson.append("\"}}"); + } + if(checkLatest){ + updateJson.append(",{\"match\":{\"latest\":true }}"); + + } + updateJson.append("]}}}"); + try { + Response updateInfo = invokeAPI("POST", index + "/" + type + "/" + "_update_by_query", updateJson.toString()); + String updateInfoJson = EntityUtils.toString(updateInfo.getEntity()); + return new JsonParser().parse(updateInfoJson).getAsJsonObject().get("updated").getAsLong(); + } catch (IOException e) { + LOGGER.error("Error in updateLoadDate",e); + } + return 0l; + } +} diff --git a/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/exception/UnAuthorisedException.java b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/exception/UnAuthorisedException.java new file mode 100644 index 000000000..c68a1a48d --- /dev/null +++ b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/exception/UnAuthorisedException.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.cso.pacbot.recommendation.exception; + +/** + * The Class UnAuthorisedException. + */ +public class UnAuthorisedException extends Exception { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new un authorised exception. + */ + public UnAuthorisedException() { + } + + /** + * Instantiates a new un authorised exception. + * + * @param msg the msg + */ + public UnAuthorisedException(String msg) { + super(msg); + } + +} diff --git a/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/ConfigUtil.java b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/ConfigUtil.java new file mode 100644 index 000000000..17aae103e --- /dev/null +++ b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/ConfigUtil.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.cso.pacbot.recommendation.util; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * The Class ConfigUtil. + */ +public class ConfigUtil { + + /** The Constant LOGGER. */ + private static final Logger LOGGER = LoggerFactory.getLogger(ConfigUtil.class); + + /** + * Sets the config properties. + * + * @param configCreds the new config properties + * @throws Exception the exception + */ + public static void setConfigProperties(String configCreds) throws Exception{ + Properties properties = new Properties(); + properties.putAll(System.getProperties()); + properties.putAll(fetchConfigProperties(configCreds)); + System.setProperties(properties); + } + + /** + * Fetch config properties. + * + * @param configCreds the config creds + * @return the map + * @throws Exception the exception + */ + @SuppressWarnings("unchecked") + public static Map fetchConfigProperties(String configCreds) throws Exception { + + Map properties = new HashMap<>(); + + String configUrl = System.getenv("CONFIG_URL"); + ObjectMapper objectMapper = new ObjectMapper(); + try { + Map appProps = new HashMap<>(); + Map batchProps = new HashMap<>(); + Map invProps = new HashMap<>(); + Map response = objectMapper.readValue(HttpUtil.httpGetMethodWithHeaders(configUrl, Util.getHeader(configCreds)), new TypeReference>(){}); + List> propertySources = (List>)response.get("propertySources"); + for(Map propertySource : propertySources) { + if(propertySource.get(Constants.NAME).toString().contains("application")) { + appProps.putAll((Map)propertySource.get(Constants.SOURCE)); + } + if(propertySource.get(Constants.NAME).toString().contains("batch")) { + batchProps.putAll((Map)propertySource.get(Constants.SOURCE)); + } + if(propertySource.get(Constants.NAME).toString().contains("recommendation-enricher")) { + invProps.putAll((Map)propertySource.get(Constants.SOURCE)); + } + properties.putAll(appProps); + properties.putAll(batchProps); + properties.putAll(invProps); + } + } catch (Exception e) { + LOGGER.error("Error in fetchConfigProperties",e); + throw e; + } + if(properties.isEmpty()){ + throw new Exception("No config properties fetched from "+configUrl); + } + LOGGER.info("Config are feteched from {}",configUrl); + properties.forEach((k,v)-> LOGGER.debug("{} : {} ",k,v)); + return properties; + } +} diff --git a/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/Constants.java b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/Constants.java new file mode 100644 index 000000000..b731e8393 --- /dev/null +++ b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/Constants.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.cso.pacbot.recommendation.util; + +/** + * The Interface Constants. + */ +public interface Constants { + + /** The rds db url. */ + String RDS_DB_URL = "spring.datasource.url"; + + /** The rds user. */ + String RDS_USER = "spring.datasource.username"; + + /** The rds pwd. */ + String RDS_PWD = "spring.datasource.password"; + + + /** The target type info. */ + String TARGET_TYPE_INFO = "targetTypes"; + + /** The config creds. */ + String CONFIG_CREDS = "config_creds"; + + + /** The target type info. */ + String TARGET_TYPE_OUTSCOPE = "typesNotInScope"; + + /** The API User:Password. */ + String API_AUTH_INFO = "apiauthinfo"; + + /** The config query. */ + String CONFIG_QUERY = "configquery"; + + /** The config url. */ + String CONFIG_URL = "CONFIG_URL"; + + + /** The failed. */ + String FAILED = "failed"; + + /** The error. */ + String ERROR = "error"; + + /** The exception. */ + String EXCEPTION = "exception"; + + /** The error type. */ + String ERROR_TYPE = "type"; + + /** The warn. */ + String WARN = "warn"; + + /** The fatal. */ + String FATAL = "fatal"; + + /** The source. */ + String SOURCE = "source"; + + /** The name. */ + String NAME = "name"; + + /** The checkid. */ + String CHECKID = "checkid"; + + /** The accountid. */ + String ACCOUNTID = "accountid"; + + /** The checkname. */ + String CHECKNAME = "checkname"; + + /** The checkcategory. */ + String CHECKCATEGORY = "checkcategory"; + + /** The resource info. */ + String RESOURCE_INFO = "resourceinfo"; + + /** The recommendation. */ + String RECOMMENDATION = "recommendation"; + + /** The load date. */ + String LOAD_DATE = "_loaddate"; + + /** The global recommendations. */ + String GLOBAL_RECOMMENDATIONS = "global_recommendations"; + + /** The monthly savings field. */ + String MONTHLY_SAVINGS_FIELD = "monthlySavingsField"; + + /** The recommendation id. */ + String RECOMMENDATION_ID = "recommendationId"; +} diff --git a/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/ErrorManageUtil.java b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/ErrorManageUtil.java new file mode 100644 index 000000000..b058a0914 --- /dev/null +++ b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/ErrorManageUtil.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.cso.pacbot.recommendation.util; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * The Class ErrorManageUtil. + */ +public class ErrorManageUtil implements Constants{ + + /** + * Instantiates a new error manage util. + */ + private ErrorManageUtil() { + + } + + /** + * Form error code. + * + * @param job the job + * @param errorList the error list + * @return the map + */ + public static Map formErrorCode(String job, List> errorList) { + Map errorCode = new HashMap<>(); + errorCode.put("jobName", job); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + errorCode.put("executionEndDate", sdf.format(new Date())); + + String status = ""; + + List> errors = new ArrayList<>(); + if(!errorList.isEmpty()) { + for(Map errorDetail :errorList) { + Map error = new HashMap<>(); + error.put(ERROR, errorDetail.get(ERROR)); + + List> details = new ArrayList<>(); + Map detail = new HashMap<>(); + detail.put(EXCEPTION,errorDetail.get(EXCEPTION)); + details.add(detail); + error.put("details",details); + errors.add(error); + + if(!FAILED.equalsIgnoreCase(status)) { + status = (FATAL.equalsIgnoreCase(errorDetail.get(ERROR_TYPE))) ? FAILED:"partial failed"; + } + } + } + else { + status = "success"; + } + + errorCode.put("errors", errors); + errorCode.put("status", status); + return errorCode; + } +} \ No newline at end of file diff --git a/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/HttpUtil.java b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/HttpUtil.java new file mode 100644 index 000000000..c0afaae09 --- /dev/null +++ b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/HttpUtil.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.cso.pacbot.recommendation.util; + +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Map; + +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.ParseException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.ssl.TrustStrategy; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Strings; +import com.tmobile.cso.pacbot.recommendation.exception.UnAuthorisedException; + + +/** + * The Class HttpUtil. + */ +public class HttpUtil { + + /** The log. */ + static final Logger LOGGER = LoggerFactory.getLogger(HttpUtil.class); + + private static final String CONTENT_TYPE = "Content-Type"; + + /** + * Instantiates a new http util. + */ + private HttpUtil(){ + } + + /** + * Gets the. + * + * @param uri the uri + * @param bearerToken the bearer token + * @return the string + * @throws Exception the exception + */ + public static String get(String uri ,String bearerToken) throws Exception { + HttpGet httpGet = new HttpGet(uri); + httpGet.addHeader("content-type", "application/json"); + httpGet.addHeader("cache-control", "no-cache"); + if(!Strings.isNullOrEmpty(bearerToken)){ + httpGet.addHeader("Authorization", "Bearer "+bearerToken); + } + CloseableHttpClient httpClient = getHttpClient(); + if(httpClient!=null){ + HttpResponse httpResponse; + try { + + httpResponse = httpClient.execute(httpGet); + if( httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_UNAUTHORIZED){ + throw new UnAuthorisedException(); + } + return EntityUtils.toString(httpResponse.getEntity()); + } catch (Exception e) { + LOGGER.error("Error getting the data " , e); + throw e; + } + } + return "{}"; + } + + /** + * Post. + * + * @param url the url + * @param requestBody the request body + * @param token the token + * @param tokeType the toke type + * @return the string + * @throws Exception the exception + */ + public static String post(String url, String requestBody,String token,String tokeType) throws Exception { + try { + CloseableHttpClient httpClient = getHttpClient(); + if(httpClient!=null){ + HttpPost httppost = new HttpPost(url); + httppost.setHeader("Content-Type", ContentType.APPLICATION_JSON.toString()); + if(!Strings.isNullOrEmpty(token)){ + httppost.addHeader("Authorization", tokeType+" "+token); + } + httppost.setEntity(new StringEntity(requestBody)); + HttpResponse httpresponse = httpClient.execute(httppost); + if( httpresponse.getStatusLine().getStatusCode()==HttpStatus.SC_UNAUTHORIZED){ + throw new UnAuthorisedException(); + } + return EntityUtils.toString(httpresponse.getEntity()); + } + } catch (Exception e) { + LOGGER.error("Error getting the data " , e); + throw e; + } + return null; + + } + + /** + * Gets the http client. + * + * @return the http client + */ + private static CloseableHttpClient getHttpClient() { + CloseableHttpClient httpClient = null; + try { + httpClient = HttpClientBuilder.create().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) + .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { + @Override + public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { + return true; + } + }).build()).build(); + } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) { + LOGGER.error("Error getting getHttpClient " , e); + } + return httpClient; + } + + /** + * Http get method with headers. + * + * @param url the url + * @param headers the headers + * @return the string + * @throws Exception the exception + */ + public static String httpGetMethodWithHeaders(String url,Map headers) throws Exception { + String json = null; + + HttpGet get = new HttpGet(url); + CloseableHttpClient httpClient = null; + if (headers != null && !headers.isEmpty()) { + for (Map.Entry entry : headers.entrySet()) { + get.setHeader(entry.getKey(), entry.getValue().toString()); + } + } + try { + httpClient = getHttpClient(); + CloseableHttpResponse res = httpClient.execute(get); + if (res.getStatusLine().getStatusCode() == 200) { + json = EntityUtils.toString(res.getEntity()); + } + } finally { + if (httpClient != null) { + httpClient.close(); + } + } + return json; + } +} diff --git a/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/Util.java b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/Util.java new file mode 100644 index 000000000..3807ab6ab --- /dev/null +++ b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/util/Util.java @@ -0,0 +1,218 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.cso.pacbot.recommendation.util; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Base64; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.xml.bind.annotation.adapters.HexBinaryAdapter; + +import org.apache.http.entity.ContentType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + + +/** + * The Class Util. + */ +public class Util { + + /** The Constant LOGGER. */ + private static final Logger LOGGER = LoggerFactory.getLogger(Util.class); + + /** + * Instantiates a new util. + */ + private Util(){ + + } + /** + * Contains. + * + * @param x + * the x + * @param y + * the y + * @param keys + * the keys + * @return true, if successful + */ + public static boolean contains(Map x, Map y, String[] keys) { + for (String key : keys) { + if (!x.get(key).equals(y.get(key))) + return false; + } + return true; + } + + /** + * Concatenate. + * + * @param map + * the map + * @param keys + * the keys + * @param delimiter + * the delimiter + * @return the string + */ + public static String concatenate(Map map, String[] keys, String delimiter) { + List values = new ArrayList<>(); + for (String key : keys) { + values.add(map.get(key)); + } + return values.stream().collect(Collectors.joining(delimiter)); + } + + /** + * Parses the json. + * + * @param json + * the json + * @return the map + */ + public static Map parseJson(String json) { + try { + return new ObjectMapper().readValue(json, new TypeReference>() { + }); + } catch (IOException e) { + LOGGER.error("Error in parseJson",e); + } + return new HashMap<>(); + } + + /** + * Gets the unique ID. + * + * @param idstring + * the idstring + * @return the unique ID + */ + public static String getUniqueID(String idstring) { + try { + MessageDigest md5 = MessageDigest.getInstance("MD5"); + return (new HexBinaryAdapter()).marshal(md5.digest(idstring.getBytes())); + } catch (NoSuchAlgorithmException e) { + LOGGER.error("Error in getUniqueID",e); + } + return ""; + } + + /** + * Gets the stack trace. + * + * @param e + * the e + * @return the stack trace + */ + public static String getStackTrace(Exception e) { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + return sw.toString(); + + } + + /** + * Base 64 decode. + * + * @param encodedStr + * the encoded str + * @return the string + */ + public static String base64Decode(String encodedStr) { + return new String(Base64.getDecoder().decode(encodedStr)); + + } + + /** + * Encode url. + * + * @param toBeEncoded + * the to be encoded + * @return the string + */ + public static String encodeUrl(String toBeEncoded) { + String encoded = toBeEncoded; + try { + encoded = URLEncoder.encode(toBeEncoded, "UTF-8"); + } catch (UnsupportedEncodingException e1) { + LOGGER.error("Error in encodeUrl",e1); + } + return encoded; + } + + /** + * Base 64 encode. + * + * @param str the str + * @return the string + */ + public static String base64Encode(String str) { + return Base64.getEncoder().encodeToString(str.getBytes()); + } + + /** + * Gets the header. + * + * @param base64Creds the base 64 creds + * @return the header + */ + public static Map getHeader(String base64Creds){ + Map authToken = new HashMap<>(); + authToken.put("Content-Type", ContentType.APPLICATION_JSON.toString()); + authToken.put("Authorization", "Basic "+base64Creds); + return authToken; + } + + public static List retrieveErrorRecords(String responseStr){ + List errorList = new ArrayList<>(); + try{ + JsonObject response = new JsonParser().parse(responseStr).getAsJsonObject(); + JsonArray items = response.getAsJsonArray("items"); + + int status; + for(JsonElement item : items){ + JsonObject updateInfo = item.getAsJsonObject(); + status = updateInfo.getAsJsonObject("index").get("status").getAsInt(); + if(!(status == 200 || status== 201)){ + errorList.add(updateInfo.getAsJsonObject("index").toString()); + } + } + }catch(Exception e){ + LOGGER.error("Error retrieving errror records",e); + } + + return errorList; + } +} From 27967d48cb2f3af8c605a47763efe813b74a206f Mon Sep 17 00:00:00 2001 From: Kanchana Date: Tue, 30 Jul 2019 18:27:40 +0530 Subject: [PATCH 09/86] Added jaxB dependency --- commons/pac-batch-commons/pom.xml | 577 +++++++++++++++--------------- 1 file changed, 292 insertions(+), 285 deletions(-) diff --git a/commons/pac-batch-commons/pom.xml b/commons/pac-batch-commons/pom.xml index e20fb0022..df37dedb2 100644 --- a/commons/pac-batch-commons/pom.xml +++ b/commons/pac-batch-commons/pom.xml @@ -1,285 +1,292 @@ - - 4.0.0 - - com.tmobile.cloud - batch-commons - 1.0.0-SNAPSHOT - jar - - commons - http://maven.apache.org - - - UTF-8 - 1.8 - 1.8 - true - true - - - - - - - com.amazonaws - aws-java-sdk-bom - 1.11.432 - pom - import - - - - - - - - - - com.amazonaws - aws-java-sdk-efs - - - - com.amazonaws - aws-java-sdk-redshift - - - - - com.amazonaws - aws-java-sdk-ses - - - - - - com.amazonaws - aws-java-sdk-route53 - - - - - com.amazonaws - aws-java-sdk-events - - - - com.amazonaws - aws-java-sdk-guardduty - - - - com.amazonaws - aws-java-sdk-ec2 - - - - aws-java-sdk-cloudwatch - com.amazonaws - - - - - - com.amazonaws - aws-java-sdk-elasticloadbalancing - - - - aws-java-sdk-elasticloadbalancingv2 - com.amazonaws - - - - - - com.amazonaws - aws-java-sdk-s3 - - - - - com.amazonaws - aws-java-sdk-rds - - - - - com.amazonaws - aws-java-sdk-sts - - - - aws-java-sdk-iam - com.amazonaws - - - - aws-java-sdk-config - com.amazonaws - - - - aws-java-sdk-lambda - com.amazonaws - - - - aws-java-sdk-api-gateway - com.amazonaws - - - - aws-java-sdk-dynamodb - com.amazonaws - - - - aws-java-sdk-cloudtrail - com.amazonaws - - - - com.amazonaws - aws-java-sdk-elasticsearch - - - - - com.amazonaws - aws-lambda-java-core - 1.1.0 - - - - - - com.google.code.gson - gson - 2.8.1 - - - - - commons-httpclient - commons-httpclient - 3.1 - - - - - - - - - - - - junit - junit - 3.8.1 - test - - - - - org.reflections - reflections - 0.9.10 - - - - - com.google.guava - guava - 19.0 - - - - - - ch.qos.logback - logback-classic - 1.2.3 - - - - - ch.qos.logback - logback-core - 1.2.3 - - - - - - - - - - - - - org.jfrog.buildinfo - artifactory-maven-plugin - 2.4.1 - false - - - build-info - - publish - - - - ${project.groupId} - ${project.artifactId} - ${project.version} - - - true - 60 - publish.properties - - - - pacman-commons - 1 - http://build-url.org - - - true - false - true - compile,runtime - kkumar@t-mobile.com - - - - - - - - - - - - - - false - - central - bintray-plugins - http://jcenter.bintray.com - - - - - - - - - - + + 4.0.0 + + com.tmobile.cloud + batch-commons + 1.0.0-SNAPSHOT + jar + + commons + http://maven.apache.org + + + UTF-8 + 1.8 + 1.8 + true + true + + + + + + + com.amazonaws + aws-java-sdk-bom + 1.11.432 + pom + import + + + + + + + + + + com.amazonaws + aws-java-sdk-efs + + + + com.amazonaws + aws-java-sdk-redshift + + + + + com.amazonaws + aws-java-sdk-ses + + + + + + com.amazonaws + aws-java-sdk-route53 + + + + + com.amazonaws + aws-java-sdk-events + + + + com.amazonaws + aws-java-sdk-guardduty + + + + com.amazonaws + aws-java-sdk-ec2 + + + + aws-java-sdk-cloudwatch + com.amazonaws + + + + + + com.amazonaws + aws-java-sdk-elasticloadbalancing + + + + aws-java-sdk-elasticloadbalancingv2 + com.amazonaws + + + + + + com.amazonaws + aws-java-sdk-s3 + + + + + com.amazonaws + aws-java-sdk-rds + + + + + com.amazonaws + aws-java-sdk-sts + + + + aws-java-sdk-iam + com.amazonaws + + + + aws-java-sdk-config + com.amazonaws + + + + aws-java-sdk-lambda + com.amazonaws + + + + aws-java-sdk-api-gateway + com.amazonaws + + + + aws-java-sdk-dynamodb + com.amazonaws + + + + aws-java-sdk-cloudtrail + com.amazonaws + + + + com.amazonaws + aws-java-sdk-elasticsearch + + + + + com.amazonaws + aws-lambda-java-core + 1.1.0 + + + + + + com.google.code.gson + gson + 2.8.1 + + + + + commons-httpclient + commons-httpclient + 3.1 + + + + + + + + + + + + junit + junit + 3.8.1 + test + + + + + org.reflections + reflections + 0.9.10 + + + + + com.google.guava + guava + 19.0 + + + + + + ch.qos.logback + logback-classic + 1.2.3 + + + + + ch.qos.logback + logback-core + 1.2.3 + + + + javax.xml.bind + jaxb-api + 2.1 + + + + + + + + + + + + + + org.jfrog.buildinfo + artifactory-maven-plugin + 2.4.1 + false + + + build-info + + publish + + + + ${project.groupId} + ${project.artifactId} + ${project.version} + + + true + 60 + publish.properties + + + + pacman-commons + 1 + http://build-url.org + + + true + false + true + compile,runtime + kkumar@t-mobile.com + + + + + + + + + + + + + + false + + central + bintray-plugins + http://jcenter.bintray.com + + + + + + + + + + From a367215fccd25a772ae5d57ef7b32192288b4660 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Wed, 31 Jul 2019 11:25:12 +0530 Subject: [PATCH 10/86] Added for recommendation scripts --- installer/resources/pacbot_app/files/DB.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer/resources/pacbot_app/files/DB.sql b/installer/resources/pacbot_app/files/DB.sql index fbf2b11a9..b3efccc1e 100644 --- a/installer/resources/pacbot_app/files/DB.sql +++ b/installer/resources/pacbot_app/files/DB.sql @@ -1953,7 +1953,7 @@ INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `pr INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.auto.fix.mail.template.columns.PacMan_RedShiftPublicAccess_version-1_RedShiftPublicAccess_redshift','Resource Id,Account Id,Region,Attached Sg,Detached Sg','rule','prd','latest',NULL,NULL,NULL,NULL); INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.auto.fix.common.email.notifications.PacMan_RedShiftPublicAccess_version-1_RedShiftPublicAccess_redshift','commonTemplate','rule','prd','latest',NULL,NULL,NULL,NULL); - +INSERT IGNORE INTO `Recommendation_Mappings`(`checkId`,`type`,`resourceInfo`,`_resourceId`,`monthlySavingsField`) values ('H7IgTzjTYb','volume','Volume ID','volumeid',NULL),('DAvU99Dc4C','volume','Volume ID','volumeid','Monthly Storage Cost'),('Qch7DwouX1','ec2','Instance ID','instanceid','Estimated Monthly Savings'),('1iG5NDGVre','sg','Security Group ID','groupid',NULL),('HCP4007jGY','sg','Security Group ID','groupid',NULL),('BueAdJ7NrP','s3','Bucket Name','name',NULL),('iqdCTZKCUp','classicelb','Load Balancer Name','loadbalancername',NULL),('R365s2Qddf','s3','Bucket Name','name',NULL),('Pfx0RwqBli','s3','Bucket Name','name',NULL),('a2sEc6ILx','classicelb','Load Balancer Name','loadbalancername',NULL),('xdeXZKIUy','classicelb','Load Balancer Name','loadbalancername',NULL),('CLOG40CDO8','asg','Auto Scaling Group Name','autoscalinggroupname',NULL),('7qGXsKIUw','classicelb','Load Balancer Name','loadbalancername',NULL),('hjLMh88uM8','classicelb','Load Balancer Name','loadbalancername','Estimated Monthly Savings'),('DqdJqYeRm5','iamuser','IAM User','username',NULL),('j3DFqYTe29','ec2','Instance ID','instanceid',NULL),('f2iK5R6Dep','rdsdb','DB Instance','dbinstanceidentifier',NULL),('1MoPEMsKx6','reservedinstance','Instance Type','instancetype','Estimated Monthly Savings'),('Ti39halfu8','rdsdb','DB Instance Name','dbinstanceidentifier','Estimated Monthly Savings (On Demand)'),('Wnwm9Il5bG','ec2','Instance ID','instanceid',NULL),('V77iOLlBqz','ec2','Instance ID','instanceid',NULL),('Z4AUBRNSmz','elasticip','IP Address','publicip',NULL),('8CNsSllI5v','asg','Auto Scaling Group Name','autoscalinggroupname',NULL),('N420c450f2','cloudfront','Distribution ID','id',NULL),('TyfdMXG69d','ec2','Instance ID','instanceid',NULL),('tfg86AVHAZ','sg','Group ID','groupid',NULL),('yHAGQJV9K5','ec2','Instance ID','instanceid',NULL),('S45wrEXrLz','vpnconnection','VPN ID','vpnconnectionid',NULL),('PPkZrjsH2q','volume','Volume ID','volumeid',NULL),('opQPADkZvH','rdsdb','DB Instance','dbinstanceidentifier',NULL),('796d6f3D83','s3','Bucket Name','name',NULL),('G31sQ1E9U','redshift','Cluster','clusteridentifier','Estimated Monthly Savings'),('xSqX82fQu','classicelb','Load Balancer Name','loadbalancername',NULL),('ZRxQlPsb6c','ec2','Instance ID','instanceid',NULL),('N430c450f2','cloudfront','Distribution ID','id',NULL),('4g3Nt5M1Th','virtualinterface','Gateway ID','virtualgatewayid',NULL),('0t121N1Ty3','directconnect','Connection ID','connectionid',NULL),('N425c450f2','cloudfront','Distribution ID','id',NULL),('xuy7H1avtl','rdscluster','Cluster','dbclusteridentifier',NULL),('1e93e4c0b5','reservedinstance','Reserved Instance ID','instanceid','Estimated Monthly Savings'),('51fC20e7I2','route53','Hosted Zone ID','hostedZoneId',NULL),('cF171Db240','route53','Hosted Zone ID','hostedZoneId',NULL),('Cb877eB72b','route53','Hosted Zone ID','hostedZoneId',NULL),('b73EEdD790','route53','Hosted Zone ID','hostedZoneId',NULL),('C056F80cR3','route53','Hosted Zone ID','hostedZoneId',NULL),('B913Ef6fb4','route53','Hosted Zone ID','hostedZoneId',NULL); From a083275c41923371004d7d5344bc10ea2fdb5752 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Wed, 31 Jul 2019 12:37:31 +0530 Subject: [PATCH 11/86] Recommendations api added --- .../asset/controller/AssetCostController.java | 232 ++ .../controller/RecommendationsController.java | 256 +++ .../api/asset/domain/ApplicationDetail.java | 62 + .../domain/ApplicationDetailsESResponse.java | 18 + .../domain/ApplicationDetailsResponse.java | 29 + .../api/asset/domain/ApplicationESDetail.java | 57 + .../pacman/api/asset/domain/Organization.java | 27 + .../api/asset/repository/AssetRepository.java | 1053 +++++---- .../asset/repository/AssetRepositoryImpl.java | 68 + .../api/asset/repository/CostRepository.java | 199 ++ .../repository/RecommendationsRepository.java | 500 ++++ .../api/asset/service/AssetService.java | 995 ++++---- .../api/asset/service/AssetServiceImpl.java | 2034 +++++++++-------- .../pacman/api/asset/service/CostService.java | 523 +++++ .../asset/service/RecommendationsService.java | 66 + .../asset/controller/AssetControllerTest.java | 654 +++--- .../controller/AssetCostControllerTest.java | 220 ++ .../controller/AssetCountControllerTest.java | 276 +-- .../controller/AssetDetailControllerTest.java | 826 +++---- .../controller/AssetListControllerTest.java | 620 ++--- .../controller/AssetTrendControllerTest.java | 104 +- .../asset/controller/ErrorHandlerTest.java | 60 +- .../RecommendationsControllerTest.java | 221 ++ .../controller/SearchControllerTest.java | 202 +- .../pacman/api/asset/controller/UtilTest.java | 242 +- .../asset/repository/CostRepositoryTest.java | 97 + .../PacmanRedshiftRepositoryTest.java | 198 +- .../RecommendationsRepositoryTest.java | 178 ++ .../repository/SearchRepositoryTest.java | 422 ++-- .../api/asset/service/AssetServiceTest.java | 918 ++++---- .../api/asset/service/CostServiceTest.java | 193 ++ .../service/RecommendationServiceTest.java | 76 + .../api/asset/service/SearchServiceTest.java | 230 +- .../tmobile/pacman/api/commons/Constants.java | 587 ++--- 34 files changed, 7826 insertions(+), 4617 deletions(-) create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/AssetCostController.java create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/RecommendationsController.java create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetail.java create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsESResponse.java create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsResponse.java create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationESDetail.java create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/Organization.java create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/CostRepository.java create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/RecommendationsRepository.java create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CostService.java create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/RecommendationsService.java create mode 100644 api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetCostControllerTest.java create mode 100644 api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/RecommendationsControllerTest.java create mode 100644 api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/CostRepositoryTest.java create mode 100644 api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/RecommendationsRepositoryTest.java create mode 100644 api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/CostServiceTest.java create mode 100644 api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/RecommendationServiceTest.java diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/AssetCostController.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/AssetCostController.java new file mode 100644 index 000000000..3a3d952a9 --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/AssetCostController.java @@ -0,0 +1,232 @@ +package com.tmobile.pacman.api.asset.controller; + + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.tmobile.pacman.api.asset.domain.ApplicationDetail; +import com.tmobile.pacman.api.asset.domain.ApplicationDetailsResponse; +import com.tmobile.pacman.api.asset.service.AssetService; +import com.tmobile.pacman.api.asset.service.CostService; +import com.tmobile.pacman.api.commons.utils.ResponseUtils; + +@RestController +@PreAuthorize("@securityService.hasPermission(authentication, 'ROLE_USER')") +@CrossOrigin +public class AssetCostController { + + @Autowired + CostService costService; + + @Autowired + private AssetService assetService; + + private static final Log LOGGER = LogFactory.getLog(AssetCostController.class); + + @GetMapping(value = "/v1/costByApplication") + public ResponseEntity getAssetCostByApplication( + @RequestParam(name = "ag", required = true) String assetGroup, + @RequestParam(name = "application", required = false) String application, + @RequestParam(name = "type", required = false) String type, + @RequestParam(name = "quarter", required = false) Integer quarter, + @RequestParam(name = "year", required = false) Integer year, + @RequestParam(name = "month", required = false) Integer month) { + return getAssetCost(assetGroup, type, application, quarter, year, month, false); + } + + @GetMapping(value = "/v1/costByType") + public ResponseEntity getAssetCostByType(@RequestParam(name = "ag", required = true) String assetGroup, + @RequestParam(name = "application", required = false) String application, + @RequestParam(name = "type", required = false) String type, + @RequestParam(name = "quarter", required = false) Integer quarter, + @RequestParam(name = "year", required = false) Integer year, + @RequestParam(name = "month", required = false) Integer month) { + return getAssetCost(assetGroup, type, application, quarter, year, month, true); + } + + @GetMapping(value = "/v1/cost/trend") + public ResponseEntity getAssetCostTrendByType(@RequestParam(name = "ag", required = true) String assetGroup, + @RequestParam(name = "application", required = false) String application, + @RequestParam(name = "type", required = false) String type, + @RequestParam(name = "period", required = true) Period period) { + try { + + ApplicationDetailsResponse appDetailsResponse = null; + appDetailsResponse = assetService.getApplicationDetailsByAssetGroup(assetGroup, null); + List validApplications = appDetailsResponse.getValidApplications(); + List appNameList = new ArrayList<>(); + Iterator it = validApplications.iterator(); + while (it.hasNext()) { + String appName = it.next().getName(); + appNameList.add(appName); + + } + + List tTypeList = new ArrayList<>(); + List> tTypeMapList = assetService.getAllCostTypes(); + Iterator> iter = tTypeMapList.iterator(); + while (iter.hasNext()) { + Map tTypeMap = iter.next(); + tTypeList.add(tTypeMap.get("type").toString()); + } + + if (StringUtils.isNotBlank(application) && !appNameList.contains(application)) { + return ResponseUtils.buildFailureResponse(new Exception("Invalid application entered"), null, null); + } + if (StringUtils.isNotBlank(type) && !tTypeList.contains(type)) { + return ResponseUtils.buildFailureResponse(new Exception("Invalid type entered"), null, null); + } + if (StringUtils.isNotBlank(application)) { + appNameList = Arrays.asList(application); + } + if (StringUtils.isNotBlank(type)) { + tTypeList = Arrays.asList(type); + }else{ + tTypeList = new ArrayList<>(); + } + + + Map response = new LinkedHashMap<>(); + response.put("ag", assetGroup); + if(StringUtils.isNotBlank(type)) { + response.put("type", type); + } + if(StringUtils.isNotBlank(application)) { + assetGroup = application.toLowerCase().replaceAll("[^a-z0-9-_]", ""); + } + List> trendList = costService.getCostTrend(appNameList,tTypeList,period.toString()); + response.put("trend", trendList); + return ResponseUtils.buildSucessResponse(response); + } catch (Exception e) { + return ResponseUtils.buildFailureResponse(e); + } + } + + + public ResponseEntity getAssetCost(@RequestParam(name = "ag", required = true) String assetGroup, + @RequestParam(name = "type", required = false) String type, + @RequestParam(name = "application", required = false) String application, + @RequestParam(name = "quarter", required = false) Integer quarter, + @RequestParam(name = "year", required = false) Integer year, + @RequestParam(name = "month", required = false) Integer month, + @RequestParam(name = "byType", required = false) boolean byType) { + try { + + if (month != null && quarter != null) { + return ResponseUtils.buildFailureResponse( + new Exception("Both quarter AND month cannot be entered together. Enter only one of these."), + null, null); + } + + if(year==null && (month != null || quarter!=null)){ + return ResponseUtils.buildFailureResponse(new Exception("Year is mandatory"), null, + null); + } + + if(year!=null && month == null && quarter==null){ + return ResponseUtils.buildFailureResponse(new Exception("Month or quarter is mandatory a year is entered"), null, + null); + } + + if (quarter != null && (quarter < 1 || quarter > 4)) { + return ResponseUtils.buildFailureResponse(new Exception("Quarter should be one of 1,2,3,4"), null, + null); + } + + if (month != null && (month < 1 || month > 12)) { + return ResponseUtils.buildFailureResponse(new Exception("Month should be a number from 1-12"), null, + null); + } + + if (year!=null && (year < 2019 || year > LocalDate.now().getYear())) { + return ResponseUtils.buildFailureResponse(new Exception("Invalid year entered : Please enter between 2019 - "+LocalDate.now().getYear()), null, null); + } + if (assetService.getAssetGroupInfo(assetGroup).isEmpty()) { + return ResponseUtils.buildFailureResponse(new Exception("Invalid asset group entered"), null, null); + } + + ApplicationDetailsResponse appDetailsResponse = null; + appDetailsResponse = assetService.getApplicationDetailsByAssetGroup(assetGroup, null); + List validApplications = appDetailsResponse.getValidApplications(); + List appNameList = new ArrayList<>(); + Iterator it = validApplications.iterator(); + while (it.hasNext()) { + String appName = it.next().getName(); + appNameList.add(appName); + + } + + List tTypeList = new ArrayList<>(); + List> tTypeMapList = assetService.getAllCostTypes(); + Iterator> iter = tTypeMapList.iterator(); + while (iter.hasNext()) { + Map tTypeMap = iter.next(); + tTypeList.add(tTypeMap.get("type").toString()); + } + + if (StringUtils.isNotBlank(application) && !appNameList.contains(application)) { + return ResponseUtils.buildFailureResponse(new Exception("Invalid application entered"), null, null); + } + if (StringUtils.isNotBlank(type) && !tTypeList.contains(type)) { + return ResponseUtils.buildFailureResponse(new Exception("Invalid type entered"), null, null); + } + if (StringUtils.isNotBlank(application)) { + appNameList = Arrays.asList(application); + } + if (StringUtils.isNotBlank(type)) { + tTypeList = Arrays.asList(type); + }else{ + tTypeList = new ArrayList<>(); + } + + List monthList = new ArrayList<>(); + + if (quarter != null) { + int monthBaseAddendum = (quarter - 1) * 3; + int firstMonth = monthBaseAddendum + 1; + int secondMonth = monthBaseAddendum + 2; + int thirdMonth = monthBaseAddendum + 3; + monthList.add(new Integer(firstMonth).toString()); + monthList.add(new Integer(secondMonth).toString()); + monthList.add(new Integer(thirdMonth).toString()); + } + + if (month != null) { + monthList.add(month + ""); + } + + Map responseMap ; + if (byType) { + responseMap = costService.getCostByType(assetGroup, year, monthList, appNameList, tTypeList); + } else{ + responseMap = costService.getCostByApplication(assetGroup, year, monthList, appNameList, tTypeList, + validApplications); + } + return ResponseUtils.buildSucessResponse(responseMap); + + } catch (Exception e) { + LOGGER.error("Error occured fetching cost info",e); + return ResponseUtils.buildFailureResponse(e, null, null); + } + } +} + +enum Period { + monthly,quarterly; +} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/RecommendationsController.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/RecommendationsController.java new file mode 100644 index 000000000..b1929aae2 --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/RecommendationsController.java @@ -0,0 +1,256 @@ +package com.tmobile.pacman.api.asset.controller; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.tmobile.pacman.api.asset.AssetConstants; +import com.tmobile.pacman.api.asset.domain.Request; +import com.tmobile.pacman.api.asset.domain.ResponseWithCount; +import com.tmobile.pacman.api.asset.service.RecommendationsService; +import com.tmobile.pacman.api.commons.Constants; +import com.tmobile.pacman.api.commons.exception.DataException; +import com.tmobile.pacman.api.commons.utils.CommonUtils; +import com.tmobile.pacman.api.commons.utils.ResponseUtils; + +@RestController +@PreAuthorize("@securityService.hasPermission(authentication, 'ROLE_USER')") +@CrossOrigin +public class RecommendationsController { + + @Autowired + RecommendationsService recommendationsService; + + private static final Log LOGGER = LogFactory.getLog(RecommendationsController.class); + + @GetMapping(value = "/v1/recommendations/summary") + public ResponseEntity getRecommendationSummary(@RequestParam(name = "ag", required = false) String assetGroup, + @RequestParam(name = "application", required = false) String application, @RequestParam(name = "general", required = true) Boolean general) { + + if(!general && StringUtils.isBlank(assetGroup)) { + return ResponseUtils.buildFailureResponse(new Exception(Constants.ASSET_MANDATORY)); + } + + try { + return ResponseUtils.buildSucessResponse(recommendationsService.getRecommendationSummary(assetGroup,application,general)); + } catch (DataException e) { + LOGGER.error("Error in getRecommendationSummary "+ e); + return ResponseUtils.buildFailureResponse(e); + } + } + + @GetMapping(value = "/v1/recommendations/summaryByApplication") + public ResponseEntity getSummaryByApplication(@RequestParam(name = "ag", required = true) String assetGroup, + @RequestParam(name = "category", required = false) String category) { + try { + return ResponseUtils.buildSucessResponse(recommendationsService.getSummaryByApplication(assetGroup,category)); + } catch (DataException e) { + LOGGER.error("Error in getSummaryByApplication "+ e); + return ResponseUtils.buildFailureResponse(e); + } + } + + @SuppressWarnings("unchecked") + @PostMapping(value = "/v1/recommendations") + public ResponseEntity getRecommendations(@RequestBody(required = true) Request request) { + + Map filter = request.getFilter(); + if (filter == null) { + filter = new HashMap<>(); + } + + List acceptedFilterKeys = Arrays.asList(AssetConstants.FILTER_APPLICATION,AssetConstants.FILTER_CATEGORY,AssetConstants.FILTER_GENERAL); + for (Map.Entry entry : filter.entrySet()) { + if (!acceptedFilterKeys.contains(entry.getKey())) { + return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.ERROR_FILTER_ACCEPTS + + StringUtils.join(acceptedFilterKeys, ", "))); + } + } + + if (!filter.containsKey(AssetConstants.FILTER_CATEGORY)) { + return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.FILTER_CATEGORY+" is mandatory in filter")); + } + + if(!filter.containsKey(AssetConstants.FILTER_GENERAL)) { + return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.FILTER_GENERAL+" is mandatory in filter")); + } + + String general = filter.get(AssetConstants.FILTER_GENERAL); + String assetGroup = request.getAg(); + if (general.equals(AssetConstants.FALSE) && StringUtils.isBlank(assetGroup)) { + return ResponseUtils.buildFailureResponse(new Exception(Constants.ASSET_MANDATORY)); + } + + int from = request.getFrom(); + int size = request.getSize(); + if (from < 0) { + return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.ERROR_FROM_NEGATIVE)); + } + + String searchText = request.getSearchtext(); + String category = filter.get(AssetConstants.FILTER_CATEGORY); + String application = filter.get(AssetConstants.FILTER_APPLICATION); + + Map recommendations; + try { + recommendations = recommendationsService.getRecommendations(assetGroup, category, application, general); + } catch (DataException e) { + LOGGER.error("Error in getRecommendations "+ e); + return ResponseUtils.buildFailureResponse(e); + } + List> masterList = (List>) recommendations.get("response"); + List> masterDetailList = (List>) CommonUtils + .filterMatchingCollectionElements(masterList, searchText, true); + + if(masterDetailList.isEmpty()) { + recommendations.put("response", new ArrayList<>()); + recommendations.put("total", 0); + + return ResponseUtils.buildSucessResponse(recommendations); + } + + if (from >= masterDetailList.size()) { + return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.ERROR_FROM_EXCEEDS)); + } + + int endIndex = 0; + + if (size == 0) { + size = masterDetailList.size(); + } + + if ((from + size) > masterDetailList.size()) { + endIndex = masterDetailList.size(); + } else { + endIndex = from + size; + } + + List> subDetailList = masterDetailList.subList(from, endIndex); + recommendations.put("response", subDetailList); + recommendations.put("total", masterDetailList.size()); + + return ResponseUtils.buildSucessResponse(recommendations); + } + + @SuppressWarnings("unchecked") + @PostMapping(value = "/v1/recommendations/detail") + public ResponseEntity getRecommendationDetail(@RequestBody(required = true) Request request) { + + Map filter = request.getFilter(); + if (filter == null) { + filter = new HashMap<>(); + } + + List acceptedFilterKeys = Arrays.asList(AssetConstants.FILTER_APPLICATION,AssetConstants.FILTER_RECOMMENDATION_ID,AssetConstants.FILTER_GENERAL); + for (Map.Entry entry : filter.entrySet()) { + if (!acceptedFilterKeys.contains(entry.getKey())) { + return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.ERROR_FILTER_ACCEPTS + + StringUtils.join(acceptedFilterKeys, ", "))); + } + } + + if (!filter.containsKey(AssetConstants.FILTER_RECOMMENDATION_ID)) { + return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.FILTER_RECOMMENDATION_ID+" is mandatory in filter")); + } + + if(!filter.containsKey(AssetConstants.FILTER_GENERAL)) { + return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.FILTER_GENERAL+" is mandatory in filter")); + } + + String general = filter.get(AssetConstants.FILTER_GENERAL); + String assetGroup = request.getAg(); + if (general.equals(AssetConstants.FALSE) && StringUtils.isBlank(assetGroup)) { + return ResponseUtils.buildFailureResponse(new Exception(Constants.ASSET_MANDATORY)); + } + + int from = request.getFrom(); + int size = request.getSize(); + if (from < 0) { + return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.ERROR_FROM_NEGATIVE)); + } + + String searchText = request.getSearchtext(); + String recommendationId = filter.get(AssetConstants.FILTER_RECOMMENDATION_ID); + String application = filter.get(AssetConstants.FILTER_APPLICATION); + Map recommendationDetails; + try { + recommendationDetails = recommendationsService.getRecommendationDetail(assetGroup,recommendationId,application,general); + } catch (DataException e) { + LOGGER.error("Error in getRecommendationDetail "+ e); + return ResponseUtils.buildFailureResponse(e); + } + + List> masterList = (List>) recommendationDetails.get("resources"); + return formResponseWithCount(masterList, from, size, searchText); + } + + @GetMapping(value = "/v1/recommendations/info") + public ResponseEntity getRecommendationInfo(@RequestParam(name = "recommendationId", required = true) String recommendationId) { + try { + return ResponseUtils.buildSucessResponse(recommendationsService.getRecommendationInfo(recommendationId)); + } catch (DataException e) { + LOGGER.error("Error in getRecommendationInfo "+ e); + return ResponseUtils.buildFailureResponse(e); + } + } + + /** + * Method returns the list with count based on the from and size. + * + * @param masterList + * @param from + * @param size + * @param searchText + * + * @return ResponseEntity + */ + @SuppressWarnings("unchecked") + private ResponseEntity formResponseWithCount(List> masterList, int from, int size, + String searchText) { + try { + List> masterDetailList = (List>) CommonUtils + .filterMatchingCollectionElements(masterList, searchText, true); + if (masterDetailList.isEmpty()) { + return ResponseUtils + .buildSucessResponse(new ResponseWithCount(new ArrayList>(), 0)); + } + + if (from >= masterDetailList.size()) { + return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.ERROR_FROM_EXCEEDS)); + } + + int endIndex = 0; + + if (size == 0) { + size = masterDetailList.size(); + } + + if ((from + size) > masterDetailList.size()) { + endIndex = masterDetailList.size(); + } else { + endIndex = from + size; + } + + List> subDetailList = masterDetailList.subList(from, endIndex); + return ResponseUtils.buildSucessResponse(new ResponseWithCount(subDetailList, masterDetailList.size())); + } catch (Exception e) { + LOGGER.error("Exception in formResponseWithCount ",e); + return ResponseUtils.buildFailureResponse(e); + } + } +} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetail.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetail.java new file mode 100644 index 000000000..681d9abfe --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetail.java @@ -0,0 +1,62 @@ +package com.tmobile.pacman.api.asset.domain; + +import java.util.List; + +public class ApplicationDetail +{ + private String name; + private String description; + private List organization; + private String assetGroupId; + private Long totalResources; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getDescription() + { + return description; + } + + public void setDescription(String description) + { + this.description = description; + } + + public List getOrganization() + { + return organization; + } + + public void setOrganization(List organization) + { + this.organization = organization; + } + + public String getAssetGroupId() + { + return assetGroupId; + } + + public void setAssetGroupId(String assetGroupId) + { + this.assetGroupId = assetGroupId; + } + + public Long getTotalResources() + { + return totalResources; + } + + public void setTotalResources(Long totalResources) + { + this.totalResources = totalResources; + } +} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsESResponse.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsESResponse.java new file mode 100644 index 000000000..8611dea69 --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsESResponse.java @@ -0,0 +1,18 @@ +package com.tmobile.pacman.api.asset.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ApplicationDetailsESResponse { + + private ApplicationESDetail _source; + + public void set_source(ApplicationESDetail _source) { + this._source = _source; + } + + public ApplicationESDetail getApplicationDetail() { + return _source; + } +} + diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsResponse.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsResponse.java new file mode 100644 index 000000000..1349a8d1e --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsResponse.java @@ -0,0 +1,29 @@ +package com.tmobile.pacman.api.asset.domain; + +import java.util.List; + +public class ApplicationDetailsResponse +{ + private List validApplications; + private List invalidApplications; + + public List getValidApplications() + { + return validApplications; + } + + public void setValidApplications(List validApplications) + { + this.validApplications = validApplications; + } + + public List getInvalidApplications() + { + return invalidApplications; + } + + public void setInvalidApplications(List invalidApplications) + { + this.invalidApplications = invalidApplications; + } +} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationESDetail.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationESDetail.java new file mode 100644 index 000000000..784bf78f2 --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationESDetail.java @@ -0,0 +1,57 @@ +package com.tmobile.pacman.api.asset.domain; + +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ApplicationESDetail { + private String director; + private String description; + private List> _orgInfo; + private String executiveSponsor; + private String appTag; + + public String getDirector() { + return director; + } + + public void setDirector(String director) { + this.director = director; + } + + public String getDescription() { + return StringUtils.chomp(description); + } + + public void setDescription(String description) { + this.description = description; + } + + public void set_orgInfo(List> _orgInfo) { + this._orgInfo = _orgInfo; + } + + public List> getOrgInfo() { + return _orgInfo; + } + + public String getExecutiveSponsor() { + return executiveSponsor; + } + + public void setExecutiveSponsor(String executiveSponsor) { + this.executiveSponsor = executiveSponsor; + } + + public String getAppTag() { + return appTag; + } + + public void setAppTag(String appTag) { + this.appTag = appTag; + } +} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/Organization.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/Organization.java new file mode 100644 index 000000000..fad1e1cc3 --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/Organization.java @@ -0,0 +1,27 @@ +package com.tmobile.pacman.api.asset.domain; + +public class Organization +{ + private String name; + private String designation; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getDesignation() + { + return designation; + } + + public void setDesignation(String designation) + { + this.designation = designation; + } +} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepository.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepository.java index 97f8b039a..d9daf65a1 100644 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepository.java +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepository.java @@ -1,508 +1,545 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ -package com.tmobile.pacman.api.asset.repository; - -import java.util.Date; -import java.util.List; -import java.util.Map; - -import org.springframework.stereotype.Repository; - -import com.tmobile.pacman.api.asset.model.DefaultUserAssetGroup; -import com.tmobile.pacman.api.commons.exception.DataException; -import com.tmobile.pacman.api.commons.exception.NoDataFoundException; - -/** - * This is the Asset Repository layer which makes call to RDS DB as well as ElasticSearch - */ -@Repository -public interface AssetRepository { - - /** - * Fetches the total count of assets for the particular asset group. If no - * type is passed, all the assets of valid target type for the asset group - * is considered. - * - * @param aseetGroupName name of the asset group - * @param type target type - * @param domain the domain of asset group - * - * @return list of type and its asset count. - */ - public Map getAssetCountByAssetGroup(String aseetGroupName, String type); - - /** - * Fetches all the target types for the particular asset group. If asset - * group is passed as aws then all the available target types is returned . - * - * @param aseetGroupName name of the asset group - * @param domain the domain of asset group - * - * @return list of target types. - */ - public List> getTargetTypesByAssetGroup(String aseetGroupName, String domain); - - /** - * Fetches all the applications for the particular asset group. - * - * @param aseetGroupName name of the asset group - * @param domain the domain of asset group - * - * @return list of applications. - * @throws DataException when there is an error while fetching data from ES - */ - public List getApplicationByAssetGroup(String aseetGroupName, String domain) throws DataException; - - /** - * Fetches all the applications for the particular asset group. - * - * @param aseetGroupName name of the asset group - * - * @return list of applications. - * @throws DataException when there is an error while fetching data from ES - */ - public List getApplicationByAssetGroup(String aseetGroupName) throws DataException; - - /** - * Fetches all the environments for the particular asset group. Application - * and Domain can also be passed to filter the environments - * - * @param assetGroup name of the asset group - * @param application application needed to be filtered - * @param domain the domain of asset group - * - * @return list of environments. - */ - public List getEnvironmentsByAssetGroup(String assetGroup, String application, String domain); - - /** - * Fetches all the target type and its details - * - * @return list of target type details. - */ - public List> getAllTargetTypes(); - - /** - * Fetches all the asset groups and its name, display name, description, - * type, createdby and domains - * - * @return list of asset group details. - */ - public List> getAllAssetGroups(); - - /** - * Fetches all the details of the asset group - name, display name, - * description, type, createdby, appcount, assetcount and domains. - * - * @param assetGroup name of the asset group - * - * @return asset group info. - */ - public Map getAssetGroupInfo(String assetGroup); - - /** - * Fetches the total asset count for each application for the given target - * type and asset group. - * - * @param assetGroup name of the asset group - * @param type target type of the asset group - * - * @return list of applications and its asset count. - * @throws DataException when there is an error while fetching data from ES - */ - public Map getAssetCountByApplication(String assetGroup, String type) throws DataException; - - /** - * Fetches the asset trends(daily min/max) over the period of last 1 month - * for the given asset group. From and to can be passed to fetch the asset - * trends for particular days. - * - * @param assetGroup name of the asset group - * @param type target type of the asset group - * @param from from date - * @param to to date - * - * @return list of days with its min/max asset count. - */ - public List> getAssetMinMax(String assetGroup, String type, Date from, Date to); - - /** - * Save/update asset group details in DB.Saves default asset group for the - * user id. - * - * @param defaultUserAssetGroup This request expects userid and assetgroup name as mandatory. - * - * @return boolean as updated status. - */ - public Integer saveOrUpdateAssetGroup(DefaultUserAssetGroup defaultUserAssetGroup); - - /** - * Fetches the default asset group the user has saved for the given asset - * group. - * - * @param userId id of the user - * - * @return asset group name. - */ - public String getUserDefaultAssetGroup(String userId); - - /** - * Fetches the total asset count for each environment for the given target - * type and asset group. - * - * @param assetGroup name of the asset group - * @param type target type of the asset group - * @param application application needed for the count - * - * @return list of environment and its asset count. - */ - public List> getAssetCountByEnvironment(String assetGroup, String application, String type); - - /** - * Saves the recently viewed asset group for the user id. - * - * @param assetGroup name of the asset group - * @param userId id of the user - * - * @return updated list of asset group for the userId. - * @throws DataException when there is an error while fetching/updating data from ES and DB - */ - public List> saveAndAppendAssetGroup(String userId, String assetGroup) throws DataException; - - /** - * Fetches all the asset for the given asset group. - * - * @param assetGroup name of the asset group - * @param filter application,environment,resourceType as optional filters - * @param searchText searchText is used to match any text you are looking for - * @param from for pagination - * @param size for pagination - * - * @return list of assets and its some details. - */ - public List> getListAssets(String assetGroup, Map filter, int from, int size, - String searchText); - - /** - * Fetches the total asset count for the given asset group. - * - * @param assetGroup name of the asset group - * @param filter application,environment,resourceType as optional filters - * @param searchText searchText is used to match any text you are looking for - * @param from for pagination - * @param size for pagination - * - * @return list of assets and its some details. - */ - long getAssetCount(String assetGroup, Map filter, String searchText); - - /** - * Fetches the CPU utilization for the given instanceid. - * - * @param instanceId id of the instance - * - * @return list of date and its CPU utilization of the instance id. - * @throws DataException when there is an error while fetching data from ES - */ - public List> getCpuUtilizationByAssetGroupAndInstanceId(String instanceId) throws DataException; - - /** - * Fetches the Disk utilization for the given instanceid. - * - * @param instanceId Id of the instance - * - * @return list of disk name, size and free space of the instance id. - * @throws DataException when there is an error while fetching data from ES - */ - public List> getDiskUtilizationByAssetGroupAndInstanceId(String instanceId) throws DataException; - - /** - * Fetches the Softwares installed for the given instanceid. - * - * @param instanceId id of the instance - * @param from for pagination - * @param size for pagination - * @param searchText used to match any text you are looking for - * - * @return list of software name and its version installed on the instance id. - * @throws DataException when there is an error while fetching data from ES - */ - public List> getSoftwareInstalledDetailsByAssetGroupAndInstanceId(String instanceId, - Integer from, Integer size, String searchText) throws DataException; - - /** - * Fetches the ec2 resource details from RHN for the given resourceId. - * - * @param resourceId id of the resource - * - * @return all the ec2 details for resourceId. - * @throws DataException when there is an error while fetching data from ES - */ - public List> getEc2ResourceDetailFromRhn(String resourceId) throws DataException; - - /** - * Fetches the ec2 resource details for the given assetgroup and resourceId. - * - * @param ag name of the asset group - * @param resourceId id of the resource - * - * @return all the ec2 details for assetgroup. - * @throws DataException when there is an error while fetching data from ES - */ - public List> getEc2ResourceDetail(String ag, String resourceId) throws DataException; - - /** - * Fetches the ec2 security details for the given resourceId. - * - * @param resourceId id of the resource - * - * @return all the ec2 security details for resourceId. - * @throws DataException when there is an error while fetching data from ES - */ - public List> getEc2ResourceSecurityGroupDetail(String resourceId) throws DataException; - - /** - * Fetches the patchable assets for the given assetgroup.If patched filter is false it returns the unpatched assets - * and if patched is true returns the patched assets.It also filters the the list based on resource type passed in filter - * else returns all the assets of the asset group - * - * @param assetGroup name of the asset group - * @param filter patched(true/false),application,environment,resourcetype, - * executivesponsor,director as optional filters - * - * @return list of assets patched/unpatched. - */ - public List> getListAssetsPatchable(String assetGroup, Map filter); - - /** - * Fetches the taggable assets for the given assetgroup.If tagged filter is false it returns the untagged assets - * and if tagged is true returns the tagged assets.It also filters the the list based on resource type passed in filter - * else returns all the assets of the asset group - * - * @param assetGroup name of the asset group - * @param filter tagged(true/false),application,environment,resourcetype, - * tagname(must with tagged) as optional filters - * - * @return list of assets tagged/untagged. - */ - public List> getListAssetsTaggable(String assetGroup, Map filter); - - /** - * Fetches the ec2 resource block devices detail for the given resourceId. - * - * @param resourceId id of the resource - * - * @return all the ec2 resource block devices details for resourceId. - * @throws DataException when there is an error while fetching data from ES - */ - List> getEc2ResourceBlockDevicesDetail(String resourceId) throws DataException; - - /** - * Fetches the resource details for the given resourceId - * - * @param ag name of the asset group - * @param resourceType type of the resource - * @param resourceId id of the resource - * - * @return name,value and category of the resourceId. - * @throws DataException when there is an error while fetching data from ES - */ - public List> getResourceDetail(String ag, String resourceType, String resourceId) - throws DataException; - - /** - * Fetches the vulnerable assets for the given assetgroup. It looks for any particular resourceType passed in the filter - * else considers ec2 and onpremserver for targetype and fetch it vulnerable asset details. - * - * @param assetGroup name of the asset group - * @param filter qid as mandatory and application,environment as optional filters - * - * @return list of vulnerable assets. - */ - public List> getListAssetsVulnerable(String assetGroup, Map filter); - - /** - * Fetches the port which are in open status for the given instanceId. - * - * @param instanceId id of the instance - * @param from for pagination - * @param size for pagination - * @param searchText used to match any text you are looking for - * - * @return list of open ports. - * @throws DataException when there is an error while fetching data from ES - */ - public List> getOpenPortDetailsByInstanceId(String instanceId, Integer from, Integer size, - String searchText) throws DataException; - - /** - * Fetches the assets with open issue status for the rule id passed in the filter. - * - * @param assetGroup name of the asset group - * @param filter ruleid as mandatory and compliant(true/false),application,environment,resourcetype as - * optional filters - * - * @return list of assets with open issue status. - */ - public List> getListAssetsScanned(String assetGroup, Map filter); - - /** - * Fetches the resource created info for the given resourceId - * - * @param resourceId id of the resource - * - * @return resource create info details - * @throws DataException when there is an error while fetching data from ES - */ - public Map getResourceCreateInfo(String resourceId) throws DataException; - - /** - * Fetches the open,closed and upcoming notification count for the given instance. - * - * @param instanceId id of the instance - * - * @return list of assets with open,closed and upcoming count. - * @throws DataException when there is an error while fetching data from ES - */ - public Map getNotificationSummary(String instanceId) throws DataException; - - /** - * Saves the config details for the given resourceId. - * - * @param resourceId id of the resource - * @param configType type of the config - * @param config config of the asset - * - * @return 1 or any Integer. - */ - public Integer saveAssetConfig(String resourceId, String configType, String config); - - /** - * Fetches the config details for the given resourceId and config type. - * - * @param resourceId id of the resource - * @param configType type of the config - * - * @return config details as string. - */ - public String retrieveAssetConfig(String resourceId, String configType); - - /** - * Fetches the notification details of the instanceId. - * - * @param instanceId id of the instance - * @param filters any filter - * @param searchText searchText is used to match any text you are looking for - * - * @return list of notification details. - * @throws DataException when there is an error while fetching data from ES - */ - public List> getNotificationDetails(String instanceId, Map filters, - String searchText) throws DataException; - - /** - * Fetches the qualys details of the resourceId. - * - * @param resourceId id of the resource - * - * @return list of qualys details. - * @throws DataException when there is an error while fetching data from ES - */ - public List> getQualysDetail(String resourceId) throws DataException; - - /** - * Updates the asset details. - * - * @param assetGroup name of the asset group - * @param targettype target type to be updated - * @param resources resources that needs to updated - * @param updatedBy user id of the user - * @param updates the values with which the resources needs to be updated. - * - * @return integer count of rows updated. - * @throws DataException when there is an error while fetching data from Es - * @throws NoDataFoundException when there is an error while fetching data from ES - */ - public int updateAsset(String assetGroup, String targettype, Map resources, String updatedBy, - List> updates) throws DataException,NoDataFoundException; - - /** - * Fetches all the asset details for the given asset group. - * - * @param assetGroup name of the asset group - * @param filter application,environment,resourceType as optional filters - * @param from for pagination - * @param size for pagination - * @param searchText is used to match any text you are looking for - * - * @return list of complete asset details. - */ - public List> getAssetLists(String assetGroup, Map filter, int from, int size, - String searchText); - - /** - * Fetches the total count of the documents for the index and type. - * - * @param index ES index - * @param type ES type - * - * @return count of docs - */ - public long getTotalCountForListingAsset(String index, String type); - - /** - * Fetches the created date for the give resourceId. - * - * @param resourceId id of the resource - * @param resourceType type of the resource - * - * @return created date as string - */ - public String getResourceCreatedDate(String resourceId, String resourceType); - - /** - * Fetches the domains for the given asset group. - * - * @param aseetGroupName name of the asset group - * - * @return created date as string - */ - List> getDomainsByAssetGroup(String aseetGroupName); - - /** - * Fetches the updatable fields info maintained in RDS for the given targettype. - * - * @param targettype name of the target type - * - * @return list of updatable fields - */ - public String getDataTypeInfoByTargetType(String targettype); - - /** - * Fetches all the asset group and its corresponding domain. - * - * @return list of asset group and its corresponding domain - */ - public List> getAssetGroupAndDomains(); - - /** - * Fetches the AD group details - * - * @return list of AD group details. - * @throws DataException - */ - public List> getAdGroupDetails() throws DataException; -} +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.api.asset.repository; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.springframework.stereotype.Repository; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.tmobile.pacman.api.asset.domain.ApplicationDetailsESResponse; +import com.tmobile.pacman.api.asset.model.DefaultUserAssetGroup; +import com.tmobile.pacman.api.commons.exception.DataException; +import com.tmobile.pacman.api.commons.exception.NoDataFoundException; + +/** + * This is the Asset Repository layer which makes call to RDS DB as well as ElasticSearch + */ +@Repository +public interface AssetRepository { + + /** + * Fetches the total count of assets for the particular asset group. If no + * type is passed, all the assets of valid target type for the asset group + * is considered. + * + * @param aseetGroupName name of the asset group + * @param type target type + * @param domain the domain of asset group + * + * @return list of type and its asset count. + */ + public Map getAssetCountByAssetGroup(String aseetGroupName, String type); + + /** + * Fetches all the target types for the particular asset group. If asset + * group is passed as aws then all the available target types is returned . + * + * @param aseetGroupName name of the asset group + * @param domain the domain of asset group + * + * @return list of target types. + */ + public List> getTargetTypesByAssetGroup(String aseetGroupName, String domain); + + /** + * Fetches all the applications for the particular asset group. + * + * @param aseetGroupName name of the asset group + * @param domain the domain of asset group + * + * @return list of applications. + * @throws DataException when there is an error while fetching data from ES + */ + public List getApplicationByAssetGroup(String aseetGroupName, String domain) throws DataException; + + /** + * Fetches all the applications for the particular asset group. + * + * @param aseetGroupName name of the asset group + * + * @return list of applications. + * @throws DataException when there is an error while fetching data from ES + */ + public List getApplicationByAssetGroup(String aseetGroupName) throws DataException; + + /** + * Fetches all the environments for the particular asset group. Application + * and Domain can also be passed to filter the environments + * + * @param assetGroup name of the asset group + * @param application application needed to be filtered + * @param domain the domain of asset group + * + * @return list of environments. + */ + public List getEnvironmentsByAssetGroup(String assetGroup, String application, String domain); + + /** + * Fetches all the target type and its details + * + * @return list of target type details. + */ + public List> getAllTargetTypes(); + + /** + * Fetches all the asset groups and its name, display name, description, + * type, createdby and domains + * + * @return list of asset group details. + */ + public List> getAllAssetGroups(); + + /** + * Fetches all the details of the asset group - name, display name, + * description, type, createdby, appcount, assetcount and domains. + * + * @param assetGroup name of the asset group + * + * @return asset group info. + */ + public Map getAssetGroupInfo(String assetGroup); + + /** + * Fetches the total asset count for each application for the given target + * type and asset group. + * + * @param assetGroup name of the asset group + * @param type target type of the asset group + * + * @return list of applications and its asset count. + * @throws DataException when there is an error while fetching data from ES + */ + public Map getAssetCountByApplication(String assetGroup, String type) throws DataException; + + /** + * Fetches the asset trends(daily min/max) over the period of last 1 month + * for the given asset group. From and to can be passed to fetch the asset + * trends for particular days. + * + * @param assetGroup name of the asset group + * @param type target type of the asset group + * @param from from date + * @param to to date + * + * @return list of days with its min/max asset count. + */ + public List> getAssetMinMax(String assetGroup, String type, Date from, Date to); + + /** + * Save/update asset group details in DB.Saves default asset group for the + * user id. + * + * @param defaultUserAssetGroup This request expects userid and assetgroup name as mandatory. + * + * @return boolean as updated status. + */ + public Integer saveOrUpdateAssetGroup(DefaultUserAssetGroup defaultUserAssetGroup); + + /** + * Fetches the default asset group the user has saved for the given asset + * group. + * + * @param userId id of the user + * + * @return asset group name. + */ + public String getUserDefaultAssetGroup(String userId); + + /** + * Fetches the total asset count for each environment for the given target + * type and asset group. + * + * @param assetGroup name of the asset group + * @param type target type of the asset group + * @param application application needed for the count + * + * @return list of environment and its asset count. + */ + public List> getAssetCountByEnvironment(String assetGroup, String application, String type); + + /** + * Saves the recently viewed asset group for the user id. + * + * @param assetGroup name of the asset group + * @param userId id of the user + * + * @return updated list of asset group for the userId. + * @throws DataException when there is an error while fetching/updating data from ES and DB + */ + public List> saveAndAppendAssetGroup(String userId, String assetGroup) throws DataException; + + /** + * Fetches all the asset for the given asset group. + * + * @param assetGroup name of the asset group + * @param filter application,environment,resourceType as optional filters + * @param searchText searchText is used to match any text you are looking for + * @param from for pagination + * @param size for pagination + * + * @return list of assets and its some details. + */ + public List> getListAssets(String assetGroup, Map filter, int from, int size, + String searchText); + + /** + * Fetches the total asset count for the given asset group. + * + * @param assetGroup name of the asset group + * @param filter application,environment,resourceType as optional filters + * @param searchText searchText is used to match any text you are looking for + * @param from for pagination + * @param size for pagination + * + * @return list of assets and its some details. + */ + long getAssetCount(String assetGroup, Map filter, String searchText); + + /** + * Fetches the CPU utilization for the given instanceid. + * + * @param instanceId id of the instance + * + * @return list of date and its CPU utilization of the instance id. + * @throws DataException when there is an error while fetching data from ES + */ + public List> getCpuUtilizationByAssetGroupAndInstanceId(String instanceId) throws DataException; + + /** + * Fetches the Disk utilization for the given instanceid. + * + * @param instanceId Id of the instance + * + * @return list of disk name, size and free space of the instance id. + * @throws DataException when there is an error while fetching data from ES + */ + public List> getDiskUtilizationByAssetGroupAndInstanceId(String instanceId) throws DataException; + + /** + * Fetches the Softwares installed for the given instanceid. + * + * @param instanceId id of the instance + * @param from for pagination + * @param size for pagination + * @param searchText used to match any text you are looking for + * + * @return list of software name and its version installed on the instance id. + * @throws DataException when there is an error while fetching data from ES + */ + public List> getSoftwareInstalledDetailsByAssetGroupAndInstanceId(String instanceId, + Integer from, Integer size, String searchText) throws DataException; + + /** + * Fetches the ec2 resource details from RHN for the given resourceId. + * + * @param resourceId id of the resource + * + * @return all the ec2 details for resourceId. + * @throws DataException when there is an error while fetching data from ES + */ + public List> getEc2ResourceDetailFromRhn(String resourceId) throws DataException; + + /** + * Fetches the ec2 resource details for the given assetgroup and resourceId. + * + * @param ag name of the asset group + * @param resourceId id of the resource + * + * @return all the ec2 details for assetgroup. + * @throws DataException when there is an error while fetching data from ES + */ + public List> getEc2ResourceDetail(String ag, String resourceId) throws DataException; + + /** + * Fetches the ec2 security details for the given resourceId. + * + * @param resourceId id of the resource + * + * @return all the ec2 security details for resourceId. + * @throws DataException when there is an error while fetching data from ES + */ + public List> getEc2ResourceSecurityGroupDetail(String resourceId) throws DataException; + + /** + * Fetches the patchable assets for the given assetgroup.If patched filter is false it returns the unpatched assets + * and if patched is true returns the patched assets.It also filters the the list based on resource type passed in filter + * else returns all the assets of the asset group + * + * @param assetGroup name of the asset group + * @param filter patched(true/false),application,environment,resourcetype, + * executivesponsor,director as optional filters + * + * @return list of assets patched/unpatched. + */ + public List> getListAssetsPatchable(String assetGroup, Map filter); + + /** + * Fetches the taggable assets for the given assetgroup.If tagged filter is false it returns the untagged assets + * and if tagged is true returns the tagged assets.It also filters the the list based on resource type passed in filter + * else returns all the assets of the asset group + * + * @param assetGroup name of the asset group + * @param filter tagged(true/false),application,environment,resourcetype, + * tagname(must with tagged) as optional filters + * + * @return list of assets tagged/untagged. + */ + public List> getListAssetsTaggable(String assetGroup, Map filter); + + /** + * Fetches the ec2 resource block devices detail for the given resourceId. + * + * @param resourceId id of the resource + * + * @return all the ec2 resource block devices details for resourceId. + * @throws DataException when there is an error while fetching data from ES + */ + List> getEc2ResourceBlockDevicesDetail(String resourceId) throws DataException; + + /** + * Fetches the resource details for the given resourceId + * + * @param ag name of the asset group + * @param resourceType type of the resource + * @param resourceId id of the resource + * + * @return name,value and category of the resourceId. + * @throws DataException when there is an error while fetching data from ES + */ + public List> getResourceDetail(String ag, String resourceType, String resourceId) + throws DataException; + + /** + * Fetches the vulnerable assets for the given assetgroup. It looks for any particular resourceType passed in the filter + * else considers ec2 and onpremserver for targetype and fetch it vulnerable asset details. + * + * @param assetGroup name of the asset group + * @param filter qid as mandatory and application,environment as optional filters + * + * @return list of vulnerable assets. + */ + public List> getListAssetsVulnerable(String assetGroup, Map filter); + + /** + * Fetches the port which are in open status for the given instanceId. + * + * @param instanceId id of the instance + * @param from for pagination + * @param size for pagination + * @param searchText used to match any text you are looking for + * + * @return list of open ports. + * @throws DataException when there is an error while fetching data from ES + */ + public List> getOpenPortDetailsByInstanceId(String instanceId, Integer from, Integer size, + String searchText) throws DataException; + + /** + * Fetches the assets with open issue status for the rule id passed in the filter. + * + * @param assetGroup name of the asset group + * @param filter ruleid as mandatory and compliant(true/false),application,environment,resourcetype as + * optional filters + * + * @return list of assets with open issue status. + */ + public List> getListAssetsScanned(String assetGroup, Map filter); + + /** + * Fetches the resource created info for the given resourceId + * + * @param resourceId id of the resource + * + * @return resource create info details + * @throws DataException when there is an error while fetching data from ES + */ + public Map getResourceCreateInfo(String resourceId) throws DataException; + + /** + * Fetches the open,closed and upcoming notification count for the given instance. + * + * @param instanceId id of the instance + * + * @return list of assets with open,closed and upcoming count. + * @throws DataException when there is an error while fetching data from ES + */ + public Map getNotificationSummary(String instanceId) throws DataException; + + /** + * Saves the config details for the given resourceId. + * + * @param resourceId id of the resource + * @param configType type of the config + * @param config config of the asset + * + * @return 1 or any Integer. + */ + public Integer saveAssetConfig(String resourceId, String configType, String config); + + /** + * Fetches the config details for the given resourceId and config type. + * + * @param resourceId id of the resource + * @param configType type of the config + * + * @return config details as string. + */ + public String retrieveAssetConfig(String resourceId, String configType); + + /** + * Fetches the notification details of the instanceId. + * + * @param instanceId id of the instance + * @param filters any filter + * @param searchText searchText is used to match any text you are looking for + * + * @return list of notification details. + * @throws DataException when there is an error while fetching data from ES + */ + public List> getNotificationDetails(String instanceId, Map filters, + String searchText) throws DataException; + + /** + * Fetches the qualys details of the resourceId. + * + * @param resourceId id of the resource + * + * @return list of qualys details. + * @throws DataException when there is an error while fetching data from ES + */ + public List> getQualysDetail(String resourceId) throws DataException; + + /** + * Updates the asset details. + * + * @param assetGroup name of the asset group + * @param targettype target type to be updated + * @param resources resources that needs to updated + * @param updatedBy user id of the user + * @param updates the values with which the resources needs to be updated. + * + * @return integer count of rows updated. + * @throws DataException when there is an error while fetching data from Es + * @throws NoDataFoundException when there is an error while fetching data from ES + */ + public int updateAsset(String assetGroup, String targettype, Map resources, String updatedBy, + List> updates) throws DataException,NoDataFoundException; + + /** + * Fetches all the asset details for the given asset group. + * + * @param assetGroup name of the asset group + * @param filter application,environment,resourceType as optional filters + * @param from for pagination + * @param size for pagination + * @param searchText is used to match any text you are looking for + * + * @return list of complete asset details. + */ + public List> getAssetLists(String assetGroup, Map filter, int from, int size, + String searchText); + + /** + * Fetches the total count of the documents for the index and type. + * + * @param index ES index + * @param type ES type + * + * @return count of docs + */ + public long getTotalCountForListingAsset(String index, String type); + + /** + * Fetches the created date for the give resourceId. + * + * @param resourceId id of the resource + * @param resourceType type of the resource + * + * @return created date as string + */ + public String getResourceCreatedDate(String resourceId, String resourceType); + + /** + * Fetches the domains for the given asset group. + * + * @param aseetGroupName name of the asset group + * + * @return created date as string + */ + List> getDomainsByAssetGroup(String aseetGroupName); + + /** + * Fetches the updatable fields info maintained in RDS for the given targettype. + * + * @param targettype name of the target type + * + * @return list of updatable fields + */ + public String getDataTypeInfoByTargetType(String targettype); + + /** + * Fetches all the asset group and its corresponding domain. + * + * @return list of asset group and its corresponding domain + */ + public List> getAssetGroupAndDomains(); + + /** + * Fetches the AD group details + * + * @return list of AD group details. + * @throws DataException + */ + public List> getAdGroupDetails() throws DataException; + + /** + * Fetches all the applications and assetcount for each application for the particular asset group. + * + * @param assetGroupName name of the asset group + * @param domain the domain of asset group + * + * @return list of applications. + * @throws DataException when there is an error while fetching data from ES + */ + public Map getApplicationAssetCountByAssetGroup(String assetGroupName, String domain) throws DataException; + + /** + * Fetches all application details by asset group name + * + * @param applications - valid list of applications + * + * @return List - valid and invalid application details list + * @throws DataException, JsonProcessingException + */ + public List getApplicationDetails() throws JsonProcessingException, DataException; + + /** + * Get the datasource for the given type list + * @param typeList + * @return + */ + public List> getDatasourceForCostMapping(List typeList); + + /** + * Gets the all cost types. + * + * @return the all cost types + */ + List> getAllCostTypes(); +} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepositoryImpl.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepositoryImpl.java index e0f8755e7..be6907f5b 100644 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepositoryImpl.java +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepositoryImpl.java @@ -55,6 +55,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Strings; import com.google.common.collect.HashMultimap; +import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; @@ -63,6 +64,7 @@ import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; import com.tmobile.pacman.api.asset.AssetConstants; +import com.tmobile.pacman.api.asset.domain.ApplicationDetailsESResponse; import com.tmobile.pacman.api.asset.domain.ResourceResponse; import com.tmobile.pacman.api.asset.domain.ResourceResponse.Source; import com.tmobile.pacman.api.asset.model.DefaultUserAssetGroup; @@ -2358,4 +2360,70 @@ private List> formGetListResponse(List fieldNames, L return assetList; } } + + @Override + public Map getApplicationAssetCountByAssetGroup(String assetGroupName, String domain) + throws DataException { + + List targetTypes = getTargetTypesByAssetGroup(assetGroupName, domain).stream() + .map(obj -> obj.get(Constants.TYPE).toString()).collect(Collectors.toList()); + Map filter = new HashMap<>(); + filter.put(Constants.LATEST, Constants.TRUE); + filter.put(AssetConstants.UNDERSCORE_ENTITY, Constants.TRUE); + Map mustTermsFilter = new HashMap<>(); + mustTermsFilter.put(AssetConstants.UNDERSCORE_TYPE, targetTypes); + Map applicationMap = new HashMap<>(); + + try { + applicationMap = esRepository.getTotalDistributionForIndexAndType(assetGroupName, null, filter, null, null, + Constants.TAGS_APPS, Constants.TEN_THOUSAND, mustTermsFilter); + } catch (Exception e) { + LOGGER.error(AssetConstants.ERROR_GETAPPSBYAG, e); + throw new DataException(e); + } + + return applicationMap; + } + + @Override + public List getApplicationDetails() throws JsonProcessingException, DataException { + String esQuery = "{\"size\":10000,\"query\":{\"bool\":{\"must\":[{\"term\":{\"latest\":\"true\"}}]}},\"_source\":[\"appTag\",\"description\",\"director\",\"executiveSponsor\",\"_orgInfo\"]}"; + String responseJson = StringUtils.EMPTY; + String url = esUrl + "/aws_apps" + "/apps/_search"; + try { + responseJson = PacHttpUtils.doHttpPost(url, esQuery); + } catch (Exception e) { + LOGGER.error("Error in getting application details", e); + throw new DataException("Error in getting application details"); + } + if (!StringUtils.isBlank(responseJson)) { + JsonParser jsonParser = new JsonParser(); + JsonObject resultJson = jsonParser.parse(responseJson).getAsJsonObject(); + JsonObject hitsJson = jsonParser.parse(resultJson.get("hits").toString()).getAsJsonObject(); + Type type = new TypeToken>() { + }.getType(); + return new Gson().fromJson(hitsJson.getAsJsonObject().get("hits").toString(), type); + } + return Lists.newArrayList(); + } + + @Override + public List> getDatasourceForCostMapping(List typeList) { + String targetTypeQuery = typeList.stream().map(targettype -> "\"" + targettype.trim() + "\"") + .collect(Collectors.joining(",")); + String query = "select distinct type as " + Constants.TYPE + ", datasource as " + Constants.PROVIDER + + " from Cost_Mappings"; + if (!CollectionUtils.isEmpty(typeList)) { + query += " WHERE type IN (" + targetTypeQuery + ")"; + } + return rdsRepository.getDataFromPacman(query); + } + + @Override + public List> getAllCostTypes() { + + String query = "select distinct type as type from Cost_Mappings"; + return rdsRepository.getDataFromPacman(query); + + } } diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/CostRepository.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/CostRepository.java new file mode 100644 index 000000000..985aa2673 --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/CostRepository.java @@ -0,0 +1,199 @@ +package com.tmobile.pacman.api.asset.repository; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Repository; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.tmobile.pacman.api.commons.Constants; +import com.tmobile.pacman.api.commons.exception.DataException; +import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; +import com.tmobile.pacman.api.commons.utils.PacHttpUtils; + +@Repository +public class CostRepository { + + @Value("${elastic-search.host}") + private String esHost; + @Value("${elastic-search.port}") + private int esPort; + private static final String PROTOCOL = "http"; + private String esUrl; + + /** The elastic search repository. */ + @Autowired + private ElasticSearchRepository elasticSearchRepository; + + @PostConstruct + void init() { + esUrl = PROTOCOL + "://" + esHost + ":" + esPort; + } + + /** The Constant LOGGER. */ + private static final Log LOGGER = LogFactory.getLog(CostRepository.class); + + public List> getCostAggs(List appNameList) throws DataException { + + List> costTrend = new ArrayList<>(); + Map latestCostFinalised = findLatestCostFinalisedMonth(); + + StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append("aws-cost/monthly-cost").append("/").append(Constants.SEARCH); + StringBuilder requestBody = new StringBuilder("{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"terms\":{\"application.keyword\":"); + requestBody.append((new Gson().toJson(appNameList))); + requestBody.append("}}]}},\"aggs\":{\"YEAR\":{\"terms\":{\"field\":\"year\",\"size\":10000},\"aggs\":{\"MONTH\":{\"terms\":{\"field\":\"month\",\"size\":12}," + + "\"aggs\":{\"COST\":{\"sum\":{\"field\":\"totalCost\"}}}}}}}}"); + String responseDetails; + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), requestBody.toString()); + } catch (Exception e) { + throw new DataException(e); + } + int currentYear = LocalDate.now().getYear(); + int currentMonth = LocalDate.now().getMonthValue(); + + JsonParser parser = new JsonParser(); + JsonObject responseDetailsjson = parser.parse(responseDetails).getAsJsonObject(); + JsonObject aggregations = responseDetailsjson.get(Constants.AGGREGATIONS).getAsJsonObject(); + JsonArray yearBuckets = aggregations.get("YEAR").getAsJsonObject().get(Constants.BUCKETS).getAsJsonArray(); + if (yearBuckets.size() > 0) { + for (int i=0; i trendMap = new HashMap<>(); + trendMap.put("year",year); + JsonObject monthObj = (JsonObject) monthBucket.get(j); + trendMap.put("month",monthObj.get("key").getAsInt()); + trendMap.put("cost",Math.round(monthObj.get("COST").getAsJsonObject().get("value").getAsDouble())); + if(year==currentYear && currentMonth== monthObj.get("key").getAsInt()) { + trendMap.put("costStatus","accumulated"); + }else { + trendMap.put("costStatus",checkForFinalised(latestCostFinalised.get("year"),latestCostFinalised.get("month"),year,monthObj.get("key").getAsInt())?"finalised":"estimated"); + } + costTrend.add(trendMap); + } + } + } + } + return costTrend; + } + + public List> getCostAggsWithTT(List appNameList, List tTypeList) throws DataException { + + List> costTrend = new ArrayList<>(); + Map latestCostFinalised = findLatestCostFinalisedMonth(); + + StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append("aws-cost/monthly-cost").append("/").append(Constants.SEARCH); + StringBuilder requestBody = new StringBuilder("{\"size\":0,\"query\":{\"terms\":{\"application.keyword\":"); + requestBody.append((new Gson().toJson(appNameList))); + requestBody.append("}},\"aggs\":{\"YEAR\":{\"terms\":{\"field\":\"year\",\"size\":10000},\"aggs\":{\"MONTH\":{\"terms\":{\"field\":\"month\",\"size\":12},"); + requestBody.append( "\"aggs\":{\"COST\":{\"sum\":{\"script\":{\"inline\":\" double cost =0.0 ; for(int i=0; i 0) { + for (int i=0; i trendMap = new HashMap<>(); + trendMap.put("year",year); + JsonObject monthObj = (JsonObject) monthBucket.get(j); + trendMap.put("month",monthObj.get("key").getAsInt()); + trendMap.put("cost",Math.round(monthObj.get("COST").getAsJsonObject().get("value").getAsDouble())); + if(year==currentYear && currentMonth== monthObj.get("key").getAsInt()) { + trendMap.put("costStatus","accumulated"); + }else { + trendMap.put("costStatus",checkForFinalised(latestCostFinalised.get("year"),latestCostFinalised.get("month"),year,monthObj.get("key").getAsInt())?"finalised":"estimated"); + } + costTrend.add(trendMap); + } + } + } + } + return costTrend; + } + + public Map findLatestCostFinalisedMonth(){ + Map yearMonthMap = new HashMap<>(); + String requestJson = "{\"size\":0,\"query\":{\"match\":{\"finalised\":true}},\"aggs\":{\"year-month\":{\"max\":{\"script\":\"Integer.parseInt((doc['year'].value+''+String.format('%02d',new def[] {doc['month'].value})))\"}}}}"; + String responseJson = ""; + try { + responseJson = PacHttpUtils.doHttpPost(esUrl+"/aws-cost/monthly-cost/_search",requestJson); + String yearMonth = ""+new JsonParser().parse(responseJson).getAsJsonObject().getAsJsonObject("aggregations").getAsJsonObject("year-month").get("value").getAsInt(); + + yearMonthMap.put("year", Integer.valueOf(yearMonth.substring(0,4))); + yearMonthMap.put("month", Integer.valueOf(yearMonth.substring(4))); + } catch (Exception e) { + LOGGER.error("Error fetching latest finalied cost year and month Info", e); + } + + return yearMonthMap; + } + + public List fetchApplicationMasterList() { + List cloudApps = new ArrayList<>(); + Map mustFilter = new HashMap<>(); + mustFilter.put("_appType.keyword","Cloud"); + mustFilter.put("latest",true); + + List sourceFields = new ArrayList<>(); + sourceFields.add("appTag"); + try { + List> result = elasticSearchRepository.getDataFromES("aws_apps", "apps", mustFilter, + null, null, sourceFields, null); + cloudApps = result.stream().filter(app-> app.get("appTag")!=null).map(app-> app.get("appTag").toString()).collect(Collectors.toList()); + } catch (Exception e) { + LOGGER.error("Error fetching applications",e); + } + return cloudApps; + } + + private boolean checkForFinalised(int finalisedYear, int finalisedMonth, int year, int month) { + + if(finalisedYear=month) { + return true; + } else { + return false; + } + } else { + return true; + } + } +} \ No newline at end of file diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/RecommendationsRepository.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/RecommendationsRepository.java new file mode 100644 index 000000000..b17675024 --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/RecommendationsRepository.java @@ -0,0 +1,500 @@ +package com.tmobile.pacman.api.asset.repository; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.PostConstruct; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Repository; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; +import com.tmobile.pacman.api.asset.AssetConstants; +import com.tmobile.pacman.api.commons.Constants; +import com.tmobile.pacman.api.commons.exception.DataException; +import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; +import com.tmobile.pacman.api.commons.repo.PacmanRdsRepository; +import com.tmobile.pacman.api.commons.utils.PacHttpUtils; + +@Repository +public class RecommendationsRepository { + + @Value("${elastic-search.host}") + private String esHost; + @Value("${elastic-search.port}") + private int esPort; + private static final String PROTOCOL = "http"; + private String esUrl; + + /** The elastic search repository. */ + @Autowired + private ElasticSearchRepository elasticSearchRepository; + + @Autowired + PacmanRdsRepository rdsRepository; + + @PostConstruct + void init() { + esUrl = PROTOCOL + "://" + esHost + ":" + esPort; + } + + /** The Constant LOGGER. */ + private static final Log LOGGER = LogFactory.getLog(RecommendationsRepository.class); + + public List> getRecommendationSummary(String assetGroup, String application) throws DataException { + + List> recommendationSummary = new ArrayList<>(); + StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append(assetGroup).append("/").append(Constants.SEARCH); + StringBuilder requestBody = new StringBuilder("{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":\"true\"}}"); + if(StringUtils.isNotBlank(application)) { + requestBody.append(",{\"match\":{\"tags.Application.keyword\":\""); + requestBody.append(application); + requestBody.append("\"}}"); + } + requestBody.append("]}},\"aggs\":{\"recommendations\":{\"children\":{\"type\":\"recommendation\"},\"aggs\":{\"latest\":{\"filter\":{\"term\":{\"latest\":\"true\"}}," + + "\"aggs\":{\"category\":{\"terms\":{\"field\":\"category.keyword\",\"size\":1000},\"aggs\":{\"savings\":{\"sum\":{\"field\":\"monthlysavings\"}}}}}}}}}}"); + String responseDetails; + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), requestBody.toString()); + } catch (Exception e) { + LOGGER.error("Error in getRecommendationSummary "+e); + throw new DataException(e); + } + JsonParser parser = new JsonParser(); + JsonObject responseDetailsjson = parser.parse(responseDetails).getAsJsonObject(); + JsonObject aggregations = responseDetailsjson.get(Constants.AGGREGATIONS).getAsJsonObject(); + JsonArray categoryBuckets = aggregations.get("recommendations").getAsJsonObject().get("latest").getAsJsonObject().get("category").getAsJsonObject().get(Constants.BUCKETS).getAsJsonArray(); + if (categoryBuckets.size() > 0) { + for (int i=0; i category = new HashMap<>(); + category.put("category", categoryObj.get("key").getAsString()); + category.put("recommendations", categoryObj.get("doc_count").getAsLong()); + JsonObject savingsObj = categoryObj.get("savings").getAsJsonObject(); + if(savingsObj.size() != 0) { + long potentialMonthlySavings = Math.round(savingsObj.get("value").getAsDouble()); + if(potentialMonthlySavings > 0) { + category.put("potentialMonthlySavings", potentialMonthlySavings); + } + } + recommendationSummary.add(category); + } + } + } + return recommendationSummary; + } + + public Map getSummaryByApplication(String assetGroup, String category) throws DataException { + + Map result = new HashMap<>(); + List> summaryByApplication = new ArrayList<>(); + Double totalMonthlySavings = 0.0; + + StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append(assetGroup).append("/").append(Constants.SEARCH); + StringBuilder requestBody = new StringBuilder("{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}},{\"match\":{\"_entity.keyword\":true}}]}}," + + "\"aggs\":{\"apps\":{\"terms\":{\"field\":\"tags.Application.keyword\",\"size\":100000},\"aggs\":{\"recommendations\":{\"children\":{\"type\":\"recommendation\"}," + + "\"aggs\":{\"latest\":{\"filter\":{\"match\":{\"latest\":true}},\"aggs\":{\"category\":{\"filter\":{\"match\":{\"category.keyword\":\""); + requestBody.append(category); + requestBody.append("\"}},\"aggs\":{\"savings\":{\"sum\":{\"field\":\"monthlysavings\"}}}}}}}}}}}}"); + String responseDetails; + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), requestBody.toString()); + } catch (Exception e) { + LOGGER.error("Error in getSummaryByApplication "+e); + throw new DataException(e); + } + JsonParser parser = new JsonParser(); + JsonObject responseDetailsjson = parser.parse(responseDetails).getAsJsonObject(); + JsonObject aggregations = responseDetailsjson.get(Constants.AGGREGATIONS).getAsJsonObject(); + JsonArray appsBuckets = aggregations.get("apps").getAsJsonObject().get(Constants.BUCKETS).getAsJsonArray(); + if (appsBuckets.size() > 0) { + for (int i=0; i app = new HashMap<>(); + app.put("application", appObj.get(Constants.KEY).getAsString()); + JsonObject categoryObj = recommendationObj.get("latest").getAsJsonObject().get("category").getAsJsonObject(); + app.put("recommendations", categoryObj.get(Constants.DOC_COUNT).getAsLong()); + if("cost_optimizing".equals(category)) { + Double monthlySavings = categoryObj.get("savings").getAsJsonObject().get(Constants.VALUE).getAsDouble(); + totalMonthlySavings += monthlySavings; + app.put("monthlySavings", Math.round(monthlySavings)); + } + if( categoryObj.get(Constants.DOC_COUNT).getAsLong() > 0) { + summaryByApplication.add(app); + } + } + } + } + } + + result.put("ag", assetGroup); + result.put("category", category); + if("cost_optimizing".equals(category)) { + result.put("totalMonthlySavings", Math.round(totalMonthlySavings)); + } + result.put("applications", summaryByApplication); + return result; + } + + public Map getSummaryByApplication(String assetGroup) throws DataException { + + Map result = new HashMap<>(); + List> summaryByApplication = new ArrayList<>(); + Double totalMonthlySavings = 0.0; + + StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append(assetGroup).append("/").append(Constants.SEARCH); + StringBuilder requestBody = new StringBuilder("{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}},{\"match\":{\"_entity.keyword\":true}}]}}" + + ",\"aggs\":{\"apps\":{\"terms\":{\"field\":\"tags.Application.keyword\",\"size\":100000},\"aggs\":{\"recommendations\":{\"children\":{\"type\":\"recommendation\"}" + + ",\"aggs\":{\"latest\":{\"filter\":{\"match\":{\"latest\":true}},\"aggs\":{\"savings\":{\"sum\":{\"field\":\"monthlysavings\"}}}}}}}}}}"); + String responseDetails; + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), requestBody.toString()); + } catch (Exception e) { + LOGGER.error("Error in getSummaryByApplication "+e); + throw new DataException(e); + } + JsonParser parser = new JsonParser(); + JsonObject responseDetailsjson = parser.parse(responseDetails).getAsJsonObject(); + JsonObject aggregations = responseDetailsjson.get(Constants.AGGREGATIONS).getAsJsonObject(); + JsonArray appsBuckets = aggregations.get("apps").getAsJsonObject().get(Constants.BUCKETS).getAsJsonArray(); + if (appsBuckets.size() > 0) { + for (int i=0; i app = new HashMap<>(); + app.put("application", appObj.get(Constants.KEY).getAsString()); + app.put("recommendations", recommendationObj.get(Constants.DOC_COUNT).getAsLong()); + Double monthlySavings = recommendationObj.get("latest").getAsJsonObject().get("savings").getAsJsonObject().get(Constants.VALUE).getAsDouble(); + totalMonthlySavings += monthlySavings; + app.put("monthlySavings", Math.round(monthlySavings)); + summaryByApplication.add(app); + } + } + } + } + + result.put("ag", assetGroup); + result.put("totalMonthlySavings", Math.round(totalMonthlySavings)); + result.put("applications", summaryByApplication); + return result; + } + + public Map getRecommendations(String assetGroup, String category, String application) throws DataException { + + Map result = new HashMap<>(); + List> recommendations = new ArrayList<>(); + Double totalMonthlySavings = 0.0; + + StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append(assetGroup).append("/").append(Constants.SEARCH); + StringBuilder requestBody = new StringBuilder("{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}},{\"match\":{\"_entity.keyword\":true}}"); + if(StringUtils.isNotBlank(application)) { + requestBody.append(",{\"match\":{\"tags.Application.keyword\":\""); + requestBody.append(application); + requestBody.append("\"}}"); + } + requestBody.append("]}},\"aggs\":{\"type\":{\"terms\":{\"field\":\"_entitytype.keyword\",\"size\":100000}," + + "\"aggs\":{\"recommendations\":{\"children\":{\"type\":\"recommendation\"},\"aggs\":{\"latest\":{\"filter\":{\"match\":{\"latest\":true}},\"aggs\":{\"category\":{\"filter\":{\"match\":{\"category.keyword\":\""); + requestBody.append(category); + requestBody.append("\"}},\"aggs\":{\"recommendation\":{\"terms\":{\"field\":\"recommendationId.keyword\",\"size\":10000}," + + "\"aggs\":{\"savings\":{\"sum\":{\"field\":\"monthlysavings\"}}}}}}}}}}}}}}"); + String responseDetails; + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), requestBody.toString()); + } catch (Exception e) { + LOGGER.error("Error in getRecommendations "+e); + throw new DataException(e); + } + JsonParser parser = new JsonParser(); + JsonObject responseDetailsjson = parser.parse(responseDetails).getAsJsonObject(); + JsonObject aggregations = responseDetailsjson.get(Constants.AGGREGATIONS).getAsJsonObject(); + JsonArray typeBuckets = aggregations.get("type").getAsJsonObject().get(Constants.BUCKETS).getAsJsonArray(); + if (typeBuckets.size() > 0) { + for (int i=0; i 0) { + for (int j=0; j recommendationInfo = getRecommendation(recommendationId); + if(!recommendationInfo.isEmpty()) { + Map recommendation = new HashMap<>(); + recommendation.put("recommendationId", recommendationId); + recommendation.put("recommendation", recommendationInfo.get("checkname")); + recommendation.put("description", recommendationInfo.get("checkdescription").toString().replace("[NL]", "
")); + recommendation.put("total", typeObj.get(Constants.DOC_COUNT).getAsLong()); + recommendation.put("recommended", recommendationObj.get(Constants.DOC_COUNT).getAsLong()); + recommendation.put("targetType", typeObj.get(Constants.KEY).getAsString()); + if("cost_optimizing".equals(category)) { + Double monthlySavings = recommendationObj.get("savings").getAsJsonObject().get(Constants.VALUE).getAsDouble(); + totalMonthlySavings += monthlySavings; + recommendation.put("monthlySavings", Math.round(monthlySavings)); + } + recommendations.add(recommendation); + } + } + } + } + } + } + } + + result.put("ag", assetGroup); + result.put("category", category); + if("cost_optimizing".equals(category)) { + result.put("totalMonthlySavings", Math.round(totalMonthlySavings)); + } + result.put("response", recommendations); + return result; + } + + public Map getRecommendationDetail(String assetGroup, String recommendationId, String application) throws DataException { + + Map recommendationDetail = new HashMap<>(); + List> resources = new ArrayList<>(); + + String parentType = ""; + if(StringUtils.isNotBlank(application)) { + String query = "SELECT type FROM Recommendation_Mappings WHERE checkId =\""+recommendationId+"\""; + try { + parentType = rdsRepository.queryForString(query); + } catch (Exception exception) { + LOGGER.error("Error in getRecommendationDetail for getting parent type " , exception); + } + } + + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append("/").append(assetGroup).append("/") + .append("recommendation").append("/").append(Constants.SEARCH).append("?scroll=") + .append(Constants.ES_PAGE_SCROLL_TTL); + + String urlToQuery = urlToQueryBuffer.toString(); + String urlToScroll = new StringBuilder(esUrl).append("/").append(Constants.SEARCH).append("/scroll") + .toString(); + + StringBuilder requestBody = new StringBuilder("{\"size\":10000,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":\"true\"}},{\"match\":{\"recommendationId.keyword\":\""); + requestBody.append(recommendationId).append("\"}}"); + if(StringUtils.isNotBlank(application)) { + requestBody.append(",{\"has_parent\":{\"parent_type\":\""); + requestBody.append(parentType); + requestBody.append("\",\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}},{\"match\":{\"_entity.keyword\":true}},{\"match\":{\"tags.Application.keyword\":\""); + requestBody.append(application); + requestBody.append("\"}}]}}}}"); + } + requestBody.append("]}}}"); + long totalDocs = getTotalDocCount(assetGroup, "recommendation", "{" + requestBody.toString().substring(14)); + String request = requestBody.toString(); + String scrollId = null; + if(totalDocs > 0){ + for (int index = 0; index <= (totalDocs / Constants.ES_PAGE_SIZE); index++) { + String responseDetails = null; + try { + if (StringUtils.isNotBlank(scrollId)) { + request = elasticSearchRepository.buildScrollRequest(scrollId, Constants.ES_PAGE_SCROLL_TTL); + urlToQuery = urlToScroll; + } + responseDetails = PacHttpUtils.doHttpPost(urlToQuery, request); + scrollId = processResponseAndSendTheScrollBack(responseDetails, resources); + } catch (Exception e) { + } + } + } + + recommendationDetail.put("resources", resources); + return recommendationDetail; + } + + @SuppressWarnings("deprecation") + public Map getRecommendation(String recommendationId) throws DataException { + + Map mustFilter = new HashMap<>(); + mustFilter.put("checkid.keyword",recommendationId); + mustFilter.put("latest",true); + + try { + List> result = elasticSearchRepository.getDataFromES("aws_checks", "checks", mustFilter, + null, null, null, null); + return result.get(0); + } catch (Exception e) { + LOGGER.error("Error fetching applications",e); + return new HashMap<>(); + } + + } + + @SuppressWarnings("unchecked") + private long getTotalDocCount(String index, String type, String requestBody) { + StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append(index); + if(StringUtils.isNotBlank(type)) { + urlToQuery.append("/").append(type); + } + urlToQuery.append("/").append("_count"); + String responseDetails = null; + Gson gson = new GsonBuilder().create(); + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), requestBody); + Map response = (Map) gson.fromJson(responseDetails, Object.class); + return (long) (Double.parseDouble(response.get("count").toString())); + } catch (Exception e) { + LOGGER.error("Error in getTotalDocCount", e); + return 0; + } + } + + @SuppressWarnings("unchecked") + private String processResponseAndSendTheScrollBack(String responseDetails, List> results) { + JsonParser parser = new JsonParser(); + JsonObject responseDetailsjson = parser.parse(responseDetails).getAsJsonObject(); + JsonArray hits = responseDetailsjson.get("hits").getAsJsonObject().get("hits").getAsJsonArray(); + for (JsonElement hit : hits) { + JsonObject source = hit.getAsJsonObject().get(AssetConstants.UNDERSCORE_SOURCE).getAsJsonObject(); + if (source != null) { + Map doc = new Gson().fromJson(source, new TypeToken>() { + }.getType()); + Map resourceinfo = (Map) doc.get("resourceinfo"); + doc.remove("resourceinfo"); + doc.remove("_loaddate"); + doc.remove("latest"); + doc.remove("monthlysavings"); + doc.remove("recommendation"); + doc.putAll(resourceinfo); + results.add(doc); + } + } + return responseDetailsjson.get("_scroll_id").getAsString(); + } + + public List> getGeneralRecommendationSummary() throws DataException { + + List> recommendationSummary = new ArrayList<>(); + StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append("global_recommendations").append("/") + .append("recommendation").append("/").append(Constants.SEARCH); + StringBuilder requestBody = new StringBuilder("{\"size\":0,\"query\":{\"term\":{\"latest\":{\"value\":\"true\"}}},\"aggs\":{\"category\":{\"terms\":{\"field\":\"category.keyword\",\"size\":100}}}}"); + String responseDetails; + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), requestBody.toString()); + } catch (Exception e) { + LOGGER.error("Error in getGlobalRecommendationSummary "+e); + throw new DataException(e); + } + JsonParser parser = new JsonParser(); + JsonObject responseDetailsjson = parser.parse(responseDetails).getAsJsonObject(); + JsonObject aggregations = responseDetailsjson.get(Constants.AGGREGATIONS).getAsJsonObject(); + JsonArray categoryBuckets = aggregations.get("category").getAsJsonObject().get(Constants.BUCKETS).getAsJsonArray(); + if (categoryBuckets.size() > 0) { + for (int i=0; i category = new HashMap<>(); + category.put("category", categoryObj.get("key").getAsString()); + category.put("recommendations", categoryObj.get("doc_count").getAsLong()); + recommendationSummary.add(category); + } + } + } + return recommendationSummary; + } + + public Map getGeneralRecommendations(String category) throws DataException { + + Map result = new HashMap<>(); + List> recommendations = new ArrayList<>(); + + StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append("global_recommendations").append("/") + .append("recommendation").append("/").append(Constants.SEARCH); + StringBuilder requestBody = new StringBuilder("{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}},{\"match\":{\"category.keyword\":\""); + requestBody.append(category); + requestBody.append("\"}}]}},\"aggs\":{\"recommendations\":{\"terms\":{\"field\":\"recommendationId.keyword\",\"size\":10000}}}}"); + String responseDetails; + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), requestBody.toString()); + } catch (Exception e) { + LOGGER.error("Error in getGeneralRecommendations "+e); + throw new DataException(e); + } + JsonParser parser = new JsonParser(); + JsonObject responseDetailsjson = parser.parse(responseDetails).getAsJsonObject(); + JsonObject aggregations = responseDetailsjson.get(Constants.AGGREGATIONS).getAsJsonObject(); + JsonArray recommendationBuckets = aggregations.get("recommendations").getAsJsonObject().get(Constants.BUCKETS).getAsJsonArray(); + if (recommendationBuckets.size() > 0) { + for (int i=0; i recommendationInfo = getRecommendation(recommendationId); + if(!recommendationInfo.isEmpty()) { + Map recommendation = new HashMap<>(); + recommendation.put("recommendationId", recommendationId); + recommendation.put("recommendation", recommendationInfo.get("checkname")); + recommendation.put("description", recommendationInfo.get("checkdescription").toString().replace("[NL]", "
")); + recommendation.put("recommended", recommendationObj.get(Constants.DOC_COUNT).getAsLong()); + recommendations.add(recommendation); + } + } + } + } + + result.put("category", category); + result.put("response", recommendations); + return result; + } + + public Map getGeneralRecommendationDetail(String recommendationId) throws DataException { + + Map recommendationDetail = new HashMap<>(); + List> resources = new ArrayList<>(); + + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append("/").append("global_recommendations").append("/") + .append("recommendation").append("/").append(Constants.SEARCH).append("?scroll=") + .append(Constants.ES_PAGE_SCROLL_TTL); + + String urlToQuery = urlToQueryBuffer.toString(); + String urlToScroll = new StringBuilder(esUrl).append("/").append(Constants.SEARCH).append("/scroll") + .toString(); + + StringBuilder requestBody = new StringBuilder("{\"size\":10000,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}},{\"match\":{\"recommendationId.keyword\":\""); + requestBody.append(recommendationId); + requestBody.append("\"}}]}}}"); + long totalDocs = getTotalDocCount("global_recommendations", "recommendation", "{" + requestBody.toString().substring(14)); + String request = requestBody.toString(); + String scrollId = null; + if(totalDocs > 0){ + for (int index = 0; index <= (totalDocs / Constants.ES_PAGE_SIZE); index++) { + String responseDetails = null; + try { + if (StringUtils.isNotBlank(scrollId)) { + request = elasticSearchRepository.buildScrollRequest(scrollId, Constants.ES_PAGE_SCROLL_TTL); + urlToQuery = urlToScroll; + } + responseDetails = PacHttpUtils.doHttpPost(urlToQuery, request); + scrollId = processResponseAndSendTheScrollBack(responseDetails, resources); + } catch (Exception e) { + } + } + } + + recommendationDetail.put("resources", resources); + return recommendationDetail; + } +} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetService.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetService.java index 4177e23bd..7d0a582df 100644 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetService.java +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetService.java @@ -1,488 +1,507 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ -package com.tmobile.pacman.api.asset.service; - -import java.util.Date; -import java.util.List; -import java.util.Map; - -import com.tmobile.pacman.api.asset.domain.ResponseWithFieldsByTargetType; -import com.tmobile.pacman.api.asset.model.DefaultUserAssetGroup; -import com.tmobile.pacman.api.commons.exception.DataException; -import com.tmobile.pacman.api.commons.exception.ServiceException; - -/** - * This is the main interface for asset service which contains business logics and method calls to repository - */ -public interface AssetService { - - /** - * Fetches the total count of assets for the particular asset group. If no - * type is passed, all the assets of valid target type for the asset group - * is considered. - * - * @param aseetGroupName name of the asset group - * @param type target type - * @param domain the domain of asset group - * - * @return list of type and its asset count. - */ - public List> getAssetCountByAssetGroup(String aseetGroupName, String type, String domain); - - /** - * Fetches all the target types for the particular asset group. If asset - * group is passed as aws then all the available target types is returned . - * - * @param aseetGroupName name of the asset group - * @param domain the domain of asset group - * - * @return list of target types. - */ - public List> getTargetTypesForAssetGroup(String aseetGroupName, String domain); - - /** - * Fetches all the applications for the particular asset group. - * - * @param aseetGroupName name of the asset group - * @param domain the domain of asset group - * - * @return list of applications. - * @throws DataException when there is an error while fetching data - */ - public List> getApplicationsByAssetGroup(String aseetGroupName, String domain) throws DataException; - - /** - * Fetches all the environments for the particular asset group. Application - * and Domain can also be passed to filter the environments - * - * @param assetGroup name of the asset group - * @param application name of the application - * @param domain the domain of asset group - * - * @return list of environments. - */ - public List> getEnvironmentsByAssetGroup(String assetGroup, String application, String domain); - - /** - * Fetches all the asset groups and its name, display name, description, - * type, createdby and domains - * - * @return list of asset group details. - */ - public List> getAllAssetGroups(); - - /** - * Fetches all the details of the asset group - name, display name, - * description, type, createdby, appcount, assetcount and domains. - * - * @param assetGroup name of the asset group - * - * @return asset group info. - */ - public Map getAssetGroupInfo(String assetGroup); - - /** - * Fetches the total asset count for each application for the given target - * type and asset group. - * - * @param assetGroup name of the asset group - * @param type target type of the asset group - * - * @return list of applications and its asset count. - * @throws DataException when there is an error while fetching data - */ - public List> getAssetCountByApplication(String assetGroup, String type) throws DataException; - - /** - * Fetches the asset trends(daily min/max) over the period of last 1 month - * for the given asset group. From and to can be passed to fetch the asset - * trends for particular days. - * - * @param assetGroup name of the asset group - * @param type target type of the asset group - * @param from from date - * @param to to date - * - * @return list of days with its min/max asset count. - */ - public List> getAssetMinMax(String assetGroup, String type, Date from, Date to); - - /** - * Save/update asset group details in DB.Saves default asset group for the - * user id. - * - * @param defaultUserAssetGroup This request expects userid and assetgroup name as mandatory. - * - * @return boolean as updated status. - */ - public Boolean saveOrUpdateAssetGroup(DefaultUserAssetGroup defaultUserAssetGroup); - - /** - * Fetches the default asset group the user has saved for the given asset - * group. - * - * @param userId id of the user - * - * @return asset group name. - */ - public String getUserDefaultAssetGroup(String userId); - - /** - * Fetches the total asset count for each environment for the given target - * type and asset group. - * - * @param assetGroup name of the asset group - * @param type target type of the asset group - * @param application application needed for the count - * - * @return list of environment and its asset count. - */ - public List> getAssetCountByEnvironment(String assetGroup, String application, String type); - - /** - * Saves the recently viewed asset group for the user id. - * - * @param assetGroup name of the asset group - * @param userId id of the user - * - * @return updated list of asset group for the userId. - * @throws DataException when there is an error while fetching data - */ - public List> saveAndAppendToRecentlyViewedAG(String userId, String assetGroup) throws DataException; - - /** - * Fetches all the asset for the given asset group. - * - * @param assetGroup name of the asset group - * @param filter application,environment,resourceType as optional filters - * @param searchText searchText is used to match any text you are looking for - * @param from for pagination - * @param size for pagination - * - * @return list of assets and its some details. - */ - public List> getListAssets(String assetGroup, Map filter, int from, int size, - String searchText); - - /** - * Fetches the total asset count for the given asset group. - * - * @param assetGroup name of the asset group - * @param filter application,environment,resourceType as optional filters - * @param searchText searchText is used to match any text you are looking for - * @param from for pagination - * @param size for pagination - * - * @return list of assets and its some details. - */ - public long getAssetCount(String assetGroup, Map filter, String searchText); - - /** - * Fetches the CPU utilization for the given instanceid. - * - * @param instanceid id of the instance - * - * @return list of date and its CPU utilization of the instance id. - * @throws DataException when there is an error while fetching data - */ - public List> getInstanceCPUUtilization(String instanceid) throws DataException; - - /** - * Fetches the Disk utilization for the given instanceid. - * - * @param instanceid id of the instance - * - * @return list of disk name, size and free space of the instance id. - * @throws DataException when there is an error while fetching data - */ - public List> getInstanceDiskUtilization(String instanceid) throws DataException; - - /** - * Fetches the Softwares installed for the given instanceid. - * - * @param instanceId id of the instance - * @param from for pagination - * @param size for pagination - * @param searchText searchText is used to match any text you are looking for - * - * @return list of software name and its version installed on the instance id. - * @throws DataException when there is an error while fetching data - */ - public List> getInstanceSoftwareInstallDetails(String instanceId, Integer from, Integer size, - String searchText) throws DataException; - - /** - * Fetches the ec2 resource details for the given assetgroup and resourceId. - * - * @param ag name of the asset group - * @param resourceId id of the resource - * - * @return all the ec2 details for assetgroup. - * @throws DataException when there is an error while fetching data - * @throws ServiceException when there is an error while fetching data - */ - public Map getEc2ResourceDetail(String ag, String resourceId) throws DataException,ServiceException; - - /** - * Fetches the patchable assets for the given assetgroup.If patched filter is false it returns the unpatched assets - * and if patched is true returns the patched assets.It also filters the the list based on resource type passed in filter - * else returns all the assets of the asset group - * - * @param assetGroup name of the asset group - * @param filter patched(true/false),application,environment,resourcetype, - * executivesponsor,director as optional filters - * - * @return list of assets patched/unpatched. - */ - public List> getListAssetsPatchable(String assetGroup, Map filter); - - /** - * Fetches the taggable assets for the given assetgroup.If tagged filter is false it returns the untagged assets - * and if tagged is true returns the tagged assets.It also filters the the list based on resource type passed in filter - * else returns all the assets of the asset group - * - * @param assetGroup name of the asset group - * @param filter tagged(true/false),application,environment,resourcetype, - * tagname(must with tagged) as optional filters - * - * @return list of assets tagged/untagged. - */ - public List> getListAssetsTaggable(String assetGroup, Map filter); - - /** - * Fetches the resource details for the given resourceId - * - * @param dataSource the dataSource - * @param resourceType type of the resource - * @param resourceId id of the resource - * - * @return name,value and category of the resourceId. - * @throws DataException when there is an error while fetching data - */ - public Map getGenericResourceDetail(String dataSource, String resourceType, String resourceId) - throws DataException; - - /** - * Fetches the vulnerable assets for the given assetgroup. It looks for any particular resourceType passed in the filter - * else considers ec2 and onpremserver for targetype and fetch it vulnerable asset details. - * - * @param assetGroup name of the asset group - * @param filter qid as mandatory and application,environment as optional filters - * - * @return list of vulnerable assets. - */ - public List> getListAssetsVulnerable(String assetGroup, Map filter); - - /** - * Fetches the port which are in open status for the given instanceId. - * - * @param instanceId id of the instance - * @param from for pagination - * @param size for pagination - * @param searchText searchText is used to match any text you are looking for - * - * @return list of open ports. - * @throws DataException when there is an error while fetching data - */ - public List> getOpenPortDetails(String instanceId, Integer from, Integer size, String searchText) - throws DataException; - - /** - * Fetches the state of the resourceId for the given asset group. - * - * @param ag name of the asset group - * @param resourceId id of the resource - * - * @return state of resourceId - * @throws DataException when there is an error while fetching data - */ - public String getEc2StateDetail(String ag, String resourceId) throws DataException; - - /** - * Fetches the assets with open issue status for the rule id passed in the filter. - * - * @param assetGroup name of the asset group - * @param filter ruleid as mandatory and compliant(true/false),application,environment,resourcetype as - * optional filters - * - * @return list of assets with open issue status. - */ - public List> getListAssetsScanned(String assetGroup, Map filter); - - /** - * Fetches the open,closed and upcoming notification count for the given instance. - * - * @param instanceId id of the instance - * - * @return list of assets with open,closed and upcoming count. - * @throws DataException when there is an error while fetching data - */ - public List> getNotificationSummary(String instanceId) throws DataException; - - /** - * Fetches the total count of the notification from the list passed. - * - * @param sevList list of assets with open,closed and upcoming count - * - * @return count of total notifications. - * @throws DataException when there is an error while fetching data - */ - public String getNotificationSummaryTotal(List> sevList) throws DataException; - - /** - * Saves the config details for the given resourceId. - * - * @param resourceId id of the resource - * @param configType type of the config - * @param config config of the asset - * - * @return 1 or any Integer. - */ - public Integer saveAssetConfig(String resourceId, String configType, String config); - - /** - * Fetches the config details for the given resourceId and config type. - * - * @param resourceId id of the resource - * @param configType type of the config - * - * @return config details as string. - */ - public String retrieveAssetConfig(String resourceId, String configType); - - /** - * Fetches the creator details for the given resourceId. - * - * @param resourceId id of the resource - * - * @return created by, creation date and email. - * @throws DataException when there is an error while fetching data - */ - public Map getEc2CreatorDetail(String resourceId) throws DataException; - - /** - * Fetches the notification details of the instanceId. - * - * @param instanceId id of the instance - * @param filter any filter - * @param searchText searchText is used to match any text you are looking for - * - * @return list of notification details. - * @throws DataException when there is an error while fetching data - */ - public List> getNotificationDetails(String instanceId, Map filter, - String searchText) throws DataException; - - /** - * Fetches the qualys details of the resourceId. - * - * @param resourceId id of the resource - * - * @return list of qualys details. - * @throws DataException when there is an error while fetching data - */ - public List> getResourceQualysDetail(String resourceId) throws DataException; - - /** - * Fetches the AD group details of the resourceId for the given asset group. - * - * @param ag name of the asset group - * @param resourceId id of the resource - * - * @return list of AD group details. - * @throws DataException when there is an error while fetching data - */ - public List> getAdGroupsDetail(String ag, String resourceId) throws DataException; - - /** - * Fetches the average last week cost and total cost of the ec2 instance. - * - * @param resourceId id of the resource - * - * @return average last week cost and total cost of ec2. - * @throws DataException when there is an error while fetching data - */ - public Map getEC2AvgAndTotalCost(String resourceId) throws DataException; - - /** - * Updates the asset details. - * - * @param assetGroup name of the asset group - * @param targettype target type to be updated - * @param resources resources that needs to updated - * @param updatedBy user id of the user - * @param updates the values with which the resources needs to be updated. - * - * @return integer count of rows updated. - * @throws DataException when there is an error while fetching data - */ - public int updateAsset(String assetGroup, String targettype, Map resources, String updatedBy, - List> updates) throws DataException; - - /** - * Fetches all the asset details for the given asset group. - * - * @param assetGroup name of the asset group - * @param filter application,environment,resourceType as optional filters - * @param from for pagination - * @param size for pagination - * @param searchText is used to match any text you are looking for - * - * @return list of complete asset details. - */ - public List> getAssetLists(String assetGroup, Map filter, int from, int size, - String searchText); - - /** - * Fetches the list of fields that can be edited for the given resource type. - * - * @param resourceType type of the resource - * - * @return ResponseWithFieldsByTargetType has list of editable fields and target type - */ - public ResponseWithFieldsByTargetType getEditFieldsByTargetType(String resourceType); - - /** - * Fetches the total count of the documents for the index and type. - * - * @param index ES index - * @param type ES type - * - * @return count of docs - */ - public long getTotalCountForListingAsset(String index, String type); - - /** - * Fetches the created date for the give resourceId. - * - * @param resourceId id of the resource - * @param resourceType type of the resource - * - * @return created date as string - */ - public String getResourceCreatedDate(String resourceId, String resourceType); - - /** - * Fetches the data type info maintained in RDS for the given resourceId. - * - * @param resourceId id of the resource - * - * @return list of data type info - * @throws ServiceException when the datatype is not maintained in RDS - */ - public List> getDataTypeInfoByTargetType(String resourceId) throws ServiceException; - -} +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.api.asset.service; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.tmobile.pacman.api.asset.domain.ApplicationDetailsResponse; +import com.tmobile.pacman.api.asset.domain.ResponseWithFieldsByTargetType; +import com.tmobile.pacman.api.asset.model.DefaultUserAssetGroup; +import com.tmobile.pacman.api.commons.exception.DataException; +import com.tmobile.pacman.api.commons.exception.ServiceException; + +/** + * This is the main interface for asset service which contains business logics and method calls to repository + */ +public interface AssetService { + + /** + * Fetches the total count of assets for the particular asset group. If no + * type is passed, all the assets of valid target type for the asset group + * is considered. + * + * @param aseetGroupName name of the asset group + * @param type target type + * @param domain the domain of asset group + * + * @return list of type and its asset count. + */ + public List> getAssetCountByAssetGroup(String aseetGroupName, String type, String domain); + + /** + * Fetches all the target types for the particular asset group. If asset + * group is passed as aws then all the available target types is returned . + * + * @param aseetGroupName name of the asset group + * @param domain the domain of asset group + * + * @return list of target types. + */ + public List> getTargetTypesForAssetGroup(String aseetGroupName, String domain); + + /** + * Fetches all the applications for the particular asset group. + * + * @param aseetGroupName name of the asset group + * @param domain the domain of asset group + * + * @return list of applications. + * @throws DataException when there is an error while fetching data + */ + public List> getApplicationsByAssetGroup(String aseetGroupName, String domain) throws DataException; + + /** + * Fetches all the environments for the particular asset group. Application + * and Domain can also be passed to filter the environments + * + * @param assetGroup name of the asset group + * @param application name of the application + * @param domain the domain of asset group + * + * @return list of environments. + */ + public List> getEnvironmentsByAssetGroup(String assetGroup, String application, String domain); + + /** + * Fetches all the asset groups and its name, display name, description, + * type, createdby and domains + * + * @return list of asset group details. + */ + public List> getAllAssetGroups(); + + /** + * Fetches all the details of the asset group - name, display name, + * description, type, createdby, appcount, assetcount and domains. + * + * @param assetGroup name of the asset group + * + * @return asset group info. + */ + public Map getAssetGroupInfo(String assetGroup); + + /** + * Fetches the total asset count for each application for the given target + * type and asset group. + * + * @param assetGroup name of the asset group + * @param type target type of the asset group + * + * @return list of applications and its asset count. + * @throws DataException when there is an error while fetching data + */ + public List> getAssetCountByApplication(String assetGroup, String type) throws DataException; + + /** + * Fetches the asset trends(daily min/max) over the period of last 1 month + * for the given asset group. From and to can be passed to fetch the asset + * trends for particular days. + * + * @param assetGroup name of the asset group + * @param type target type of the asset group + * @param from from date + * @param to to date + * + * @return list of days with its min/max asset count. + */ + public List> getAssetMinMax(String assetGroup, String type, Date from, Date to); + + /** + * Save/update asset group details in DB.Saves default asset group for the + * user id. + * + * @param defaultUserAssetGroup This request expects userid and assetgroup name as mandatory. + * + * @return boolean as updated status. + */ + public Boolean saveOrUpdateAssetGroup(DefaultUserAssetGroup defaultUserAssetGroup); + + /** + * Fetches the default asset group the user has saved for the given asset + * group. + * + * @param userId id of the user + * + * @return asset group name. + */ + public String getUserDefaultAssetGroup(String userId); + + /** + * Fetches the total asset count for each environment for the given target + * type and asset group. + * + * @param assetGroup name of the asset group + * @param type target type of the asset group + * @param application application needed for the count + * + * @return list of environment and its asset count. + */ + public List> getAssetCountByEnvironment(String assetGroup, String application, String type); + + /** + * Saves the recently viewed asset group for the user id. + * + * @param assetGroup name of the asset group + * @param userId id of the user + * + * @return updated list of asset group for the userId. + * @throws DataException when there is an error while fetching data + */ + public List> saveAndAppendToRecentlyViewedAG(String userId, String assetGroup) throws DataException; + + /** + * Fetches all the asset for the given asset group. + * + * @param assetGroup name of the asset group + * @param filter application,environment,resourceType as optional filters + * @param searchText searchText is used to match any text you are looking for + * @param from for pagination + * @param size for pagination + * + * @return list of assets and its some details. + */ + public List> getListAssets(String assetGroup, Map filter, int from, int size, + String searchText); + + /** + * Fetches the total asset count for the given asset group. + * + * @param assetGroup name of the asset group + * @param filter application,environment,resourceType as optional filters + * @param searchText searchText is used to match any text you are looking for + * @param from for pagination + * @param size for pagination + * + * @return list of assets and its some details. + */ + public long getAssetCount(String assetGroup, Map filter, String searchText); + + /** + * Fetches the CPU utilization for the given instanceid. + * + * @param instanceid id of the instance + * + * @return list of date and its CPU utilization of the instance id. + * @throws DataException when there is an error while fetching data + */ + public List> getInstanceCPUUtilization(String instanceid) throws DataException; + + /** + * Fetches the Disk utilization for the given instanceid. + * + * @param instanceid id of the instance + * + * @return list of disk name, size and free space of the instance id. + * @throws DataException when there is an error while fetching data + */ + public List> getInstanceDiskUtilization(String instanceid) throws DataException; + + /** + * Fetches the Softwares installed for the given instanceid. + * + * @param instanceId id of the instance + * @param from for pagination + * @param size for pagination + * @param searchText searchText is used to match any text you are looking for + * + * @return list of software name and its version installed on the instance id. + * @throws DataException when there is an error while fetching data + */ + public List> getInstanceSoftwareInstallDetails(String instanceId, Integer from, Integer size, + String searchText) throws DataException; + + /** + * Fetches the ec2 resource details for the given assetgroup and resourceId. + * + * @param ag name of the asset group + * @param resourceId id of the resource + * + * @return all the ec2 details for assetgroup. + * @throws DataException when there is an error while fetching data + * @throws ServiceException when there is an error while fetching data + */ + public Map getEc2ResourceDetail(String ag, String resourceId) throws DataException,ServiceException; + + /** + * Fetches the patchable assets for the given assetgroup.If patched filter is false it returns the unpatched assets + * and if patched is true returns the patched assets.It also filters the the list based on resource type passed in filter + * else returns all the assets of the asset group + * + * @param assetGroup name of the asset group + * @param filter patched(true/false),application,environment,resourcetype, + * executivesponsor,director as optional filters + * + * @return list of assets patched/unpatched. + */ + public List> getListAssetsPatchable(String assetGroup, Map filter); + + /** + * Fetches the taggable assets for the given assetgroup.If tagged filter is false it returns the untagged assets + * and if tagged is true returns the tagged assets.It also filters the the list based on resource type passed in filter + * else returns all the assets of the asset group + * + * @param assetGroup name of the asset group + * @param filter tagged(true/false),application,environment,resourcetype, + * tagname(must with tagged) as optional filters + * + * @return list of assets tagged/untagged. + */ + public List> getListAssetsTaggable(String assetGroup, Map filter); + + /** + * Fetches the resource details for the given resourceId + * + * @param dataSource the dataSource + * @param resourceType type of the resource + * @param resourceId id of the resource + * + * @return name,value and category of the resourceId. + * @throws DataException when there is an error while fetching data + */ + public Map getGenericResourceDetail(String dataSource, String resourceType, String resourceId) + throws DataException; + + /** + * Fetches the vulnerable assets for the given assetgroup. It looks for any particular resourceType passed in the filter + * else considers ec2 and onpremserver for targetype and fetch it vulnerable asset details. + * + * @param assetGroup name of the asset group + * @param filter qid as mandatory and application,environment as optional filters + * + * @return list of vulnerable assets. + */ + public List> getListAssetsVulnerable(String assetGroup, Map filter); + + /** + * Fetches the port which are in open status for the given instanceId. + * + * @param instanceId id of the instance + * @param from for pagination + * @param size for pagination + * @param searchText searchText is used to match any text you are looking for + * + * @return list of open ports. + * @throws DataException when there is an error while fetching data + */ + public List> getOpenPortDetails(String instanceId, Integer from, Integer size, String searchText) + throws DataException; + + /** + * Fetches the state of the resourceId for the given asset group. + * + * @param ag name of the asset group + * @param resourceId id of the resource + * + * @return state of resourceId + * @throws DataException when there is an error while fetching data + */ + public String getEc2StateDetail(String ag, String resourceId) throws DataException; + + /** + * Fetches the assets with open issue status for the rule id passed in the filter. + * + * @param assetGroup name of the asset group + * @param filter ruleid as mandatory and compliant(true/false),application,environment,resourcetype as + * optional filters + * + * @return list of assets with open issue status. + */ + public List> getListAssetsScanned(String assetGroup, Map filter); + + /** + * Fetches the open,closed and upcoming notification count for the given instance. + * + * @param instanceId id of the instance + * + * @return list of assets with open,closed and upcoming count. + * @throws DataException when there is an error while fetching data + */ + public List> getNotificationSummary(String instanceId) throws DataException; + + /** + * Fetches the total count of the notification from the list passed. + * + * @param sevList list of assets with open,closed and upcoming count + * + * @return count of total notifications. + * @throws DataException when there is an error while fetching data + */ + public String getNotificationSummaryTotal(List> sevList) throws DataException; + + /** + * Saves the config details for the given resourceId. + * + * @param resourceId id of the resource + * @param configType type of the config + * @param config config of the asset + * + * @return 1 or any Integer. + */ + public Integer saveAssetConfig(String resourceId, String configType, String config); + + /** + * Fetches the config details for the given resourceId and config type. + * + * @param resourceId id of the resource + * @param configType type of the config + * + * @return config details as string. + */ + public String retrieveAssetConfig(String resourceId, String configType); + + /** + * Fetches the creator details for the given resourceId. + * + * @param resourceId id of the resource + * + * @return created by, creation date and email. + * @throws DataException when there is an error while fetching data + */ + public Map getEc2CreatorDetail(String resourceId) throws DataException; + + /** + * Fetches the notification details of the instanceId. + * + * @param instanceId id of the instance + * @param filter any filter + * @param searchText searchText is used to match any text you are looking for + * + * @return list of notification details. + * @throws DataException when there is an error while fetching data + */ + public List> getNotificationDetails(String instanceId, Map filter, + String searchText) throws DataException; + + /** + * Fetches the qualys details of the resourceId. + * + * @param resourceId id of the resource + * + * @return list of qualys details. + * @throws DataException when there is an error while fetching data + */ + public List> getResourceQualysDetail(String resourceId) throws DataException; + + /** + * Fetches the AD group details of the resourceId for the given asset group. + * + * @param ag name of the asset group + * @param resourceId id of the resource + * + * @return list of AD group details. + * @throws DataException when there is an error while fetching data + */ + public List> getAdGroupsDetail(String ag, String resourceId) throws DataException; + + /** + * Fetches the average last week cost and total cost of the ec2 instance. + * + * @param resourceId id of the resource + * + * @return average last week cost and total cost of ec2. + * @throws DataException when there is an error while fetching data + */ + public Map getEC2AvgAndTotalCost(String resourceId) throws DataException; + + /** + * Updates the asset details. + * + * @param assetGroup name of the asset group + * @param targettype target type to be updated + * @param resources resources that needs to updated + * @param updatedBy user id of the user + * @param updates the values with which the resources needs to be updated. + * + * @return integer count of rows updated. + * @throws DataException when there is an error while fetching data + */ + public int updateAsset(String assetGroup, String targettype, Map resources, String updatedBy, + List> updates) throws DataException; + + /** + * Fetches all the asset details for the given asset group. + * + * @param assetGroup name of the asset group + * @param filter application,environment,resourceType as optional filters + * @param from for pagination + * @param size for pagination + * @param searchText is used to match any text you are looking for + * + * @return list of complete asset details. + */ + public List> getAssetLists(String assetGroup, Map filter, int from, int size, + String searchText); + + /** + * Fetches the list of fields that can be edited for the given resource type. + * + * @param resourceType type of the resource + * + * @return ResponseWithFieldsByTargetType has list of editable fields and target type + */ + public ResponseWithFieldsByTargetType getEditFieldsByTargetType(String resourceType); + + /** + * Fetches the total count of the documents for the index and type. + * + * @param index ES index + * @param type ES type + * + * @return count of docs + */ + public long getTotalCountForListingAsset(String index, String type); + + /** + * Fetches the created date for the give resourceId. + * + * @param resourceId id of the resource + * @param resourceType type of the resource + * + * @return created date as string + */ + public String getResourceCreatedDate(String resourceId, String resourceType); + + /** + * Fetches the data type info maintained in RDS for the given resourceId. + * + * @param resourceId id of the resource + * + * @return list of data type info + * @throws ServiceException when the datatype is not maintained in RDS + */ + public List> getDataTypeInfoByTargetType(String resourceId) throws ServiceException; + + /** + * Fetches all application details by asset group name + * + * @param assetGroup - valid assetGroup id + * + * @return ApplicationDetailsResponse - valid and invalid application details list + * @throws DataException, JsonProcessingException + */ + public ApplicationDetailsResponse getApplicationDetailsByAssetGroup(String assetGroup, String applicationName) throws DataException, JsonProcessingException, Exception; + + /** + * Gets the all cost types. + * + * @return the all cost types + */ + List> getAllCostTypes(); + +} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetServiceImpl.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetServiceImpl.java index 58b8a600f..a97972b52 100644 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetServiceImpl.java +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetServiceImpl.java @@ -1,952 +1,1082 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ -package com.tmobile.pacman.api.asset.service; - -import java.io.IOException; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.StringTokenizer; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - -import org.apache.commons.lang.StringUtils; -import org.apache.http.ParseException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.cache.annotation.Cacheable; -import org.springframework.stereotype.Service; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.tmobile.pacman.api.asset.AssetConstants; -import com.tmobile.pacman.api.asset.domain.ResponseWithFieldsByTargetType; -import com.tmobile.pacman.api.asset.model.DefaultUserAssetGroup; -import com.tmobile.pacman.api.asset.repository.AssetRepository; -import com.tmobile.pacman.api.commons.Constants; -import com.tmobile.pacman.api.commons.exception.DataException; -import com.tmobile.pacman.api.commons.exception.NoDataFoundException; -import com.tmobile.pacman.api.commons.exception.ServiceException; -import com.tmobile.pacman.api.commons.utils.PacHttpUtils; - -/** - * Implemented class for AssetService and all its method - */ -@Service -public class AssetServiceImpl implements AssetService { - - private static final Logger LOGGER = LoggerFactory.getLogger(AssetServiceImpl.class); - - @Autowired - private AssetRepository repository; - - @Value("${cloudinsights.tokenurl}") - String insightsTokenUrl; - - @Value("${cloudinsights.costurl}") - String insightsCostUrl; - - @Value("${cloudinsights.corp-user-id}") - String svcCorpUserId; - - @Value("${cloudinsights.corp-password}") - String svcCorpPassword; - - @Override - public List> getAssetCountByAssetGroup(String assetGroup, String type, String domain) { - // TODO : Need to see if its better to get the count based on target - // types in domain. Currently we are fetching everything and filtering - // the unwanted one. - LOGGER.debug("Fetch counts from elastic search"); - - // ES query may possibly return other types as well. - Map countMap = repository.getAssetCountByAssetGroup(assetGroup, type); - - if (AssetConstants.ALL.equals(type)) { - LOGGER.debug("Remove the entries which are not valid types"); - List> targetTypes = getTargetTypesForAssetGroup(assetGroup, domain); - List validTypes = targetTypes.stream().map(obj -> obj.get(Constants.TYPE).toString()) - .collect(Collectors.toList()); - List countTypes = new ArrayList<>(countMap.keySet()); - for (String _type : validTypes) { - if (!countMap.containsKey(_type)) { - countMap.put(_type, 0L); - } - } - - for (String _type : countTypes) { - if (!validTypes.contains(_type)) { - countMap.remove(_type); - } - } - } - - LOGGER.debug("Creating response objects "); - List> countList = new ArrayList<>(); - countMap.entrySet().stream().forEach(entry -> { - Map typeMap = new HashMap<>(); - typeMap.put(Constants.TYPE, entry.getKey()); - typeMap.put(Constants.COUNT, entry.getValue()); - countList.add(typeMap); - }); - - return countList; - } - - @Override - @Cacheable(cacheNames = "assets", unless = "#result == null") - public List> getTargetTypesForAssetGroup(String assetGroup, String domain) { - if (Constants.AWS.equals(assetGroup)) { - return repository.getAllTargetTypes(); - } else { - return repository.getTargetTypesByAssetGroup(assetGroup, domain); - } - } - - @Override - public List> getApplicationsByAssetGroup(String assetGroup, String domain) throws DataException { - - List applications ; - if (StringUtils.isEmpty(domain)) { - applications = repository.getApplicationByAssetGroup(assetGroup); - } else { - applications = repository.getApplicationByAssetGroup(assetGroup, domain); - } - - List> applicationList = new ArrayList<>(); - applications.forEach(app -> { - Map appMap = new HashMap<>(); - appMap.put(Constants.NAME, app); - applicationList.add(appMap); - }); - return applicationList; - } - - @Override - public List> getEnvironmentsByAssetGroup(String assetGroup, String application, String domain) { - List environments = repository.getEnvironmentsByAssetGroup(assetGroup, application, domain); - List> envList = new ArrayList<>(); - environments.forEach(env -> { - Map envMapp = new HashMap<>(); - envMapp.put(Constants.NAME, env); - envList.add(envMapp); - }); - return envList; - } - - @Override - public List> getAllAssetGroups() { - List> assetGroups = repository.getAllAssetGroups(); - List> assetGroupDomains = repository.getAssetGroupAndDomains(); - Map> agDomainMap = new ConcurrentHashMap<>(); - assetGroupDomains.parallelStream().forEach(obj -> { - String groupName = obj.get(Constants.NAME).toString(); - String domain = obj.get(Constants.DOMAIN).toString(); - List domains = agDomainMap.get(groupName); - if (domains == null) { - domains = new ArrayList<>(); - agDomainMap.put(groupName, domains); - } - domains.add(domain); - }); - assetGroups.parallelStream().forEach( - obj -> obj.put("domains", agDomainMap.get(obj.get(Constants.NAME).toString()))); - return assetGroups; - } - - @Override - public Map getAssetGroupInfo(String assetGroup) { - Map assetGroupInfoMap = repository.getAssetGroupInfo(assetGroup); - if (!assetGroupInfoMap.isEmpty()) { - List applications = new ArrayList<>(); - try { - applications = repository.getApplicationByAssetGroup(assetGroup, null); - } catch (Exception e) { - LOGGER.error("Error in getAssetGroupInfo " , e); - } - assetGroupInfoMap.put("appcount", applications.size()); - List> countMap = getAssetCountByAssetGroup(assetGroup, AssetConstants.ALL, null); - assetGroupInfoMap.put("assetcount", - countMap.stream().mapToLong(obj -> Long.valueOf(obj.get(Constants.COUNT).toString())).sum()); - assetGroupInfoMap.put("domains", getDomains(assetGroup)); - } - return assetGroupInfoMap; - } - - @Override - public List> getAssetCountByApplication(String assetGroup, String type) throws DataException { - Map countMap = repository.getAssetCountByApplication(assetGroup, type); - List> countList = new ArrayList<>(); - countMap.entrySet().stream().forEach(entry -> { - Map typeMap = new HashMap<>(); - typeMap.put("application", entry.getKey()); - typeMap.put(Constants.COUNT, entry.getValue()); - countList.add(typeMap); - }); - return countList; - - } - - @Override - public List> getAssetMinMax(String assetGroup, String type, Date from, Date to) { - return repository.getAssetMinMax(assetGroup, type, from, to); - } - - @Override - public Boolean saveOrUpdateAssetGroup(final DefaultUserAssetGroup defaultUserAssetGroup) { - int response = repository.saveOrUpdateAssetGroup(defaultUserAssetGroup); - return response > 0 ? true : false; - } - - @Override - public String getUserDefaultAssetGroup(final String userId) { - return repository.getUserDefaultAssetGroup(userId); - } - - @Override - public List> getAssetCountByEnvironment(String assetGroup, String application, String type) { - return repository.getAssetCountByEnvironment(assetGroup, application, type); - } - - @Override - public List> saveAndAppendToRecentlyViewedAG(String userId, String assetGroup) throws DataException { - return repository.saveAndAppendAssetGroup(userId, assetGroup); - } - - @Override - public List> getListAssets(String assetGroup, Map filter, int from, int size, - String searchText) { - return repository.getListAssets(assetGroup, filter, from, size, searchText); - } - - @Override - public long getAssetCount(String assetGroup, Map filter, String searchText) { - return repository.getAssetCount(assetGroup, filter, searchText); - } - - /** - * - * @author Kanchana - * @param assetGroup - * @param instanceId - * @return - * @throws Exception - */ - public List> getInstanceCPUUtilization(String instanceId) throws DataException { - return repository.getCpuUtilizationByAssetGroupAndInstanceId(instanceId); - } - - /** - * - * @author Kanchana - * @param assetGroup - * @param instanceId - * @return - * @throws Exception - */ - public List> getInstanceDiskUtilization(String instanceId) throws DataException { - return repository.getDiskUtilizationByAssetGroupAndInstanceId(instanceId); - } - - /** - * - * @author Kanchana - * @param assetGroup - * @param instanceId - * @return - * @throws Exception - */ - public List> getInstanceSoftwareInstallDetails(String instanceId, Integer from, Integer size, - String searchText) throws DataException { - return repository.getSoftwareInstalledDetailsByAssetGroupAndInstanceId(instanceId, from, size, searchText); - } - - private List> createAttributes(Map data, String[] fields, String category) { - List> attributes = new ArrayList<>(); - - for (String field : fields) { - Map attribute = new LinkedHashMap<>(); - attribute.put(Constants.NAME, field); - String strValue = data.get(field).toString(); - attribute.put(Constants.VALUE, new String[] { strValue }); - attribute.put(Constants.CATEGORY, category); - if (StringUtils.isNotEmpty(strValue) && StringUtils.isNotBlank(strValue)) { - attributes.add(attribute); - } - } - return attributes; - } - - @Override - public List> getListAssetsPatchable(String assetGroup, Map filter) { - return repository.getListAssetsPatchable(assetGroup, filter); - } - - @Override - public List> getListAssetsTaggable(String assetGroup, Map filter) { - return repository.getListAssetsTaggable(assetGroup, filter); - } - - public Map getEc2ResourceDetail(String ag, String resourceId) throws DataException, ServiceException { - - List> rhnDataList = repository.getEc2ResourceDetailFromRhn(resourceId); - Map rhnData = null; - if (rhnDataList != null && !rhnDataList.isEmpty()) { - rhnData = repository.getEc2ResourceDetailFromRhn(resourceId).get(0); - } - - List> ec2DataList = repository.getEc2ResourceDetail(ag, resourceId); - Map ec2DetailParentMap = new LinkedHashMap<>(); - - if (null == ec2DataList || ec2DataList.isEmpty()) { - return ec2DetailParentMap; - } - - Map ec2Data = ec2DataList.get(0); - - List> attributesList = new ArrayList<>(); - - String[] fields1 = { "imageid", "subnetid", "instancetype", "accountname", "vpcid", "availabilityzone" }; - attributesList.addAll(createAttributes(ec2Data, fields1, "AWS Metadata")); - String[] fields2 = { AssetConstants.PUBLIC_IP_ADDRESS, AssetConstants.PRIVATE_IP_ADDRESS }; - attributesList.addAll(createAttributes(ec2Data, fields2, "IP Address")); - String[] fields3 = { Constants.STATE_NAME, "monitoringstate", "hostid", "statereasoncode", - "virtualizationtype", "rootdevicename", "keyname", "kernelid", Constants.STATE_NAME, "hypervisor", - "architecture", "tenancy" }; - attributesList.addAll(createAttributes(ec2Data, fields3, "AWS Attributes")); - - Map ipAddressKvPairs = new LinkedHashMap<>(); - ipAddressKvPairs - .put(AssetConstants.PUBLIC_IP_ADDRESS, ec2Data.get(AssetConstants.PUBLIC_IP_ADDRESS).toString()); - ipAddressKvPairs.put(AssetConstants.PRIVATE_IP_ADDRESS, ec2Data.get(AssetConstants.PRIVATE_IP_ADDRESS) - .toString()); - - Map tagsKvPairs = new LinkedHashMap<>(); - ec2Data.forEach((key, value) -> { - String tagsPrefix = "tags."; - if (key.startsWith(tagsPrefix)) { - tagsKvPairs.put(key.substring(tagsPrefix.length(), key.length()), value.toString()); - } - }); - - List listOfSecurityGroupIds = new ArrayList<>(); - List> securityGroupDataList = repository.getEc2ResourceSecurityGroupDetail(resourceId); - securityGroupDataList.forEach(securityGroupData -> { - listOfSecurityGroupIds.add(securityGroupData.get("securitygroupid").toString()); - }); - - List listOfVolumeIds = new ArrayList<>(); - List> volumeIdDataList = repository.getEc2ResourceBlockDevicesDetail(resourceId); - volumeIdDataList.forEach(volumeIdData -> { - listOfVolumeIds.add(volumeIdData.get("volumeid").toString()); - }); - - if (rhnData != null) { - Map attributeForLastBoot = new LinkedHashMap<>(); - attributeForLastBoot.put(Constants.NAME, "Last System Boot"); - attributeForLastBoot.put(Constants.VALUE, Arrays.asList(rhnData.get("last_boot"))); - attributeForLastBoot.put(Constants.CATEGORY, "RHN INFO"); - addAttributeIfNotEmpty(attributeForLastBoot, attributesList); - - Map attributeForLastCheckedIn = new LinkedHashMap<>(); - attributeForLastCheckedIn.put(Constants.NAME, "Last Checked In"); - attributeForLastCheckedIn.put(Constants.VALUE, Arrays.asList(rhnData.get("last_checkin"))); - attributeForLastCheckedIn.put(Constants.CATEGORY, "RHN INFO"); - addAttributeIfNotEmpty(attributeForLastCheckedIn, attributesList); - } - - Map attributeForVolumes = new LinkedHashMap<>(); - attributeForVolumes.put(Constants.NAME, "EBS Volumes"); - attributeForVolumes.put(Constants.VALUE, listOfVolumeIds); - attributeForVolumes.put(Constants.CATEGORY, AssetConstants.RELATED_ASSETS); - addAttributeIfNotEmpty(attributeForVolumes, attributesList); - - Map attributeForSG = new LinkedHashMap<>(); - attributeForSG.put(Constants.NAME, "Security Groups"); - attributeForSG.put(Constants.VALUE, listOfSecurityGroupIds); - attributeForSG.put(Constants.CATEGORY, AssetConstants.RELATED_ASSETS); - addAttributeIfNotEmpty(attributeForSG, attributesList); - - Object publicIp = ec2Data.get(AssetConstants.PUBLIC_IP_ADDRESS); - if (publicIp != null && StringUtils.isNotEmpty(publicIp.toString())) { - Map attributeForPublicIP = new LinkedHashMap<>(); - List listOfPublicIPs = new ArrayList<>(); - listOfPublicIPs.add(publicIp.toString()); - attributeForPublicIP.put(Constants.NAME, "Public IPs"); - attributeForPublicIP.put(Constants.VALUE, listOfPublicIPs); - attributeForPublicIP.put(Constants.CATEGORY, AssetConstants.RELATED_ASSETS); - addAttributeIfNotEmpty(attributeForPublicIP, attributesList); - } - - Object instanceProfile = ec2Data.get("iaminstanceprofilearn"); - if (instanceProfile != null && StringUtils.isNotEmpty(instanceProfile.toString())) { - Map attributeForInstancesRole = new LinkedHashMap<>(); - attributeForInstancesRole.put(Constants.NAME, "Instance Roles"); - attributeForInstancesRole.put(Constants.VALUE, instanceProfile); - attributeForInstancesRole.put(Constants.CATEGORY, AssetConstants.RELATED_ASSETS); - addAttributeIfNotEmpty(attributeForInstancesRole, attributesList); - } - - try { - Map createInfo = repository.getResourceCreateInfo(resourceId); - if (createInfo != null) { - String[] attrFields = { AssetConstants.CREATED_BY, AssetConstants.CREATION_DATE, AssetConstants.EMAIL }; - attributesList.addAll(createAttributes(createInfo, attrFields, "Creators")); - } - } catch (Exception e) { - LOGGER.error("Error Fetching created info for resource " + resourceId , e); - throw new ServiceException(e); - } - - // Qualys was earlier a separate api. Lets add it to the generic EC2 API - // just like RHN INFO - A separate category - try { - attributesList.addAll(getResourceQualysDetail(resourceId)); - } catch (Exception e) { - LOGGER.error("Exception in getEc2ResourceDetail ",e); - throw new ServiceException(e); - } - - ec2DetailParentMap.put("resourceId", resourceId); - ec2DetailParentMap.put("tags", tagsKvPairs); - ec2DetailParentMap.put("attributes", attributesList); - - return ec2DetailParentMap; - - } - - private void addAttributeIfNotEmpty(Map attribute, List> attributesList) { - Object value = attribute.get(Constants.VALUE); - - if (value instanceof List) { - if (!((List) value).isEmpty()) { - attributesList.add(attribute); - } - - } else { - if (StringUtils.isNotEmpty(value.toString()) && StringUtils.isNotBlank(value.toString())) { - - attributesList.add(attribute); - } - } - } - - @Override - public Map getGenericResourceDetail(String ag, String resourceType, String resourceId) - throws DataException { - - Map assetDetailMap = new LinkedHashMap<>(); - - List> resourceDataList = repository.getResourceDetail(ag, resourceType, resourceId); - - if (null == resourceDataList || resourceDataList.isEmpty()) { - return assetDetailMap; - } - - Map resourceData = resourceDataList.get(0); - - List> attributesList = new ArrayList<>(); - Map tagsKvPairs = new LinkedHashMap<>(); - - List fieldsToBeSkipped = Arrays.asList(Constants.RESOURCEID, Constants.DOCID, - AssetConstants.UNDERSCORE_DISCOVERY_DATE, AssetConstants.DISCOVERY_DATE, - AssetConstants.FIRST_DISCOVEREDON, Constants._ID, AssetConstants.UNDERSCORE_ENTITY, - AssetConstants.UNDERSCORE_ENTITY_TYPE, Constants.LATEST, AssetConstants.UNDERSCORE_LOADDATE); - - resourceData.forEach((key, value) -> { - - if (!fieldsToBeSkipped.contains(key) && StringUtils.isNotBlank(value.toString())) { - - String tagsPrefix = "tags."; - if (key.startsWith(tagsPrefix)) { - tagsKvPairs.put(key.substring(tagsPrefix.length(), key.length()), value.toString()); - } else { - - Map attribute = new LinkedHashMap<>(); - attribute.put(Constants.NAME, key); - attribute.put(Constants.VALUE, new String[] { value.toString() }); - attribute.put(Constants.CATEGORY, ""); - attributesList.add(attribute); - } - } - }); - - try { - Map createInfo = repository.getResourceCreateInfo(resourceId); - if (createInfo != null) { - String[] attrFields = { AssetConstants.CREATED_BY, AssetConstants.CREATION_DATE, AssetConstants.EMAIL }; - attributesList.addAll(createAttributes(createInfo, attrFields, "Creators")); - } - } catch (Exception e) { - LOGGER.error("Error Fetching created info for resrouce " + resourceId , e); - } - assetDetailMap.put("tags", tagsKvPairs); - assetDetailMap.put("attributes", attributesList); - - return assetDetailMap; - } - - @Override - public List> getListAssetsVulnerable(String assetGroup, Map filter) { - return repository.getListAssetsVulnerable(assetGroup, filter); - } - - public List> getOpenPortDetails(String instanceId, Integer from, Integer size, String searchText) - throws DataException { - return repository.getOpenPortDetailsByInstanceId(instanceId, from, size, searchText); - } - - @Override - public List> getListAssetsScanned(String assetGroup, Map filter) { - return repository.getListAssetsScanned(assetGroup, filter); - } - - @Override - public String getEc2StateDetail(String ag, String resourceId) throws DataException { - List> ec2Details = repository.getEc2ResourceDetail(ag, resourceId); - if (ec2Details != null && !ec2Details.isEmpty()) { - return ec2Details.get(0).get(Constants.STATE_NAME).toString(); - } - return ""; - - } - - @Override - public List> getNotificationSummary(String instanceId) throws DataException { - Map summaryAggregationMap = repository.getNotificationSummary(instanceId); - - List> sevList = new ArrayList<>(); - - addStatusCountsForStatus(sevList, summaryAggregationMap, "open"); - addStatusCountsForStatus(sevList, summaryAggregationMap, "closed"); - addStatusCountsForStatus(sevList, summaryAggregationMap, "upcoming"); - - return sevList; - } - - private void addStatusCountsForStatus(List> sevList, Map summaryAggregationMap, - String status) { - Map sevInfo = new LinkedHashMap<>(); - - sevInfo.put("status", status); - if (null != summaryAggregationMap.get(status) - && StringUtils.isNotBlank(summaryAggregationMap.get(status).toString())) { - sevInfo.put(Constants.COUNT, summaryAggregationMap.get(status).toString()); - } else { - sevInfo.put(Constants.COUNT, "0"); - } - sevList.add(sevInfo); - - } - - @Override - public String getNotificationSummaryTotal(List> sevList) throws DataException { - - List numList = new ArrayList<>(); - sevList.forEach(sevInfo -> numList.add(Integer.parseInt(sevInfo.get(Constants.COUNT).toString()))); - - int total = 0; - for (int num : numList) { - total += num; - } - return Integer.toString(total); - } - - @Override - public Integer saveAssetConfig(String resourceId, String configType, String config) { - return repository.saveAssetConfig(resourceId, configType, config); - } - - @Override - public String retrieveAssetConfig(String resourceId, String configType) { - return repository.retrieveAssetConfig(resourceId, configType); - } - - @Override - public List> getResourceQualysDetail(String resourceId) throws DataException { - - List> qualysDataList = repository.getQualysDetail(resourceId); - - List> attributesList = new ArrayList<>(); - - if (null == qualysDataList || qualysDataList.isEmpty()) { - return attributesList; - } - - Map qualysData = qualysDataList.get(0); - - List fieldsToBeSkipped = Arrays.asList(Constants.RESOURCEID, Constants.DOCID, - AssetConstants.UNDERSCORE_DISCOVERY_DATE, AssetConstants.DISCOVERY_DATE, - AssetConstants.FIRST_DISCOVEREDON, Constants._ID, AssetConstants.UNDERSCORE_ENTITY, - AssetConstants.UNDERSCORE_ENTITY_TYPE, Constants.LATEST, Constants.ES_DOC_ROUTING_KEY, - Constants.ES_DOC_PARENT_KEY); - - qualysData.forEach((key, value) -> { - if (!fieldsToBeSkipped.contains(key) && StringUtils.isNotBlank(value.toString())) { - - Map attribute = new LinkedHashMap<>(); - attribute.put(Constants.NAME, key); - attribute.put(Constants.VALUE, new String[] { value.toString() }); - attribute.put(Constants.CATEGORY, "QUALYS INFO"); - - if ("list".equals(key) && value.toString().contains(AssetConstants.USERNAME)) { - attribute = createUserListAttributeFromQualysData(value.toString()); - } - - attributesList.add(attribute); - } - }); - - return attributesList; - - } - - private Map createUserListAttributeFromQualysData(String usernameJsonString) { - List userNameList = new ArrayList<>(); - JsonParser jsonParser = new JsonParser(); - JsonArray usernameArray = (JsonArray) jsonParser.parse(usernameJsonString); - for (JsonElement usernameElement : usernameArray) { - - JsonObject userNameJsonObj = usernameElement.getAsJsonObject(); - - String username = userNameJsonObj.get(AssetConstants.USERNAME).toString(); - if (!(username.contains("ec2-user") || (username.contains("root")))) { - userNameList.add(username); - } - } - - Map attribute = new LinkedHashMap<>(); - attribute.put(Constants.NAME, AssetConstants.USERNAME); - attribute.put(Constants.VALUE, userNameList); - attribute.put(Constants.CATEGORY, "QUALYS INFO"); - - return attribute; - } - - @Override - public List> getAdGroupsDetail(String ag, String resourceId) throws DataException { - - List> matchingAdGroups = new ArrayList<>(); - - List> ec2DataList = repository.getEc2ResourceDetail(ag, resourceId); - - if (null == ec2DataList || ec2DataList.isEmpty()) { - return matchingAdGroups; - } - - Map ec2Data = ec2DataList.get(0); - Object nameTagValueObj = ec2Data.get("tags.Name"); - String nameTagValue = ""; - if (null != nameTagValueObj) { - nameTagValue = nameTagValueObj.toString(); - } - - LOGGER.info("EC2 Tag value is: {}" , nameTagValue); - - String platform = ec2Data.get("platform").toString(); - - LOGGER.info("EC2 Tag value is: {}" , nameTagValue); - - StringTokenizer stTknzr = new StringTokenizer(nameTagValue, "-"); - String envSectionOfTag = ""; - String ouSectionOfTag = ""; - - String ouAndEnvOfTag = ""; - try { - // First token is env. Second is ou. - envSectionOfTag = stTknzr.nextToken(); - ouSectionOfTag = stTknzr.nextToken(); - ouAndEnvOfTag = ouSectionOfTag + "_" + envSectionOfTag + "_"; - } catch (NoSuchElementException e) { - LOGGER.error("Error in getAdGroupsDetail" , e); - ouAndEnvOfTag = ""; - } - - LOGGER.info("Resource id : {}",resourceId); - LOGGER.info("OU and ENV section of Name Tag of EC2 instance is: {}" , ouAndEnvOfTag); - - String tagValue = ouAndEnvOfTag; - - List> adDataList = repository.getAdGroupDetails(); - - if (null == adDataList || adDataList.isEmpty()) { - return matchingAdGroups; - } - - adDataList.forEach(adMap -> { - - String osString = ""; - - // For windows instances, consider only group names which - // have 'r_win' in them - // if platform is blank, it denotes linux. So look for group - // names which have - // 'r_rhel' - if ("windows".equalsIgnoreCase(platform)) { - osString = "r_win"; - } else { - osString = "r_rhel"; - } - Map adOutputMap = new LinkedHashMap<>(); - - String groupNameStr = adMap.get(Constants.NAME) == null ? "" : adMap.get(Constants.NAME).toString(); - String ownerNameStr = adMap.get(AssetConstants.MANAGED_BY) == null ? "" : adMap.get( - AssetConstants.MANAGED_BY).toString(); - - LOGGER.debug("Comparing the groupNameStr: {} with the value from tag:{}",groupNameStr,tagValue); - if (!StringUtils.isEmpty(tagValue) && groupNameStr.contains(tagValue) - && groupNameStr.contains(osString)) { - adOutputMap.put(Constants.NAME, groupNameStr); - adOutputMap.put(AssetConstants.MANAGED_BY, ownerNameStr); - - matchingAdGroups.add(adOutputMap); - } - - }); - - return matchingAdGroups; - } - - @Override - public List> getNotificationDetails(String instanceId, Map filters, - String searchText) throws DataException { - - List> processedNotificationList = new ArrayList<>(); - - List> notificationDataList = repository.getNotificationDetails(instanceId, filters, - searchText); - - List fieldsToBeSkipped = Arrays.asList(Constants.RESOURCEID, Constants.DOCID, - AssetConstants.UNDERSCORE_DISCOVERY_DATE, AssetConstants.DISCOVERY_DATE, - AssetConstants.FIRST_DISCOVEREDON, Constants._ID, AssetConstants.UNDERSCORE_ENTITY, - AssetConstants.UNDERSCORE_ENTITY_TYPE, Constants.LATEST); - notificationDataList.forEach(notificationDataMap -> { - Map processedNotificationMap = new LinkedHashMap<>(); - - notificationDataMap.forEach((key, value) -> { - - if (!fieldsToBeSkipped.contains(key) && StringUtils.isNotBlank(value.toString())) { - processedNotificationMap.put(key, value); - } - }); - - processedNotificationList.add(processedNotificationMap); - - }); - - return processedNotificationList; - } - - @Override - public Map getEc2CreatorDetail(String resourceId) throws DataException { - - Map creatorReturnObj = new LinkedHashMap<>(); - - try { - Map createInfo = repository.getResourceCreateInfo(resourceId); - - if (null != createInfo) { - creatorReturnObj.put(AssetConstants.CREATION_DATE, createInfo.get(AssetConstants.CREATION_DATE)); - creatorReturnObj.put(AssetConstants.CREATED_BY, createInfo.get(AssetConstants.CREATED_BY)); - creatorReturnObj.put(AssetConstants.EMAIL, createInfo.get(AssetConstants.EMAIL)); - - creatorReturnObj.put("eventInfo", createInfo); - } - return creatorReturnObj; - - } catch (Exception e) { - LOGGER.error("Error Fetching created info for resource " + resourceId , e); - } - - return null; - - } - - @Override - public Map getEC2AvgAndTotalCost(String resourceId) throws DataException { - - String corpUserId = svcCorpUserId; - String corpPassword = svcCorpPassword; - String jwtTokenGeneratorUrl = insightsTokenUrl; - String cloudInsightsBaseUrl = insightsCostUrl; - - String startDate = "2014-01-01"; - LocalDate endDateObj = LocalDate.now(); - String endDate = endDateObj.format(DateTimeFormatter.ISO_DATE); - - String requestBodyStr = "{\"username\": \"" + corpUserId + "\",\"password\": \"" + corpPassword + "\"}"; - LOGGER.info("Invoking JWT Token Generator URL: {} with requestBody as: {}",jwtTokenGeneratorUrl, requestBodyStr); - String jwtTokenJsonString; - try { - jwtTokenJsonString = PacHttpUtils.doHttpPost(jwtTokenGeneratorUrl, requestBodyStr); - } catch (Exception e) { - LOGGER.error("Exception in getEC2AvgAndTotalCost ",e); - throw new DataException(e); - } - Gson serializer = new GsonBuilder().create(); - Map tokenMap = (Map) serializer.fromJson(jwtTokenJsonString, Object.class); - String jwtToken = tokenMap.get("token"); - LOGGER.info("Received JWT Token back successfully: {}" , jwtToken); - - String cloudInsightsCostMonthlyUrl = cloudInsightsBaseUrl + resourceId + "/cost?" + "startDate=" + startDate - + "&endDate=" + endDate; - Map headers = new HashMap<>(); - headers.put("Authorization", "Bearer " + jwtToken); - LOGGER.info("Invoking Insights URL for monthly data: {}" , cloudInsightsCostMonthlyUrl); - String costResponseMonthlyStr; - try { - costResponseMonthlyStr = PacHttpUtils.getHttpGet(cloudInsightsCostMonthlyUrl, headers); - } catch (ParseException | IOException e) { - LOGGER.error(AssetConstants.ERROR_GETAPPSBYAG,e); - throw new DataException(); - } - - LOGGER.info("Received cost response monthly as: {}" , costResponseMonthlyStr); - Map costResponseMonthlyMap = (Map) serializer.fromJson(costResponseMonthlyStr, - Object.class); - - // We'll have to make the API call againto get the last week (or rather - // last 10 days) average. - - // We will ask for only last 10 days data. Ideally, it should be 7, but - // there - // might be a 1 or 2 days delay, do current and previous data might not - // have - // data in some cases - startDate = endDateObj.minusDays(Constants.TEN).format(DateTimeFormatter.ISO_DATE); - - String cloudInsightsCostDailyUrl = cloudInsightsBaseUrl + resourceId + "/cost?" + "startDate=" + startDate - + "&endDate=" + endDate; - LOGGER.info("Invoking Insights URL for daily data: {}" , cloudInsightsCostDailyUrl); - String costResponseDailyStr; - try { - costResponseDailyStr = PacHttpUtils.getHttpGet(cloudInsightsCostDailyUrl, headers); - } catch (ParseException | IOException e) { - throw new DataException(e); - } - LOGGER.info("Received cost response daily as: {}" , costResponseDailyStr); - - Map costResponseDailyMap = (Map) serializer.fromJson(costResponseDailyStr, - Object.class); - Map avgAndTotalCostMap = new LinkedHashMap<>(); - avgAndTotalCostMap.put(AssetConstants.TOTAL_COST, costResponseMonthlyMap.get(AssetConstants.TOTAL_COST)); - avgAndTotalCostMap.put("lastWeekCost", costResponseDailyMap.get(AssetConstants.TOTAL_COST)); - - return avgAndTotalCostMap; - } - - @Override - public int updateAsset(String assetGroup, String targettype, Map resources, String updatedBy, - List> updates) throws DataException { - try { - return repository.updateAsset(assetGroup, targettype, resources, updatedBy, updates); - } catch (NoDataFoundException e) { - LOGGER.error(AssetConstants.ERROR_GETAPPSBYAG,e); - throw new DataException(e); - } - } - - @Override - public List> getAssetLists(String assetGroup, Map filter, int from, int size, - String searchText) { - return repository.getAssetLists(assetGroup, filter, from, size, searchText); - } - - @Override - public ResponseWithFieldsByTargetType getEditFieldsByTargetType(String resourceType) { - - List editableFieldsList = new ArrayList<>(); - JsonParser jsonParser = new JsonParser(); - String field = null; - - String dataTypeInfo = repository.getDataTypeInfoByTargetType(resourceType); - - if (dataTypeInfo != null) { - JsonObject datatypeInfoJson = (JsonObject) jsonParser.parse(dataTypeInfo); - JsonObject dataTypes = datatypeInfoJson.get("dataTypes_info").getAsJsonObject(); - Iterator it = dataTypes.keySet().iterator(); - while (it.hasNext()) { - field = it.next(); - editableFieldsList.add(field); - } - } - - return new ResponseWithFieldsByTargetType(resourceType, editableFieldsList); - } - - public long getTotalCountForListingAsset(String index, String type) { - return repository.getTotalCountForListingAsset(index, type); - } - - @Override - public String getResourceCreatedDate(String resourceId, String resourceType) { - return repository.getResourceCreatedDate(resourceId, resourceType); - } - - private List getDomains(String assetGroup) { - List> domains = repository.getDomainsByAssetGroup(assetGroup); - List domainsList = new ArrayList<>(); - if (!domains.isEmpty()) { - domainsList = domains.stream().map(obj -> obj.get(Constants.DOMAIN).toString()) - .collect(Collectors.toList()); - } - return domainsList; - } - - @Override - public List> getDataTypeInfoByTargetType(String resourceType) throws ServiceException { - JsonParser jsonParser = new JsonParser(); - String field = null; - String datatype = null; - Map editablefieldsAndValues = new HashMap<>(); - List> dataTypeList = new ArrayList<>(); - - String dataTypeInfo = repository.getDataTypeInfoByTargetType(resourceType); - - if (dataTypeInfo != null) { - JsonObject datatypeInfoJson = (JsonObject) jsonParser.parse(dataTypeInfo); - JsonObject dataTypes = datatypeInfoJson.get("dataTypes_info").getAsJsonObject(); - Iterator it = dataTypes.keySet().iterator(); - while (it.hasNext()) { - field = it.next(); - if (!dataTypes.get(field).isJsonNull()) { - datatype = dataTypes.get(field).getAsString(); - editablefieldsAndValues.put(field, datatype); - } else { - throw new ServiceException("datatype not maintained in RDS"); - } - } - if (!editablefieldsAndValues.isEmpty()) { - dataTypeList.add(editablefieldsAndValues); - } - } - return dataTypeList; - } -} +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.api.asset.service; + +import java.io.IOException; +import java.time.LocalDate; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.collect.Lists; + +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.StringTokenizer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +import org.apache.commons.lang.StringUtils; +import org.apache.http.ParseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.tmobile.pacman.api.asset.AssetConstants; +import com.tmobile.pacman.api.asset.domain.ApplicationDetail; +import com.tmobile.pacman.api.asset.domain.ApplicationDetailsESResponse; +import com.tmobile.pacman.api.asset.domain.ApplicationDetailsResponse; +import com.tmobile.pacman.api.asset.domain.ApplicationESDetail; +import com.tmobile.pacman.api.asset.domain.Organization; +import com.tmobile.pacman.api.asset.domain.ResponseWithFieldsByTargetType; +import com.tmobile.pacman.api.asset.model.DefaultUserAssetGroup; +import com.tmobile.pacman.api.asset.repository.AssetRepository; +import com.tmobile.pacman.api.commons.Constants; +import com.tmobile.pacman.api.commons.exception.DataException; +import com.tmobile.pacman.api.commons.exception.NoDataFoundException; +import com.tmobile.pacman.api.commons.exception.ServiceException; +import com.tmobile.pacman.api.commons.utils.PacHttpUtils; + +/** + * Implemented class for AssetService and all its method + */ +@Service +public class AssetServiceImpl implements AssetService { + + private static final Logger LOGGER = LoggerFactory.getLogger(AssetServiceImpl.class); + + @Autowired + private AssetRepository repository; + + @Value("${cloudinsights.tokenurl}") + String insightsTokenUrl; + + @Value("${cloudinsights.costurl}") + String insightsCostUrl; + + @Value("${cloudinsights.corp-user-id}") + String svcCorpUserId; + + @Value("${cloudinsights.corp-password}") + String svcCorpPassword; + + @Override + public List> getAssetCountByAssetGroup(String assetGroup, String type, String domain) { + // TODO : Need to see if its better to get the count based on target + // types in domain. Currently we are fetching everything and filtering + // the unwanted one. + LOGGER.debug("Fetch counts from elastic search"); + + // ES query may possibly return other types as well. + Map countMap = repository.getAssetCountByAssetGroup(assetGroup, type); + + if (AssetConstants.ALL.equals(type)) { + LOGGER.debug("Remove the entries which are not valid types"); + List> targetTypes = getTargetTypesForAssetGroup(assetGroup, domain); + List validTypes = targetTypes.stream().map(obj -> obj.get(Constants.TYPE).toString()) + .collect(Collectors.toList()); + List countTypes = new ArrayList<>(countMap.keySet()); + for (String _type : validTypes) { + if (!countMap.containsKey(_type)) { + countMap.put(_type, 0L); + } + } + + for (String _type : countTypes) { + if (!validTypes.contains(_type)) { + countMap.remove(_type); + } + } + } + + LOGGER.debug("Creating response objects "); + List> countList = new ArrayList<>(); + countMap.entrySet().stream().forEach(entry -> { + Map typeMap = new HashMap<>(); + typeMap.put(Constants.TYPE, entry.getKey()); + typeMap.put(Constants.COUNT, entry.getValue()); + countList.add(typeMap); + }); + + return countList; + } + + @Override + @Cacheable(cacheNames = "assets", unless = "#result == null") + public List> getTargetTypesForAssetGroup(String assetGroup, String domain) { + if (Constants.AWS.equals(assetGroup)) { + return repository.getAllTargetTypes(); + } else { + return repository.getTargetTypesByAssetGroup(assetGroup, domain); + } + } + + @Override + public List> getApplicationsByAssetGroup(String assetGroup, String domain) throws DataException { + + List applications ; + if (StringUtils.isEmpty(domain)) { + applications = repository.getApplicationByAssetGroup(assetGroup); + } else { + applications = repository.getApplicationByAssetGroup(assetGroup, domain); + } + + List> applicationList = new ArrayList<>(); + applications.forEach(app -> { + Map appMap = new HashMap<>(); + appMap.put(Constants.NAME, app); + applicationList.add(appMap); + }); + return applicationList; + } + + @Override + public List> getEnvironmentsByAssetGroup(String assetGroup, String application, String domain) { + List environments = repository.getEnvironmentsByAssetGroup(assetGroup, application, domain); + List> envList = new ArrayList<>(); + environments.forEach(env -> { + Map envMapp = new HashMap<>(); + envMapp.put(Constants.NAME, env); + envList.add(envMapp); + }); + return envList; + } + + @Override + public List> getAllAssetGroups() { + List> assetGroups = repository.getAllAssetGroups(); + List> assetGroupDomains = repository.getAssetGroupAndDomains(); + Map> agDomainMap = new ConcurrentHashMap<>(); + assetGroupDomains.parallelStream().forEach(obj -> { + String groupName = obj.get(Constants.NAME).toString(); + String domain = obj.get(Constants.DOMAIN).toString(); + List domains = agDomainMap.get(groupName); + if (domains == null) { + domains = new ArrayList<>(); + agDomainMap.put(groupName, domains); + } + domains.add(domain); + }); + assetGroups.parallelStream().forEach( + obj -> obj.put("domains", agDomainMap.get(obj.get(Constants.NAME).toString()))); + return assetGroups; + } + + @Override + public Map getAssetGroupInfo(String assetGroup) { + Map assetGroupInfoMap = repository.getAssetGroupInfo(assetGroup); + if (!assetGroupInfoMap.isEmpty()) { + List applications = new ArrayList<>(); + try { + applications = repository.getApplicationByAssetGroup(assetGroup, null); + } catch (Exception e) { + LOGGER.error("Error in getAssetGroupInfo " , e); + } + assetGroupInfoMap.put("appcount", applications.size()); + List> countMap = getAssetCountByAssetGroup(assetGroup, AssetConstants.ALL, null); + assetGroupInfoMap.put("assetcount", + countMap.stream().mapToLong(obj -> Long.valueOf(obj.get(Constants.COUNT).toString())).sum()); + assetGroupInfoMap.put("domains", getDomains(assetGroup)); + } + return assetGroupInfoMap; + } + + @Override + public List> getAssetCountByApplication(String assetGroup, String type) throws DataException { + Map countMap = repository.getAssetCountByApplication(assetGroup, type); + List> countList = new ArrayList<>(); + countMap.entrySet().stream().forEach(entry -> { + Map typeMap = new HashMap<>(); + typeMap.put("application", entry.getKey()); + typeMap.put(Constants.COUNT, entry.getValue()); + countList.add(typeMap); + }); + return countList; + + } + + @Override + public List> getAssetMinMax(String assetGroup, String type, Date from, Date to) { + return repository.getAssetMinMax(assetGroup, type, from, to); + } + + @Override + public Boolean saveOrUpdateAssetGroup(final DefaultUserAssetGroup defaultUserAssetGroup) { + int response = repository.saveOrUpdateAssetGroup(defaultUserAssetGroup); + return response > 0 ? true : false; + } + + @Override + public String getUserDefaultAssetGroup(final String userId) { + return repository.getUserDefaultAssetGroup(userId); + } + + @Override + public List> getAssetCountByEnvironment(String assetGroup, String application, String type) { + return repository.getAssetCountByEnvironment(assetGroup, application, type); + } + + @Override + public List> saveAndAppendToRecentlyViewedAG(String userId, String assetGroup) throws DataException { + return repository.saveAndAppendAssetGroup(userId, assetGroup); + } + + @Override + public List> getListAssets(String assetGroup, Map filter, int from, int size, + String searchText) { + return repository.getListAssets(assetGroup, filter, from, size, searchText); + } + + @Override + public long getAssetCount(String assetGroup, Map filter, String searchText) { + return repository.getAssetCount(assetGroup, filter, searchText); + } + + /** + * + * @author Kanchana + * @param assetGroup + * @param instanceId + * @return + * @throws Exception + */ + public List> getInstanceCPUUtilization(String instanceId) throws DataException { + return repository.getCpuUtilizationByAssetGroupAndInstanceId(instanceId); + } + + /** + * + * @author Kanchana + * @param assetGroup + * @param instanceId + * @return + * @throws Exception + */ + public List> getInstanceDiskUtilization(String instanceId) throws DataException { + return repository.getDiskUtilizationByAssetGroupAndInstanceId(instanceId); + } + + /** + * + * @author Kanchana + * @param assetGroup + * @param instanceId + * @return + * @throws Exception + */ + public List> getInstanceSoftwareInstallDetails(String instanceId, Integer from, Integer size, + String searchText) throws DataException { + return repository.getSoftwareInstalledDetailsByAssetGroupAndInstanceId(instanceId, from, size, searchText); + } + + private List> createAttributes(Map data, String[] fields, String category) { + List> attributes = new ArrayList<>(); + + for (String field : fields) { + Map attribute = new LinkedHashMap<>(); + attribute.put(Constants.NAME, field); + String strValue = data.get(field).toString(); + attribute.put(Constants.VALUE, new String[] { strValue }); + attribute.put(Constants.CATEGORY, category); + if (StringUtils.isNotEmpty(strValue) && StringUtils.isNotBlank(strValue)) { + attributes.add(attribute); + } + } + return attributes; + } + + @Override + public List> getListAssetsPatchable(String assetGroup, Map filter) { + return repository.getListAssetsPatchable(assetGroup, filter); + } + + @Override + public List> getListAssetsTaggable(String assetGroup, Map filter) { + return repository.getListAssetsTaggable(assetGroup, filter); + } + + public Map getEc2ResourceDetail(String ag, String resourceId) throws DataException, ServiceException { + + List> rhnDataList = repository.getEc2ResourceDetailFromRhn(resourceId); + Map rhnData = null; + if (rhnDataList != null && !rhnDataList.isEmpty()) { + rhnData = repository.getEc2ResourceDetailFromRhn(resourceId).get(0); + } + + List> ec2DataList = repository.getEc2ResourceDetail(ag, resourceId); + Map ec2DetailParentMap = new LinkedHashMap<>(); + + if (null == ec2DataList || ec2DataList.isEmpty()) { + return ec2DetailParentMap; + } + + Map ec2Data = ec2DataList.get(0); + + List> attributesList = new ArrayList<>(); + + String[] fields1 = { "imageid", "subnetid", "instancetype", "accountname", "vpcid", "availabilityzone" }; + attributesList.addAll(createAttributes(ec2Data, fields1, "AWS Metadata")); + String[] fields2 = { AssetConstants.PUBLIC_IP_ADDRESS, AssetConstants.PRIVATE_IP_ADDRESS }; + attributesList.addAll(createAttributes(ec2Data, fields2, "IP Address")); + String[] fields3 = { Constants.STATE_NAME, "monitoringstate", "hostid", "statereasoncode", + "virtualizationtype", "rootdevicename", "keyname", "kernelid", Constants.STATE_NAME, "hypervisor", + "architecture", "tenancy" }; + attributesList.addAll(createAttributes(ec2Data, fields3, "AWS Attributes")); + + Map ipAddressKvPairs = new LinkedHashMap<>(); + ipAddressKvPairs + .put(AssetConstants.PUBLIC_IP_ADDRESS, ec2Data.get(AssetConstants.PUBLIC_IP_ADDRESS).toString()); + ipAddressKvPairs.put(AssetConstants.PRIVATE_IP_ADDRESS, ec2Data.get(AssetConstants.PRIVATE_IP_ADDRESS) + .toString()); + + Map tagsKvPairs = new LinkedHashMap<>(); + ec2Data.forEach((key, value) -> { + String tagsPrefix = "tags."; + if (key.startsWith(tagsPrefix)) { + tagsKvPairs.put(key.substring(tagsPrefix.length(), key.length()), value.toString()); + } + }); + + List listOfSecurityGroupIds = new ArrayList<>(); + List> securityGroupDataList = repository.getEc2ResourceSecurityGroupDetail(resourceId); + securityGroupDataList.forEach(securityGroupData -> { + listOfSecurityGroupIds.add(securityGroupData.get("securitygroupid").toString()); + }); + + List listOfVolumeIds = new ArrayList<>(); + List> volumeIdDataList = repository.getEc2ResourceBlockDevicesDetail(resourceId); + volumeIdDataList.forEach(volumeIdData -> { + listOfVolumeIds.add(volumeIdData.get("volumeid").toString()); + }); + + if (rhnData != null) { + Map attributeForLastBoot = new LinkedHashMap<>(); + attributeForLastBoot.put(Constants.NAME, "Last System Boot"); + attributeForLastBoot.put(Constants.VALUE, Arrays.asList(rhnData.get("last_boot"))); + attributeForLastBoot.put(Constants.CATEGORY, "RHN INFO"); + addAttributeIfNotEmpty(attributeForLastBoot, attributesList); + + Map attributeForLastCheckedIn = new LinkedHashMap<>(); + attributeForLastCheckedIn.put(Constants.NAME, "Last Checked In"); + attributeForLastCheckedIn.put(Constants.VALUE, Arrays.asList(rhnData.get("last_checkin"))); + attributeForLastCheckedIn.put(Constants.CATEGORY, "RHN INFO"); + addAttributeIfNotEmpty(attributeForLastCheckedIn, attributesList); + } + + Map attributeForVolumes = new LinkedHashMap<>(); + attributeForVolumes.put(Constants.NAME, "EBS Volumes"); + attributeForVolumes.put(Constants.VALUE, listOfVolumeIds); + attributeForVolumes.put(Constants.CATEGORY, AssetConstants.RELATED_ASSETS); + addAttributeIfNotEmpty(attributeForVolumes, attributesList); + + Map attributeForSG = new LinkedHashMap<>(); + attributeForSG.put(Constants.NAME, "Security Groups"); + attributeForSG.put(Constants.VALUE, listOfSecurityGroupIds); + attributeForSG.put(Constants.CATEGORY, AssetConstants.RELATED_ASSETS); + addAttributeIfNotEmpty(attributeForSG, attributesList); + + Object publicIp = ec2Data.get(AssetConstants.PUBLIC_IP_ADDRESS); + if (publicIp != null && StringUtils.isNotEmpty(publicIp.toString())) { + Map attributeForPublicIP = new LinkedHashMap<>(); + List listOfPublicIPs = new ArrayList<>(); + listOfPublicIPs.add(publicIp.toString()); + attributeForPublicIP.put(Constants.NAME, "Public IPs"); + attributeForPublicIP.put(Constants.VALUE, listOfPublicIPs); + attributeForPublicIP.put(Constants.CATEGORY, AssetConstants.RELATED_ASSETS); + addAttributeIfNotEmpty(attributeForPublicIP, attributesList); + } + + Object instanceProfile = ec2Data.get("iaminstanceprofilearn"); + if (instanceProfile != null && StringUtils.isNotEmpty(instanceProfile.toString())) { + Map attributeForInstancesRole = new LinkedHashMap<>(); + attributeForInstancesRole.put(Constants.NAME, "Instance Roles"); + attributeForInstancesRole.put(Constants.VALUE, instanceProfile); + attributeForInstancesRole.put(Constants.CATEGORY, AssetConstants.RELATED_ASSETS); + addAttributeIfNotEmpty(attributeForInstancesRole, attributesList); + } + + try { + Map createInfo = repository.getResourceCreateInfo(resourceId); + if (createInfo != null) { + String[] attrFields = { AssetConstants.CREATED_BY, AssetConstants.CREATION_DATE, AssetConstants.EMAIL }; + attributesList.addAll(createAttributes(createInfo, attrFields, "Creators")); + } + } catch (Exception e) { + LOGGER.error("Error Fetching created info for resource " + resourceId , e); + throw new ServiceException(e); + } + + // Qualys was earlier a separate api. Lets add it to the generic EC2 API + // just like RHN INFO - A separate category + try { + attributesList.addAll(getResourceQualysDetail(resourceId)); + } catch (Exception e) { + LOGGER.error("Exception in getEc2ResourceDetail ",e); + throw new ServiceException(e); + } + + ec2DetailParentMap.put("resourceId", resourceId); + ec2DetailParentMap.put("tags", tagsKvPairs); + ec2DetailParentMap.put("attributes", attributesList); + + return ec2DetailParentMap; + + } + + private void addAttributeIfNotEmpty(Map attribute, List> attributesList) { + Object value = attribute.get(Constants.VALUE); + + if (value instanceof List) { + if (!((List) value).isEmpty()) { + attributesList.add(attribute); + } + + } else { + if (StringUtils.isNotEmpty(value.toString()) && StringUtils.isNotBlank(value.toString())) { + + attributesList.add(attribute); + } + } + } + + @Override + public Map getGenericResourceDetail(String ag, String resourceType, String resourceId) + throws DataException { + + Map assetDetailMap = new LinkedHashMap<>(); + + List> resourceDataList = repository.getResourceDetail(ag, resourceType, resourceId); + + if (null == resourceDataList || resourceDataList.isEmpty()) { + return assetDetailMap; + } + + Map resourceData = resourceDataList.get(0); + + List> attributesList = new ArrayList<>(); + Map tagsKvPairs = new LinkedHashMap<>(); + + List fieldsToBeSkipped = Arrays.asList(Constants.RESOURCEID, Constants.DOCID, + AssetConstants.UNDERSCORE_DISCOVERY_DATE, AssetConstants.DISCOVERY_DATE, + AssetConstants.FIRST_DISCOVEREDON, Constants._ID, AssetConstants.UNDERSCORE_ENTITY, + AssetConstants.UNDERSCORE_ENTITY_TYPE, Constants.LATEST, AssetConstants.UNDERSCORE_LOADDATE); + + resourceData.forEach((key, value) -> { + + if (!fieldsToBeSkipped.contains(key) && StringUtils.isNotBlank(value.toString())) { + + String tagsPrefix = "tags."; + if (key.startsWith(tagsPrefix)) { + tagsKvPairs.put(key.substring(tagsPrefix.length(), key.length()), value.toString()); + } else { + + Map attribute = new LinkedHashMap<>(); + attribute.put(Constants.NAME, key); + attribute.put(Constants.VALUE, new String[] { value.toString() }); + attribute.put(Constants.CATEGORY, ""); + attributesList.add(attribute); + } + } + }); + + try { + Map createInfo = repository.getResourceCreateInfo(resourceId); + if (createInfo != null) { + String[] attrFields = { AssetConstants.CREATED_BY, AssetConstants.CREATION_DATE, AssetConstants.EMAIL }; + attributesList.addAll(createAttributes(createInfo, attrFields, "Creators")); + } + } catch (Exception e) { + LOGGER.error("Error Fetching created info for resrouce " + resourceId , e); + } + assetDetailMap.put("tags", tagsKvPairs); + assetDetailMap.put("attributes", attributesList); + + return assetDetailMap; + } + + @Override + public List> getListAssetsVulnerable(String assetGroup, Map filter) { + return repository.getListAssetsVulnerable(assetGroup, filter); + } + + public List> getOpenPortDetails(String instanceId, Integer from, Integer size, String searchText) + throws DataException { + return repository.getOpenPortDetailsByInstanceId(instanceId, from, size, searchText); + } + + @Override + public List> getListAssetsScanned(String assetGroup, Map filter) { + return repository.getListAssetsScanned(assetGroup, filter); + } + + @Override + public String getEc2StateDetail(String ag, String resourceId) throws DataException { + List> ec2Details = repository.getEc2ResourceDetail(ag, resourceId); + if (ec2Details != null && !ec2Details.isEmpty()) { + return ec2Details.get(0).get(Constants.STATE_NAME).toString(); + } + return ""; + + } + + @Override + public List> getNotificationSummary(String instanceId) throws DataException { + Map summaryAggregationMap = repository.getNotificationSummary(instanceId); + + List> sevList = new ArrayList<>(); + + addStatusCountsForStatus(sevList, summaryAggregationMap, "open"); + addStatusCountsForStatus(sevList, summaryAggregationMap, "closed"); + addStatusCountsForStatus(sevList, summaryAggregationMap, "upcoming"); + + return sevList; + } + + private void addStatusCountsForStatus(List> sevList, Map summaryAggregationMap, + String status) { + Map sevInfo = new LinkedHashMap<>(); + + sevInfo.put("status", status); + if (null != summaryAggregationMap.get(status) + && StringUtils.isNotBlank(summaryAggregationMap.get(status).toString())) { + sevInfo.put(Constants.COUNT, summaryAggregationMap.get(status).toString()); + } else { + sevInfo.put(Constants.COUNT, "0"); + } + sevList.add(sevInfo); + + } + + @Override + public String getNotificationSummaryTotal(List> sevList) throws DataException { + + List numList = new ArrayList<>(); + sevList.forEach(sevInfo -> numList.add(Integer.parseInt(sevInfo.get(Constants.COUNT).toString()))); + + int total = 0; + for (int num : numList) { + total += num; + } + return Integer.toString(total); + } + + @Override + public Integer saveAssetConfig(String resourceId, String configType, String config) { + return repository.saveAssetConfig(resourceId, configType, config); + } + + @Override + public String retrieveAssetConfig(String resourceId, String configType) { + return repository.retrieveAssetConfig(resourceId, configType); + } + + @Override + public List> getResourceQualysDetail(String resourceId) throws DataException { + + List> qualysDataList = repository.getQualysDetail(resourceId); + + List> attributesList = new ArrayList<>(); + + if (null == qualysDataList || qualysDataList.isEmpty()) { + return attributesList; + } + + Map qualysData = qualysDataList.get(0); + + List fieldsToBeSkipped = Arrays.asList(Constants.RESOURCEID, Constants.DOCID, + AssetConstants.UNDERSCORE_DISCOVERY_DATE, AssetConstants.DISCOVERY_DATE, + AssetConstants.FIRST_DISCOVEREDON, Constants._ID, AssetConstants.UNDERSCORE_ENTITY, + AssetConstants.UNDERSCORE_ENTITY_TYPE, Constants.LATEST, Constants.ES_DOC_ROUTING_KEY, + Constants.ES_DOC_PARENT_KEY); + + qualysData.forEach((key, value) -> { + if (!fieldsToBeSkipped.contains(key) && StringUtils.isNotBlank(value.toString())) { + + Map attribute = new LinkedHashMap<>(); + attribute.put(Constants.NAME, key); + attribute.put(Constants.VALUE, new String[] { value.toString() }); + attribute.put(Constants.CATEGORY, "QUALYS INFO"); + + if ("list".equals(key) && value.toString().contains(AssetConstants.USERNAME)) { + attribute = createUserListAttributeFromQualysData(value.toString()); + } + + attributesList.add(attribute); + } + }); + + return attributesList; + + } + + private Map createUserListAttributeFromQualysData(String usernameJsonString) { + List userNameList = new ArrayList<>(); + JsonParser jsonParser = new JsonParser(); + JsonArray usernameArray = (JsonArray) jsonParser.parse(usernameJsonString); + for (JsonElement usernameElement : usernameArray) { + + JsonObject userNameJsonObj = usernameElement.getAsJsonObject(); + + String username = userNameJsonObj.get(AssetConstants.USERNAME).toString(); + if (!(username.contains("ec2-user") || (username.contains("root")))) { + userNameList.add(username); + } + } + + Map attribute = new LinkedHashMap<>(); + attribute.put(Constants.NAME, AssetConstants.USERNAME); + attribute.put(Constants.VALUE, userNameList); + attribute.put(Constants.CATEGORY, "QUALYS INFO"); + + return attribute; + } + + @Override + public List> getAdGroupsDetail(String ag, String resourceId) throws DataException { + + List> matchingAdGroups = new ArrayList<>(); + + List> ec2DataList = repository.getEc2ResourceDetail(ag, resourceId); + + if (null == ec2DataList || ec2DataList.isEmpty()) { + return matchingAdGroups; + } + + Map ec2Data = ec2DataList.get(0); + Object nameTagValueObj = ec2Data.get("tags.Name"); + String nameTagValue = ""; + if (null != nameTagValueObj) { + nameTagValue = nameTagValueObj.toString(); + } + + LOGGER.info("EC2 Tag value is: {}" , nameTagValue); + + String platform = ec2Data.get("platform").toString(); + + LOGGER.info("EC2 Tag value is: {}" , nameTagValue); + + StringTokenizer stTknzr = new StringTokenizer(nameTagValue, "-"); + String envSectionOfTag = ""; + String ouSectionOfTag = ""; + + String ouAndEnvOfTag = ""; + try { + // First token is env. Second is ou. + envSectionOfTag = stTknzr.nextToken(); + ouSectionOfTag = stTknzr.nextToken(); + ouAndEnvOfTag = ouSectionOfTag + "_" + envSectionOfTag + "_"; + } catch (NoSuchElementException e) { + LOGGER.error("Error in getAdGroupsDetail" , e); + ouAndEnvOfTag = ""; + } + + LOGGER.info("Resource id : {}",resourceId); + LOGGER.info("OU and ENV section of Name Tag of EC2 instance is: {}" , ouAndEnvOfTag); + + String tagValue = ouAndEnvOfTag; + + List> adDataList = repository.getAdGroupDetails(); + + if (null == adDataList || adDataList.isEmpty()) { + return matchingAdGroups; + } + + adDataList.forEach(adMap -> { + + String osString = ""; + + // For windows instances, consider only group names which + // have 'r_win' in them + // if platform is blank, it denotes linux. So look for group + // names which have + // 'r_rhel' + if ("windows".equalsIgnoreCase(platform)) { + osString = "r_win"; + } else { + osString = "r_rhel"; + } + Map adOutputMap = new LinkedHashMap<>(); + + String groupNameStr = adMap.get(Constants.NAME) == null ? "" : adMap.get(Constants.NAME).toString(); + String ownerNameStr = adMap.get(AssetConstants.MANAGED_BY) == null ? "" : adMap.get( + AssetConstants.MANAGED_BY).toString(); + + LOGGER.debug("Comparing the groupNameStr: {} with the value from tag:{}",groupNameStr,tagValue); + if (!StringUtils.isEmpty(tagValue) && groupNameStr.contains(tagValue) + && groupNameStr.contains(osString)) { + adOutputMap.put(Constants.NAME, groupNameStr); + adOutputMap.put(AssetConstants.MANAGED_BY, ownerNameStr); + + matchingAdGroups.add(adOutputMap); + } + + }); + + return matchingAdGroups; + } + + @Override + public List> getNotificationDetails(String instanceId, Map filters, + String searchText) throws DataException { + + List> processedNotificationList = new ArrayList<>(); + + List> notificationDataList = repository.getNotificationDetails(instanceId, filters, + searchText); + + List fieldsToBeSkipped = Arrays.asList(Constants.RESOURCEID, Constants.DOCID, + AssetConstants.UNDERSCORE_DISCOVERY_DATE, AssetConstants.DISCOVERY_DATE, + AssetConstants.FIRST_DISCOVEREDON, Constants._ID, AssetConstants.UNDERSCORE_ENTITY, + AssetConstants.UNDERSCORE_ENTITY_TYPE, Constants.LATEST); + notificationDataList.forEach(notificationDataMap -> { + Map processedNotificationMap = new LinkedHashMap<>(); + + notificationDataMap.forEach((key, value) -> { + + if (!fieldsToBeSkipped.contains(key) && StringUtils.isNotBlank(value.toString())) { + processedNotificationMap.put(key, value); + } + }); + + processedNotificationList.add(processedNotificationMap); + + }); + + return processedNotificationList; + } + + @Override + public Map getEc2CreatorDetail(String resourceId) throws DataException { + + Map creatorReturnObj = new LinkedHashMap<>(); + + try { + Map createInfo = repository.getResourceCreateInfo(resourceId); + + if (null != createInfo) { + creatorReturnObj.put(AssetConstants.CREATION_DATE, createInfo.get(AssetConstants.CREATION_DATE)); + creatorReturnObj.put(AssetConstants.CREATED_BY, createInfo.get(AssetConstants.CREATED_BY)); + creatorReturnObj.put(AssetConstants.EMAIL, createInfo.get(AssetConstants.EMAIL)); + + creatorReturnObj.put("eventInfo", createInfo); + } + return creatorReturnObj; + + } catch (Exception e) { + LOGGER.error("Error Fetching created info for resource " + resourceId , e); + } + + return null; + + } + + @Override + public Map getEC2AvgAndTotalCost(String resourceId) throws DataException { + + String corpUserId = svcCorpUserId; + String corpPassword = svcCorpPassword; + String jwtTokenGeneratorUrl = insightsTokenUrl; + String cloudInsightsBaseUrl = insightsCostUrl; + + String startDate = "2014-01-01"; + LocalDate endDateObj = LocalDate.now(); + String endDate = endDateObj.format(DateTimeFormatter.ISO_DATE); + + String requestBodyStr = "{\"username\": \"" + corpUserId + "\",\"password\": \"" + corpPassword + "\"}"; + LOGGER.info("Invoking JWT Token Generator URL: {} with requestBody as: {}",jwtTokenGeneratorUrl, requestBodyStr); + String jwtTokenJsonString; + try { + jwtTokenJsonString = PacHttpUtils.doHttpPost(jwtTokenGeneratorUrl, requestBodyStr); + } catch (Exception e) { + LOGGER.error("Exception in getEC2AvgAndTotalCost ",e); + throw new DataException(e); + } + Gson serializer = new GsonBuilder().create(); + Map tokenMap = (Map) serializer.fromJson(jwtTokenJsonString, Object.class); + String jwtToken = tokenMap.get("token"); + LOGGER.info("Received JWT Token back successfully: {}" , jwtToken); + + String cloudInsightsCostMonthlyUrl = cloudInsightsBaseUrl + resourceId + "/cost?" + "startDate=" + startDate + + "&endDate=" + endDate; + Map headers = new HashMap<>(); + headers.put("Authorization", "Bearer " + jwtToken); + LOGGER.info("Invoking Insights URL for monthly data: {}" , cloudInsightsCostMonthlyUrl); + String costResponseMonthlyStr; + try { + costResponseMonthlyStr = PacHttpUtils.getHttpGet(cloudInsightsCostMonthlyUrl, headers); + } catch (ParseException | IOException e) { + LOGGER.error(AssetConstants.ERROR_GETAPPSBYAG,e); + throw new DataException(); + } + + LOGGER.info("Received cost response monthly as: {}" , costResponseMonthlyStr); + Map costResponseMonthlyMap = (Map) serializer.fromJson(costResponseMonthlyStr, + Object.class); + + // We'll have to make the API call againto get the last week (or rather + // last 10 days) average. + + // We will ask for only last 10 days data. Ideally, it should be 7, but + // there + // might be a 1 or 2 days delay, do current and previous data might not + // have + // data in some cases + startDate = endDateObj.minusDays(Constants.TEN).format(DateTimeFormatter.ISO_DATE); + + String cloudInsightsCostDailyUrl = cloudInsightsBaseUrl + resourceId + "/cost?" + "startDate=" + startDate + + "&endDate=" + endDate; + LOGGER.info("Invoking Insights URL for daily data: {}" , cloudInsightsCostDailyUrl); + String costResponseDailyStr; + try { + costResponseDailyStr = PacHttpUtils.getHttpGet(cloudInsightsCostDailyUrl, headers); + } catch (ParseException | IOException e) { + throw new DataException(e); + } + LOGGER.info("Received cost response daily as: {}" , costResponseDailyStr); + + Map costResponseDailyMap = (Map) serializer.fromJson(costResponseDailyStr, + Object.class); + Map avgAndTotalCostMap = new LinkedHashMap<>(); + avgAndTotalCostMap.put(AssetConstants.TOTAL_COST, costResponseMonthlyMap.get(AssetConstants.TOTAL_COST)); + avgAndTotalCostMap.put("lastWeekCost", costResponseDailyMap.get(AssetConstants.TOTAL_COST)); + + return avgAndTotalCostMap; + } + + @Override + public int updateAsset(String assetGroup, String targettype, Map resources, String updatedBy, + List> updates) throws DataException { + try { + return repository.updateAsset(assetGroup, targettype, resources, updatedBy, updates); + } catch (NoDataFoundException e) { + LOGGER.error(AssetConstants.ERROR_GETAPPSBYAG,e); + throw new DataException(e); + } + } + + @Override + public List> getAssetLists(String assetGroup, Map filter, int from, int size, + String searchText) { + return repository.getAssetLists(assetGroup, filter, from, size, searchText); + } + + @Override + public ResponseWithFieldsByTargetType getEditFieldsByTargetType(String resourceType) { + + List editableFieldsList = new ArrayList<>(); + JsonParser jsonParser = new JsonParser(); + String field = null; + + String dataTypeInfo = repository.getDataTypeInfoByTargetType(resourceType); + + if (dataTypeInfo != null) { + JsonObject datatypeInfoJson = (JsonObject) jsonParser.parse(dataTypeInfo); + JsonObject dataTypes = datatypeInfoJson.get("dataTypes_info").getAsJsonObject(); + Iterator it = dataTypes.keySet().iterator(); + while (it.hasNext()) { + field = it.next(); + editableFieldsList.add(field); + } + } + + return new ResponseWithFieldsByTargetType(resourceType, editableFieldsList); + } + + public long getTotalCountForListingAsset(String index, String type) { + return repository.getTotalCountForListingAsset(index, type); + } + + @Override + public String getResourceCreatedDate(String resourceId, String resourceType) { + return repository.getResourceCreatedDate(resourceId, resourceType); + } + + private List getDomains(String assetGroup) { + List> domains = repository.getDomainsByAssetGroup(assetGroup); + List domainsList = new ArrayList<>(); + if (!domains.isEmpty()) { + domainsList = domains.stream().map(obj -> obj.get(Constants.DOMAIN).toString()) + .collect(Collectors.toList()); + } + return domainsList; + } + + @Override + public List> getDataTypeInfoByTargetType(String resourceType) throws ServiceException { + JsonParser jsonParser = new JsonParser(); + String field = null; + String datatype = null; + Map editablefieldsAndValues = new HashMap<>(); + List> dataTypeList = new ArrayList<>(); + + String dataTypeInfo = repository.getDataTypeInfoByTargetType(resourceType); + + if (dataTypeInfo != null) { + JsonObject datatypeInfoJson = (JsonObject) jsonParser.parse(dataTypeInfo); + JsonObject dataTypes = datatypeInfoJson.get("dataTypes_info").getAsJsonObject(); + Iterator it = dataTypes.keySet().iterator(); + while (it.hasNext()) { + field = it.next(); + if (!dataTypes.get(field).isJsonNull()) { + datatype = dataTypes.get(field).getAsString(); + editablefieldsAndValues.put(field, datatype); + } else { + throw new ServiceException("datatype not maintained in RDS"); + } + } + if (!editablefieldsAndValues.isEmpty()) { + dataTypeList.add(editablefieldsAndValues); + } + } + return dataTypeList; + } + + @Override + public ApplicationDetailsResponse getApplicationDetailsByAssetGroup(String assetGroup, String applicationName) + throws DataException, JsonProcessingException { + List infraValidApplications = repository.getApplicationDetails(); + Map infraValidApplicationMap = infraValidApplications.stream() + .collect(Collectors.toMap(app -> app.getApplicationDetail().getAppTag(), + ApplicationDetailsESResponse::getApplicationDetail)); + + String domain = "Infra & Platforms"; + Map applicationAssetCountMap = this.filterAppAssetCountByApplicationName( + repository.getApplicationAssetCountByAssetGroup(assetGroup, domain), applicationName); + List applications = new ArrayList<>(applicationAssetCountMap.keySet()); + + List validApplications = new ArrayList<>(); + List invalidApplications = new ArrayList<>(); + applications.stream().forEach(application -> { + ApplicationDetail applicationDetail = new ApplicationDetail(); + ApplicationESDetail applicationESDetail = infraValidApplicationMap.get(application); + if (applicationESDetail != null) { + List organizations = Lists.newArrayList(); + String description = StringUtils.EMPTY; + if (applicationESDetail.getDescription() != null) { + description = StringUtils.chomp(applicationESDetail.getDescription()); + } else { + description = application; + } + List> orgDetails = Lists.newArrayList(); + if (applicationESDetail.getOrgInfo() != null) { + orgDetails = applicationESDetail.getOrgInfo(); + } + orgDetails.forEach(orgDetail -> { + Organization organization = new Organization(); + int mgmntLevel = 0; + if (StringUtils.isNotBlank(orgDetail.get("mgmntLevel"))) { + mgmntLevel = Integer.parseInt(orgDetail.get("mgmntLevel")); + organization.setName(orgDetail.get("name")); + switch (mgmntLevel) { + case 1: + organization.setDesignation("EVP"); + break; + case 2: + organization.setDesignation("SVP"); + break; + case 3: + organization.setDesignation("VP"); + break; + case 4: + organization.setDesignation("Sr Director"); + break; + default: + organization.setDesignation("Director"); + break; + } + } else { + if (StringUtils.isNotBlank(orgDetail.get("isOwner"))) { + if (Boolean.parseBoolean(orgDetail.get("isOwner"))) { + organization.setDesignation("Director"); + } + } else { + organization.setDesignation("NA"); + } + } + organizations.add(organization); + }); + String assetGroupId = application.toLowerCase().replaceAll("[^a-z0-9-_]", StringUtils.EMPTY); + applicationDetail.setDescription(description); + applicationDetail.setName(application); + applicationDetail.setOrganization(organizations); + applicationDetail.setAssetGroupId(assetGroupId); + applicationDetail.setTotalResources(applicationAssetCountMap.get(application)); + validApplications.add(applicationDetail); + } else { + applicationDetail.setDescription("NA"); + applicationDetail.setName(application); + applicationDetail.setOrganization(Lists.newArrayList()); + applicationDetail.setAssetGroupId("NA"); + applicationDetail.setTotalResources(applicationAssetCountMap.get(application)); + invalidApplications.add(applicationDetail); + } + + }); + ApplicationDetailsResponse applicationDetailsResponse = new ApplicationDetailsResponse(); + applicationDetailsResponse.setValidApplications(validApplications); + applicationDetailsResponse.setInvalidApplications(invalidApplications); + return applicationDetailsResponse; + } + + /** + * Function for filtering out the asset count by application name if application + * name is present Else return full application list + * + * @param applicationAssetCountMap + * @param applicationName + * @return + * @throws DataException + */ + private Map filterAppAssetCountByApplicationName(Map applicationAssetCountMap, + String applicationName) throws DataException { + if (applicationName == null) { + return applicationAssetCountMap; + } else { + Map filteredMap = new HashMap(); + if (applicationAssetCountMap.containsKey(applicationName)) { + filteredMap.put(applicationName, applicationAssetCountMap.get(applicationName)); + return filteredMap; + } else { + throw new DataException("Invalid Application Name!"); + } + } + } + + /* (non-Javadoc) + * @see com.tmobile.pacman.api.asset.service.AssetService#getAllCostTypes() + */ + @Override + public List> getAllCostTypes() { + + return repository.getAllCostTypes(); + + } +} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CostService.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CostService.java new file mode 100644 index 000000000..46540219a --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CostService.java @@ -0,0 +1,523 @@ +package com.tmobile.pacman.api.asset.service; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.tmobile.pacman.api.asset.domain.ApplicationDetail; +import com.tmobile.pacman.api.asset.domain.Organization; +import com.tmobile.pacman.api.asset.repository.AssetRepository; +import com.tmobile.pacman.api.asset.repository.CostRepository; +import com.tmobile.pacman.api.commons.Constants; +import com.tmobile.pacman.api.commons.exception.ServiceException; +import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; +import com.tmobile.pacman.api.commons.utils.CommonUtils; + +@Service +public class CostService { + /** The es host. */ + @Value("${elastic-search.host}") + private String esHost; + + /** The es port. */ + @Value("${elastic-search.port}") + private int esPort; + + /** The cost indicator percent. */ + @Value("${cost-indicator.percent}") + private int costIndicatorPercent; + + /** The Constant PROTOCOL. */ + static final String PROTOCOL = "http"; + + /** The es url. */ + private String esUrl; + + /** The elastic search repository. */ + @Autowired + private ElasticSearchRepository elasticSearchRepository; + + @Autowired + private AssetRepository assetRepository; + + @Autowired + private CostRepository costRepository; + + @PostConstruct + void init() { + esUrl = PROTOCOL + "://" + esHost + ":" + esPort; + } + + /** The Constant LOGGER. */ + private static final Log LOGGER = LogFactory.getLog(CostService.class); + + @SuppressWarnings("deprecation") + public Map getCostByType(String assetGroup, Integer year, List monthList, + List appNameList, List tTypeList) throws Exception { + + Integer prevYear = year; + List prevMonthList = new ArrayList<>(); + if(year==null && monthList.isEmpty()){ // Defaulted to latest finalised + Map yearMonth = costRepository.findLatestCostFinalisedMonth(); + if(yearMonth.isEmpty()){ + throw new ServiceException("Could not find cost as year/month to fetch the data can not be determined"); + } + year = yearMonth.get("year"); + monthList.add(yearMonth.get("month")+""); + Integer currMonth = Integer.valueOf(yearMonth.get("month").toString()); + if(currMonth >1 ) { + prevYear = year; + prevMonthList.add(String.valueOf(currMonth-1)+""); + } else { + prevYear = year -1; + prevMonthList.add("12"); + } + } else { + if(monthList.size() > 1) { + if(monthList.contains("1") && monthList.contains("2") && monthList.contains("3")) { + prevYear = year-1; + prevMonthList.add("10"); + prevMonthList.add("11"); + prevMonthList.add("12"); + } else { + for(String month : monthList) { + prevMonthList.add(String.valueOf(Integer.valueOf(month)-1)+""); + } + } + + } else { + if(Integer.valueOf(monthList.get(0)) >1 ) { + prevYear = year; + prevMonthList.add(String.valueOf(Integer.valueOf(monthList.get(0))-1)+""); + } else { + prevYear = year -1; + prevMonthList.add("12"); + } + } + } + Map responseMap = new HashMap<>(); + Map mustFilter = new HashMap<>(); + Map mustTermsFilter = new HashMap<>(); + mustFilter.put("year", year); + mustTermsFilter.put(CommonUtils.convertAttributetoKeyword("application"), filterApps(appNameList)); + if(!tTypeList.isEmpty()){ + mustTermsFilter.put(CommonUtils.convertAttributetoKeyword("costInfo.type"), tTypeList); + } + mustTermsFilter.put("month", monthList); + List> currResult = elasticSearchRepository.getDataFromES("aws-cost", "monthly-cost", mustFilter, + null, null, null, mustTermsFilter); + mustFilter.put("year", prevYear); + mustTermsFilter.put("month", prevMonthList); + List> prevResult = elasticSearchRepository.getDataFromES("aws-cost", "monthly-cost", mustFilter, + null, null, null, mustTermsFilter); + + boolean finalised = true; + for(Map resultMap :currResult){ + finalised = finalised && Boolean.valueOf(resultMap.get("finalised").toString()); + } + List> currCostByTypeMapList = formCostByType(currResult, tTypeList); + List> prevCostByTypeMapList = formCostByType(prevResult, tTypeList); + + findCostIndicatorByType(currCostByTypeMapList, prevCostByTypeMapList); + + LocalDate date1 = LocalDate.of(year, new Integer(monthList.get(0)), 1); + LocalDate start = date1.withDayOfMonth(1); + + LocalDate date2 = LocalDate.of(year, new Integer(monthList.get(monthList.size() - 1)), 1); + LocalDate end = date2.withDayOfMonth(date2.lengthOfMonth()); + + responseMap.put("ag", assetGroup); + responseMap.put("startDate", start.format(DateTimeFormatter.ISO_LOCAL_DATE)); + responseMap.put("endDate", end.format(DateTimeFormatter.ISO_LOCAL_DATE)); + responseMap.put("costByType", currCostByTypeMapList); + responseMap.put("finalised", finalised); + + responseMap.put("year", start.getYear()); + if(start.getMonthValue() == end.getMonth().getValue()){ + responseMap.put("month", start.getMonthValue()); + }else{ + responseMap.put("quarter", ((start.getMonthValue()-1)/3)+1); + } + return responseMap; + + } + + private List> formCostByType(List> result, List tTypeList) { + + Map> typeToAppMap = new HashMap<>(); + for(Map resultMap :result){ + String application = resultMap.get("application").toString(); + String typeCostListJson = resultMap.get("list").toString(); + List> typeCostList = new Gson().fromJson(typeCostListJson, new TypeToken>>() {}.getType()); + typeCostList.stream().filter(typeCost -> tTypeList.isEmpty()?true:tTypeList.contains(typeCost.get("type").toString()) ).forEach(typeCost-> { + String type = typeCost.get("type").toString(); + long cost = Math.round(Double.valueOf(typeCost.get("cost").toString())); + if(cost>0){ + Map appMap = typeToAppMap.get(type); + if(appMap==null){ + appMap = new HashMap<>(); + typeToAppMap.put(type, appMap); + } + Long currCost = appMap.get(application); + currCost = currCost==null?0l:currCost; + appMap.put(application, cost+currCost); + } + }); + } + + List typeList = new ArrayList(typeToAppMap.keySet()); + List> typeDataSource = assetRepository.getDatasourceForCostMapping(typeList); + + List> costByTypeMapList = new ArrayList<>(); + Iterator typeIterator = typeToAppMap.keySet().iterator(); + while (typeIterator.hasNext()) { + String typeValue = typeIterator.next(); + Map typeDataMap = new HashMap<>(); + typeDataMap.put("type", typeValue); + + typeDataMap.put(Constants.PROVIDER, + typeDataSource.stream() + .filter(datasource -> datasource.get(Constants.TYPE).toString().equals(typeValue)) + .findFirst().get().get(Constants.PROVIDER)); + + Map appMap = (typeToAppMap.get(typeValue) != null) + ? ((Map) (typeToAppMap.get(typeValue))) + : new HashMap<>(); + + Double typeCost = appMap.values().stream().mapToDouble(value -> value).sum(); + typeDataMap.put("typeTotalCost", typeCost); + List> appLineItemsMapList = new ArrayList<>(); + typeDataMap.put("applicationLineItems", appLineItemsMapList); + + Iterator appIterator = appMap.keySet().iterator(); + while (appIterator.hasNext()) { + Map appLineItemsMap = new HashMap<>(); + String appName = appIterator.next(); + Long cost = appMap.get(appName); + appLineItemsMap.put("lineItemName", appName); + appLineItemsMap.put("lineItemCost", cost); + appLineItemsMapList.add(appLineItemsMap); + } + + costByTypeMapList.add(typeDataMap); + } + + return costByTypeMapList; + } + + private void findCostIndicatorByType(List> currCostList, List> prevCostList) { + for(Map currCost : currCostList) { + String costIndicator = "NC"; + for(Map prevCost : prevCostList) { + if(currCost.get("type").equals(prevCost.get("type"))) { + Double currTotalCost = Double.valueOf(currCost.get("typeTotalCost").toString()); + Double prevTotalCost = Double.valueOf(prevCost.get("typeTotalCost").toString()); + Double percentage = (currTotalCost-prevTotalCost)/prevTotalCost*100; + if(percentage>0){ + if(percentage>costIndicatorPercent) { + costIndicator = "UP"; + } + } else if(percentage<0){ + costIndicator = "DOWN"; + } + break; + } + } + currCost.put("costTrendIndicator", costIndicator); + } + } + + @SuppressWarnings("deprecation") + public Map getCostByApplication(String assetGroup, Integer year, List monthList, + List appNameList, List tTypeList, List validApplications) + throws Exception { + + Integer prevYear = year; + List prevMonthList = new ArrayList<>(); + if(year==null && monthList.isEmpty()){ // Defaulted to latest finalised + Map yearMonth = costRepository.findLatestCostFinalisedMonth(); + if(yearMonth.isEmpty()){ + throw new ServiceException("Could not find cost as year/month to fetch the data can not be determined"); + } + year = yearMonth.get("year"); + monthList.add(yearMonth.get("month")+""); + Integer currMonth = Integer.valueOf(yearMonth.get("month").toString()); + if(currMonth >1 ) { + prevYear = year; + prevMonthList.add(String.valueOf(currMonth-1)+""); + } else { + prevYear = year -1; + prevMonthList.add("12"); + } + } else { + if(monthList.size() > 1) { + if(monthList.contains("1") && monthList.contains("2") && monthList.contains("3")) { + prevYear = year-1; + prevMonthList.add("10"); + prevMonthList.add("11"); + prevMonthList.add("12"); + } else { + for(String month : monthList) { + prevMonthList.add(String.valueOf(Integer.valueOf(month)-1)+""); + } + } + + } else { + if(Integer.valueOf(monthList.get(0)) >1 ) { + prevYear = year; + prevMonthList.add(String.valueOf(Integer.valueOf(monthList.get(0))-1)+""); + } else { + prevYear = year -1; + prevMonthList.add("12"); + } + } + } + + Map responseMap = new HashMap<>(); + Map mustFilter = new HashMap<>(); + Map mustTermsFilter = new HashMap<>(); + mustFilter.put("year", year); + mustTermsFilter.put(CommonUtils.convertAttributetoKeyword("application"), filterApps(appNameList)); + if(!tTypeList.isEmpty()){ + mustTermsFilter.put(CommonUtils.convertAttributetoKeyword("costInfo.type"), tTypeList); + } + mustTermsFilter.put("month", monthList); + List> currResult = elasticSearchRepository.getDataFromES("aws-cost", "monthly-cost", mustFilter, + null, null, null, mustTermsFilter); + + mustFilter.put("year", prevYear); + mustTermsFilter.put("month", prevMonthList); + List> prevResult = elasticSearchRepository.getDataFromES("aws-cost", "monthly-cost", mustFilter, + null, null, null, mustTermsFilter); + + boolean finalised = true; + for(Map resultMap :currResult){ + finalised = finalised && Boolean.valueOf(resultMap.get("finalised").toString()); + } + + List> currCostByAPPMapList = formCostByApplication(currResult, tTypeList, validApplications); + List> prevCostByAPPMapList = formCostByApplication(prevResult, tTypeList, validApplications); + + findCostIndicatorByApplication(currCostByAPPMapList,prevCostByAPPMapList); + + LocalDate date1 = LocalDate.of(year, new Integer(monthList.get(0)), 1); + LocalDate start = date1.withDayOfMonth(1); + + LocalDate date2 = LocalDate.of(year, new Integer(monthList.get(monthList.size() - 1)), 1); + LocalDate end = date2.withDayOfMonth(date2.lengthOfMonth()); + + + responseMap.put("ag", assetGroup); + responseMap.put("finalised", finalised); + responseMap.put("startDate", start.format(DateTimeFormatter.ISO_LOCAL_DATE)); + responseMap.put("endDate", end.format(DateTimeFormatter.ISO_LOCAL_DATE)); + responseMap.put("costByApplication", currCostByAPPMapList); + + responseMap.put("year", start.getYear()); + if(start.getMonthValue() == end.getMonth().getValue()){ + responseMap.put("month", start.getMonthValue()); + }else{ + responseMap.put("quarter", ((start.getMonthValue()-1)/3)+1); + } + + return responseMap; + } + +private List> formCostByApplication(List> result, List tTypeList, List validApplications) { + + Map> appToTypeMap = new HashMap<>(); + for(Map resultMap :result){ + String appllcation = resultMap.get("application").toString(); + String typeCostListJson = resultMap.get("list").toString(); + List> typeCostList = new Gson().fromJson(typeCostListJson, new TypeToken>>() {}.getType()); + if(!typeCostList.isEmpty()){ + typeCostList.stream().filter(typeCost -> tTypeList.isEmpty()?true:tTypeList.contains(typeCost.get("type").toString()) ).forEach(typeCost-> { + String type = typeCost.get("type").toString(); + long cost = Math.round(Double.valueOf(typeCost.get("cost").toString())); + Map typeMap = appToTypeMap.get(appllcation); + if(typeMap==null){ + typeMap = new HashMap<>(); + appToTypeMap.put(appllcation, typeMap); + } + Long currCost = typeMap.get(type); + currCost = currCost==null?0l:currCost; + typeMap.put(type, cost+currCost); + + }); + }else{ + Map typeMap = new HashMap<>(); + typeMap.put("", 0l); + appToTypeMap.put(appllcation, typeMap); + } + + } + + List> costByApplicationMapList = new ArrayList<>(); + Iterator appIterator = appToTypeMap.keySet().iterator(); + while (appIterator.hasNext()) { + String appValue = appIterator.next(); + Map applicationDataMap = new HashMap<>(); + applicationDataMap.put("name", appValue); + List orgList = getOrganization(appValue, validApplications); + if (null != orgList && !orgList.isEmpty()) { + applicationDataMap.put("organization", orgList); + } + + Map typeMap = (appToTypeMap.get(appValue) != null) + ? ( (appToTypeMap.get(appValue))) + : new HashMap<>(); + + Long applicationCost = typeMap.values().stream().mapToLong(value -> value).sum(); + applicationDataMap.put("applicationTotalCost", applicationCost); + List> typeLineItemsMapList = new ArrayList<>(); + applicationDataMap.put("typeLineItems", typeLineItemsMapList); + + Iterator typeIterator = typeMap.keySet().iterator(); + while (typeIterator.hasNext()) { + Map typeLineItemsMap = new HashMap<>(); + String typeName = typeIterator.next(); + Long cost = typeMap.get(typeName); + if(cost>0){ + typeLineItemsMap.put("lineItemName", typeName); + typeLineItemsMap.put("lineItemCost", cost); + typeLineItemsMapList.add(typeLineItemsMap); + } + } + + costByApplicationMapList.add(applicationDataMap); + } + return costByApplicationMapList; + } + + private void findCostIndicatorByApplication(List> currCostList, List> prevCostList) { + for(Map currCost : currCostList) { + String costIndicator = "NC"; + for(Map prevCost : prevCostList) { + if(currCost.get("name").equals(prevCost.get("name"))) { + Double currTotalCost = Double.valueOf(currCost.get("applicationTotalCost").toString()); + Double prevTotalCost = Double.valueOf(prevCost.get("applicationTotalCost").toString()); + Double percentage = (currTotalCost-prevTotalCost)/prevTotalCost*100; + if(percentage>0){ + if(percentage>5) { + costIndicator = "UP"; + } + } else { + costIndicator = "DOWN"; + } + break; + } + } + currCost.put("costTrendIndicator", costIndicator); + } + } + + private List getOrganization(String appName, List validApplications) { + Iterator appDetailIterator = validApplications.iterator(); + while (appDetailIterator.hasNext()) { + ApplicationDetail appDetail = appDetailIterator.next(); + if (appName.equals(appDetail.getName())) { + return appDetail.getOrganization(); + } + } + return null; + } + + + private List filterApps(List apps){ + List masterList = costRepository.fetchApplicationMasterList(); + if(masterList.isEmpty()){ + return apps; + }else{ + return apps.stream().filter(masterList::contains).collect(Collectors.toList()); + } + } + + @SuppressWarnings("unchecked") + public List> getCostTrend(List appNameList, List tTypeList, String period) throws Exception { + + List> trendList = new ArrayList<>(); + + if(tTypeList.isEmpty()) { + trendList.addAll(costRepository.getCostAggs(appNameList)); + } else { + trendList.addAll(costRepository.getCostAggsWithTT(appNameList, tTypeList)); + } + sortByYearAndMonth(trendList,"month"); + if("monthly".equals(period)) { + return trendList; + } else { + Map yearMap = new HashMap<>(); + for(Map trend : trendList) { + if(!yearMap.isEmpty() && yearMap.containsKey(trend.get("year").toString())) { + Map quarterMap = (Map) yearMap.get(trend.get("year").toString()); + int quarter = ((Integer.valueOf(trend.get("month").toString())-1) / 3)+1; + if(quarterMap.containsKey(quarter)) { + Map costMap = (Map) quarterMap.get(quarter); + costMap.put("cost", Double.valueOf(costMap.get("cost").toString()) + Double.valueOf(trend.get("cost").toString())); + costMap.put("costStatus", trend.get("costStatus")); + quarterMap.put(quarter, costMap); + } else { + Map costMap = new HashMap<>(); + costMap.put("cost", trend.get("cost")); + costMap.put("costStatus", trend.get("costStatus")); + quarterMap.put(quarter, costMap); + } + } else { + Map quarterMap = new HashMap<>(); + Map costMap = new HashMap<>(); + costMap.put("cost", trend.get("cost")); + costMap.put("costStatus", trend.get("costStatus")); + quarterMap.put(((Integer.valueOf(trend.get("month").toString())-1) / 3)+1, costMap); + yearMap.put(trend.get("year").toString(), quarterMap); + } + } + + trendList = new ArrayList<>(); + + + for(Entry year : yearMap.entrySet()) { + for(Entry quarter : ((Map)year.getValue()).entrySet()) { + Map trend = new HashMap<>(); + trend.put("year", year.getKey()); + trend.put("quarter", quarter.getKey()); + Map cost = (Map)quarter.getValue(); + trend.put("cost", cost.get("cost")); + trend.put("costStatus", cost.get("costStatus")); + trendList.add(trend); + } + } + sortByYearAndMonth(trendList,"quarter"); + return trendList; + } + } + + private void sortByYearAndMonth(List> trendList, String compartor) { + Comparator> comp1 = (m1, m2) -> Integer.compare( + new Integer(m1.get("year").toString()), new Integer(m2.get("year").toString())); + Collections.sort(trendList, comp1); + + Comparator> comp2 = (m1, m2) -> Integer.compare( + new Integer(m1.get(compartor).toString()), new Integer(m2.get(compartor).toString())); + Collections.sort(trendList, comp2); + } +} + + diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/RecommendationsService.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/RecommendationsService.java new file mode 100644 index 000000000..74c5f9af8 --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/RecommendationsService.java @@ -0,0 +1,66 @@ +package com.tmobile.pacman.api.asset.service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.tmobile.pacman.api.asset.AssetConstants; +import com.tmobile.pacman.api.asset.repository.RecommendationsRepository; +import com.tmobile.pacman.api.commons.exception.DataException; + +@Service +public class RecommendationsService { + + @Autowired + RecommendationsRepository recommendationsRepository; + + public List> getRecommendationSummary(String assetGroup, String application, Boolean general) throws DataException { + if(general) { + return recommendationsRepository.getGeneralRecommendationSummary(); + } else { + return recommendationsRepository.getRecommendationSummary(assetGroup,application); + } + } + + public Map getSummaryByApplication(String assetGroup, String category) throws DataException { + + if(StringUtils.isBlank(category)) { + return recommendationsRepository.getSummaryByApplication(assetGroup); + } else { + return recommendationsRepository.getSummaryByApplication(assetGroup, category); + } + + } + + public Map getRecommendations(String assetGroup, String category, String application, String general) throws DataException { + if(general.equals(AssetConstants.FALSE)) { + return recommendationsRepository.getRecommendations(assetGroup, category, application); + } else { + return recommendationsRepository.getGeneralRecommendations(category); + } + } + + public Map getRecommendationDetail(String assetGroup, String recommendationId, String application, String general) throws DataException { + if(general.equals(AssetConstants.FALSE)) { + return recommendationsRepository.getRecommendationDetail(assetGroup, recommendationId,application); + } else { + return recommendationsRepository.getGeneralRecommendationDetail(recommendationId); + } + } + + public Map getRecommendationInfo(String recommendationId) throws DataException { + + String description = recommendationsRepository.getRecommendation(recommendationId).get("checkdescription").toString(); + String[] description1 = description.split("Alert Criteria"); + String[] description2 = description1[1].split("Recommended Action"); + Map recommendationInfo = new HashMap<>(); + recommendationInfo.put("summary", description1[0].replace("
", "").replace("[NL]", "").replace("", "").replace("", "")); + recommendationInfo.put("alert criteria", description2[0].replace("
", "").replace("[NL]", "").replace("", "").replace("", "")); + recommendationInfo.put("recommended action", description2[1].substring(12,description2[1].length()-1).replace("[NL]", "
")); + return recommendationInfo; + } +} diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetControllerTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetControllerTest.java index 277505e16..ce1394bdd 100644 --- a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetControllerTest.java +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetControllerTest.java @@ -1,327 +1,327 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ -package com.tmobile.pacman.api.asset.controller; - -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.anyString; -import static org.powermock.api.mockito.PowerMockito.doThrow; -import static org.powermock.api.mockito.PowerMockito.when; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.util.ReflectionTestUtils; - -import com.tmobile.pacman.api.asset.domain.AssetUpdateRequest; -import com.tmobile.pacman.api.asset.model.DefaultUserAssetGroup; -import com.tmobile.pacman.api.asset.service.AssetService; -import com.tmobile.pacman.api.commons.exception.DataException; -import com.tmobile.pacman.api.commons.utils.ResponseUtils; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({ ResponseUtils.class }) -public class AssetControllerTest { - - @Mock - AssetService service; - - AssetController controller = new AssetController(); - - @Test - public void testgetListOfTargetTypes() throws Exception { - List> tTypeList = new ArrayList<>(); - - when(service.getTargetTypesForAssetGroup(anyObject(), anyObject())).thenReturn(tTypeList); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj0 = controller.getListOfTargetTypes("ag", "domain"); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - Map tTypeMap = new HashMap<>(); - tTypeMap.put("type", "ec2"); - tTypeMap.put("category", "Compute"); - tTypeMap.put("domain", "Infra & Platforms"); - tTypeList.add(tTypeMap); - - ResponseEntity responseObj = controller.getListOfTargetTypes("ag", "domain"); - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj.getBody()).get("data") != null); - } - - @Test - public void testgetListOfApplications() throws Exception { - List> tTypeList = new ArrayList<>(); - Map tTypeMap = new HashMap<>(); - tTypeMap.put("name", "pacman"); - tTypeList.add(tTypeMap); - - when(service.getApplicationsByAssetGroup(anyObject(), anyObject())).thenReturn(tTypeList); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj = controller.getListOfApplications("ag", "domain"); - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj.getBody()).get("data") != null); - - doThrow(new DataException()).when(service).getApplicationsByAssetGroup(anyObject(), anyObject()); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj0 = controller.getListOfApplications("ag", "domain"); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - } - - @Test - public void testgetListOfEnvironments() throws Exception { - List> tTypeList = new ArrayList<>(); - - when(service.getEnvironmentsByAssetGroup(anyObject(), anyObject(), anyObject())).thenReturn(tTypeList); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj0 = controller.getListOfEnvironments("ag", "application", "domain"); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - Map tTypeMap = new HashMap<>(); - tTypeMap.put("name", "pacman"); - tTypeList.add(tTypeMap); - - when(service.getEnvironmentsByAssetGroup(anyObject(), anyObject(), anyObject())).thenReturn(tTypeList); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj = controller.getListOfEnvironments("ag", "application", "domain"); - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj.getBody()).get("data") != null); - } - - @Test - public void testgetAllAssetGroups() throws Exception { - List> tTypeList = new ArrayList<>(); - Map tTypeMap = new HashMap<>(); - tTypeMap.put("name", "pacman"); - tTypeList.add(tTypeMap); - - when(service.getAllAssetGroups()).thenReturn(tTypeList); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj = controller.getAllAssetGroups(); - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj.getBody()).get("data") != null); - - doThrow(new NumberFormatException()).when(service).getAllAssetGroups(); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj0 = controller.getAllAssetGroups(); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - } - - @Test - public void testgetAssetGroupInfo() throws Exception { - List> tTypeList = new ArrayList<>(); - Map tTypeMap = new HashMap<>(); - - when(service.getAssetGroupInfo("ag")).thenReturn(tTypeMap); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj0 = controller.getAssetGroupInfo("ag"); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - tTypeMap.put("name", "aws-all"); - tTypeList.add(tTypeMap); - - when(service.getAssetGroupInfo("ag")).thenReturn(tTypeMap); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj = controller.getAssetGroupInfo("ag"); - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj.getBody()).get("data") != null); - } - - @Test - public void testgetUserDefaultAssetGroup() throws Exception { - - when(service.getUserDefaultAssetGroup(anyString())).thenReturn("aws-all"); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj = controller.getUserDefaultAssetGroup("userid"); - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj.getBody()).get("data") != null); - - when(service.getUserDefaultAssetGroup(anyString())).thenReturn(""); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj0 = controller.getUserDefaultAssetGroup("userid"); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - } - - @Test - public void testsaveOrUpdateAssetGroup() throws Exception { - DefaultUserAssetGroup defaultUserAssetGroup = new DefaultUserAssetGroup(); - defaultUserAssetGroup.setDefaultAssetGroup("aws-all"); - defaultUserAssetGroup.setUserId("userId"); - defaultUserAssetGroup.getUserId(); - defaultUserAssetGroup.getDefaultAssetGroup(); - - when(service.saveOrUpdateAssetGroup(anyObject())).thenReturn(true); - ReflectionTestUtils.setField(controller, "assetService", service); - - - ResponseEntity responseObj = controller.saveOrUpdateAssetGroup(defaultUserAssetGroup); - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj.getBody()).get("data") != null); - - when(service.saveOrUpdateAssetGroup(anyObject())).thenReturn(false); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj0 = controller.saveOrUpdateAssetGroup(defaultUserAssetGroup); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - } - - @Test - public void testappendToRecentlyViewedAG() throws Exception { - List> agList = new ArrayList<>(); - Map agMap = new HashMap<>(); - agMap.put("name", "aws-all"); - agList.add(agMap); - when(service.saveAndAppendToRecentlyViewedAG(anyObject(), anyObject())).thenReturn(agList); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj = controller.appendToRecentlyViewedAG("userId", "ag"); - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj.getBody()).get("data") != null); - ResponseEntity responseObj0 = controller.appendToRecentlyViewedAG("userId", ""); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - doThrow(new DataException()).when(service).saveAndAppendToRecentlyViewedAG(anyString(),anyString()); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj1 = controller.appendToRecentlyViewedAG("userId", "ag"); - assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - } - - @Test - public void testretrieveAssetConfig() throws Exception { - - when(service.retrieveAssetConfig(anyObject(), anyObject())).thenReturn("{}"); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj = controller.retrieveAssetConfig("a1", "passwordPolicy"); - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj.getBody()).get("data") != null); - - when(service.retrieveAssetConfig(anyObject(), anyObject())).thenReturn(""); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj0 = controller.retrieveAssetConfig("a1", "passwordPolicy"); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - } - - - @Test - public void testsaveAssetConfig() throws Exception { - - when(service.saveAssetConfig(anyObject(), anyObject(), anyObject())).thenReturn(1); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj = controller.saveAssetConfig("a1", "passwordPolicy", "{}"); - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj.getBody()).get("data") != null); - - when(service.saveAssetConfig(anyObject(), anyObject(), anyObject())).thenReturn(0); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj0 = controller.saveAssetConfig("a1", "passwordPolicy", "{}"); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - } - - @Test - public void testupdateAsset() throws Exception { - - AssetUpdateRequest assetUpdateRequest = new AssetUpdateRequest(); - assetUpdateRequest.setAg("ag"); - assetUpdateRequest.setTargettype("targetType"); - assetUpdateRequest.setUpdateBy("update_by"); - assetUpdateRequest.setUpdates(new ArrayList<>()); - assetUpdateRequest.setResources(new HashMap<>()); - - when(service.updateAsset(anyObject(), anyObject(), anyObject(), anyObject(), anyObject())).thenReturn(0); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj4 = controller.updateAsset(assetUpdateRequest); - assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - when(service.updateAsset(anyObject(), anyObject(), anyObject(), anyObject(), anyObject())).thenReturn(1); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj = controller.updateAsset(assetUpdateRequest); - - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj.getBody()).get("data") != null); - - - - assetUpdateRequest.setUpdateBy(null); - ResponseEntity responseObj0 = controller.updateAsset(assetUpdateRequest); - assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); - - assetUpdateRequest.setAg(""); - ResponseEntity responseObj2 = controller.updateAsset(assetUpdateRequest); - assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - assetUpdateRequest.setAg("aws-all"); - assetUpdateRequest.setTargettype(""); - ResponseEntity responseObj3 = controller.updateAsset(assetUpdateRequest); - assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - - - } - - @Test - public void testgetResourceCreatedDate() throws Exception { - - AssetUpdateRequest assetUpdateRequest = new AssetUpdateRequest(); - assetUpdateRequest.setAg("ag"); - assetUpdateRequest.setTargettype("targetType"); - assetUpdateRequest.setUpdateBy("update_by"); - assetUpdateRequest.setUpdates(new ArrayList<>()); - assetUpdateRequest.setResources(new HashMap<>()); - - when(service.getResourceCreatedDate(anyObject(), anyObject())).thenReturn("01-01-2018"); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj = controller.getResourceCreatedDate("a1", "ec2"); - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj.getBody()).get("data").toString().equals("01-01-2018")); - - when(service.getResourceCreatedDate(anyObject(), anyObject())).thenReturn(""); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj1 = controller.getResourceCreatedDate("a1", "ec2"); - assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - when(service.getResourceCreatedDate(anyObject(), anyObject())).thenReturn(null); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj2 = controller.getResourceCreatedDate("a1", "ec2"); - assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - } -} +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.api.asset.controller; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.powermock.api.mockito.PowerMockito.doThrow; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.util.ReflectionTestUtils; + +import com.tmobile.pacman.api.asset.domain.AssetUpdateRequest; +import com.tmobile.pacman.api.asset.model.DefaultUserAssetGroup; +import com.tmobile.pacman.api.asset.service.AssetService; +import com.tmobile.pacman.api.commons.exception.DataException; +import com.tmobile.pacman.api.commons.utils.ResponseUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ ResponseUtils.class }) +public class AssetControllerTest { + + @Mock + AssetService service; + + AssetController controller = new AssetController(); + + @Test + public void testgetListOfTargetTypes() throws Exception { + List> tTypeList = new ArrayList<>(); + + when(service.getTargetTypesForAssetGroup(anyObject(), anyObject())).thenReturn(tTypeList); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj0 = controller.getListOfTargetTypes("ag", "domain"); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + Map tTypeMap = new HashMap<>(); + tTypeMap.put("type", "ec2"); + tTypeMap.put("category", "Compute"); + tTypeMap.put("domain", "Infra & Platforms"); + tTypeList.add(tTypeMap); + + ResponseEntity responseObj = controller.getListOfTargetTypes("ag", "domain"); + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj.getBody()).get("data") != null); + } + + @Test + public void testgetListOfApplications() throws Exception { + List> tTypeList = new ArrayList<>(); + Map tTypeMap = new HashMap<>(); + tTypeMap.put("name", "pacman"); + tTypeList.add(tTypeMap); + + when(service.getApplicationsByAssetGroup(anyObject(), anyObject())).thenReturn(tTypeList); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj = controller.getListOfApplications("ag", "domain"); + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj.getBody()).get("data") != null); + + doThrow(new DataException()).when(service).getApplicationsByAssetGroup(anyObject(), anyObject()); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj0 = controller.getListOfApplications("ag", "domain"); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + } + + @Test + public void testgetListOfEnvironments() throws Exception { + List> tTypeList = new ArrayList<>(); + + when(service.getEnvironmentsByAssetGroup(anyObject(), anyObject(), anyObject())).thenReturn(tTypeList); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj0 = controller.getListOfEnvironments("ag", "application", "domain"); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + Map tTypeMap = new HashMap<>(); + tTypeMap.put("name", "pacman"); + tTypeList.add(tTypeMap); + + when(service.getEnvironmentsByAssetGroup(anyObject(), anyObject(), anyObject())).thenReturn(tTypeList); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj = controller.getListOfEnvironments("ag", "application", "domain"); + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj.getBody()).get("data") != null); + } + + @Test + public void testgetAllAssetGroups() throws Exception { + List> tTypeList = new ArrayList<>(); + Map tTypeMap = new HashMap<>(); + tTypeMap.put("name", "pacman"); + tTypeList.add(tTypeMap); + + when(service.getAllAssetGroups()).thenReturn(tTypeList); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj = controller.getAllAssetGroups(); + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj.getBody()).get("data") != null); + + doThrow(new NumberFormatException()).when(service).getAllAssetGroups(); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj0 = controller.getAllAssetGroups(); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + } + + @Test + public void testgetAssetGroupInfo() throws Exception { + List> tTypeList = new ArrayList<>(); + Map tTypeMap = new HashMap<>(); + + when(service.getAssetGroupInfo("ag")).thenReturn(tTypeMap); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj0 = controller.getAssetGroupInfo("ag"); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + tTypeMap.put("name", "aws-all"); + tTypeList.add(tTypeMap); + + when(service.getAssetGroupInfo("ag")).thenReturn(tTypeMap); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj = controller.getAssetGroupInfo("ag"); + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj.getBody()).get("data") != null); + } + + @Test + public void testgetUserDefaultAssetGroup() throws Exception { + + when(service.getUserDefaultAssetGroup(anyString())).thenReturn("aws-all"); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj = controller.getUserDefaultAssetGroup("userid"); + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj.getBody()).get("data") != null); + + when(service.getUserDefaultAssetGroup(anyString())).thenReturn(""); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj0 = controller.getUserDefaultAssetGroup("userid"); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + } + + @Test + public void testsaveOrUpdateAssetGroup() throws Exception { + DefaultUserAssetGroup defaultUserAssetGroup = new DefaultUserAssetGroup(); + defaultUserAssetGroup.setDefaultAssetGroup("aws-all"); + defaultUserAssetGroup.setUserId("userId"); + defaultUserAssetGroup.getUserId(); + defaultUserAssetGroup.getDefaultAssetGroup(); + + when(service.saveOrUpdateAssetGroup(anyObject())).thenReturn(true); + ReflectionTestUtils.setField(controller, "assetService", service); + + + ResponseEntity responseObj = controller.saveOrUpdateAssetGroup(defaultUserAssetGroup); + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj.getBody()).get("data") != null); + + when(service.saveOrUpdateAssetGroup(anyObject())).thenReturn(false); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj0 = controller.saveOrUpdateAssetGroup(defaultUserAssetGroup); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + } + + @Test + public void testappendToRecentlyViewedAG() throws Exception { + List> agList = new ArrayList<>(); + Map agMap = new HashMap<>(); + agMap.put("name", "aws-all"); + agList.add(agMap); + when(service.saveAndAppendToRecentlyViewedAG(anyObject(), anyObject())).thenReturn(agList); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj = controller.appendToRecentlyViewedAG("userId", "ag"); + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj.getBody()).get("data") != null); + ResponseEntity responseObj0 = controller.appendToRecentlyViewedAG("userId", ""); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + doThrow(new DataException()).when(service).saveAndAppendToRecentlyViewedAG(anyString(),anyString()); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj1 = controller.appendToRecentlyViewedAG("userId", "ag"); + assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + } + + @Test + public void testretrieveAssetConfig() throws Exception { + + when(service.retrieveAssetConfig(anyObject(), anyObject())).thenReturn("{}"); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj = controller.retrieveAssetConfig("a1", "passwordPolicy"); + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj.getBody()).get("data") != null); + + when(service.retrieveAssetConfig(anyObject(), anyObject())).thenReturn(""); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj0 = controller.retrieveAssetConfig("a1", "passwordPolicy"); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + } + + + @Test + public void testsaveAssetConfig() throws Exception { + + when(service.saveAssetConfig(anyObject(), anyObject(), anyObject())).thenReturn(1); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj = controller.saveAssetConfig("a1", "passwordPolicy", "{}"); + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj.getBody()).get("data") != null); + + when(service.saveAssetConfig(anyObject(), anyObject(), anyObject())).thenReturn(0); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj0 = controller.saveAssetConfig("a1", "passwordPolicy", "{}"); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + } + + @Test + public void testupdateAsset() throws Exception { + + AssetUpdateRequest assetUpdateRequest = new AssetUpdateRequest(); + assetUpdateRequest.setAg("ag"); + assetUpdateRequest.setTargettype("targetType"); + assetUpdateRequest.setUpdateBy("update_by"); + assetUpdateRequest.setUpdates(new ArrayList<>()); + assetUpdateRequest.setResources(new HashMap<>()); + + when(service.updateAsset(anyObject(), anyObject(), anyObject(), anyObject(), anyObject())).thenReturn(0); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj4 = controller.updateAsset(assetUpdateRequest); + assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + when(service.updateAsset(anyObject(), anyObject(), anyObject(), anyObject(), anyObject())).thenReturn(1); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj = controller.updateAsset(assetUpdateRequest); + + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj.getBody()).get("data") != null); + + + + assetUpdateRequest.setUpdateBy(null); + ResponseEntity responseObj0 = controller.updateAsset(assetUpdateRequest); + assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); + + assetUpdateRequest.setAg(""); + ResponseEntity responseObj2 = controller.updateAsset(assetUpdateRequest); + assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + assetUpdateRequest.setAg("aws-all"); + assetUpdateRequest.setTargettype(""); + ResponseEntity responseObj3 = controller.updateAsset(assetUpdateRequest); + assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + + + } + + @Test + public void testgetResourceCreatedDate() throws Exception { + + AssetUpdateRequest assetUpdateRequest = new AssetUpdateRequest(); + assetUpdateRequest.setAg("ag"); + assetUpdateRequest.setTargettype("targetType"); + assetUpdateRequest.setUpdateBy("update_by"); + assetUpdateRequest.setUpdates(new ArrayList<>()); + assetUpdateRequest.setResources(new HashMap<>()); + + when(service.getResourceCreatedDate(anyObject(), anyObject())).thenReturn("01-01-2018"); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj = controller.getResourceCreatedDate("a1", "ec2"); + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj.getBody()).get("data").toString().equals("01-01-2018")); + + when(service.getResourceCreatedDate(anyObject(), anyObject())).thenReturn(""); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj1 = controller.getResourceCreatedDate("a1", "ec2"); + assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + when(service.getResourceCreatedDate(anyObject(), anyObject())).thenReturn(null); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj2 = controller.getResourceCreatedDate("a1", "ec2"); + assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + } +} diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetCostControllerTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetCostControllerTest.java new file mode 100644 index 000000000..937b0f0db --- /dev/null +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetCostControllerTest.java @@ -0,0 +1,220 @@ +package com.tmobile.pacman.api.asset.controller; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyList; +import static org.mockito.Matchers.anyString; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.util.ReflectionTestUtils; + +import com.google.common.collect.Lists; +import com.tmobile.pacman.api.asset.domain.ApplicationDetail; +import com.tmobile.pacman.api.asset.domain.ApplicationDetailsResponse; +import com.tmobile.pacman.api.asset.domain.Organization; +import com.tmobile.pacman.api.asset.service.AssetService; +import com.tmobile.pacman.api.asset.service.CostService; +import com.tmobile.pacman.api.commons.utils.ResponseUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ ResponseUtils.class }) +public class AssetCostControllerTest { + + @Mock + CostService costService; + + @Mock + AssetService assetService; + + AssetCostController controller = new AssetCostController(); + + @SuppressWarnings("unchecked") + @Test + public void getAssetCostByApplicationTest() throws Exception { + Map agInfo = new HashMap<>(); + agInfo.put("count","1"); + when(assetService.getAssetGroupInfo(anyString())).thenReturn(agInfo); + ReflectionTestUtils.setField(controller, "assetService", assetService); + ApplicationDetailsResponse applications = buildApplicationDetails(); + when(assetService.getApplicationDetailsByAssetGroup(anyString(), anyString())).thenReturn(applications); + when(assetService.getAllCostTypes()).thenReturn(buildCostTypes()); + when(costService.getCostByApplication(anyString(), anyInt(), anyList(), anyList(), anyList(), anyList())).thenReturn(new HashMap<>()); + ReflectionTestUtils.setField(controller, "costService", costService); + ResponseEntity responseObj0 = controller.getAssetCostByApplication("assetGroupId123", null, null, null, null, null); + assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); + + responseObj0 = controller.getAssetCostByApplication("assetGroupId123", "name123", null, null, null, null); + assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); + + responseObj0 = controller.getAssetCostByApplication("assetGroupId123", null, "type1", null, null, null); + assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); + + responseObj0 = controller.getAssetCostByApplication("assetGroupId123", null, null , 1, 2019, null); + assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); + + responseObj0 = controller.getAssetCostByApplication("assetGroupId123", null, null , null, 2019, 1); + assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); + } + + @Test + public void getAssetCostByApplicationTest_Failed() throws Exception { + + ResponseEntity responseObj0 = controller.getAssetCostByApplication("assetGroupId123", null, null, 1, null, 5); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + ResponseEntity responseObj1 = controller.getAssetCostByApplication("assetGroupId123", null, null, 1, null, null); + assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + ResponseEntity responseObj2 = controller.getAssetCostByApplication("assetGroupId123", null, null, null, 2019, null); + assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + ResponseEntity responseObj3 = controller.getAssetCostByApplication("assetGroupId123", null, null, null, null, 5); + assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + ResponseEntity responseObj4 = controller.getAssetCostByApplication("assetGroupId123", null, null, 5, 2019, null); + assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + responseObj4 = controller.getAssetCostByApplication("assetGroupId123", null, null, 0, 2019, null); + assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + ResponseEntity responseObj5 = controller.getAssetCostByApplication("assetGroupId123", null, null, null, 2019, 13); + assertTrue(responseObj5.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + responseObj5 = controller.getAssetCostByApplication("assetGroupId123", null, null, null, 2019, 0); + assertTrue(responseObj5.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + ResponseEntity responseObj6 = controller.getAssetCostByApplication("assetGroupId123", null, null, 1, 2017, null); + assertTrue(responseObj6.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + when(assetService.getAssetGroupInfo(anyString())).thenReturn(new HashMap<>()); + ReflectionTestUtils.setField(controller, "assetService", assetService); + ResponseEntity responseObj9 = controller.getAssetCostByApplication("assetGroupId123", null, null, null, null, null); + assertTrue(responseObj9.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + Map agInfo = new HashMap<>(); + agInfo.put("count","1"); + when(assetService.getAssetGroupInfo(anyString())).thenReturn(agInfo); + ReflectionTestUtils.setField(controller, "assetService", assetService); + ApplicationDetailsResponse applications = buildApplicationDetails(); + when(assetService.getApplicationDetailsByAssetGroup(anyString(), anyString())).thenReturn(applications); + + ResponseEntity responseObj7 = controller.getAssetCostByApplication("assetGroupId123", "test", null, null, null, null); + assertTrue(responseObj7.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + ResponseEntity responseObj8 = controller.getAssetCostByApplication("assetGroupId123", null, "test", null, null, null); + assertTrue(responseObj8.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + } + + @SuppressWarnings("unchecked") + @Test + public void getAssetCostByApplicationTest_Exception() throws Exception { + Map agInfo = new HashMap<>(); + agInfo.put("count","1"); + when(assetService.getAssetGroupInfo(anyString())).thenReturn(agInfo); + ReflectionTestUtils.setField(controller, "assetService", assetService); + ApplicationDetailsResponse applications = buildApplicationDetails(); + when(assetService.getApplicationDetailsByAssetGroup(anyString(), anyString())).thenReturn(applications); + when(assetService.getAllCostTypes()).thenReturn(buildCostTypes()); + when(costService.getCostByApplication(anyString(), anyInt(), anyList(), anyList(), anyList(), anyList())).thenThrow(new Exception()); + ReflectionTestUtils.setField(controller, "costService", costService); + ResponseEntity responseObj0 = controller.getAssetCostByApplication("assetGroupId123", null, null, null, null, null); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + } + + @SuppressWarnings("unchecked") + @Test + public void getAssetCostByTypeTest() throws Exception { + Map agInfo = new HashMap<>(); + agInfo.put("count","1"); + when(assetService.getAssetGroupInfo(anyString())).thenReturn(agInfo); + ReflectionTestUtils.setField(controller, "assetService", assetService); + ApplicationDetailsResponse applications = buildApplicationDetails(); + when(assetService.getApplicationDetailsByAssetGroup(anyString(), anyString())).thenReturn(applications); + when(assetService.getAllCostTypes()).thenReturn(buildCostTypes()); + when(costService.getCostByType(anyString(), anyInt(), anyList(), anyList(), anyList())).thenReturn(new HashMap<>()); + ReflectionTestUtils.setField(controller, "costService", costService); + ResponseEntity responseObj0 = controller.getAssetCostByType("assetGroupId123", null, null, null, null, null); + assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); + + } + + private ApplicationDetailsResponse buildApplicationDetails() + { + Organization organization = new Organization(); + organization.setDesignation("designation123"); + organization.setName("name123"); + ApplicationDetail applicationDetail = new ApplicationDetail(); + applicationDetail.setAssetGroupId("assetGroupId123"); + applicationDetail.setDescription("description123"); + applicationDetail.setName("name123"); + applicationDetail.setOrganization(Lists.newArrayList(organization)); + ApplicationDetailsResponse applicationDetailsResponse = new ApplicationDetailsResponse(); + applicationDetailsResponse.setInvalidApplications(Lists.newArrayList(applicationDetail)); + applicationDetailsResponse.setValidApplications(Lists.newArrayList(applicationDetail)); + return applicationDetailsResponse; + } + + private List> buildCostTypes() { + List> costTypes = new ArrayList<>(); + Map costType = new HashMap<>(); + costType.put("type", "type1"); + costTypes.add(costType); + return costTypes; + } + + @SuppressWarnings("unchecked") + @Test + public void getAssetCostTrendByTypeTest() throws Exception { + + ApplicationDetailsResponse applications = buildApplicationDetails(); + when(assetService.getApplicationDetailsByAssetGroup(anyString(), anyString())).thenReturn(applications); + ReflectionTestUtils.setField(controller, "assetService", assetService); + when(assetService.getAllCostTypes()).thenReturn(buildCostTypes()); + when(costService.getCostTrend(anyList(), anyList(), anyString())).thenReturn(new ArrayList<>()); + ReflectionTestUtils.setField(controller, "costService", costService); + ResponseEntity responseObj0 = controller.getAssetCostTrendByType("assetGroupId123", null, null, Period.monthly); + assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); + + responseObj0 = controller.getAssetCostTrendByType("assetGroupId123", "name123", null, Period.monthly); + assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); + + responseObj0 = controller.getAssetCostTrendByType("assetGroupId123", null, "type1", Period.quarterly); + assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); + + } + + @SuppressWarnings("unchecked") + @Test + public void getAssetCostTrendByTypeTest_Failed() throws Exception { + + ResponseEntity responseObj7 = controller.getAssetCostTrendByType("assetGroupId123", "test", null, Period.monthly); + assertTrue(responseObj7.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + ResponseEntity responseObj8 = controller.getAssetCostTrendByType("assetGroupId123", null, "test", Period.monthly); + assertTrue(responseObj8.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + ApplicationDetailsResponse applications = buildApplicationDetails(); + when(assetService.getApplicationDetailsByAssetGroup(anyString(), anyString())).thenReturn(applications); + ReflectionTestUtils.setField(controller, "assetService", assetService); + when(assetService.getAllCostTypes()).thenReturn(buildCostTypes()); + when(costService.getCostTrend(anyList(), anyList(), anyString())).thenThrow(new Exception()); + ReflectionTestUtils.setField(controller, "costService", costService); + ResponseEntity responseObj0 = controller.getAssetCostTrendByType("assetGroupId123", null, null, Period.monthly); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + } +} diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetCountControllerTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetCountControllerTest.java index adf8635e6..b8d12f28b 100644 --- a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetCountControllerTest.java +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetCountControllerTest.java @@ -1,138 +1,138 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ -package com.tmobile.pacman.api.asset.controller; - -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.anyString; -import static org.powermock.api.mockito.PowerMockito.doThrow; -import static org.powermock.api.mockito.PowerMockito.mockStatic; -import static org.powermock.api.mockito.PowerMockito.when; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.util.ReflectionTestUtils; - -import com.tmobile.pacman.api.asset.service.AssetService; -import com.tmobile.pacman.api.commons.exception.DataException; -import com.tmobile.pacman.api.commons.utils.ResponseUtils; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({ ResponseUtils.class, Util.class }) -public class AssetCountControllerTest { - - @Mock - AssetService service; - - AssetCountController controller = new AssetCountController(); - - @Test - public void testgeAssetCount() throws Exception { - List> tTypeList = new ArrayList<>(); - - when(service.getAssetCountByAssetGroup(anyObject(), anyObject(), anyObject())).thenReturn(tTypeList); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj3 = controller.geAssetCount("ag", "type", "domain"); - - assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - Map tTypeMap = new HashMap<>(); - tTypeMap.put("count", "100"); - tTypeMap.put("type", "ec2"); - tTypeList.add(tTypeMap); - - when(service.getAssetCountByAssetGroup(anyObject(), anyObject(), anyObject())).thenReturn(tTypeList); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj = controller.geAssetCount("ag", "type", "domain"); - - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj.getBody()).get("data") != null); - - ResponseEntity responseObj2 = controller.geAssetCount("ag", null, "domain"); - assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); - - } - - @Test - public void testgeAssetCountByTypeAndApplication() throws Exception { - List> tTypeList = new ArrayList<>(); - Map tTypeMap = new HashMap<>(); - tTypeMap.put("count", "100"); - tTypeMap.put("type", "ec2"); - tTypeList.add(tTypeMap); - - mockStatic(Util.class); - when(Util.isValidTargetType(anyString(), anyString())).thenReturn(true, true, false); - when(service.getAssetCountByApplication(anyObject(), anyObject())).thenReturn(tTypeList); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj = controller.geAssetCountByTypeAndApplication("ag", "type"); - - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj.getBody()).get("data") != null); - - doThrow(new DataException()).when(service).getAssetCountByApplication(anyObject(), anyObject()); - responseObj = controller.geAssetCountByTypeAndApplication("ag", "type"); - - assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - responseObj = controller.geAssetCountByTypeAndApplication("ag", "type"); - - assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - } - - @Test - public void testgeAssetCountByTypeEnvironment() throws Exception { - List> tTypeList = new ArrayList<>(); - Map tTypeMap = new HashMap<>(); - tTypeMap.put("count", "100"); - tTypeMap.put("type", "ec2"); - tTypeList.add(tTypeMap); - - mockStatic(Util.class); - when(Util.isValidTargetType(anyString(), anyString())).thenReturn(true, true, false); - when(service.getAssetCountByEnvironment(anyObject(), anyObject(), anyObject())).thenReturn(tTypeList); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj = controller.geAssetCountByTypeEnvironment("ag", "app", "type"); - - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj.getBody()).get("data") != null); - - doThrow(new NullPointerException()).when(service).getAssetCountByEnvironment(anyObject(), anyObject(), anyObject()); - responseObj = controller.geAssetCountByTypeEnvironment("ag", "app", "type"); - - assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - responseObj = controller.geAssetCountByTypeEnvironment("ag", "app", "type"); - - assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - } -} +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.api.asset.controller; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.powermock.api.mockito.PowerMockito.doThrow; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.util.ReflectionTestUtils; + +import com.tmobile.pacman.api.asset.service.AssetService; +import com.tmobile.pacman.api.commons.exception.DataException; +import com.tmobile.pacman.api.commons.utils.ResponseUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ ResponseUtils.class, Util.class }) +public class AssetCountControllerTest { + + @Mock + AssetService service; + + AssetCountController controller = new AssetCountController(); + + @Test + public void testgeAssetCount() throws Exception { + List> tTypeList = new ArrayList<>(); + + when(service.getAssetCountByAssetGroup(anyObject(), anyObject(), anyObject())).thenReturn(tTypeList); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj3 = controller.geAssetCount("ag", "type", "domain"); + + assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + Map tTypeMap = new HashMap<>(); + tTypeMap.put("count", "100"); + tTypeMap.put("type", "ec2"); + tTypeList.add(tTypeMap); + + when(service.getAssetCountByAssetGroup(anyObject(), anyObject(), anyObject())).thenReturn(tTypeList); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj = controller.geAssetCount("ag", "type", "domain"); + + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj.getBody()).get("data") != null); + + ResponseEntity responseObj2 = controller.geAssetCount("ag", null, "domain"); + assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); + + } + + @Test + public void testgeAssetCountByTypeAndApplication() throws Exception { + List> tTypeList = new ArrayList<>(); + Map tTypeMap = new HashMap<>(); + tTypeMap.put("count", "100"); + tTypeMap.put("type", "ec2"); + tTypeList.add(tTypeMap); + + mockStatic(Util.class); + when(Util.isValidTargetType(anyString(), anyString())).thenReturn(true, true, false); + when(service.getAssetCountByApplication(anyObject(), anyObject())).thenReturn(tTypeList); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj = controller.geAssetCountByTypeAndApplication("ag", "type"); + + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj.getBody()).get("data") != null); + + doThrow(new DataException()).when(service).getAssetCountByApplication(anyObject(), anyObject()); + responseObj = controller.geAssetCountByTypeAndApplication("ag", "type"); + + assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + responseObj = controller.geAssetCountByTypeAndApplication("ag", "type"); + + assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + } + + @Test + public void testgeAssetCountByTypeEnvironment() throws Exception { + List> tTypeList = new ArrayList<>(); + Map tTypeMap = new HashMap<>(); + tTypeMap.put("count", "100"); + tTypeMap.put("type", "ec2"); + tTypeList.add(tTypeMap); + + mockStatic(Util.class); + when(Util.isValidTargetType(anyString(), anyString())).thenReturn(true, true, false); + when(service.getAssetCountByEnvironment(anyObject(), anyObject(), anyObject())).thenReturn(tTypeList); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj = controller.geAssetCountByTypeEnvironment("ag", "app", "type"); + + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj.getBody()).get("data") != null); + + doThrow(new NullPointerException()).when(service).getAssetCountByEnvironment(anyObject(), anyObject(), anyObject()); + responseObj = controller.geAssetCountByTypeEnvironment("ag", "app", "type"); + + assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + responseObj = controller.geAssetCountByTypeEnvironment("ag", "app", "type"); + + assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + } +} diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetDetailControllerTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetDetailControllerTest.java index 8c4a18d2f..5b11a73dc 100644 --- a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetDetailControllerTest.java +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetDetailControllerTest.java @@ -1,413 +1,413 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ -package com.tmobile.pacman.api.asset.controller; - -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.anyString; -import static org.powermock.api.mockito.PowerMockito.doThrow; -import static org.powermock.api.mockito.PowerMockito.when; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.util.ReflectionTestUtils; - -import com.tmobile.pacman.api.asset.client.ComplianceServiceClient; -import com.tmobile.pacman.api.asset.domain.PageFilterRequest; -import com.tmobile.pacman.api.asset.domain.PolicyViolationApi; -import com.tmobile.pacman.api.asset.domain.PolicyViolationApiData; -import com.tmobile.pacman.api.asset.service.AssetService; -import com.tmobile.pacman.api.commons.exception.DataException; -import com.tmobile.pacman.api.commons.utils.ResponseUtils; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({ ResponseUtils.class }) -public class AssetDetailControllerTest { - - @Mock - AssetService service; - - @Mock - ComplianceServiceClient complianceServiceClient; - - AssetDetailController controller = new AssetDetailController(); - - @Test - public void testgetCPUUtilizationByInstanceId() throws Exception { - List> utilList = new ArrayList<>(); - Map utilMap = new HashMap<>(); - utilMap.put("date", "d1"); - utilMap.put("cpu-utilization", 50); - utilList.add(utilMap); - - when(service.getInstanceCPUUtilization(anyObject())).thenReturn(utilList); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj1 = controller.getCPUUtilizationByInstanceId(""); - assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - ResponseEntity responseObj2 = controller.getCPUUtilizationByInstanceId("a1"); - assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj2.getBody()).get("data") != null); - - doThrow(new DataException()).when(service).getInstanceCPUUtilization(anyObject()); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj0 = controller.getCPUUtilizationByInstanceId("a1"); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - } - - @Test - public void testgetDiskUtilizationByInstanceId() throws Exception { - List> utilList = new ArrayList<>(); - Map utilMap = new HashMap<>(); - utilMap.put("date", "d1"); - utilMap.put("disk-utilization", 50); - utilList.add(utilMap); - - when(service.getInstanceDiskUtilization(anyObject())).thenReturn(utilList); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj1 = controller.getDiskUtilizationByInstanceId(""); - assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - ReflectionTestUtils.setField(controller, "qualysEnabled", true); - ResponseEntity responseObj2 = controller.getDiskUtilizationByInstanceId("a1"); - assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj2.getBody()).get("data") != null); - - doThrow(new DataException()).when(service).getInstanceDiskUtilization(anyObject()); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj0 = controller.getDiskUtilizationByInstanceId("a1"); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - } - - @Test - public void testgetInstalledSoftwareDetailsByInstanceId() throws Exception { - List> softwareList = new ArrayList<>(); - - when(service.getInstanceSoftwareInstallDetails(anyObject(), anyObject(), anyObject(), anyObject())) - .thenReturn(softwareList); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj0 = controller.getInstalledSoftwareDetailsByInstanceId("a1", 1, 1, "pacman"); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - Map softwareMap1 = new HashMap<>(); - softwareMap1.put("name", "x"); - softwareMap1.put("value", "y"); - Map softwareMap2 = new HashMap<>(); - softwareMap2.put("name", "p"); - softwareMap2.put("value", "q"); - softwareList.add(softwareMap2); - Map softwareMap3 = new HashMap<>(); - softwareMap3.put("name", "a"); - softwareMap3.put("value", "b"); - softwareList.add(softwareMap3); - - when(service.getInstanceSoftwareInstallDetails(anyObject(), anyObject(), anyObject(), anyObject())) - .thenReturn(softwareList); - ReflectionTestUtils.setField(controller, "assetService", service); - ReflectionTestUtils.setField(controller, "qualysEnabled", true); - - ResponseEntity responseObj1 = controller.getInstalledSoftwareDetailsByInstanceId("a1", 0, 1, "pacman"); - assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj1.getBody()).get("data") != null); - - ResponseEntity responseObj2 = controller.getInstalledSoftwareDetailsByInstanceId("a1", 1, 1, "pacman"); - assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj2.getBody()).get("data") != null); - - ResponseEntity responseObj3 = controller.getInstalledSoftwareDetailsByInstanceId("a1", 6, 1, "pacman"); - assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - ResponseEntity responseObj4 = controller.getInstalledSoftwareDetailsByInstanceId("", 1, 1, "pacman"); - assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - ResponseEntity responseObj5 = controller.getInstalledSoftwareDetailsByInstanceId("a1", 1, 8, "pacman"); - assertTrue(responseObj5.getStatusCode() == HttpStatus.OK); - - ResponseEntity responseObj6 = controller.getInstalledSoftwareDetailsByInstanceId("a1", 0, 0, "pacman"); - assertTrue(responseObj6.getStatusCode() == HttpStatus.OK); - - ResponseEntity responseObj7 = controller.getInstalledSoftwareDetailsByInstanceId("a1", null, 0, - "pacman"); - assertTrue(responseObj7.getStatusCode() == HttpStatus.OK); - } - - @Test - public void testgetOpenPortsByInstanceId() throws Exception { - List> softwareList = new ArrayList<>(); - - when(service.getInstanceSoftwareInstallDetails(anyObject(), anyObject(), anyObject(), anyObject())) - .thenReturn(softwareList); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj0 = controller.getOpenPortsByInstanceId("a1", 1, 1, "pacman"); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - Map softwareMap1 = new HashMap<>(); - softwareMap1.put("name", "x"); - softwareMap1.put("value", "y"); - Map softwareMap2 = new HashMap<>(); - softwareMap2.put("name", "p"); - softwareMap2.put("value", "q"); - softwareList.add(softwareMap2); - Map softwareMap3 = new HashMap<>(); - softwareMap3.put("name", "a"); - softwareMap3.put("value", "b"); - softwareList.add(softwareMap3); - - when(service.getOpenPortDetails(anyObject(), anyObject(), anyObject(), anyObject())).thenReturn(softwareList); - ReflectionTestUtils.setField(controller, "assetService", service); - ReflectionTestUtils.setField(controller, "qualysEnabled", true); - - ResponseEntity responseObj1 = controller.getOpenPortsByInstanceId("a1", 0, 1, "pacman"); - assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj1.getBody()).get("data") != null); - - ResponseEntity responseObj2 = controller.getOpenPortsByInstanceId("a1", 1, 1, "pacman"); - assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj2.getBody()).get("data") != null); - - ResponseEntity responseObj3 = controller.getOpenPortsByInstanceId("a1", 6, 1, "pacman"); - assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - ResponseEntity responseObj4 = controller.getOpenPortsByInstanceId("", 1, 1, "pacman"); - assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - ResponseEntity responseObj5 = controller.getOpenPortsByInstanceId("a1", 1, 8, "pacman"); - assertTrue(responseObj5.getStatusCode() == HttpStatus.OK); - - ResponseEntity responseObj6 = controller.getOpenPortsByInstanceId("a1", 0, 0, "pacman"); - assertTrue(responseObj6.getStatusCode() == HttpStatus.OK); - - ResponseEntity responseObj7 = controller.getOpenPortsByInstanceId("a1", null, 0, "pacman"); - assertTrue(responseObj7.getStatusCode() == HttpStatus.OK); - } - - @Test - public void testgetAwsNotificationSummary() throws Exception { - List> notiList = new ArrayList<>(); - Map notiMap = new HashMap<>(); - notiMap.put("name", "a"); - notiMap.put("vaule", "b"); - notiList.add(notiMap); - when(service.getNotificationSummary(anyString())).thenReturn(notiList); - when(service.getNotificationSummaryTotal(anyObject())).thenReturn("total"); - - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj1 = controller.getAwsNotificationSummary("a1"); - assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj1.getBody()).get("data") != null); - - ResponseEntity responseObj2 = controller.getAwsNotificationSummary(""); - assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - doThrow(new NullPointerException()).when(service).getNotificationSummary(anyString()); - ResponseEntity responseObj3 = controller.getAwsNotificationSummary("a1"); - assertTrue(((Map) responseObj3.getBody()).get("data") != null); - - } - - @Test - public void testgetAwsNotificationDetails() throws Exception { - List> notiList = new ArrayList<>(); - PageFilterRequest pageFilterRequest = new PageFilterRequest(); - pageFilterRequest.setFrom(1); - pageFilterRequest.setSize(1); - pageFilterRequest.setSearchText("pacman"); - pageFilterRequest.setFilter(null); - - pageFilterRequest.getFilter(); - pageFilterRequest.getFrom(); - pageFilterRequest.getSize(); - pageFilterRequest.getSearchText(); - - when(service.getNotificationDetails(anyString(), anyObject(), anyString())).thenReturn(notiList); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj0 = controller.getAwsNotificationDetails(pageFilterRequest, "a1"); - assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); - - Map notiMap1 = new HashMap<>(); - notiMap1.put("name", "x"); - notiMap1.put("value", "y"); - notiList.add(notiMap1); - Map notiMap2 = new HashMap<>(); - notiMap2.put("name", "p"); - notiMap2.put("value", "q"); - notiList.add(notiMap2); - Map notiMap3 = new HashMap<>(); - notiMap3.put("name", "a"); - notiMap3.put("value", "b"); - notiList.add(notiMap3); - - when(service.getNotificationDetails(anyString(), anyObject(), anyString())).thenReturn(notiList); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj1 = controller.getAwsNotificationDetails(pageFilterRequest, "a1"); - assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); - - ResponseEntity responseObj2 = controller.getAwsNotificationDetails(pageFilterRequest, ""); - assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - pageFilterRequest.setFrom(-1); - ResponseEntity responseObj3 = controller.getAwsNotificationDetails(pageFilterRequest, "a1"); - assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - pageFilterRequest.setFrom(18); - ResponseEntity responseObj4 = controller.getAwsNotificationDetails(pageFilterRequest, "a1"); - assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - pageFilterRequest.setFrom(1); - pageFilterRequest.setSize(8); - ResponseEntity responseObj5 = controller.getAwsNotificationDetails(pageFilterRequest, "a1"); - assertTrue(responseObj5.getStatusCode() == HttpStatus.OK); - - pageFilterRequest.setFrom(1); - pageFilterRequest.setSize(-1); - ResponseEntity responseObj6 = controller.getAwsNotificationDetails(pageFilterRequest, "a1"); - assertTrue(responseObj6.getStatusCode() == HttpStatus.OK); - - } - - @Test - public void testgetEc2CreatorDetail() throws Exception { - Map creatorMap = new HashMap<>(); - creatorMap.put("creationDate", "x"); - creatorMap.put("userid", "y"); - when(service.getEc2CreatorDetail(anyString())).thenReturn(creatorMap); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj1 = controller.getEc2CreatorDetail("ag", "ec2", "a1"); - assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); - - doThrow(new NullPointerException()).when(service).getEc2CreatorDetail("a1"); - ResponseEntity responseObj2 = controller.getEc2CreatorDetail("ag", "ec2", "a1"); - assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); - } - - @Test - public void testgetAdGroupsDetail() throws Exception { - List> adList = new ArrayList<>(); - Map adMap = new HashMap<>(); - adMap.put("group", "x"); - adMap.put("admin", "y"); - adList.add(adMap); - when(service.getAdGroupsDetail(anyString(), anyString())).thenReturn(adList); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj1 = controller.getAdGroupsDetail("ag", "a1"); - assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); - - doThrow(new NullPointerException()).when(service).getAdGroupsDetail(anyString(), anyString()); - ResponseEntity responseObj2 = controller.getAdGroupsDetail("ag", "a1"); - assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); - } - - @Test - public void testgetEc2ResourceSummary() throws Exception { - List> ec2List = new ArrayList<>(); - Map ec2Map = new HashMap<>(); - ec2Map.put("resourceid", "x"); - ec2Map.put("ipaddress", "y"); - ec2List.add(ec2Map); - when(service.getEC2AvgAndTotalCost(anyString())).thenReturn(ec2Map); - - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj1 = controller.getEc2ResourceSummary("a1"); - assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj1.getBody()).get("data") != null); - - doThrow(new NullPointerException()).when(service).getEC2AvgAndTotalCost(anyString()); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj2 = controller.getEc2ResourceSummary("a1"); - assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); - - } - - @Test - public void testgetEc2ResourceDetail() throws Exception { - List> ec2List = new ArrayList<>(); - Map ec2Map = new HashMap<>(); - ec2Map.put("resourceid", "x"); - ec2Map.put("ipaddress", "y"); - ec2List.add(ec2Map); - when(service.getEc2ResourceDetail(anyString(), anyString())).thenReturn(ec2Map); - when(service.getGenericResourceDetail(anyString(), anyString(), anyString())).thenReturn(ec2Map); - - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj1 = controller.getEc2ResourceDetail("ag", "ec2", "a1"); - assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj1.getBody()).get("data") != null); - - doThrow(new NullPointerException()).when(service).getEc2ResourceDetail(anyString(), anyString()); - ResponseEntity responseObj2 = controller.getEc2ResourceDetail("ag", "ec2", "a1"); - assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); - - ResponseEntity responseObj3 = controller.getEc2ResourceDetail("ag", "s3", "a1"); - assertTrue(responseObj3.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj3.getBody()).get("data") != null); - - } - - @Test - public void testgetEc2ResourceSummary1() throws Exception { - - PolicyViolationApiData violationData = new PolicyViolationApiData(); - violationData.setCompliance("75"); - String compliance = violationData.getCompliance(); - - PolicyViolationApi violationSummary = new PolicyViolationApi(); - violationSummary.setData(violationData); - violationSummary.getData(); - violationSummary.setMessage("Compliance Data"); - violationSummary.getMessage(); - violationSummary.toString(); - - List> utilList = new ArrayList<>(); - Map utilMap = new HashMap<>(); - utilMap.put("date", "d1"); - utilMap.put("cpu-utilization", 50); - utilList.add(utilMap); - - when(complianceServiceClient.getPolicyViolationSummary(anyString(), anyString(), anyString())) - .thenReturn(violationSummary); - when(service.getEc2StateDetail(anyString(), anyString())).thenReturn("Started"); - when(service.getInstanceCPUUtilization(anyString())).thenReturn(utilList); - - ReflectionTestUtils.setField(controller, "complianceServiceClient", complianceServiceClient); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj1 = controller.getEc2ResourceSummary("ag", "ec2", "a1"); - assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); - assertTrue(((Map) responseObj1.getBody()).get("data") != null); - - doThrow(new NullPointerException()).when(service).getInstanceCPUUtilization(anyString()); - ResponseEntity responseObj2 = controller.getEc2ResourceSummary("ag", "ec2", "a1"); - assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); - - doThrow(new NullPointerException()).when(service).getEc2StateDetail(anyString(),anyString()); - ResponseEntity responseObj3 = controller.getEc2ResourceSummary("ag", "ec2", "a1"); - assertTrue(responseObj3.getStatusCode() == HttpStatus.OK); - } - -} +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.api.asset.controller; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.powermock.api.mockito.PowerMockito.doThrow; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.util.ReflectionTestUtils; + +import com.tmobile.pacman.api.asset.client.ComplianceServiceClient; +import com.tmobile.pacman.api.asset.domain.PageFilterRequest; +import com.tmobile.pacman.api.asset.domain.PolicyViolationApi; +import com.tmobile.pacman.api.asset.domain.PolicyViolationApiData; +import com.tmobile.pacman.api.asset.service.AssetService; +import com.tmobile.pacman.api.commons.exception.DataException; +import com.tmobile.pacman.api.commons.utils.ResponseUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ ResponseUtils.class }) +public class AssetDetailControllerTest { + + @Mock + AssetService service; + + @Mock + ComplianceServiceClient complianceServiceClient; + + AssetDetailController controller = new AssetDetailController(); + + @Test + public void testgetCPUUtilizationByInstanceId() throws Exception { + List> utilList = new ArrayList<>(); + Map utilMap = new HashMap<>(); + utilMap.put("date", "d1"); + utilMap.put("cpu-utilization", 50); + utilList.add(utilMap); + + when(service.getInstanceCPUUtilization(anyObject())).thenReturn(utilList); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj1 = controller.getCPUUtilizationByInstanceId(""); + assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + ResponseEntity responseObj2 = controller.getCPUUtilizationByInstanceId("a1"); + assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj2.getBody()).get("data") != null); + + doThrow(new DataException()).when(service).getInstanceCPUUtilization(anyObject()); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj0 = controller.getCPUUtilizationByInstanceId("a1"); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + } + + @Test + public void testgetDiskUtilizationByInstanceId() throws Exception { + List> utilList = new ArrayList<>(); + Map utilMap = new HashMap<>(); + utilMap.put("date", "d1"); + utilMap.put("disk-utilization", 50); + utilList.add(utilMap); + + when(service.getInstanceDiskUtilization(anyObject())).thenReturn(utilList); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj1 = controller.getDiskUtilizationByInstanceId(""); + assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + ReflectionTestUtils.setField(controller, "qualysEnabled", true); + ResponseEntity responseObj2 = controller.getDiskUtilizationByInstanceId("a1"); + assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj2.getBody()).get("data") != null); + + doThrow(new DataException()).when(service).getInstanceDiskUtilization(anyObject()); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj0 = controller.getDiskUtilizationByInstanceId("a1"); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + } + + @Test + public void testgetInstalledSoftwareDetailsByInstanceId() throws Exception { + List> softwareList = new ArrayList<>(); + + when(service.getInstanceSoftwareInstallDetails(anyObject(), anyObject(), anyObject(), anyObject())) + .thenReturn(softwareList); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj0 = controller.getInstalledSoftwareDetailsByInstanceId("a1", 1, 1, "pacman"); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + Map softwareMap1 = new HashMap<>(); + softwareMap1.put("name", "x"); + softwareMap1.put("value", "y"); + Map softwareMap2 = new HashMap<>(); + softwareMap2.put("name", "p"); + softwareMap2.put("value", "q"); + softwareList.add(softwareMap2); + Map softwareMap3 = new HashMap<>(); + softwareMap3.put("name", "a"); + softwareMap3.put("value", "b"); + softwareList.add(softwareMap3); + + when(service.getInstanceSoftwareInstallDetails(anyObject(), anyObject(), anyObject(), anyObject())) + .thenReturn(softwareList); + ReflectionTestUtils.setField(controller, "assetService", service); + ReflectionTestUtils.setField(controller, "qualysEnabled", true); + + ResponseEntity responseObj1 = controller.getInstalledSoftwareDetailsByInstanceId("a1", 0, 1, "pacman"); + assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj1.getBody()).get("data") != null); + + ResponseEntity responseObj2 = controller.getInstalledSoftwareDetailsByInstanceId("a1", 1, 1, "pacman"); + assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj2.getBody()).get("data") != null); + + ResponseEntity responseObj3 = controller.getInstalledSoftwareDetailsByInstanceId("a1", 6, 1, "pacman"); + assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + ResponseEntity responseObj4 = controller.getInstalledSoftwareDetailsByInstanceId("", 1, 1, "pacman"); + assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + ResponseEntity responseObj5 = controller.getInstalledSoftwareDetailsByInstanceId("a1", 1, 8, "pacman"); + assertTrue(responseObj5.getStatusCode() == HttpStatus.OK); + + ResponseEntity responseObj6 = controller.getInstalledSoftwareDetailsByInstanceId("a1", 0, 0, "pacman"); + assertTrue(responseObj6.getStatusCode() == HttpStatus.OK); + + ResponseEntity responseObj7 = controller.getInstalledSoftwareDetailsByInstanceId("a1", null, 0, + "pacman"); + assertTrue(responseObj7.getStatusCode() == HttpStatus.OK); + } + + @Test + public void testgetOpenPortsByInstanceId() throws Exception { + List> softwareList = new ArrayList<>(); + + when(service.getInstanceSoftwareInstallDetails(anyObject(), anyObject(), anyObject(), anyObject())) + .thenReturn(softwareList); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj0 = controller.getOpenPortsByInstanceId("a1", 1, 1, "pacman"); + assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + Map softwareMap1 = new HashMap<>(); + softwareMap1.put("name", "x"); + softwareMap1.put("value", "y"); + Map softwareMap2 = new HashMap<>(); + softwareMap2.put("name", "p"); + softwareMap2.put("value", "q"); + softwareList.add(softwareMap2); + Map softwareMap3 = new HashMap<>(); + softwareMap3.put("name", "a"); + softwareMap3.put("value", "b"); + softwareList.add(softwareMap3); + + when(service.getOpenPortDetails(anyObject(), anyObject(), anyObject(), anyObject())).thenReturn(softwareList); + ReflectionTestUtils.setField(controller, "assetService", service); + ReflectionTestUtils.setField(controller, "qualysEnabled", true); + + ResponseEntity responseObj1 = controller.getOpenPortsByInstanceId("a1", 0, 1, "pacman"); + assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj1.getBody()).get("data") != null); + + ResponseEntity responseObj2 = controller.getOpenPortsByInstanceId("a1", 1, 1, "pacman"); + assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj2.getBody()).get("data") != null); + + ResponseEntity responseObj3 = controller.getOpenPortsByInstanceId("a1", 6, 1, "pacman"); + assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + ResponseEntity responseObj4 = controller.getOpenPortsByInstanceId("", 1, 1, "pacman"); + assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + ResponseEntity responseObj5 = controller.getOpenPortsByInstanceId("a1", 1, 8, "pacman"); + assertTrue(responseObj5.getStatusCode() == HttpStatus.OK); + + ResponseEntity responseObj6 = controller.getOpenPortsByInstanceId("a1", 0, 0, "pacman"); + assertTrue(responseObj6.getStatusCode() == HttpStatus.OK); + + ResponseEntity responseObj7 = controller.getOpenPortsByInstanceId("a1", null, 0, "pacman"); + assertTrue(responseObj7.getStatusCode() == HttpStatus.OK); + } + + @Test + public void testgetAwsNotificationSummary() throws Exception { + List> notiList = new ArrayList<>(); + Map notiMap = new HashMap<>(); + notiMap.put("name", "a"); + notiMap.put("vaule", "b"); + notiList.add(notiMap); + when(service.getNotificationSummary(anyString())).thenReturn(notiList); + when(service.getNotificationSummaryTotal(anyObject())).thenReturn("total"); + + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj1 = controller.getAwsNotificationSummary("a1"); + assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj1.getBody()).get("data") != null); + + ResponseEntity responseObj2 = controller.getAwsNotificationSummary(""); + assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + doThrow(new NullPointerException()).when(service).getNotificationSummary(anyString()); + ResponseEntity responseObj3 = controller.getAwsNotificationSummary("a1"); + assertTrue(((Map) responseObj3.getBody()).get("data") != null); + + } + + @Test + public void testgetAwsNotificationDetails() throws Exception { + List> notiList = new ArrayList<>(); + PageFilterRequest pageFilterRequest = new PageFilterRequest(); + pageFilterRequest.setFrom(1); + pageFilterRequest.setSize(1); + pageFilterRequest.setSearchText("pacman"); + pageFilterRequest.setFilter(null); + + pageFilterRequest.getFilter(); + pageFilterRequest.getFrom(); + pageFilterRequest.getSize(); + pageFilterRequest.getSearchText(); + + when(service.getNotificationDetails(anyString(), anyObject(), anyString())).thenReturn(notiList); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj0 = controller.getAwsNotificationDetails(pageFilterRequest, "a1"); + assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); + + Map notiMap1 = new HashMap<>(); + notiMap1.put("name", "x"); + notiMap1.put("value", "y"); + notiList.add(notiMap1); + Map notiMap2 = new HashMap<>(); + notiMap2.put("name", "p"); + notiMap2.put("value", "q"); + notiList.add(notiMap2); + Map notiMap3 = new HashMap<>(); + notiMap3.put("name", "a"); + notiMap3.put("value", "b"); + notiList.add(notiMap3); + + when(service.getNotificationDetails(anyString(), anyObject(), anyString())).thenReturn(notiList); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj1 = controller.getAwsNotificationDetails(pageFilterRequest, "a1"); + assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); + + ResponseEntity responseObj2 = controller.getAwsNotificationDetails(pageFilterRequest, ""); + assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + pageFilterRequest.setFrom(-1); + ResponseEntity responseObj3 = controller.getAwsNotificationDetails(pageFilterRequest, "a1"); + assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + pageFilterRequest.setFrom(18); + ResponseEntity responseObj4 = controller.getAwsNotificationDetails(pageFilterRequest, "a1"); + assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + pageFilterRequest.setFrom(1); + pageFilterRequest.setSize(8); + ResponseEntity responseObj5 = controller.getAwsNotificationDetails(pageFilterRequest, "a1"); + assertTrue(responseObj5.getStatusCode() == HttpStatus.OK); + + pageFilterRequest.setFrom(1); + pageFilterRequest.setSize(-1); + ResponseEntity responseObj6 = controller.getAwsNotificationDetails(pageFilterRequest, "a1"); + assertTrue(responseObj6.getStatusCode() == HttpStatus.OK); + + } + + @Test + public void testgetEc2CreatorDetail() throws Exception { + Map creatorMap = new HashMap<>(); + creatorMap.put("creationDate", "x"); + creatorMap.put("userid", "y"); + when(service.getEc2CreatorDetail(anyString())).thenReturn(creatorMap); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj1 = controller.getEc2CreatorDetail("ag", "ec2", "a1"); + assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); + + doThrow(new NullPointerException()).when(service).getEc2CreatorDetail("a1"); + ResponseEntity responseObj2 = controller.getEc2CreatorDetail("ag", "ec2", "a1"); + assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); + } + + @Test + public void testgetAdGroupsDetail() throws Exception { + List> adList = new ArrayList<>(); + Map adMap = new HashMap<>(); + adMap.put("group", "x"); + adMap.put("admin", "y"); + adList.add(adMap); + when(service.getAdGroupsDetail(anyString(), anyString())).thenReturn(adList); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj1 = controller.getAdGroupsDetail("ag", "a1"); + assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); + + doThrow(new NullPointerException()).when(service).getAdGroupsDetail(anyString(), anyString()); + ResponseEntity responseObj2 = controller.getAdGroupsDetail("ag", "a1"); + assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); + } + + @Test + public void testgetEc2ResourceSummary() throws Exception { + List> ec2List = new ArrayList<>(); + Map ec2Map = new HashMap<>(); + ec2Map.put("resourceid", "x"); + ec2Map.put("ipaddress", "y"); + ec2List.add(ec2Map); + when(service.getEC2AvgAndTotalCost(anyString())).thenReturn(ec2Map); + + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj1 = controller.getEc2ResourceSummary("a1"); + assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj1.getBody()).get("data") != null); + + doThrow(new NullPointerException()).when(service).getEC2AvgAndTotalCost(anyString()); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj2 = controller.getEc2ResourceSummary("a1"); + assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); + + } + + @Test + public void testgetEc2ResourceDetail() throws Exception { + List> ec2List = new ArrayList<>(); + Map ec2Map = new HashMap<>(); + ec2Map.put("resourceid", "x"); + ec2Map.put("ipaddress", "y"); + ec2List.add(ec2Map); + when(service.getEc2ResourceDetail(anyString(), anyString())).thenReturn(ec2Map); + when(service.getGenericResourceDetail(anyString(), anyString(), anyString())).thenReturn(ec2Map); + + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj1 = controller.getEc2ResourceDetail("ag", "ec2", "a1"); + assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj1.getBody()).get("data") != null); + + doThrow(new NullPointerException()).when(service).getEc2ResourceDetail(anyString(), anyString()); + ResponseEntity responseObj2 = controller.getEc2ResourceDetail("ag", "ec2", "a1"); + assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); + + ResponseEntity responseObj3 = controller.getEc2ResourceDetail("ag", "s3", "a1"); + assertTrue(responseObj3.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj3.getBody()).get("data") != null); + + } + + @Test + public void testgetEc2ResourceSummary1() throws Exception { + + PolicyViolationApiData violationData = new PolicyViolationApiData(); + violationData.setCompliance("75"); + String compliance = violationData.getCompliance(); + + PolicyViolationApi violationSummary = new PolicyViolationApi(); + violationSummary.setData(violationData); + violationSummary.getData(); + violationSummary.setMessage("Compliance Data"); + violationSummary.getMessage(); + violationSummary.toString(); + + List> utilList = new ArrayList<>(); + Map utilMap = new HashMap<>(); + utilMap.put("date", "d1"); + utilMap.put("cpu-utilization", 50); + utilList.add(utilMap); + + when(complianceServiceClient.getPolicyViolationSummary(anyString(), anyString(), anyString())) + .thenReturn(violationSummary); + when(service.getEc2StateDetail(anyString(), anyString())).thenReturn("Started"); + when(service.getInstanceCPUUtilization(anyString())).thenReturn(utilList); + + ReflectionTestUtils.setField(controller, "complianceServiceClient", complianceServiceClient); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj1 = controller.getEc2ResourceSummary("ag", "ec2", "a1"); + assertTrue(responseObj1.getStatusCode() == HttpStatus.OK); + assertTrue(((Map) responseObj1.getBody()).get("data") != null); + + doThrow(new NullPointerException()).when(service).getInstanceCPUUtilization(anyString()); + ResponseEntity responseObj2 = controller.getEc2ResourceSummary("ag", "ec2", "a1"); + assertTrue(responseObj2.getStatusCode() == HttpStatus.OK); + + doThrow(new NullPointerException()).when(service).getEc2StateDetail(anyString(),anyString()); + ResponseEntity responseObj3 = controller.getEc2ResourceSummary("ag", "ec2", "a1"); + assertTrue(responseObj3.getStatusCode() == HttpStatus.OK); + } + +} diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetListControllerTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetListControllerTest.java index 290115100..f7dd5ffe7 100644 --- a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetListControllerTest.java +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetListControllerTest.java @@ -1,310 +1,310 @@ -package com.tmobile.pacman.api.asset.controller; - -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.anyString; -import static org.powermock.api.mockito.PowerMockito.doThrow; -import static org.powermock.api.mockito.PowerMockito.when; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.util.ReflectionTestUtils; - -import com.tmobile.pacman.api.asset.domain.Request; -import com.tmobile.pacman.api.asset.service.AssetService; -import com.tmobile.pacman.api.commons.utils.ResponseUtils; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({ ResponseUtils.class }) -public class AssetListControllerTest { - - @Mock - AssetService service; - - AssetListController controller = new AssetListController(); - - @Test - public void testlistAssets() throws Exception { - List> aList = new ArrayList<>(); - Request request = new Request(); - - when(service.getAssetCount(anyObject(), anyObject(), anyObject())).thenReturn((long)100); - when(service.getListAssets(anyObject(), anyObject(), anyInt(),anyInt(),anyObject())).thenReturn(aList); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj0 = controller.listAssets(request, "domain"); - assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); - - request.setFrom(-1); - ResponseEntity responseObj = controller.listAssets(request, "domain"); - assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - request.setFrom(0); - - Map filter = new HashMap<>(); - filter.put("filterKey", "filterValue"); - request.setFilter(filter); - when(service.getListAssets(anyObject(), anyObject(), anyInt(),anyInt(),anyObject())).thenReturn(aList); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj1 = controller.listAssets(request, "domain"); - assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - request.setFilter(null); - doThrow(new NullPointerException()).when(service).getListAssets(anyObject(), anyObject(), anyInt(),anyInt(),anyObject()); - ResponseEntity responseObj2 = controller.listAssets(request, "domain"); - assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - - - } - @Test - public void testlistTaggableAssets() throws Exception{ - List> aList = new ArrayList<>(); - Request request = new Request(); - - ResponseEntity responseObj1 = controller.listTaggableAssets(request); - assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - request.setFrom(-1); - request.setAg("ag"); - ResponseEntity responseObj2 = controller.listTaggableAssets(request); - assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - request.setFrom(0); - ResponseEntity responseObj3 = controller.listTaggableAssets(request); - assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - - Map filter = new HashMap<>(); - filter.put("filterKey", "filterValue"); - request.setFilter(filter); - ResponseEntity responseObj4 = controller.listTaggableAssets(request); - assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - filter.clear(); - filter.put("tagName", "filterValue"); - request.setFilter(filter); - when(service.getListAssetsTaggable(anyString(), anyObject())).thenReturn(aList); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj5 = controller.listTaggableAssets(request); - assertTrue(responseObj5.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - filter.clear(); - request.setFilter(filter); - when(service.getListAssetsTaggable(anyString(), anyObject())).thenReturn(aList); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj6 = controller.listTaggableAssets(request); - assertTrue(responseObj6.getStatusCode() == HttpStatus.OK); - - } - - @Test - public void testlistPatchableAssets() throws Exception{ - List> aList = new ArrayList<>(); - Request request = new Request(); - - ResponseEntity responseObj1 = controller.listPatchableAssets(request); - assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - request.setFrom(-1); - request.setAg("ag"); - ResponseEntity responseObj2 = controller.listPatchableAssets(request); - assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - request.setFrom(0); - ResponseEntity responseObj3 = controller.listPatchableAssets(request); - assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - - Map filter = new HashMap<>(); - filter.put("filterKey", "filterValue"); - request.setFilter(filter); - ResponseEntity responseObj4 = controller.listPatchableAssets(request); - assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - filter.clear(); - filter.put("resourceType", "filterValue"); - request.setFilter(filter); - when(service.getListAssetsPatchable(anyString(), anyObject())).thenReturn(aList); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj5 = controller.listPatchableAssets(request); - assertTrue(responseObj5.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - filter.clear(); - request.setFilter(filter); - when(service.getListAssetsPatchable(anyString(), anyObject())).thenReturn(aList); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj6 = controller.listPatchableAssets(request); - assertTrue(responseObj6.getStatusCode() == HttpStatus.OK); - - Map aMap = new HashMap<>(); - aMap.put("type", "ec2"); - aList.add(aMap); - request.setFrom(3); - ResponseEntity responseObj7 = controller.listPatchableAssets(request); - assertTrue(responseObj7.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - request.setFrom(0); - ResponseEntity responseObj8 = controller.listPatchableAssets(request); - assertTrue(responseObj8.getStatusCode() == HttpStatus.OK); - - request.setSize(8); - ResponseEntity responseObj9 = controller.listPatchableAssets(request); - assertTrue(responseObj9.getStatusCode() == HttpStatus.OK); - - } - - @Test - public void testlistVulnerableAssets() throws Exception{ - List> aList = new ArrayList<>(); - Request request = new Request(); - - ResponseEntity responseObj1 = controller.listVulnerableAssets(request); - assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - request.setFrom(-1); - request.setAg("ag"); - ResponseEntity responseObj2 = controller.listVulnerableAssets(request); - assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - request.setFrom(0); - ResponseEntity responseObj3 = controller.listVulnerableAssets(request); - assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - - Map filter = new HashMap<>(); - filter.put("filterKey", "filterValue"); - filter.put("qid", "filterValue"); - request.setFilter(filter); - ResponseEntity responseObj4 = controller.listVulnerableAssets(request); - assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - filter.remove("qid"); - filter.put("resourceType", "filterValue"); - request.setFilter(filter); - when(service.getListAssetsVulnerable(anyString(), anyObject())).thenReturn(aList); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj5 = controller.listVulnerableAssets(request); - assertTrue(responseObj5.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - filter.clear(); - filter.put("qid", "filterValue"); - request.setFilter(filter); - when(service.getListAssetsVulnerable(anyString(), anyObject())).thenReturn(aList); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj6 = controller.listVulnerableAssets(request); - assertTrue(responseObj6.getStatusCode() == HttpStatus.OK); - - } - - @Test - public void testlistScannedAssets() throws Exception{ - List> aList = new ArrayList<>(); - Request request = new Request(); - - ResponseEntity responseObj1 = controller.listScannedAssets(request,"domain"); - assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - request.setFrom(-1); - request.setAg("ag"); - ResponseEntity responseObj2 = controller.listScannedAssets(request,"domain"); - assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - request.setFrom(0); - ResponseEntity responseObj3 = controller.listScannedAssets(request,"domain"); - assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - - Map filter = new HashMap<>(); - filter.put("filterKey", "filterValue"); - filter.put("ruleId", "filterValue"); - request.setFilter(filter); - ResponseEntity responseObj4 = controller.listScannedAssets(request,"domain"); - assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - filter.remove("ruleId"); - filter.put("resourceType", "filterValue"); - request.setFilter(filter); - when(service.getListAssetsScanned(anyString(), anyObject())).thenReturn(aList); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj5 = controller.listScannedAssets(request,"domain"); - assertTrue(responseObj5.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - filter.clear(); - filter.put("ruleId", "filterValue"); - request.setFilter(filter); - when(service.getListAssetsScanned(anyString(), anyObject())).thenReturn(aList); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj6 = controller.listScannedAssets(request,"domain"); - assertTrue(responseObj6.getStatusCode() == HttpStatus.OK); - - } - @Test - public void testgetAssetLists() throws Exception{ - Request request = new Request(); - ResponseEntity responseObj1 = controller.getAssetLists(request); - assertTrue(responseObj1.getStatusCode()==HttpStatus.EXPECTATION_FAILED); - - request.setAg("ag"); - ResponseEntity responseObj2 = controller.getAssetLists(request); - assertTrue(responseObj2.getStatusCode()==HttpStatus.EXPECTATION_FAILED); - - Map filter = new HashMap<>(); - filter.put("resourceType", "filterValue"); - request.setFilter(filter); - ResponseEntity responseObj3 = controller.getAssetLists(request); - assertTrue(responseObj3.getStatusCode()==HttpStatus.EXPECTATION_FAILED); - - request.setFrom(-1); - request.setSearchtext("pacman"); - request.toString(); - assertTrue(request.getKey().contains("pacman")); - ResponseEntity responseObj4 = controller.getAssetLists(request); - assertTrue(responseObj4.getStatusCode()==HttpStatus.EXPECTATION_FAILED); - request.setFrom(0); - - filter.put("filterType", "filterValue"); - ResponseEntity responseObj5 = controller.getAssetLists(request); - assertTrue(responseObj5.getStatusCode()==HttpStatus.EXPECTATION_FAILED); - - filter.remove("filterType"); - ResponseEntity responseObj6 = controller.getAssetLists(request); - assertTrue(responseObj6.getStatusCode()==HttpStatus.EXPECTATION_FAILED); - - List> aList = new ArrayList<>(); - when(service.getAssetLists(anyString(), anyObject(),anyInt(),anyInt(),anyString())).thenReturn(aList); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj7 = controller.getAssetLists(request); - assertTrue(responseObj7.getStatusCode()==HttpStatus.OK); - } - - @Test - public void testgetEditableFieldsByTargetType() throws Exception{ - ResponseEntity responseObj1 = controller.getEditableFieldsByTargetType("","ec2"); - assertTrue(responseObj1.getStatusCode()==HttpStatus.EXPECTATION_FAILED); - - List> aList = new ArrayList<>(); - Map aMap = new HashMap<>(); - aMap.put("type", "ec2"); - aList.add(aMap); - - when(service.getTargetTypesForAssetGroup(anyString(),anyString())).thenReturn(aList); - ReflectionTestUtils.setField(controller, "assetService", service); - ResponseEntity responseObj2 = controller.getEditableFieldsByTargetType("ag","ec2"); - assertTrue(responseObj2.getStatusCode()==HttpStatus.OK); - - ResponseEntity responseObj3 = controller.getEditableFieldsByTargetType("ag","s3"); - assertTrue(responseObj3.getStatusCode()==HttpStatus.EXPECTATION_FAILED); - - } -} +package com.tmobile.pacman.api.asset.controller; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.powermock.api.mockito.PowerMockito.doThrow; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.util.ReflectionTestUtils; + +import com.tmobile.pacman.api.asset.domain.Request; +import com.tmobile.pacman.api.asset.service.AssetService; +import com.tmobile.pacman.api.commons.utils.ResponseUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ ResponseUtils.class }) +public class AssetListControllerTest { + + @Mock + AssetService service; + + AssetListController controller = new AssetListController(); + + @Test + public void testlistAssets() throws Exception { + List> aList = new ArrayList<>(); + Request request = new Request(); + + when(service.getAssetCount(anyObject(), anyObject(), anyObject())).thenReturn((long)100); + when(service.getListAssets(anyObject(), anyObject(), anyInt(),anyInt(),anyObject())).thenReturn(aList); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj0 = controller.listAssets(request, "domain"); + assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); + + request.setFrom(-1); + ResponseEntity responseObj = controller.listAssets(request, "domain"); + assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + request.setFrom(0); + + Map filter = new HashMap<>(); + filter.put("filterKey", "filterValue"); + request.setFilter(filter); + when(service.getListAssets(anyObject(), anyObject(), anyInt(),anyInt(),anyObject())).thenReturn(aList); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj1 = controller.listAssets(request, "domain"); + assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + request.setFilter(null); + doThrow(new NullPointerException()).when(service).getListAssets(anyObject(), anyObject(), anyInt(),anyInt(),anyObject()); + ResponseEntity responseObj2 = controller.listAssets(request, "domain"); + assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + + + } + @Test + public void testlistTaggableAssets() throws Exception{ + List> aList = new ArrayList<>(); + Request request = new Request(); + + ResponseEntity responseObj1 = controller.listTaggableAssets(request); + assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + request.setFrom(-1); + request.setAg("ag"); + ResponseEntity responseObj2 = controller.listTaggableAssets(request); + assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + request.setFrom(0); + ResponseEntity responseObj3 = controller.listTaggableAssets(request); + assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + + Map filter = new HashMap<>(); + filter.put("filterKey", "filterValue"); + request.setFilter(filter); + ResponseEntity responseObj4 = controller.listTaggableAssets(request); + assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + filter.clear(); + filter.put("tagName", "filterValue"); + request.setFilter(filter); + when(service.getListAssetsTaggable(anyString(), anyObject())).thenReturn(aList); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj5 = controller.listTaggableAssets(request); + assertTrue(responseObj5.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + filter.clear(); + request.setFilter(filter); + when(service.getListAssetsTaggable(anyString(), anyObject())).thenReturn(aList); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj6 = controller.listTaggableAssets(request); + assertTrue(responseObj6.getStatusCode() == HttpStatus.OK); + + } + + @Test + public void testlistPatchableAssets() throws Exception{ + List> aList = new ArrayList<>(); + Request request = new Request(); + + ResponseEntity responseObj1 = controller.listPatchableAssets(request); + assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + request.setFrom(-1); + request.setAg("ag"); + ResponseEntity responseObj2 = controller.listPatchableAssets(request); + assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + request.setFrom(0); + ResponseEntity responseObj3 = controller.listPatchableAssets(request); + assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + + Map filter = new HashMap<>(); + filter.put("filterKey", "filterValue"); + request.setFilter(filter); + ResponseEntity responseObj4 = controller.listPatchableAssets(request); + assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + filter.clear(); + filter.put("resourceType", "filterValue"); + request.setFilter(filter); + when(service.getListAssetsPatchable(anyString(), anyObject())).thenReturn(aList); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj5 = controller.listPatchableAssets(request); + assertTrue(responseObj5.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + filter.clear(); + request.setFilter(filter); + when(service.getListAssetsPatchable(anyString(), anyObject())).thenReturn(aList); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj6 = controller.listPatchableAssets(request); + assertTrue(responseObj6.getStatusCode() == HttpStatus.OK); + + Map aMap = new HashMap<>(); + aMap.put("type", "ec2"); + aList.add(aMap); + request.setFrom(3); + ResponseEntity responseObj7 = controller.listPatchableAssets(request); + assertTrue(responseObj7.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + request.setFrom(0); + ResponseEntity responseObj8 = controller.listPatchableAssets(request); + assertTrue(responseObj8.getStatusCode() == HttpStatus.OK); + + request.setSize(8); + ResponseEntity responseObj9 = controller.listPatchableAssets(request); + assertTrue(responseObj9.getStatusCode() == HttpStatus.OK); + + } + + @Test + public void testlistVulnerableAssets() throws Exception{ + List> aList = new ArrayList<>(); + Request request = new Request(); + + ResponseEntity responseObj1 = controller.listVulnerableAssets(request); + assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + request.setFrom(-1); + request.setAg("ag"); + ResponseEntity responseObj2 = controller.listVulnerableAssets(request); + assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + request.setFrom(0); + ResponseEntity responseObj3 = controller.listVulnerableAssets(request); + assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + + Map filter = new HashMap<>(); + filter.put("filterKey", "filterValue"); + filter.put("qid", "filterValue"); + request.setFilter(filter); + ResponseEntity responseObj4 = controller.listVulnerableAssets(request); + assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + filter.remove("qid"); + filter.put("resourceType", "filterValue"); + request.setFilter(filter); + when(service.getListAssetsVulnerable(anyString(), anyObject())).thenReturn(aList); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj5 = controller.listVulnerableAssets(request); + assertTrue(responseObj5.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + filter.clear(); + filter.put("qid", "filterValue"); + request.setFilter(filter); + when(service.getListAssetsVulnerable(anyString(), anyObject())).thenReturn(aList); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj6 = controller.listVulnerableAssets(request); + assertTrue(responseObj6.getStatusCode() == HttpStatus.OK); + + } + + @Test + public void testlistScannedAssets() throws Exception{ + List> aList = new ArrayList<>(); + Request request = new Request(); + + ResponseEntity responseObj1 = controller.listScannedAssets(request,"domain"); + assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + request.setFrom(-1); + request.setAg("ag"); + ResponseEntity responseObj2 = controller.listScannedAssets(request,"domain"); + assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + request.setFrom(0); + ResponseEntity responseObj3 = controller.listScannedAssets(request,"domain"); + assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + + Map filter = new HashMap<>(); + filter.put("filterKey", "filterValue"); + filter.put("ruleId", "filterValue"); + request.setFilter(filter); + ResponseEntity responseObj4 = controller.listScannedAssets(request,"domain"); + assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + filter.remove("ruleId"); + filter.put("resourceType", "filterValue"); + request.setFilter(filter); + when(service.getListAssetsScanned(anyString(), anyObject())).thenReturn(aList); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj5 = controller.listScannedAssets(request,"domain"); + assertTrue(responseObj5.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + filter.clear(); + filter.put("ruleId", "filterValue"); + request.setFilter(filter); + when(service.getListAssetsScanned(anyString(), anyObject())).thenReturn(aList); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj6 = controller.listScannedAssets(request,"domain"); + assertTrue(responseObj6.getStatusCode() == HttpStatus.OK); + + } + @Test + public void testgetAssetLists() throws Exception{ + Request request = new Request(); + ResponseEntity responseObj1 = controller.getAssetLists(request); + assertTrue(responseObj1.getStatusCode()==HttpStatus.EXPECTATION_FAILED); + + request.setAg("ag"); + ResponseEntity responseObj2 = controller.getAssetLists(request); + assertTrue(responseObj2.getStatusCode()==HttpStatus.EXPECTATION_FAILED); + + Map filter = new HashMap<>(); + filter.put("resourceType", "filterValue"); + request.setFilter(filter); + ResponseEntity responseObj3 = controller.getAssetLists(request); + assertTrue(responseObj3.getStatusCode()==HttpStatus.EXPECTATION_FAILED); + + request.setFrom(-1); + request.setSearchtext("pacman"); + request.toString(); + assertTrue(request.getKey().contains("pacman")); + ResponseEntity responseObj4 = controller.getAssetLists(request); + assertTrue(responseObj4.getStatusCode()==HttpStatus.EXPECTATION_FAILED); + request.setFrom(0); + + filter.put("filterType", "filterValue"); + ResponseEntity responseObj5 = controller.getAssetLists(request); + assertTrue(responseObj5.getStatusCode()==HttpStatus.EXPECTATION_FAILED); + + filter.remove("filterType"); + ResponseEntity responseObj6 = controller.getAssetLists(request); + assertTrue(responseObj6.getStatusCode()==HttpStatus.EXPECTATION_FAILED); + + List> aList = new ArrayList<>(); + when(service.getAssetLists(anyString(), anyObject(),anyInt(),anyInt(),anyString())).thenReturn(aList); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj7 = controller.getAssetLists(request); + assertTrue(responseObj7.getStatusCode()==HttpStatus.OK); + } + + @Test + public void testgetEditableFieldsByTargetType() throws Exception{ + ResponseEntity responseObj1 = controller.getEditableFieldsByTargetType("","ec2"); + assertTrue(responseObj1.getStatusCode()==HttpStatus.EXPECTATION_FAILED); + + List> aList = new ArrayList<>(); + Map aMap = new HashMap<>(); + aMap.put("type", "ec2"); + aList.add(aMap); + + when(service.getTargetTypesForAssetGroup(anyString(),anyString())).thenReturn(aList); + ReflectionTestUtils.setField(controller, "assetService", service); + ResponseEntity responseObj2 = controller.getEditableFieldsByTargetType("ag","ec2"); + assertTrue(responseObj2.getStatusCode()==HttpStatus.OK); + + ResponseEntity responseObj3 = controller.getEditableFieldsByTargetType("ag","s3"); + assertTrue(responseObj3.getStatusCode()==HttpStatus.EXPECTATION_FAILED); + + } +} diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetTrendControllerTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetTrendControllerTest.java index 0934d8698..e5ae5d807 100644 --- a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetTrendControllerTest.java +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetTrendControllerTest.java @@ -1,52 +1,52 @@ -package com.tmobile.pacman.api.asset.controller; - -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyObject; -import static org.powermock.api.mockito.PowerMockito.doThrow; -import static org.powermock.api.mockito.PowerMockito.when; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.util.ReflectionTestUtils; - -import com.tmobile.pacman.api.asset.service.AssetService; -import com.tmobile.pacman.api.commons.utils.ResponseUtils; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({ ResponseUtils.class }) -public class AssetTrendControllerTest { - - @Mock - AssetService service; - - AssetTrendController controller = new AssetTrendController(); - - @Test - public void testgetMinMaxAssetCount() throws Exception { - List> trendList = new ArrayList<>(); - - when(service.getAssetMinMax(anyObject(), anyObject(), anyObject(), anyObject())).thenReturn(trendList); - ReflectionTestUtils.setField(controller, "assetService", service); - - ResponseEntity responseObj0 = controller.getMinMaxAssetCount("ag","type",null,null, "domain"); - assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); - - doThrow(new NullPointerException()).when(service).getAssetMinMax(anyObject(), anyObject(), anyObject(), anyObject()); - ResponseEntity responseObj1 = controller.getMinMaxAssetCount("ag","type",null,null, "domain"); - assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - - - } - - -} +package com.tmobile.pacman.api.asset.controller; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyObject; +import static org.powermock.api.mockito.PowerMockito.doThrow; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.util.ReflectionTestUtils; + +import com.tmobile.pacman.api.asset.service.AssetService; +import com.tmobile.pacman.api.commons.utils.ResponseUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ ResponseUtils.class }) +public class AssetTrendControllerTest { + + @Mock + AssetService service; + + AssetTrendController controller = new AssetTrendController(); + + @Test + public void testgetMinMaxAssetCount() throws Exception { + List> trendList = new ArrayList<>(); + + when(service.getAssetMinMax(anyObject(), anyObject(), anyObject(), anyObject())).thenReturn(trendList); + ReflectionTestUtils.setField(controller, "assetService", service); + + ResponseEntity responseObj0 = controller.getMinMaxAssetCount("ag","type",null,null, "domain"); + assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); + + doThrow(new NullPointerException()).when(service).getAssetMinMax(anyObject(), anyObject(), anyObject(), anyObject()); + ResponseEntity responseObj1 = controller.getMinMaxAssetCount("ag","type",null,null, "domain"); + assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + + + } + + +} diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/ErrorHandlerTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/ErrorHandlerTest.java index c3604b2bf..71c8177d5 100644 --- a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/ErrorHandlerTest.java +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/ErrorHandlerTest.java @@ -1,30 +1,30 @@ -package com.tmobile.pacman.api.asset.controller; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; - -import com.tmobile.pacman.api.commons.utils.ResponseUtils; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({ ResponseUtils.class }) -public class ErrorHandlerTest { - - ErrorHandler handler = new ErrorHandler(); - - @Test - public void testprocessValidationError() throws Exception { - handler.processValidationError(new IllegalArgumentException()); - - ResponseEntity response = handler.processValidationError(new Exception()); - assertTrue(response.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - } - - -} +package com.tmobile.pacman.api.asset.controller; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import com.tmobile.pacman.api.commons.utils.ResponseUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ ResponseUtils.class }) +public class ErrorHandlerTest { + + ErrorHandler handler = new ErrorHandler(); + + @Test + public void testprocessValidationError() throws Exception { + handler.processValidationError(new IllegalArgumentException()); + + ResponseEntity response = handler.processValidationError(new Exception()); + assertTrue(response.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + } + + +} diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/RecommendationsControllerTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/RecommendationsControllerTest.java new file mode 100644 index 000000000..cde7ced25 --- /dev/null +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/RecommendationsControllerTest.java @@ -0,0 +1,221 @@ +package com.tmobile.pacman.api.asset.controller; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyString; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.http.HttpStatus; +import org.springframework.test.util.ReflectionTestUtils; + +import com.tmobile.pacman.api.asset.AssetConstants; +import com.tmobile.pacman.api.asset.domain.Request; +import com.tmobile.pacman.api.asset.service.RecommendationsService; +import com.tmobile.pacman.api.commons.exception.DataException; +import com.tmobile.pacman.api.commons.utils.ResponseUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ ResponseUtils.class }) +public class RecommendationsControllerTest { + + @Mock + RecommendationsService recommendationsService; + + RecommendationsController recommendationsController = new RecommendationsController(); + + @Test + public void getRecommendationSummaryTest() throws Exception { + + when(recommendationsService.getRecommendationSummary(anyString(),anyString(),anyBoolean())).thenReturn(new ArrayList<>()); + ReflectionTestUtils.setField(recommendationsController, "recommendationsService", recommendationsService); + assertTrue(recommendationsController.getRecommendationSummary("ag", null, false).getStatusCode() == HttpStatus.OK); + assertTrue(recommendationsController.getRecommendationSummary(null, null, true).getStatusCode() == HttpStatus.OK); + } + + @Test + public void getRecommendationSummaryTest_Exception() throws Exception { + + when(recommendationsService.getRecommendationSummary(anyString(),anyString(),anyBoolean())).thenThrow(new DataException()); + ReflectionTestUtils.setField(recommendationsController, "recommendationsService", recommendationsService); + assertTrue(recommendationsController.getRecommendationSummary("ag", null, false).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + assertTrue(recommendationsController.getRecommendationSummary(null, null, false).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + } + + @Test + public void getSummaryByApplicationTest() throws Exception { + + when(recommendationsService.getSummaryByApplication(anyString(),anyString())).thenReturn(new HashMap<>()); + ReflectionTestUtils.setField(recommendationsController, "recommendationsService", recommendationsService); + assertTrue(recommendationsController.getSummaryByApplication("ag", "app").getStatusCode() == HttpStatus.OK); + + when(recommendationsService.getSummaryByApplication(anyString(),anyString())).thenThrow(new DataException()); + assertTrue(recommendationsController.getSummaryByApplication("ag", "app").getStatusCode() == HttpStatus.EXPECTATION_FAILED); + } + + @Test + public void getRecommendationsTest() throws Exception { + + Map recommendations = new HashMap<>(); + recommendations.put("response", new ArrayList<>()); + when(recommendationsService.getRecommendations(anyString(),anyString(),anyString(),anyString())).thenReturn(recommendations); + ReflectionTestUtils.setField(recommendationsController, "recommendationsService", recommendationsService); + Request request = new Request(); + request.setAg("ag"); + Map filter = new HashMap<>(); + filter.put("general", "false"); + filter.put("category", "category"); + request.setFilter(filter); + assertTrue(recommendationsController.getRecommendations(request).getStatusCode() == HttpStatus.OK); + + List> resp = new ArrayList<>(); + Map recommendation = new HashMap<>(); + recommendation.put("recommendationId", "id"); + resp.add(recommendation); + recommendations.put("response", resp); + when(recommendationsService.getRecommendations(anyString(),anyString(),anyString(),anyString())).thenReturn(recommendations); + assertTrue(recommendationsController.getRecommendations(request).getStatusCode() == HttpStatus.OK); + + request.setFrom(0); + request.setSize(2); + assertTrue(recommendationsController.getRecommendations(request).getStatusCode() == HttpStatus.OK); + } + + @Test + public void getRecommendationsTest_Exception() throws Exception { + + Request request = new Request(); + assertTrue(recommendationsController.getRecommendations(request).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + Map filter = new HashMap<>(); + filter.put("test", "test"); + request.setFilter(filter); + assertTrue(recommendationsController.getRecommendations(request).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + filter = new HashMap<>(); + filter.put("category", "category"); + request.setFilter(filter); + assertTrue(recommendationsController.getRecommendations(request).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + filter.put("general", "false"); + request.setFilter(filter); + assertTrue(recommendationsController.getRecommendations(request).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + filter.put("general", "true"); + request.setFilter(filter); + request.setAg("ag"); + request.setFrom(-1); + assertTrue(recommendationsController.getRecommendations(request).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + Map recommendations = new HashMap<>(); + List> resp = new ArrayList<>(); + Map recommendation = new HashMap<>(); + recommendation.put("recommendationId", "id"); + resp.add(recommendation); + recommendations.put("response", resp); + + request.setFrom(2); + when(recommendationsService.getRecommendations(anyString(),anyString(),anyString(),anyString())).thenReturn(recommendations); + ReflectionTestUtils.setField(recommendationsController, "recommendationsService", recommendationsService); + assertTrue(recommendationsController.getRecommendations(request).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + request.setFrom(0); + request.setSize(1); + when(recommendationsService.getRecommendations(anyString(),anyString(),anyString(),anyString())).thenThrow(new DataException()); + assertTrue(recommendationsController.getRecommendations(request).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + } + + @Test + public void getRecommendationDetailTest() throws Exception { + + Map recommendations = new HashMap<>(); + recommendations.put("resources", new ArrayList<>()); + when(recommendationsService.getRecommendationDetail(anyString(),anyString(),anyString(),anyString())).thenReturn(recommendations); + ReflectionTestUtils.setField(recommendationsController, "recommendationsService", recommendationsService); + Request request = new Request(); + request.setAg("ag"); + Map filter = new HashMap<>(); + filter.put("general", "false"); + filter.put(AssetConstants.FILTER_RECOMMENDATION_ID,AssetConstants.FILTER_RECOMMENDATION_ID); + request.setFilter(filter); + assertTrue(recommendationsController.getRecommendationDetail(request).getStatusCode() == HttpStatus.OK); + + List> resp = new ArrayList<>(); + Map recommendation = new HashMap<>(); + recommendation.put("recommendationId", "id"); + resp.add(recommendation); + recommendations.put("resources", resp); + when(recommendationsService.getRecommendationDetail(anyString(),anyString(),anyString(),anyString())).thenReturn(recommendations); + assertTrue(recommendationsController.getRecommendationDetail(request).getStatusCode() == HttpStatus.OK); + + request.setFrom(0); + request.setSize(2); + assertTrue(recommendationsController.getRecommendationDetail(request).getStatusCode() == HttpStatus.OK); + } + + @Test + public void getRecommendationDetailTest_Exception() throws Exception { + + Request request = new Request(); + assertTrue(recommendationsController.getRecommendationDetail(request).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + Map filter = new HashMap<>(); + filter.put("test", "test"); + request.setFilter(filter); + assertTrue(recommendationsController.getRecommendationDetail(request).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + filter = new HashMap<>(); + filter.put(AssetConstants.FILTER_RECOMMENDATION_ID,AssetConstants.FILTER_RECOMMENDATION_ID); + request.setFilter(filter); + assertTrue(recommendationsController.getRecommendationDetail(request).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + filter.put("general", "false"); + request.setFilter(filter); + assertTrue(recommendationsController.getRecommendationDetail(request).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + filter.put("general", "true"); + request.setFilter(filter); + request.setAg("ag"); + request.setFrom(-1); + assertTrue(recommendationsController.getRecommendationDetail(request).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + Map recommendations = new HashMap<>(); + List> resp = new ArrayList<>(); + Map recommendation = new HashMap<>(); + recommendation.put("recommendationId", "id"); + resp.add(recommendation); + recommendations.put("resources", resp); + + request.setFrom(2); + when(recommendationsService.getRecommendationDetail(anyString(),anyString(),anyString(),anyString())).thenReturn(recommendations); + ReflectionTestUtils.setField(recommendationsController, "recommendationsService", recommendationsService); + assertTrue(recommendationsController.getRecommendationDetail(request).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + request.setFrom(0); + request.setSize(1); + when(recommendationsService.getRecommendationDetail(anyString(),anyString(),anyString(),anyString())).thenThrow(new DataException()); + assertTrue(recommendationsController.getRecommendationDetail(request).getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + } + + @Test + public void getRecommendationInfoTest() throws Exception { + + when(recommendationsService.getRecommendationInfo(anyString())).thenReturn(new HashMap<>()); + ReflectionTestUtils.setField(recommendationsController, "recommendationsService", recommendationsService); + assertTrue(recommendationsController.getRecommendationInfo("id").getStatusCode() == HttpStatus.OK); + + when(recommendationsService.getRecommendationInfo(anyString())).thenThrow(new DataException()); + assertTrue(recommendationsController.getRecommendationInfo("id").getStatusCode() == HttpStatus.EXPECTATION_FAILED); + } +} \ No newline at end of file diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/SearchControllerTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/SearchControllerTest.java index ae9794916..040ff003c 100644 --- a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/SearchControllerTest.java +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/SearchControllerTest.java @@ -1,101 +1,101 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ -package com.tmobile.pacman.api.asset.controller; - -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.powermock.api.mockito.PowerMockito.doThrow; -import static org.powermock.api.mockito.PowerMockito.when; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.util.ReflectionTestUtils; - -import com.tmobile.pacman.api.asset.domain.SearchCriteria; -import com.tmobile.pacman.api.asset.domain.SearchResult; -import com.tmobile.pacman.api.asset.service.SearchService; -import com.tmobile.pacman.api.commons.utils.ResponseUtils; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({ ResponseUtils.class, Util.class }) -public class SearchControllerTest { - - @Mock - SearchService service; - - SearchController controller = new SearchController(); - - @Test - public void testSearch() throws Exception { - SearchCriteria criteria = new SearchCriteria(); - criteria.setAg("ag"); - criteria.setSize(1); - criteria.setFrom(0); - criteria.setSearchText("pacman"); - - SearchResult sr = new SearchResult(); - when(service.search(any(SearchCriteria.class))).thenReturn(sr); - ReflectionTestUtils.setField(controller, "searchService", service); - - ResponseEntity responseObj = controller.search(criteria); - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - - criteria.setSize(-1); - responseObj = controller.search(criteria); - assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - criteria.setSize(1); - criteria.setFrom(-1); - responseObj = controller.search(criteria); - assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - criteria.setFrom(1); - criteria.setSearchText(null); - responseObj = controller.search(criteria); - assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - criteria.setSearchText("pacman"); - criteria.setAg(null); - responseObj = controller.search(criteria); - assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - criteria.setAg("aws-all"); - doThrow(new NullPointerException()).when(service).search(any(SearchCriteria.class)); - ReflectionTestUtils.setField(controller, "searchService", service); - responseObj = controller.search(criteria); - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - - } - - @Test - public void testgetSearchCategories() throws Exception { - when(service.getSearchCategories("domain")).thenReturn(Arrays.asList("cat1", "cat2")); - ReflectionTestUtils.setField(controller, "searchService", service); - ResponseEntity responseObj = controller.getSearchCategories("domain"); - assertTrue(responseObj.getStatusCode() == HttpStatus.OK); - assertTrue(((List) (((Map) responseObj.getBody()).get("data"))).size() == 2); - } - -} +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.api.asset.controller; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.powermock.api.mockito.PowerMockito.doThrow; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.util.ReflectionTestUtils; + +import com.tmobile.pacman.api.asset.domain.SearchCriteria; +import com.tmobile.pacman.api.asset.domain.SearchResult; +import com.tmobile.pacman.api.asset.service.SearchService; +import com.tmobile.pacman.api.commons.utils.ResponseUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ ResponseUtils.class, Util.class }) +public class SearchControllerTest { + + @Mock + SearchService service; + + SearchController controller = new SearchController(); + + @Test + public void testSearch() throws Exception { + SearchCriteria criteria = new SearchCriteria(); + criteria.setAg("ag"); + criteria.setSize(1); + criteria.setFrom(0); + criteria.setSearchText("pacman"); + + SearchResult sr = new SearchResult(); + when(service.search(any(SearchCriteria.class))).thenReturn(sr); + ReflectionTestUtils.setField(controller, "searchService", service); + + ResponseEntity responseObj = controller.search(criteria); + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + + criteria.setSize(-1); + responseObj = controller.search(criteria); + assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + criteria.setSize(1); + criteria.setFrom(-1); + responseObj = controller.search(criteria); + assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + criteria.setFrom(1); + criteria.setSearchText(null); + responseObj = controller.search(criteria); + assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + criteria.setSearchText("pacman"); + criteria.setAg(null); + responseObj = controller.search(criteria); + assertTrue(responseObj.getStatusCode() == HttpStatus.EXPECTATION_FAILED); + + criteria.setAg("aws-all"); + doThrow(new NullPointerException()).when(service).search(any(SearchCriteria.class)); + ReflectionTestUtils.setField(controller, "searchService", service); + responseObj = controller.search(criteria); + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + + } + + @Test + public void testgetSearchCategories() throws Exception { + when(service.getSearchCategories("domain")).thenReturn(Arrays.asList("cat1", "cat2")); + ReflectionTestUtils.setField(controller, "searchService", service); + ResponseEntity responseObj = controller.getSearchCategories("domain"); + assertTrue(responseObj.getStatusCode() == HttpStatus.OK); + assertTrue(((List) (((Map) responseObj.getBody()).get("data"))).size() == 2); + } + +} diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/UtilTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/UtilTest.java index dabf7b939..65f6c49e8 100644 --- a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/UtilTest.java +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/UtilTest.java @@ -1,122 +1,122 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ -package com.tmobile.pacman.api.asset.controller; - -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyObject; -import static org.powermock.api.mockito.PowerMockito.doThrow; -import static org.powermock.api.mockito.PowerMockito.when; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.springframework.test.util.ReflectionTestUtils; - -import com.tmobile.pacman.api.asset.service.AssetService; -import com.tmobile.pacman.api.commons.utils.ResponseUtils; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({ ResponseUtils.class }) -public class UtilTest { - - @Mock - AssetService service; - - @Test - public void testisValidTargetType() throws Exception { - - List> tTypeList = new ArrayList<>(); - Map tTypeMap = new HashMap<>(); - tTypeMap.put("type", "ec2"); - tTypeMap.put("category", "aws-all"); - tTypeMap.put("domain", "Infra & Platforms"); - tTypeList.add(tTypeMap); - - when(service.getTargetTypesForAssetGroup(anyObject(), anyObject())).thenReturn(tTypeList); - - ReflectionTestUtils.setField(Util.class, "assetService", service); - boolean valid = Util.isValidTargetType("aws-all", "ec2"); - - assertTrue(valid); - - doThrow(new NullPointerException()).when(service).getTargetTypesForAssetGroup(anyObject(), anyObject()); - valid = Util.isValidTargetType("aws-all", "ec2"); - - assertTrue(!valid); - } - - @Test - public void testisValidAssetGroup() throws Exception { - - List> tTypeList = new ArrayList<>(); - Map tTypeMap = new HashMap<>(); - tTypeMap.put("name", "aws-all"); - tTypeList.add(tTypeMap); - - when(service.getAllAssetGroups()).thenReturn(tTypeList); - - new Util().setassetService(service); - boolean valid = Util.isValidAssetGroup("aws-all"); - - assertTrue(valid); - - } - - @Test - public void testgetUtilisationScore() throws Exception { - - int score = Util.getUtilisationScore(75); - assertTrue(score == 10); - - score = Util.getUtilisationScore(55); - assertTrue(score == 9); - - score = Util.getUtilisationScore(45); - assertTrue(score == 8); - - score = Util.getUtilisationScore(35); - assertTrue(score == 7); - - score = Util.getUtilisationScore(26); - assertTrue(score == 6); - - score = Util.getUtilisationScore(13); - assertTrue(score == 3); - - score = Util.getUtilisationScore(7); - assertTrue(score == 2); - - score = Util.getUtilisationScore(3); - assertTrue(score == 1); - - } - - @Test - public void encodeUrl() throws Exception{ - String encoded = Util.encodeUrl("http://wwww.google.com"); - assertTrue(encoded.equals("http%3A%2F%2Fwwww.google.com")); - - - } - +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.api.asset.controller; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyObject; +import static org.powermock.api.mockito.PowerMockito.doThrow; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.test.util.ReflectionTestUtils; + +import com.tmobile.pacman.api.asset.service.AssetService; +import com.tmobile.pacman.api.commons.utils.ResponseUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ ResponseUtils.class }) +public class UtilTest { + + @Mock + AssetService service; + + @Test + public void testisValidTargetType() throws Exception { + + List> tTypeList = new ArrayList<>(); + Map tTypeMap = new HashMap<>(); + tTypeMap.put("type", "ec2"); + tTypeMap.put("category", "aws-all"); + tTypeMap.put("domain", "Infra & Platforms"); + tTypeList.add(tTypeMap); + + when(service.getTargetTypesForAssetGroup(anyObject(), anyObject())).thenReturn(tTypeList); + + ReflectionTestUtils.setField(Util.class, "assetService", service); + boolean valid = Util.isValidTargetType("aws-all", "ec2"); + + assertTrue(valid); + + doThrow(new NullPointerException()).when(service).getTargetTypesForAssetGroup(anyObject(), anyObject()); + valid = Util.isValidTargetType("aws-all", "ec2"); + + assertTrue(!valid); + } + + @Test + public void testisValidAssetGroup() throws Exception { + + List> tTypeList = new ArrayList<>(); + Map tTypeMap = new HashMap<>(); + tTypeMap.put("name", "aws-all"); + tTypeList.add(tTypeMap); + + when(service.getAllAssetGroups()).thenReturn(tTypeList); + + new Util().setassetService(service); + boolean valid = Util.isValidAssetGroup("aws-all"); + + assertTrue(valid); + + } + + @Test + public void testgetUtilisationScore() throws Exception { + + int score = Util.getUtilisationScore(75); + assertTrue(score == 10); + + score = Util.getUtilisationScore(55); + assertTrue(score == 9); + + score = Util.getUtilisationScore(45); + assertTrue(score == 8); + + score = Util.getUtilisationScore(35); + assertTrue(score == 7); + + score = Util.getUtilisationScore(26); + assertTrue(score == 6); + + score = Util.getUtilisationScore(13); + assertTrue(score == 3); + + score = Util.getUtilisationScore(7); + assertTrue(score == 2); + + score = Util.getUtilisationScore(3); + assertTrue(score == 1); + + } + + @Test + public void encodeUrl() throws Exception{ + String encoded = Util.encodeUrl("http://wwww.google.com"); + assertTrue(encoded.equals("http%3A%2F%2Fwwww.google.com")); + + + } + } \ No newline at end of file diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/CostRepositoryTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/CostRepositoryTest.java new file mode 100644 index 000000000..f56baedf6 --- /dev/null +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/CostRepositoryTest.java @@ -0,0 +1,97 @@ +package com.tmobile.pacman.api.asset.repository; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.http.util.EntityUtils; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; +import com.tmobile.pacman.api.commons.utils.PacHttpUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ PacHttpUtils.class, EntityUtils.class, Response.class, RestClient.class }) +public class CostRepositoryTest { + + @Mock + ElasticSearchRepository elasticSearchRepository; + + @InjectMocks + CostRepository costRepository; + + @Before + public void init() { + costRepository.init(); + } + + @Test + public void getCostAggsTest() throws Exception { + + String yearMonth = "{\"aggregations\":{\"year-month\":{\"value\":201903.0}}}"; + String costAggs = "{\"aggregations\":{\"YEAR\":{\"buckets\":[{\"key\":2019,\"doc_count\":5,\"MONTH\":{\"buckets\":[{\"key\":1,\"doc_count\":1," + + "\"COST\":{\"value\":57220.640625}},{\"key\":2,\"doc_count\":1,\"COST\":{\"value\":50138.328125}},{\"key\":3,\"doc_count\":1," + + "\"COST\":{\"value\":44942.09765625}},{\"key\":4,\"doc_count\":1,\"COST\":{\"value\":37133.69921875}},{\"key\":5,\"doc_count\":1," + + "\"COST\":{\"value\":6517.2265625}}]}}]}}}"; + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenReturn(yearMonth,costAggs); + assertTrue(costRepository.getCostAggs(Arrays.asList("app")).size() == 5); + } + + @Test + public void getCostAggsTest_Exception() throws Exception { + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenThrow(new Exception()); + assertThatThrownBy(() -> costRepository.getCostAggs(Arrays.asList("app"))) + .isInstanceOf(Exception.class); + } + + @Test + public void getCostAggsWithTTTest() throws Exception { + + String yearMonth = "{\"aggregations\":{\"year-month\":{\"value\":201903.0}}}"; + String costAggs = "{\"aggregations\":{\"YEAR\":{\"buckets\":[{\"key\":2019,\"doc_count\":5,\"MONTH\":{\"buckets\":[{\"key\":1,\"doc_count\":1," + + "\"COST\":{\"value\":57220.640625}},{\"key\":2,\"doc_count\":1,\"COST\":{\"value\":50138.328125}},{\"key\":3,\"doc_count\":1," + + "\"COST\":{\"value\":44942.09765625}},{\"key\":4,\"doc_count\":1,\"COST\":{\"value\":37133.69921875}},{\"key\":5,\"doc_count\":1," + + "\"COST\":{\"value\":6517.2265625}}]}}]}}}"; + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenReturn(yearMonth,costAggs); + assertTrue(costRepository.getCostAggsWithTT(Arrays.asList("app"),Arrays.asList("type")).size() == 5); + } + + @Test + public void getCostAggsWithTT_Exception() throws Exception { + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenThrow(new Exception()); + assertThatThrownBy(() -> costRepository.getCostAggsWithTT(Arrays.asList("app"),Arrays.asList("type"))) + .isInstanceOf(Exception.class); + } + + @Test + public void fetchApplicationMasterListTest() throws Exception { + + List> appList = new ArrayList<>(); + Map app = new HashMap<>(); + app.put("appTag", "app"); + appList.add(app); + when(elasticSearchRepository.getDataFromES(anyString(),anyString(),anyObject(),anyObject(),anyObject(),anyObject(),anyObject())).thenReturn(appList); + assertTrue(costRepository.fetchApplicationMasterList().size() == 1); + } +} diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/PacmanRedshiftRepositoryTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/PacmanRedshiftRepositoryTest.java index d6bf8e087..927190382 100644 --- a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/PacmanRedshiftRepositoryTest.java +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/PacmanRedshiftRepositoryTest.java @@ -1,99 +1,99 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ -package com.tmobile.pacman.api.asset.repository; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.anyString; -import static org.powermock.api.mockito.PowerMockito.mockStatic; -import static org.powermock.api.mockito.PowerMockito.when; -import static org.powermock.api.mockito.PowerMockito.doNothing; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import org.apache.http.Header; -import org.apache.http.HttpEntity; -import org.apache.http.StatusLine; -import org.apache.http.util.EntityUtils; -import org.elasticsearch.client.Response; -import org.elasticsearch.client.RestClient; -import org.elasticsearch.client.RestClientBuilder; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PowerMockIgnore; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.springframework.test.util.ReflectionTestUtils; - -import com.tmobile.pacman.api.asset.AssetConstants; -import com.tmobile.pacman.api.asset.model.DefaultUserAssetGroup; -import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; -import com.tmobile.pacman.api.commons.repo.PacmanRdsRepository; -import com.tmobile.pacman.api.commons.utils.PacHttpUtils; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({ DriverManager.class, PacmanRedshiftRepository.class }) -public class PacmanRedshiftRepositoryTest { - - @Mock - Connection connection; - - @Mock - Statement statement; - - @Mock - ResultSet rs; - - PacmanRedshiftRepository repository = new PacmanRedshiftRepository(); - - @Test - public void testcount() throws Exception { - when(connection.createStatement()).thenReturn(statement); - when(statement.executeQuery(anyString())).thenReturn(rs); - when(rs.next()).thenReturn(true, false); - when(rs.getInt(anyString())).thenReturn(5); - doNothing().when(rs).close(); - doNothing().when(connection).close(); - doNothing().when(statement).close(); - - mockStatic(DriverManager.class); - when(DriverManager.getConnection(anyString(), any(Properties.class))).thenReturn(connection); - ReflectionTestUtils.setField(repository, "userName", ""); - ReflectionTestUtils.setField(repository, "password", ""); - ReflectionTestUtils.setField(repository, "dbURL", ""); - - int a = repository.count("query"); - - assertTrue(a == 5); - } - -} +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.api.asset.repository; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; +import static org.powermock.api.mockito.PowerMockito.doNothing; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.StatusLine; +import org.apache.http.util.EntityUtils; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestClientBuilder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.test.util.ReflectionTestUtils; + +import com.tmobile.pacman.api.asset.AssetConstants; +import com.tmobile.pacman.api.asset.model.DefaultUserAssetGroup; +import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; +import com.tmobile.pacman.api.commons.repo.PacmanRdsRepository; +import com.tmobile.pacman.api.commons.utils.PacHttpUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ DriverManager.class, PacmanRedshiftRepository.class }) +public class PacmanRedshiftRepositoryTest { + + @Mock + Connection connection; + + @Mock + Statement statement; + + @Mock + ResultSet rs; + + PacmanRedshiftRepository repository = new PacmanRedshiftRepository(); + + @Test + public void testcount() throws Exception { + when(connection.createStatement()).thenReturn(statement); + when(statement.executeQuery(anyString())).thenReturn(rs); + when(rs.next()).thenReturn(true, false); + when(rs.getInt(anyString())).thenReturn(5); + doNothing().when(rs).close(); + doNothing().when(connection).close(); + doNothing().when(statement).close(); + + mockStatic(DriverManager.class); + when(DriverManager.getConnection(anyString(), any(Properties.class))).thenReturn(connection); + ReflectionTestUtils.setField(repository, "userName", ""); + ReflectionTestUtils.setField(repository, "password", ""); + ReflectionTestUtils.setField(repository, "dbURL", ""); + + int a = repository.count("query"); + + assertTrue(a == 5); + } + +} diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/RecommendationsRepositoryTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/RecommendationsRepositoryTest.java new file mode 100644 index 000000000..131f6c6a6 --- /dev/null +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/RecommendationsRepositoryTest.java @@ -0,0 +1,178 @@ +package com.tmobile.pacman.api.asset.repository; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.anyObject; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.http.util.EntityUtils; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.tmobile.pacman.api.commons.exception.DataException; +import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; +import com.tmobile.pacman.api.commons.repo.PacmanRdsRepository; +import com.tmobile.pacman.api.commons.utils.PacHttpUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ PacHttpUtils.class, EntityUtils.class, Response.class, RestClient.class }) +public class RecommendationsRepositoryTest { + + @Mock + ElasticSearchRepository elasticSearchRepository; + + @Mock + PacmanRdsRepository rdsRepository; + + @InjectMocks + RecommendationsRepository recommendationsRepository; + + @Before + public void init() { + recommendationsRepository.init(); + } + + @Test + public void getRecommendationSummaryTest() throws Exception { + String summary = "{\"aggregations\":{\"recommendations\":{\"doc_count\":81294,\"latest\":{\"doc_count\":58372,\"category\":" + + "{\"buckets\":[{\"key\":\"cost\",\"doc_count\":9766,\"savings\":{\"value\":716724.5030126646}},{\"key\":\"perf\",\"doc_count\":876,\"savings\":{\"value\":0}}]}}}}}"; + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenReturn(summary); + assertTrue(recommendationsRepository.getRecommendationSummary("ag", "app").size() == 2); + } + + @Test + public void getRecommendationSummaryTest_Exception() throws Exception { + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenThrow(new DataException()); + assertThatThrownBy(() -> recommendationsRepository.getRecommendationSummary("ag", null)).isInstanceOf(DataException.class); + } + + @Test + public void getSummaryByApplicationTest() throws Exception { + + String summaryApp = "{\"aggregations\":{\"apps\":{\"buckets\":[{\"key\":\"PacMan\",\"doc_count\":1486,\"recommendations\":" + + "{\"doc_count\":593,\"latest\":{\"doc_count\":325,\"savings\":{\"value\":1008.0500058233738}}}}]}}}"; + String summaryAppByCat = "{\"aggregations\":{\"apps\":{\"buckets\":[{\"key\":\"app\",\"doc_count\":1486," + + "\"recommendations\":{\"doc_count\":590,\"latest\":{\"doc_count\":323,\"category\":{\"doc_count\":1,\"savings\":{\"value\":0}}}}}]}}}"; + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenReturn(summaryAppByCat,summaryApp); + assertTrue(recommendationsRepository.getSummaryByApplication("ag", "cost_optimizing").size() == 4); + assertTrue(recommendationsRepository.getSummaryByApplication("ag").size() == 3); + } + + @Test + public void getSummaryByApplicationTest_Exception() throws Exception { + + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenThrow(new DataException()); + assertThatThrownBy(() -> recommendationsRepository.getSummaryByApplication("ag", "cost_optimizing")).isInstanceOf(DataException.class); + assertThatThrownBy(() -> recommendationsRepository.getSummaryByApplication("ag")).isInstanceOf(DataException.class); + + } + + @SuppressWarnings("deprecation") + @Test + public void getRecommendationsTest() throws Exception { + String recommendationJson = "{\"aggregations\":{\"type\":{\"buckets\":[{\"key\":\"lambda\",\"doc_count\":270,\"recommendations\":{\"doc_count\":0}},{\"key\":\"volume\",\"doc_count\":199,\"recommendations\":{\"doc_count\":470,\"latest\":{\"doc_count\":242,\"category\":" + + "{\"doc_count\":43,\"recommendation\":{\"buckets\":[{\"key\":\"DAvU99Dc4C\",\"doc_count\":43,\"savings\":{\"value\":518.8000001013279}}]}}}}}]}}}"; + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenReturn(recommendationJson); + List> recommendations = new ArrayList<>(); + Map recommendation = new HashMap<>(); + recommendation.put("checkname","name"); + recommendation.put("checkdescription","description"); + recommendations.add(recommendation); + when(elasticSearchRepository.getDataFromES(anyString(), anyString(), anyObject(), anyObject(), anyObject(), anyObject(), anyObject())).thenReturn(recommendations); + assertTrue(recommendationsRepository.getRecommendations("ag", "cost_optimizing","app").size() == 4); + } + + @Test + public void getRecommendationsTest_Exception() throws Exception { + + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenThrow(new DataException()); + assertThatThrownBy(() -> recommendationsRepository.getRecommendations("ag", "cost_optimizing","app")).isInstanceOf(DataException.class); + } + + @Test + public void getRecommendationDetailTest() throws Exception { + + String response = "{\"_scroll_id\":\"id\",\"hits\":{\"hits\":[{\"_source\":{\"_resourceid\":\"123\",\"monthlysavings\":2," + + "\"recommendation\":\"Amazon EBS Volumes\",\"recommendationId\":\"DAvU99Dc4C\",\"resourceinfo\":{\"Volume Type\":\"General purpose(SSD)\"," + + "\"Volume Size\":\"20\",\"Snapshot Name\":\"null\",\"Monthly Storage Cost\":\"$2.00\"},\"category\":\"cost_optimizing\"," + + "\"type\":\"volume\",\"_loaddate\":\"2019-06-12\",\"status\":\"warning\",\"latest\":true}}]}}"; + String countresponse = "{\"count\":43}"; + when(rdsRepository.queryForString(anyString())).thenReturn("parent"); + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenReturn(countresponse,response); + when(elasticSearchRepository.buildScrollRequest(anyString(), anyString())).thenReturn("request"); + assertTrue(recommendationsRepository.getRecommendationDetail("ag", "id","app").size() == 1); + } + + @Test + public void getGeneralRecommendationSummaryTest() throws Exception { + String summary = "{\"aggregations\":{\"category\":{\"buckets\":[{\"key\":\"performance\",\"doc_count\":55}]}}}"; + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenReturn(summary); + assertTrue(recommendationsRepository.getGeneralRecommendationSummary().size() == 1); + } + + @Test + public void getGeneralRecommendationSummaryTest_Exception() throws Exception { + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenThrow(new DataException()); + assertThatThrownBy(() -> recommendationsRepository.getGeneralRecommendationSummary()).isInstanceOf(DataException.class); + } + + @SuppressWarnings("deprecation") + @Test + public void getGeneralRecommendationsTest() throws Exception { + String recommendationJson = "{\"aggregations\":{\"recommendations\":{\"buckets\":[{\"key\":\"abcd\",\"doc_count\":29}]}}}"; + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenReturn(recommendationJson); + List> recommendations = new ArrayList<>(); + Map recommendation = new HashMap<>(); + recommendation.put("checkname","name"); + recommendation.put("checkdescription","description"); + recommendations.add(recommendation); + when(elasticSearchRepository.getDataFromES(anyString(), anyString(), anyObject(), anyObject(), anyObject(), anyObject(), anyObject())).thenReturn(recommendations); + assertTrue(recommendationsRepository.getGeneralRecommendations("category").size() == 2); + } + + @Test + public void getGeneralRecommendationsTest_Exception() throws Exception { + + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenThrow(new DataException()); + assertThatThrownBy(() -> recommendationsRepository.getGeneralRecommendations("category")).isInstanceOf(DataException.class); + } + + @Test + public void getGeneralRecommendationDetailTest() throws Exception { + + String response = "{\"_scroll_id\":\"id\",\"hits\":{\"hits\":[{\"_source\":{\"recommendation\":\"Route 53 recommendation\",\"recommendationId\":\"B913Ef6fb4\"," + + "\"resourceinfo\":{\"Hosted Zone Name\":\"asdsd\",\"Hosted Zone ID\":\"asdad\",\"Resource Record Set Type\":\"name\"," + + "\"Resource Record Set Identifier\":\"null\",\"Alias Target\":\"Load balancer\",\"Status\":\"Yellow\"},\"category\":\"performance\"," + + "\"_loaddate\":\"2019-06-13T16:39:30+0530\",\"status\":\"warning\",\"latest\":true}}]}}"; + String countresponse = "{\"count\":43}"; + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenReturn(countresponse,response); + when(elasticSearchRepository.buildScrollRequest(anyString(), anyString())).thenReturn("request"); + assertTrue(recommendationsRepository.getGeneralRecommendationDetail("id").size() == 1); + } +} \ No newline at end of file diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/SearchRepositoryTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/SearchRepositoryTest.java index 1b4bb9b05..34ac29322 100644 --- a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/SearchRepositoryTest.java +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/repository/SearchRepositoryTest.java @@ -1,211 +1,211 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ -package com.tmobile.pacman.api.asset.repository; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.anyString; -import static org.powermock.api.mockito.PowerMockito.mockStatic; -import static org.powermock.api.mockito.PowerMockito.when; - -import org.apache.http.Header; -import org.apache.http.HttpEntity; -import org.apache.http.StatusLine; -import org.apache.http.util.EntityUtils; -import org.elasticsearch.client.Response; -import org.elasticsearch.client.RestClient; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Matchers; -import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.springframework.test.util.ReflectionTestUtils; - -import com.tmobile.pacman.api.asset.domain.SearchResult; -import com.tmobile.pacman.api.asset.service.AssetService; -import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; -import com.tmobile.pacman.api.commons.repo.PacmanRdsRepository; -import com.tmobile.pacman.api.commons.utils.PacHttpUtils; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({ PacHttpUtils.class, EntityUtils.class, Response.class, RestClient.class }) -public class SearchRepositoryTest { - - @Mock - ElasticSearchRepository elasticSearchRepository; - - @Mock - PacmanRedshiftRepository redshiftRepository; - - @Mock - RestClient restClient; - - @Mock - StatusLine sl; - - @Mock - Response response; - - @Mock - PacmanRdsRepository pacmanRdsRepository; - - @Mock - AssetService assetService; - - SearchRepositoryImpl repository = new SearchRepositoryImpl(); - - @Test - public void testgetAssetCountByAssetGroup() throws Exception { - - List> returnFieldsData = new ArrayList<>(); - Map firstRow = new HashMap<>(); - firstRow.put("SEARCH_CATEGORY", "Assets"); - firstRow.put("RESOURCE_TYPE", "All"); - firstRow.put("REFINE_BY_FIELDS", "accountname,region,tags.Application,tags.Environment,tags.Stack,tags.Role"); - firstRow.put("RETURN_FIELDS", "_resourceid,searchcategory,tags,accountname,_entitytype"); - - Map secondRow = new HashMap<>(); - secondRow.put("SEARCH_CATEGORY", "Policy Violations"); - secondRow.put("RESOURCE_TYPE", "All"); - secondRow.put("REFINE_BY_FIELDS", "severity,policyId"); - secondRow.put("RETURN_FIELDS", "_id,issueid,resourceid,severity,_entitytype,_resourceid"); - - Map thirdRow = new HashMap<>(); - thirdRow.put("SEARCH_CATEGORY", "Vulnerabilities"); - thirdRow.put("RESOURCE_TYPE", "All"); - thirdRow.put("REFINE_BY_FIELDS", "severity,category,vulntype"); - thirdRow.put("RETURN_FIELDS", "qid,vulntype,category,_entitytype,_resourceid"); - - returnFieldsData.add(firstRow); - returnFieldsData.add(secondRow); - returnFieldsData.add(thirdRow); - - Map tTypeMap1 = new HashMap<>(); - tTypeMap1.put("type", "ec2"); - Map tTypeMap2 = new HashMap<>(); - tTypeMap1.put("type", "s3"); - List> tTypeList = new ArrayList<>(); - tTypeList.add(tTypeMap1); - tTypeList.add(tTypeMap2); - Map queryMap = new HashMap<>(); - queryMap.put("a", "1"); - - String responseJson = "{\"aggregations\":{\"qids\":{\"doc_count_error_upper_bound\":0,\"sum_other_doc_count\":0,\"buckets\":[]}}}"; - - mockStatic(PacHttpUtils.class); - when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenReturn(responseJson); - - when(pacmanRdsRepository.getDataFromPacman(anyString())).thenReturn(returnFieldsData); - ReflectionTestUtils.setField(repository, "rdsRepository", pacmanRdsRepository); - when(assetService.getTargetTypesForAssetGroup(anyString(), anyString())).thenReturn(tTypeList); - ReflectionTestUtils.setField(repository, "assetService", assetService); - when(elasticSearchRepository.buildQuery(anyObject(), anyObject(), anyObject(), anyObject(), anyObject(), - anyObject())).thenReturn(queryMap); - when(elasticSearchRepository.processResponseAndSendTheScrollBack(anyString(), anyObject())) - .thenCallRealMethod(); - ReflectionTestUtils.setField(repository, "esRepository", elasticSearchRepository); - mockStatic(EntityUtils.class); - String json = "{\"hits\":{\"total\":10,\"hits\":[{\"_source\":{\"_resourceid\":\"a1\"},\"sort\":[\"s1\"]}]}}"; - - when(EntityUtils.toString(anyObject())).thenReturn(json); - when(response.getEntity()).thenReturn(null); - when(restClient.performRequest(anyString(), anyString(), any(Map.class), any(HttpEntity.class), - Matchers.
anyVararg())).thenReturn(response); - ReflectionTestUtils.setField(repository, "restClient", restClient); - - SearchResult sr = new SearchResult(); - sr = repository.fetchSearchResultsAndSetTotal("aws-all", null, true, null, "pacman", new HashMap<>(), 0, 1, sr, - "Vulnerabilities"); - assertTrue(sr.getTotal() == 0); - - sr = repository.fetchSearchResultsAndSetTotal("aws-all", null, true, null, "pacman", new HashMap<>(), 0, 1, sr, - "Assets"); - assertTrue(sr.getTotal() == 10); - - } - - @Test - public void testfetchTargetTypes() throws Exception { - - List> returnFieldsData = new ArrayList<>(); - Map firstRow = new HashMap<>(); - firstRow.put("SEARCH_CATEGORY", "Assets"); - firstRow.put("RESOURCE_TYPE", "All"); - firstRow.put("REFINE_BY_FIELDS", "accountname,region,tags.Application,tags.Environment,tags.Stack,tags.Role"); - firstRow.put("RETURN_FIELDS", "_resourceid,searchcategory,tags,accountname,_entitytype"); - - Map secondRow = new HashMap<>(); - secondRow.put("SEARCH_CATEGORY", "Policy Violations"); - secondRow.put("RESOURCE_TYPE", "All"); - secondRow.put("REFINE_BY_FIELDS", "severity,policyId"); - secondRow.put("RETURN_FIELDS", "_id,issueid,resourceid,severity,_entitytype,_resourceid"); - - Map thirdRow = new HashMap<>(); - thirdRow.put("SEARCH_CATEGORY", "Vulnerabilities"); - thirdRow.put("RESOURCE_TYPE", "All"); - thirdRow.put("REFINE_BY_FIELDS", "severity,category,vulntype"); - thirdRow.put("RETURN_FIELDS", "qid,vulntype,category,_entitytype,_resourceid"); - - returnFieldsData.add(firstRow); - returnFieldsData.add(secondRow); - returnFieldsData.add(thirdRow); - - Map tTypeMap1 = new HashMap<>(); - tTypeMap1.put("type", "ec2"); - Map tTypeMap2 = new HashMap<>(); - tTypeMap2.put("type", "s3"); - List> tTypeList = new ArrayList<>(); - tTypeList.add(tTypeMap1); - tTypeList.add(tTypeMap2); - - String responseJson = "{\"aggregations\":{\"targetTypes\":{\"buckets\":[{\"key\":\"ec2\",\"doc_count\":2774},{\"key\":\"volume\",\"doc_count\":1880}]}}}"; - - mockStatic(PacHttpUtils.class); - when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenReturn(responseJson); - when(pacmanRdsRepository.getDataFromPacman(anyString())).thenReturn(returnFieldsData); - ReflectionTestUtils.setField(repository, "rdsRepository", pacmanRdsRepository); - - String json = "{\"aggregations\":{\"severity\":{\"buckets\":[{\"key\":\"low\",\"doc_count\":2158},{\"key\":\"high\",\"doc_count\":1998}]}}}"; - mockStatic(EntityUtils.class); - - when(EntityUtils.toString(anyObject())).thenReturn(json); - when(response.getEntity()).thenReturn(null); - when(restClient.performRequest(anyString(), anyString(), any(Map.class), any(HttpEntity.class), - Matchers.
anyVararg())).thenReturn(response); - ReflectionTestUtils.setField(repository, "restClient", restClient); - - when(assetService.getTargetTypesForAssetGroup(anyString(), anyString())).thenReturn(tTypeList); - ReflectionTestUtils.setField(repository, "assetService", assetService); - - List> x = repository.fetchTargetTypes("aws-all", "pacman", "Assets", "", true); - - Map>> a = repository.fetchDistributionForTargetType("aws-all", "ec2", "pacman", - "Assets", true); - assertTrue(x.size() > 0); - - } - -} +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.api.asset.repository; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.StatusLine; +import org.apache.http.util.EntityUtils; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.test.util.ReflectionTestUtils; + +import com.tmobile.pacman.api.asset.domain.SearchResult; +import com.tmobile.pacman.api.asset.service.AssetService; +import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; +import com.tmobile.pacman.api.commons.repo.PacmanRdsRepository; +import com.tmobile.pacman.api.commons.utils.PacHttpUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ PacHttpUtils.class, EntityUtils.class, Response.class, RestClient.class }) +public class SearchRepositoryTest { + + @Mock + ElasticSearchRepository elasticSearchRepository; + + @Mock + PacmanRedshiftRepository redshiftRepository; + + @Mock + RestClient restClient; + + @Mock + StatusLine sl; + + @Mock + Response response; + + @Mock + PacmanRdsRepository pacmanRdsRepository; + + @Mock + AssetService assetService; + + SearchRepositoryImpl repository = new SearchRepositoryImpl(); + + @Test + public void testgetAssetCountByAssetGroup() throws Exception { + + List> returnFieldsData = new ArrayList<>(); + Map firstRow = new HashMap<>(); + firstRow.put("SEARCH_CATEGORY", "Assets"); + firstRow.put("RESOURCE_TYPE", "All"); + firstRow.put("REFINE_BY_FIELDS", "accountname,region,tags.Application,tags.Environment,tags.Stack,tags.Role"); + firstRow.put("RETURN_FIELDS", "_resourceid,searchcategory,tags,accountname,_entitytype"); + + Map secondRow = new HashMap<>(); + secondRow.put("SEARCH_CATEGORY", "Policy Violations"); + secondRow.put("RESOURCE_TYPE", "All"); + secondRow.put("REFINE_BY_FIELDS", "severity,policyId"); + secondRow.put("RETURN_FIELDS", "_id,issueid,resourceid,severity,_entitytype,_resourceid"); + + Map thirdRow = new HashMap<>(); + thirdRow.put("SEARCH_CATEGORY", "Vulnerabilities"); + thirdRow.put("RESOURCE_TYPE", "All"); + thirdRow.put("REFINE_BY_FIELDS", "severity,category,vulntype"); + thirdRow.put("RETURN_FIELDS", "qid,vulntype,category,_entitytype,_resourceid"); + + returnFieldsData.add(firstRow); + returnFieldsData.add(secondRow); + returnFieldsData.add(thirdRow); + + Map tTypeMap1 = new HashMap<>(); + tTypeMap1.put("type", "ec2"); + Map tTypeMap2 = new HashMap<>(); + tTypeMap1.put("type", "s3"); + List> tTypeList = new ArrayList<>(); + tTypeList.add(tTypeMap1); + tTypeList.add(tTypeMap2); + Map queryMap = new HashMap<>(); + queryMap.put("a", "1"); + + String responseJson = "{\"aggregations\":{\"qids\":{\"doc_count_error_upper_bound\":0,\"sum_other_doc_count\":0,\"buckets\":[]}}}"; + + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenReturn(responseJson); + + when(pacmanRdsRepository.getDataFromPacman(anyString())).thenReturn(returnFieldsData); + ReflectionTestUtils.setField(repository, "rdsRepository", pacmanRdsRepository); + when(assetService.getTargetTypesForAssetGroup(anyString(), anyString())).thenReturn(tTypeList); + ReflectionTestUtils.setField(repository, "assetService", assetService); + when(elasticSearchRepository.buildQuery(anyObject(), anyObject(), anyObject(), anyObject(), anyObject(), + anyObject())).thenReturn(queryMap); + when(elasticSearchRepository.processResponseAndSendTheScrollBack(anyString(), anyObject())) + .thenCallRealMethod(); + ReflectionTestUtils.setField(repository, "esRepository", elasticSearchRepository); + mockStatic(EntityUtils.class); + String json = "{\"hits\":{\"total\":10,\"hits\":[{\"_source\":{\"_resourceid\":\"a1\"},\"sort\":[\"s1\"]}]}}"; + + when(EntityUtils.toString(anyObject())).thenReturn(json); + when(response.getEntity()).thenReturn(null); + when(restClient.performRequest(anyString(), anyString(), any(Map.class), any(HttpEntity.class), + Matchers.
anyVararg())).thenReturn(response); + ReflectionTestUtils.setField(repository, "restClient", restClient); + + SearchResult sr = new SearchResult(); + sr = repository.fetchSearchResultsAndSetTotal("aws-all", null, true, null, "pacman", new HashMap<>(), 0, 1, sr, + "Vulnerabilities"); + assertTrue(sr.getTotal() == 0); + + sr = repository.fetchSearchResultsAndSetTotal("aws-all", null, true, null, "pacman", new HashMap<>(), 0, 1, sr, + "Assets"); + assertTrue(sr.getTotal() == 10); + + } + + @Test + public void testfetchTargetTypes() throws Exception { + + List> returnFieldsData = new ArrayList<>(); + Map firstRow = new HashMap<>(); + firstRow.put("SEARCH_CATEGORY", "Assets"); + firstRow.put("RESOURCE_TYPE", "All"); + firstRow.put("REFINE_BY_FIELDS", "accountname,region,tags.Application,tags.Environment,tags.Stack,tags.Role"); + firstRow.put("RETURN_FIELDS", "_resourceid,searchcategory,tags,accountname,_entitytype"); + + Map secondRow = new HashMap<>(); + secondRow.put("SEARCH_CATEGORY", "Policy Violations"); + secondRow.put("RESOURCE_TYPE", "All"); + secondRow.put("REFINE_BY_FIELDS", "severity,policyId"); + secondRow.put("RETURN_FIELDS", "_id,issueid,resourceid,severity,_entitytype,_resourceid"); + + Map thirdRow = new HashMap<>(); + thirdRow.put("SEARCH_CATEGORY", "Vulnerabilities"); + thirdRow.put("RESOURCE_TYPE", "All"); + thirdRow.put("REFINE_BY_FIELDS", "severity,category,vulntype"); + thirdRow.put("RETURN_FIELDS", "qid,vulntype,category,_entitytype,_resourceid"); + + returnFieldsData.add(firstRow); + returnFieldsData.add(secondRow); + returnFieldsData.add(thirdRow); + + Map tTypeMap1 = new HashMap<>(); + tTypeMap1.put("type", "ec2"); + Map tTypeMap2 = new HashMap<>(); + tTypeMap2.put("type", "s3"); + List> tTypeList = new ArrayList<>(); + tTypeList.add(tTypeMap1); + tTypeList.add(tTypeMap2); + + String responseJson = "{\"aggregations\":{\"targetTypes\":{\"buckets\":[{\"key\":\"ec2\",\"doc_count\":2774},{\"key\":\"volume\",\"doc_count\":1880}]}}}"; + + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenReturn(responseJson); + when(pacmanRdsRepository.getDataFromPacman(anyString())).thenReturn(returnFieldsData); + ReflectionTestUtils.setField(repository, "rdsRepository", pacmanRdsRepository); + + String json = "{\"aggregations\":{\"severity\":{\"buckets\":[{\"key\":\"low\",\"doc_count\":2158},{\"key\":\"high\",\"doc_count\":1998}]}}}"; + mockStatic(EntityUtils.class); + + when(EntityUtils.toString(anyObject())).thenReturn(json); + when(response.getEntity()).thenReturn(null); + when(restClient.performRequest(anyString(), anyString(), any(Map.class), any(HttpEntity.class), + Matchers.
anyVararg())).thenReturn(response); + ReflectionTestUtils.setField(repository, "restClient", restClient); + + when(assetService.getTargetTypesForAssetGroup(anyString(), anyString())).thenReturn(tTypeList); + ReflectionTestUtils.setField(repository, "assetService", assetService); + + List> x = repository.fetchTargetTypes("aws-all", "pacman", "Assets", "", true); + + Map>> a = repository.fetchDistributionForTargetType("aws-all", "ec2", "pacman", + "Assets", true); + assertTrue(x.size() > 0); + + } + +} diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/AssetServiceTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/AssetServiceTest.java index 696596d6d..0dc85a98a 100644 --- a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/AssetServiceTest.java +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/AssetServiceTest.java @@ -1,459 +1,459 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ -package com.tmobile.pacman.api.asset.service; - -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.anyString; -import static org.powermock.api.mockito.PowerMockito.mockStatic; -import static org.powermock.api.mockito.PowerMockito.when; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.http.StatusLine; -import org.apache.http.util.EntityUtils; -import org.elasticsearch.client.Response; -import org.elasticsearch.client.RestClient; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.springframework.test.util.ReflectionTestUtils; - -import com.tmobile.pacman.api.asset.domain.ResponseWithFieldsByTargetType; -import com.tmobile.pacman.api.asset.repository.AssetRepository; -import com.tmobile.pacman.api.asset.repository.PacmanRedshiftRepository; -import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; -import com.tmobile.pacman.api.commons.repo.PacmanRdsRepository; -import com.tmobile.pacman.api.commons.utils.PacHttpUtils; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({ PacHttpUtils.class, EntityUtils.class, Response.class, RestClient.class }) -public class AssetServiceTest { - - @Mock - ElasticSearchRepository elasticSearchRepository; - - @Mock - PacmanRedshiftRepository redshiftRepository; - - @Mock - RestClient restClient; - - @Mock - StatusLine sl; - - @Mock - Response response; - - @Mock - PacmanRdsRepository pacmanRdsRepository; - - @Mock - AssetRepository assetRepository; - - AssetServiceImpl service = new AssetServiceImpl(); - - @Test - public void testgetAssetCountByAssetGroup() throws Exception { - - Map tTypeMap1 = new HashMap<>(); - tTypeMap1.put("type", "ec2"); - - Map tTypeMap2 = new HashMap<>(); - tTypeMap2.put("type", "s3"); - - List> tTypeList = new ArrayList<>(); - tTypeList.add(tTypeMap1); - tTypeList.add(tTypeMap2); - - Map mockMap = new HashMap<>(); - mockMap.put("ec2", (long) 300); - mockMap.put("s3", (long) 655); - mockMap.put("stack", (long) 655); - - when(assetRepository.getAllTargetTypes()).thenReturn(tTypeList); - when(assetRepository.getTargetTypesByAssetGroup(anyObject(), anyObject())).thenReturn(tTypeList); - when(assetRepository.getAssetCountByAssetGroup(anyObject(), anyObject())).thenReturn(mockMap); - ReflectionTestUtils.setField(service, "repository", assetRepository); - - List> listOfCountMaps = new ArrayList<>(); - listOfCountMaps = service.getAssetCountByAssetGroup("testAg", "all", "testDomain"); - assertTrue(listOfCountMaps.size() == 2); - } - - @Test - public void testgetApplicationsByAssetGroup() throws Exception { - List appList = Arrays.asList("pacman", "monitor"); - when(assetRepository.getApplicationByAssetGroup(anyObject(), anyObject())).thenReturn(appList); - ReflectionTestUtils.setField(service, "repository", assetRepository); - List> a = service.getApplicationsByAssetGroup("testAg", "testDomain"); - assertTrue(a.size() == 2); - } - - @Test - public void testgetEnvironmentsByAssetGroup() throws Exception { - List appList = Arrays.asList("dev", "prd"); - when(assetRepository.getEnvironmentsByAssetGroup(anyObject(), anyObject(), anyObject())).thenReturn(appList); - ReflectionTestUtils.setField(service, "repository", assetRepository); - List> a = service.getEnvironmentsByAssetGroup("testAg", "pacman", "testDomain"); - assertTrue(a.size() == 2); - } - - @Test - public void testgetAllAssetGroups() throws Exception { - Map agAndDomain1 = new HashMap<>(); - Map agAndDomain2 = new HashMap<>(); - agAndDomain1.put("name", "testDomain"); - agAndDomain1.put("domain", "domain1"); - agAndDomain2.put("name", "name"); - agAndDomain2.put("domain", "domain2"); - List> agAndDomList = new ArrayList<>(); - agAndDomList.add(agAndDomain1); - agAndDomList.add(agAndDomain2); - - when(assetRepository.getAssetGroupAndDomains()).thenReturn(agAndDomList); - when(assetRepository.getAllAssetGroups()).thenReturn(agAndDomList); - ReflectionTestUtils.setField(service, "repository", assetRepository); - - List> a = service.getAllAssetGroups(); - assertTrue(a.size() == 2); - - } - - @Test - public void testgetAssetGroupInfo() throws Exception { - - Map agMap1 = new HashMap<>(); - agMap1.put("name", "testDomain"); - - List> agList = new ArrayList<>(); - agList.add(agMap1); - - when(assetRepository.getAssetGroupInfo(anyString())).thenReturn(agMap1); - when(assetRepository.getApplicationByAssetGroup(anyString())).thenReturn(Arrays.asList("pacman", "monitor")); - ReflectionTestUtils.setField(service, "repository", assetRepository); - - Map a = service.getAssetGroupInfo("testAg"); - System.out.println(a); - assertTrue(a.size() == 4); - - } - - @Test - public void testgetAssetCountByApplication() throws Exception { - Map mockMap = new HashMap<>(); - mockMap.put("app1", (long) 300); - mockMap.put("app2", (long) 655); - mockMap.put("app3", (long) 655); - - when(assetRepository.getAssetCountByApplication(anyString(), anyString())).thenReturn(mockMap); - ReflectionTestUtils.setField(service, "repository", assetRepository); - List> a = service.getAssetCountByApplication("testAg", "ec2"); - assertTrue(a.size() == 3); - } - - @Test - public void testgetAssetMinMax() throws Exception { - Map mockMap = new HashMap<>(); - mockMap.put("app1", (long) 300); - mockMap.put("app2", (long) 655); - mockMap.put("app3", (long) 655); - - when(assetRepository.getAssetCountByApplication(anyString(), anyString())).thenReturn(mockMap); - ReflectionTestUtils.setField(service, "repository", assetRepository); - List> a = service.getAssetCountByApplication("testAg", "ec2"); - assertTrue(a.size() == 3); - } - - @Test - public void testgetEc2ResourceDetail() throws Exception { - - List> rhnResourceList = new ArrayList<>(); - List> ec2ResourceList = new ArrayList<>(); - - Map resource = new HashMap<>(); - resource.put("last_boot", "value"); - resource.put("instanceid", "value"); - resource.put("ip", "value"); - resource.put("_id", "value"); - resource.put("creationdate", "value"); - resource.put("last_checkin", "value"); - resource.put("imageid", "value"); - resource.put("subnetid", "value"); - resource.put("instancetype", "value"); - resource.put("accountname", "value"); - resource.put("vpcid", "value"); - resource.put("availabilityzone", "value"); - resource.put("publicipaddress", "value"); - resource.put("privateipaddress", "value"); - resource.put("statename", "value"); - resource.put("monitoringstate", "value"); - resource.put("hostid", "value"); - resource.put("statereasoncode", "value"); - resource.put("virtualizationtype", "value"); - resource.put("rootdevicename", "value"); - resource.put("keyname", "value"); - resource.put("kernelid", "value"); - resource.put("statename", "value"); - resource.put("hypervisor", "value"); - resource.put("architecture", "value"); - resource.put("tenancy", "value"); - resource.put("createdBy", "value"); - resource.put("creationDate", "value"); - resource.put("email", "value"); - - rhnResourceList.add(resource); - ec2ResourceList.add(resource); - - when(assetRepository.getEc2ResourceDetailFromRhn(anyObject())).thenReturn(rhnResourceList); - when(assetRepository.getEc2ResourceDetail(anyObject(), anyObject())).thenReturn(ec2ResourceList); - when(assetRepository.getResourceCreateInfo(anyObject())).thenReturn(resource); - ReflectionTestUtils.setField(service, "repository", assetRepository); - - Map a = service.getEc2ResourceDetail("ag", "resourceId"); - - assertTrue(a.size() > 0); - } - - @Test - public void testgetGenericResourceDetail() throws Exception { - List> ec2ResourceList = new ArrayList<>(); - - Map ec2Resource = new HashMap<>(); - ec2Resource.put("last_boot", "value"); - ec2Resource.put("instanceid", "value"); - ec2Resource.put("ip", "value"); - ec2Resource.put("creationdate", "value"); - ec2Resource.put("_id", "value"); - ec2Resource.put("last_checkin", "value"); - ec2Resource.put("imageid", "value"); - ec2Resource.put("subnetid", "value"); - ec2Resource.put("instancetype", "value"); - ec2Resource.put("accountname", "value"); - ec2Resource.put("vpcid", "value"); - ec2Resource.put("availabilityzone", "value"); - ec2Resource.put("publicipaddress", "value"); - ec2Resource.put("privateipaddress", "value"); - ec2Resource.put("statename", "value"); - ec2Resource.put("monitoringstate", "value"); - ec2Resource.put("hostid", "value"); - ec2Resource.put("statereasoncode", "value"); - ec2Resource.put("virtualizationtype", "value"); - ec2Resource.put("rootdevicename", "value"); - ec2Resource.put("keyname", "value"); - ec2Resource.put("kernelid", "value"); - ec2Resource.put("statename", "value"); - ec2Resource.put("hypervisor", "value"); - ec2Resource.put("architecture", "value"); - ec2Resource.put("tenancy", "value"); - ec2Resource.put("createdBy", "value"); - ec2Resource.put("creationDate", "value"); - ec2Resource.put("email", "value"); - - ec2ResourceList.add(ec2Resource); - - when(assetRepository.getResourceDetail(anyObject(), anyObject(), anyObject())).thenReturn(ec2ResourceList); - ReflectionTestUtils.setField(service, "repository", assetRepository); - - Map a = service.getGenericResourceDetail("ag", "resourceType", "resourceId"); - - assertTrue(a.size() > 0); - } - - @Test - public void testgetEc2StateDetail() throws Exception { - List> ec2ResourceList = new ArrayList<>(); - - Map ec2Resource = new HashMap<>(); - ec2Resource.put("statename", "state1"); - ec2Resource.put("createdBy", "value"); - ec2Resource.put("creationDate", "value"); - ec2Resource.put("email", "value"); - - ec2ResourceList.add(ec2Resource); - - when(assetRepository.getEc2ResourceDetail(anyObject(), anyObject())).thenReturn(ec2ResourceList); - ReflectionTestUtils.setField(service, "repository", assetRepository); - String a = service.getEc2StateDetail("ag", "a1"); - assertTrue(a.equals("state1")); - } - - @Test - public void testgetNotificationSummary() throws Exception { - Map mockMap = new HashMap<>(); - mockMap.put("open", (long) 3); - mockMap.put("closed", (long) 7); - mockMap.put("upcoming", (long) 10); - - when(assetRepository.getNotificationSummary(anyObject())).thenReturn(mockMap); - ReflectionTestUtils.setField(service, "repository", assetRepository); - - List> a = service.getNotificationSummary("instanceId"); - assertTrue(a.size() == 3); - - } - - @Test - public void testgetNotificationSummaryTotal() throws Exception { - Map countMap1 = new HashMap<>(); - countMap1.put("count", 3); - Map countMap2 = new HashMap<>(); - countMap2.put("count", 4); - Map countMap3 = new HashMap<>(); - countMap3.put("count", 5); - - List> countList = new ArrayList<>(); - countList.add(countMap1); - countList.add(countMap2); - countList.add(countMap3); - - String a = service.getNotificationSummaryTotal(countList); - - assertTrue(a.equals("12")); - - } - - @Test - public void testgetResourceQualysDetail() throws Exception { - - List> ec2ResourceList = new ArrayList<>(); - - Map ec2Resource = new HashMap<>(); - ec2Resource.put("statename", "state1"); - ec2Resource.put("createdBy", "value"); - ec2Resource.put("creationDate", "value"); - ec2Resource.put("email", "value"); - ec2Resource.put("list", "[{\"username\":\"user\"}]"); - - ec2ResourceList.add(ec2Resource); - when(assetRepository.getQualysDetail(anyString())).thenReturn(ec2ResourceList); - ReflectionTestUtils.setField(service, "repository", assetRepository); - - List> a = service.getResourceQualysDetail("a1"); - - assertTrue(a.size() > 0); - - } - - @Test - public void testgetAdGroupsDetail() throws Exception { - - List> ec2ResourceList = new ArrayList<>(); - - Map ec2Resource = new HashMap<>(); - ec2Resource.put("tags.Name", "dev-rpl"); - ec2Resource.put("platform", "value"); - - ec2ResourceList.add(ec2Resource); - - when(assetRepository.getEc2ResourceDetail(anyString(), anyString())).thenReturn(ec2ResourceList); - ReflectionTestUtils.setField(service, "repository", assetRepository); - - List> adList = new ArrayList<>(); - Map adMap = new HashMap<>(); - adMap.put("name", "r_rhel_rpl_dev_"); - adMap.put("managedBy", "admin"); - adList.add(adMap); - - when(assetRepository.getAdGroupDetails()).thenReturn(adList); - - List> a = service.getAdGroupsDetail("testAg", "a1"); - - assertTrue(a.size() > 0); - - } - - @Test - public void testgetNotificationDetails() throws Exception { - List> notiList = new ArrayList<>(); - - Map notiMap = new HashMap<>(); - notiMap.put("_resourceid", "a1"); - notiMap.put("open", "p1"); - notiMap.put("closed", "P2"); - notiList.add(notiMap); - - when(assetRepository.getNotificationDetails(anyObject(),anyObject(),anyObject())).thenReturn(notiList); - ReflectionTestUtils.setField(service, "repository", assetRepository); - - List> a = service.getNotificationDetails("a1", null, ""); - - assertTrue(a.size() == 1); - - } - - @Test - public void testgetEc2CreatorDetail() throws Exception{ - Map ec2Resource = new HashMap<>(); - ec2Resource.put("statename", "state1"); - ec2Resource.put("createdBy", "value"); - ec2Resource.put("creationDate", "value"); - ec2Resource.put("email", "value"); - - - when(assetRepository.getResourceCreateInfo(anyObject())).thenReturn(ec2Resource); - ReflectionTestUtils.setField(service, "repository", assetRepository); - - - Map a = service.getEc2CreatorDetail("a1"); - assertTrue(a.size()==4); - } - - @Test - public void testgetEC2AvgAndTotalCost() throws Exception { - - ReflectionTestUtils.setField(service, "svcCorpUserId", ""); - ReflectionTestUtils.setField(service, "svcCorpPassword", ""); - ReflectionTestUtils.setField(service, "insightsTokenUrl", ""); - ReflectionTestUtils.setField(service, "insightsCostUrl", ""); - - String costResponse = "{\"totalCost\":500}"; - mockStatic(PacHttpUtils.class); - when(PacHttpUtils.getHttpGet(anyString(), anyObject())).thenReturn(costResponse); - when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenReturn("{\"token\":\"123\"}"); - - - - Map a = service.getEC2AvgAndTotalCost("a1"); - assertTrue(a.get("totalCost").toString().equals("500.0")); - } - - @Test - public void testgetEditFieldsByTargetType() throws Exception{ - String responseJson = "{\"dataTypes_info\":{\"key1\":\"value1\",\"key2\":\"value2\"}}"; - when(assetRepository.getDataTypeInfoByTargetType(anyObject())).thenReturn(responseJson); - ReflectionTestUtils.setField(service, "repository", assetRepository); - - ResponseWithFieldsByTargetType resp = service.getEditFieldsByTargetType("ec2"); - assertTrue(resp.getEditableFields().size()==2); - } - - @Test - public void testgetDataTypeInfoByTargetType() throws Exception{ - String responseJson = "{\"dataTypes_info\":{\"key1\":\"value1\",\"key2\":\"value2\"}}"; - when(assetRepository.getDataTypeInfoByTargetType(anyObject())).thenReturn(responseJson); - ReflectionTestUtils.setField(service, "repository", assetRepository); - - List> resp = service.getDataTypeInfoByTargetType("ec2"); - assertTrue(resp.size()==1); - } -} +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.api.asset.service; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.http.StatusLine; +import org.apache.http.util.EntityUtils; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.test.util.ReflectionTestUtils; + +import com.tmobile.pacman.api.asset.domain.ResponseWithFieldsByTargetType; +import com.tmobile.pacman.api.asset.repository.AssetRepository; +import com.tmobile.pacman.api.asset.repository.PacmanRedshiftRepository; +import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; +import com.tmobile.pacman.api.commons.repo.PacmanRdsRepository; +import com.tmobile.pacman.api.commons.utils.PacHttpUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ PacHttpUtils.class, EntityUtils.class, Response.class, RestClient.class }) +public class AssetServiceTest { + + @Mock + ElasticSearchRepository elasticSearchRepository; + + @Mock + PacmanRedshiftRepository redshiftRepository; + + @Mock + RestClient restClient; + + @Mock + StatusLine sl; + + @Mock + Response response; + + @Mock + PacmanRdsRepository pacmanRdsRepository; + + @Mock + AssetRepository assetRepository; + + AssetServiceImpl service = new AssetServiceImpl(); + + @Test + public void testgetAssetCountByAssetGroup() throws Exception { + + Map tTypeMap1 = new HashMap<>(); + tTypeMap1.put("type", "ec2"); + + Map tTypeMap2 = new HashMap<>(); + tTypeMap2.put("type", "s3"); + + List> tTypeList = new ArrayList<>(); + tTypeList.add(tTypeMap1); + tTypeList.add(tTypeMap2); + + Map mockMap = new HashMap<>(); + mockMap.put("ec2", (long) 300); + mockMap.put("s3", (long) 655); + mockMap.put("stack", (long) 655); + + when(assetRepository.getAllTargetTypes()).thenReturn(tTypeList); + when(assetRepository.getTargetTypesByAssetGroup(anyObject(), anyObject())).thenReturn(tTypeList); + when(assetRepository.getAssetCountByAssetGroup(anyObject(), anyObject())).thenReturn(mockMap); + ReflectionTestUtils.setField(service, "repository", assetRepository); + + List> listOfCountMaps = new ArrayList<>(); + listOfCountMaps = service.getAssetCountByAssetGroup("testAg", "all", "testDomain"); + assertTrue(listOfCountMaps.size() == 2); + } + + @Test + public void testgetApplicationsByAssetGroup() throws Exception { + List appList = Arrays.asList("pacman", "monitor"); + when(assetRepository.getApplicationByAssetGroup(anyObject(), anyObject())).thenReturn(appList); + ReflectionTestUtils.setField(service, "repository", assetRepository); + List> a = service.getApplicationsByAssetGroup("testAg", "testDomain"); + assertTrue(a.size() == 2); + } + + @Test + public void testgetEnvironmentsByAssetGroup() throws Exception { + List appList = Arrays.asList("dev", "prd"); + when(assetRepository.getEnvironmentsByAssetGroup(anyObject(), anyObject(), anyObject())).thenReturn(appList); + ReflectionTestUtils.setField(service, "repository", assetRepository); + List> a = service.getEnvironmentsByAssetGroup("testAg", "pacman", "testDomain"); + assertTrue(a.size() == 2); + } + + @Test + public void testgetAllAssetGroups() throws Exception { + Map agAndDomain1 = new HashMap<>(); + Map agAndDomain2 = new HashMap<>(); + agAndDomain1.put("name", "testDomain"); + agAndDomain1.put("domain", "domain1"); + agAndDomain2.put("name", "name"); + agAndDomain2.put("domain", "domain2"); + List> agAndDomList = new ArrayList<>(); + agAndDomList.add(agAndDomain1); + agAndDomList.add(agAndDomain2); + + when(assetRepository.getAssetGroupAndDomains()).thenReturn(agAndDomList); + when(assetRepository.getAllAssetGroups()).thenReturn(agAndDomList); + ReflectionTestUtils.setField(service, "repository", assetRepository); + + List> a = service.getAllAssetGroups(); + assertTrue(a.size() == 2); + + } + + @Test + public void testgetAssetGroupInfo() throws Exception { + + Map agMap1 = new HashMap<>(); + agMap1.put("name", "testDomain"); + + List> agList = new ArrayList<>(); + agList.add(agMap1); + + when(assetRepository.getAssetGroupInfo(anyString())).thenReturn(agMap1); + when(assetRepository.getApplicationByAssetGroup(anyString())).thenReturn(Arrays.asList("pacman", "monitor")); + ReflectionTestUtils.setField(service, "repository", assetRepository); + + Map a = service.getAssetGroupInfo("testAg"); + System.out.println(a); + assertTrue(a.size() == 4); + + } + + @Test + public void testgetAssetCountByApplication() throws Exception { + Map mockMap = new HashMap<>(); + mockMap.put("app1", (long) 300); + mockMap.put("app2", (long) 655); + mockMap.put("app3", (long) 655); + + when(assetRepository.getAssetCountByApplication(anyString(), anyString())).thenReturn(mockMap); + ReflectionTestUtils.setField(service, "repository", assetRepository); + List> a = service.getAssetCountByApplication("testAg", "ec2"); + assertTrue(a.size() == 3); + } + + @Test + public void testgetAssetMinMax() throws Exception { + Map mockMap = new HashMap<>(); + mockMap.put("app1", (long) 300); + mockMap.put("app2", (long) 655); + mockMap.put("app3", (long) 655); + + when(assetRepository.getAssetCountByApplication(anyString(), anyString())).thenReturn(mockMap); + ReflectionTestUtils.setField(service, "repository", assetRepository); + List> a = service.getAssetCountByApplication("testAg", "ec2"); + assertTrue(a.size() == 3); + } + + @Test + public void testgetEc2ResourceDetail() throws Exception { + + List> rhnResourceList = new ArrayList<>(); + List> ec2ResourceList = new ArrayList<>(); + + Map resource = new HashMap<>(); + resource.put("last_boot", "value"); + resource.put("instanceid", "value"); + resource.put("ip", "value"); + resource.put("_id", "value"); + resource.put("creationdate", "value"); + resource.put("last_checkin", "value"); + resource.put("imageid", "value"); + resource.put("subnetid", "value"); + resource.put("instancetype", "value"); + resource.put("accountname", "value"); + resource.put("vpcid", "value"); + resource.put("availabilityzone", "value"); + resource.put("publicipaddress", "value"); + resource.put("privateipaddress", "value"); + resource.put("statename", "value"); + resource.put("monitoringstate", "value"); + resource.put("hostid", "value"); + resource.put("statereasoncode", "value"); + resource.put("virtualizationtype", "value"); + resource.put("rootdevicename", "value"); + resource.put("keyname", "value"); + resource.put("kernelid", "value"); + resource.put("statename", "value"); + resource.put("hypervisor", "value"); + resource.put("architecture", "value"); + resource.put("tenancy", "value"); + resource.put("createdBy", "value"); + resource.put("creationDate", "value"); + resource.put("email", "value"); + + rhnResourceList.add(resource); + ec2ResourceList.add(resource); + + when(assetRepository.getEc2ResourceDetailFromRhn(anyObject())).thenReturn(rhnResourceList); + when(assetRepository.getEc2ResourceDetail(anyObject(), anyObject())).thenReturn(ec2ResourceList); + when(assetRepository.getResourceCreateInfo(anyObject())).thenReturn(resource); + ReflectionTestUtils.setField(service, "repository", assetRepository); + + Map a = service.getEc2ResourceDetail("ag", "resourceId"); + + assertTrue(a.size() > 0); + } + + @Test + public void testgetGenericResourceDetail() throws Exception { + List> ec2ResourceList = new ArrayList<>(); + + Map ec2Resource = new HashMap<>(); + ec2Resource.put("last_boot", "value"); + ec2Resource.put("instanceid", "value"); + ec2Resource.put("ip", "value"); + ec2Resource.put("creationdate", "value"); + ec2Resource.put("_id", "value"); + ec2Resource.put("last_checkin", "value"); + ec2Resource.put("imageid", "value"); + ec2Resource.put("subnetid", "value"); + ec2Resource.put("instancetype", "value"); + ec2Resource.put("accountname", "value"); + ec2Resource.put("vpcid", "value"); + ec2Resource.put("availabilityzone", "value"); + ec2Resource.put("publicipaddress", "value"); + ec2Resource.put("privateipaddress", "value"); + ec2Resource.put("statename", "value"); + ec2Resource.put("monitoringstate", "value"); + ec2Resource.put("hostid", "value"); + ec2Resource.put("statereasoncode", "value"); + ec2Resource.put("virtualizationtype", "value"); + ec2Resource.put("rootdevicename", "value"); + ec2Resource.put("keyname", "value"); + ec2Resource.put("kernelid", "value"); + ec2Resource.put("statename", "value"); + ec2Resource.put("hypervisor", "value"); + ec2Resource.put("architecture", "value"); + ec2Resource.put("tenancy", "value"); + ec2Resource.put("createdBy", "value"); + ec2Resource.put("creationDate", "value"); + ec2Resource.put("email", "value"); + + ec2ResourceList.add(ec2Resource); + + when(assetRepository.getResourceDetail(anyObject(), anyObject(), anyObject())).thenReturn(ec2ResourceList); + ReflectionTestUtils.setField(service, "repository", assetRepository); + + Map a = service.getGenericResourceDetail("ag", "resourceType", "resourceId"); + + assertTrue(a.size() > 0); + } + + @Test + public void testgetEc2StateDetail() throws Exception { + List> ec2ResourceList = new ArrayList<>(); + + Map ec2Resource = new HashMap<>(); + ec2Resource.put("statename", "state1"); + ec2Resource.put("createdBy", "value"); + ec2Resource.put("creationDate", "value"); + ec2Resource.put("email", "value"); + + ec2ResourceList.add(ec2Resource); + + when(assetRepository.getEc2ResourceDetail(anyObject(), anyObject())).thenReturn(ec2ResourceList); + ReflectionTestUtils.setField(service, "repository", assetRepository); + String a = service.getEc2StateDetail("ag", "a1"); + assertTrue(a.equals("state1")); + } + + @Test + public void testgetNotificationSummary() throws Exception { + Map mockMap = new HashMap<>(); + mockMap.put("open", (long) 3); + mockMap.put("closed", (long) 7); + mockMap.put("upcoming", (long) 10); + + when(assetRepository.getNotificationSummary(anyObject())).thenReturn(mockMap); + ReflectionTestUtils.setField(service, "repository", assetRepository); + + List> a = service.getNotificationSummary("instanceId"); + assertTrue(a.size() == 3); + + } + + @Test + public void testgetNotificationSummaryTotal() throws Exception { + Map countMap1 = new HashMap<>(); + countMap1.put("count", 3); + Map countMap2 = new HashMap<>(); + countMap2.put("count", 4); + Map countMap3 = new HashMap<>(); + countMap3.put("count", 5); + + List> countList = new ArrayList<>(); + countList.add(countMap1); + countList.add(countMap2); + countList.add(countMap3); + + String a = service.getNotificationSummaryTotal(countList); + + assertTrue(a.equals("12")); + + } + + @Test + public void testgetResourceQualysDetail() throws Exception { + + List> ec2ResourceList = new ArrayList<>(); + + Map ec2Resource = new HashMap<>(); + ec2Resource.put("statename", "state1"); + ec2Resource.put("createdBy", "value"); + ec2Resource.put("creationDate", "value"); + ec2Resource.put("email", "value"); + ec2Resource.put("list", "[{\"username\":\"user\"}]"); + + ec2ResourceList.add(ec2Resource); + when(assetRepository.getQualysDetail(anyString())).thenReturn(ec2ResourceList); + ReflectionTestUtils.setField(service, "repository", assetRepository); + + List> a = service.getResourceQualysDetail("a1"); + + assertTrue(a.size() > 0); + + } + + @Test + public void testgetAdGroupsDetail() throws Exception { + + List> ec2ResourceList = new ArrayList<>(); + + Map ec2Resource = new HashMap<>(); + ec2Resource.put("tags.Name", "dev-rpl"); + ec2Resource.put("platform", "value"); + + ec2ResourceList.add(ec2Resource); + + when(assetRepository.getEc2ResourceDetail(anyString(), anyString())).thenReturn(ec2ResourceList); + ReflectionTestUtils.setField(service, "repository", assetRepository); + + List> adList = new ArrayList<>(); + Map adMap = new HashMap<>(); + adMap.put("name", "r_rhel_rpl_dev_"); + adMap.put("managedBy", "admin"); + adList.add(adMap); + + when(assetRepository.getAdGroupDetails()).thenReturn(adList); + + List> a = service.getAdGroupsDetail("testAg", "a1"); + + assertTrue(a.size() > 0); + + } + + @Test + public void testgetNotificationDetails() throws Exception { + List> notiList = new ArrayList<>(); + + Map notiMap = new HashMap<>(); + notiMap.put("_resourceid", "a1"); + notiMap.put("open", "p1"); + notiMap.put("closed", "P2"); + notiList.add(notiMap); + + when(assetRepository.getNotificationDetails(anyObject(),anyObject(),anyObject())).thenReturn(notiList); + ReflectionTestUtils.setField(service, "repository", assetRepository); + + List> a = service.getNotificationDetails("a1", null, ""); + + assertTrue(a.size() == 1); + + } + + @Test + public void testgetEc2CreatorDetail() throws Exception{ + Map ec2Resource = new HashMap<>(); + ec2Resource.put("statename", "state1"); + ec2Resource.put("createdBy", "value"); + ec2Resource.put("creationDate", "value"); + ec2Resource.put("email", "value"); + + + when(assetRepository.getResourceCreateInfo(anyObject())).thenReturn(ec2Resource); + ReflectionTestUtils.setField(service, "repository", assetRepository); + + + Map a = service.getEc2CreatorDetail("a1"); + assertTrue(a.size()==4); + } + + @Test + public void testgetEC2AvgAndTotalCost() throws Exception { + + ReflectionTestUtils.setField(service, "svcCorpUserId", ""); + ReflectionTestUtils.setField(service, "svcCorpPassword", ""); + ReflectionTestUtils.setField(service, "insightsTokenUrl", ""); + ReflectionTestUtils.setField(service, "insightsCostUrl", ""); + + String costResponse = "{\"totalCost\":500}"; + mockStatic(PacHttpUtils.class); + when(PacHttpUtils.getHttpGet(anyString(), anyObject())).thenReturn(costResponse); + when(PacHttpUtils.doHttpPost(anyString(), anyString())).thenReturn("{\"token\":\"123\"}"); + + + + Map a = service.getEC2AvgAndTotalCost("a1"); + assertTrue(a.get("totalCost").toString().equals("500.0")); + } + + @Test + public void testgetEditFieldsByTargetType() throws Exception{ + String responseJson = "{\"dataTypes_info\":{\"key1\":\"value1\",\"key2\":\"value2\"}}"; + when(assetRepository.getDataTypeInfoByTargetType(anyObject())).thenReturn(responseJson); + ReflectionTestUtils.setField(service, "repository", assetRepository); + + ResponseWithFieldsByTargetType resp = service.getEditFieldsByTargetType("ec2"); + assertTrue(resp.getEditableFields().size()==2); + } + + @Test + public void testgetDataTypeInfoByTargetType() throws Exception{ + String responseJson = "{\"dataTypes_info\":{\"key1\":\"value1\",\"key2\":\"value2\"}}"; + when(assetRepository.getDataTypeInfoByTargetType(anyObject())).thenReturn(responseJson); + ReflectionTestUtils.setField(service, "repository", assetRepository); + + List> resp = service.getDataTypeInfoByTargetType("ec2"); + assertTrue(resp.size()==1); + } +} diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/CostServiceTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/CostServiceTest.java new file mode 100644 index 000000000..dd67bcb44 --- /dev/null +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/CostServiceTest.java @@ -0,0 +1,193 @@ +package com.tmobile.pacman.api.asset.service; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.test.util.ReflectionTestUtils; + +import com.tmobile.pacman.api.asset.domain.ApplicationDetail; +import com.tmobile.pacman.api.asset.repository.AssetRepository; +import com.tmobile.pacman.api.asset.repository.CostRepository; +import com.tmobile.pacman.api.commons.Constants; +import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; + +@RunWith(PowerMockRunner.class) +public class CostServiceTest { + + @Mock + ElasticSearchRepository elasticSearchRepository; + + @Mock + AssetService assetService; + + @Mock + CostRepository costRepository; + + @Mock + AssetRepository assetRepository; + + @InjectMocks + CostService costService; + + @SuppressWarnings({ "deprecation", "unchecked" }) + @Test + public void getCostByTypeTest() throws Exception { + Map yearMonth = new HashMap<>(); + yearMonth.put("month", 5); + yearMonth.put("year", 2019); + when(costRepository.findLatestCostFinalisedMonth()).thenReturn(yearMonth); + when(costRepository.fetchApplicationMasterList()).thenReturn(new ArrayList<>()); + ReflectionTestUtils.setField(costService, "costRepository", costRepository); + when(elasticSearchRepository.getDataFromES(anyString(),anyString(),anyObject(),anyObject(),anyObject(),anyObject(),anyObject())).thenReturn(getCurrentCost(),getPreviousCost()); + List> typeDataSource = new ArrayList<>(); + Map dataSource = new HashMap<>(); + dataSource.put(Constants.TYPE, Constants.TYPE); + dataSource.put(Constants.PROVIDER, "aws"); + typeDataSource.add(dataSource); + when(assetRepository.getDatasourceForCostMapping(anyObject())).thenReturn(typeDataSource); + + assertTrue(costService.getCostByType("ag", 2019, Arrays.asList("4"), Arrays.asList("app"), Arrays.asList("type")).size() == 7); + assertTrue(costService.getCostByType("ag", null, new ArrayList<>(), Arrays.asList("app"), Arrays.asList("type")).size() == 7); + assertTrue(costService.getCostByType("ag", 2019, Arrays.asList("2","3"), Arrays.asList("app"), Arrays.asList("type")).size() == 7); + assertTrue(costService.getCostByType("ag", 2019, Arrays.asList("1","2","3"), Arrays.asList("app"), Arrays.asList("type")).size() == 7); + assertTrue(costService.getCostByType("ag", 2019, Arrays.asList("1"), Arrays.asList("app"), Arrays.asList("type")).size() == 7); + } + + @Test + public void getCostByTypeTest_Exception() throws Exception { + when(costRepository.findLatestCostFinalisedMonth()).thenReturn(new HashMap<>()); + assertThatThrownBy(() -> costService.getCostByType("ag", null, new ArrayList<>(), Arrays.asList("app"), Arrays.asList("type"))) + .isInstanceOf(Exception.class); + } + + @SuppressWarnings({ "deprecation", "unchecked" }) + @Test + public void getCostByApplicationTest() throws Exception { + Map yearMonth = new HashMap<>(); + yearMonth.put("month", 5); + yearMonth.put("year", 2019); + when(costRepository.findLatestCostFinalisedMonth()).thenReturn(yearMonth); + when( costRepository.fetchApplicationMasterList()).thenReturn(Arrays.asList("app")); + ReflectionTestUtils.setField(costService, "costRepository", costRepository); + when(elasticSearchRepository.getDataFromES(anyString(),anyString(),anyObject(),anyObject(),anyObject(),anyObject(),anyObject())).thenReturn(getCurrentCost(),getPreviousCost()); + + assertTrue(costService.getCostByApplication("ag", 2019, Arrays.asList("4"), Arrays.asList("app"), Arrays.asList("type"), getValidApplications()).size() == 7); + assertTrue(costService.getCostByApplication("ag", null, new ArrayList<>(), Arrays.asList("app"), Arrays.asList("type"), getValidApplications()).size() == 7); + assertTrue(costService.getCostByApplication("ag", 2019, Arrays.asList("2","3"), Arrays.asList("app"), Arrays.asList("type"), getValidApplications()).size() == 7); + assertTrue(costService.getCostByApplication("ag", 2019, Arrays.asList("1","2","3"), Arrays.asList("app"), Arrays.asList("type"), getValidApplications()).size() == 7); + assertTrue(costService.getCostByApplication("ag", 2019, Arrays.asList("1"), Arrays.asList("app"), Arrays.asList("type"), getValidApplications()).size() == 7); + } + + @Test + public void getCostByApplicationTest_Exception() throws Exception { + when(costRepository.findLatestCostFinalisedMonth()).thenReturn(new HashMap<>()); + assertThatThrownBy(() -> costService.getCostByApplication("ag", null, new ArrayList<>(), Arrays.asList("app"), Arrays.asList("type"), getValidApplications())) + .isInstanceOf(Exception.class); + } + + @Test + public void getCostTrendTest() throws Exception { + + when(costRepository.getCostAggs(anyObject())).thenReturn(getCostTrend()); + assertTrue(costService.getCostTrend(Arrays.asList("app"), new ArrayList<>(), "monthly").size() == 5); + + when(costRepository.getCostAggsWithTT(anyObject(), anyObject())).thenReturn(getCostTrend()); + assertTrue(costService.getCostTrend(Arrays.asList("app"), Arrays.asList("type"), "quarterly").size() == 2); + } + + private List> getCurrentCost() { + + List> currentCost = new ArrayList<>(); + Map cost = new HashMap<>(); + cost.put("application", "app"); + cost.put("month", 4.0); + cost.put("year", 2019.0); + cost.put("finalised", "false"); + cost.put("totalCost", 44942.096); + List> typeCost = new ArrayList<>(); + Map type = new HashMap<>(); + type.put("cost", 44942.096); + type.put("type", "type"); + typeCost.add(type); + cost.put("list",typeCost); + currentCost.add(cost); + return currentCost; + } + + private List> getPreviousCost() { + + List> previousCost = new ArrayList<>(); + Map cost = new HashMap<>(); + cost.put("application", "app"); + cost.put("month", 4.0); + cost.put("year", 2019.0); + cost.put("finalised", "false"); + cost.put("totalCost", 44942.096); + List> typeCost = new ArrayList<>(); + Map type = new HashMap<>(); + type.put("cost", 44942.096); + type.put("type", "type"); + typeCost.add(type); + cost.put("list",typeCost); + previousCost.add(cost); + return previousCost; + } + + private List getValidApplications() { + List validApplications = new ArrayList<>(); + ApplicationDetail app = new ApplicationDetail(); + app.setName("app"); + validApplications.add(app); + return validApplications; + } + + private List> getCostTrend() { + + List> costTrend = new ArrayList<>(); + Map trend = new HashMap<>(); + trend.put("month", 1); + trend.put("year", 2019); + trend.put("cost", 57221); + trend.put("finalised", true); + costTrend.add(trend); + trend = new HashMap<>(); + trend.put("month", 2); + trend.put("year", 2019); + trend.put("cost", 50138); + trend.put("finalised", true); + costTrend.add(trend); + trend = new HashMap<>(); + trend.put("month", 3); + trend.put("year", 2019); + trend.put("cost", 44942); + trend.put("finalised", true); + costTrend.add(trend); + trend = new HashMap<>(); + trend.put("month", 4); + trend.put("year", 2019); + trend.put("cost", 37134); + trend.put("finalised", false); + costTrend.add(trend); + trend = new HashMap<>(); + trend.put("month", 5); + trend.put("year", 2019); + trend.put("cost", 6517); + trend.put("finalised", false); + costTrend.add(trend); + return costTrend; + } +} diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/RecommendationServiceTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/RecommendationServiceTest.java new file mode 100644 index 000000000..1cf71fdcb --- /dev/null +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/RecommendationServiceTest.java @@ -0,0 +1,76 @@ +package com.tmobile.pacman.api.asset.service; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyString; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.test.util.ReflectionTestUtils; + +import com.tmobile.pacman.api.asset.repository.RecommendationsRepository; + +@RunWith(PowerMockRunner.class) +public class RecommendationServiceTest { + + @Mock + RecommendationsRepository recommendationsRepository; + + RecommendationsService recommendationsService = new RecommendationsService(); + + @Test + public void getRecommendationSummaryTest() throws Exception { + + when(recommendationsRepository.getGeneralRecommendationSummary()).thenReturn(new ArrayList<>()); + ReflectionTestUtils.setField(recommendationsService, "recommendationsRepository", recommendationsRepository); + assertTrue(recommendationsService.getRecommendationSummary(null,null,true).size() == 0); + when(recommendationsRepository.getRecommendationSummary(anyString(), anyString())).thenReturn(new ArrayList<>()); + assertTrue(recommendationsService.getRecommendationSummary("ag","app",false).size() == 0); + } + + @Test + public void getSummaryByApplicationTest() throws Exception { + + when(recommendationsRepository.getSummaryByApplication(anyString())).thenReturn(new HashMap<>()); + ReflectionTestUtils.setField(recommendationsService, "recommendationsRepository", recommendationsRepository); + assertTrue(recommendationsService.getSummaryByApplication("ag",null).size() == 0); + when(recommendationsRepository.getSummaryByApplication(anyString(), anyString())).thenReturn(new HashMap<>()); + assertTrue(recommendationsService.getSummaryByApplication("ag","category").size() == 0); + } + + @Test + public void getRecommendationsTest() throws Exception { + + when(recommendationsRepository.getGeneralRecommendations(anyString())).thenReturn(new HashMap<>()); + ReflectionTestUtils.setField(recommendationsService, "recommendationsRepository", recommendationsRepository); + assertTrue(recommendationsService.getRecommendations(null,"category",null,"false").size() == 0); + when(recommendationsRepository.getRecommendations(anyString(), anyString(), anyString())).thenReturn(new HashMap<>()); + assertTrue(recommendationsService.getRecommendations("ag","category","app","true").size() == 0); + } + + @Test + public void getRecommendationDetailTest() throws Exception { + + when(recommendationsRepository.getGeneralRecommendationDetail(anyString())).thenReturn(new HashMap<>()); + ReflectionTestUtils.setField(recommendationsService, "recommendationsRepository", recommendationsRepository); + assertTrue(recommendationsService.getRecommendationDetail(null,"id",null,"false").size() == 0); + when(recommendationsRepository.getRecommendationDetail(anyString(), anyString(), anyString())).thenReturn(new HashMap<>()); + assertTrue(recommendationsService.getRecommendationDetail("ag","id","app","true").size() == 0); + } + + @Test + public void getRecommendationInfoTest() throws Exception { + + Map recommendationInfo = new HashMap<>(); + recommendationInfo.put("checkdescription", "Checks for Provisioned IOPS (SSD) volume.Alert Criteria Yellow: An Amazon EC2 instance that can be EBS-optimized.Recommended Action Create a new instance that is EBS-optimized, detach the volume, and reattach the volume to your new instance."); + when(recommendationsRepository.getRecommendation(anyString())).thenReturn(recommendationInfo); + ReflectionTestUtils.setField(recommendationsService, "recommendationsRepository", recommendationsRepository); + assertTrue(recommendationsService.getRecommendationInfo("id").size() == 3); + } +} \ No newline at end of file diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/SearchServiceTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/SearchServiceTest.java index f766a713f..a9b1c7f62 100644 --- a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/SearchServiceTest.java +++ b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/SearchServiceTest.java @@ -1,115 +1,115 @@ -package com.tmobile.pacman.api.asset.service; - -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyBoolean; - -import static org.powermock.api.mockito.PowerMockito.mockStatic; -import static org.powermock.api.mockito.PowerMockito.when; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.http.StatusLine; -import org.apache.http.util.EntityUtils; -import org.elasticsearch.client.Response; -import org.elasticsearch.client.RestClient; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.springframework.test.util.ReflectionTestUtils; - -import com.tmobile.pacman.api.asset.domain.ResponseWithFieldsByTargetType; -import com.tmobile.pacman.api.asset.domain.SearchCriteria; -import com.tmobile.pacman.api.asset.domain.SearchResult; -import com.tmobile.pacman.api.asset.repository.AssetRepository; -import com.tmobile.pacman.api.asset.repository.PacmanRedshiftRepository; -import com.tmobile.pacman.api.asset.repository.SearchRepository; -import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; -import com.tmobile.pacman.api.commons.repo.PacmanRdsRepository; -import com.tmobile.pacman.api.commons.utils.PacHttpUtils; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({ PacHttpUtils.class, EntityUtils.class, Response.class, RestClient.class }) -public class SearchServiceTest { - - @Mock - ElasticSearchRepository elasticSearchRepository; - - @Mock - RestClient restClient; - - @Mock - StatusLine sl; - - @Mock - Response response; - - @Mock - PacmanRdsRepository pacmanRdsRepository; - - @Mock - SearchRepository searchRepository; - - SearchServiceImpl service = new SearchServiceImpl(); - - @Test - public void testgetSearchCategories() throws Exception { - - List categs = service.getSearchCategories("Infra"); - assertTrue(categs.size() == 3); - - categs = service.getSearchCategories("other"); - assertTrue(categs.size() == 2); - - } - - @Test - public void testSearch() throws Exception { - SearchCriteria incomingCrit = new SearchCriteria(); - SearchResult sr = new SearchResult(); - List> dataList = new ArrayList<>(); - Map dataMap1 = new HashMap<>(); - dataMap1.put("_id", "a1"); - dataMap1.put("searchCategory", "Assets"); - dataList.add(dataMap1); - sr.setResults(dataList); - sr.setTotal(1); - - List> tTypeList = new ArrayList<>(); - Map tTypeMap = new HashMap<>(); - tTypeMap.put("fieldName", "snapshot"); - tTypeMap.put("count",(long)1); - tTypeList.add(tTypeMap); - - - Map>> distMap = new HashMap<>(); - List> distList = new ArrayList(); - Map dataMap = new HashMap<>(); - dataMap.put("type", "searchFilterAttribute"); - dataMap.put("fieldName", "low"); - dataMap.put("applied", true); - dataMap.put("groupBy", null); - dataMap.put("count", (long)3); - distList.add(dataMap); - distMap.put("severity", distList); - - - when(searchRepository.fetchSearchResultsAndSetTotal(anyString(), anyString(), anyBoolean(), anyString(), - anyString(), anyObject(), anyInt(), anyInt(), anyObject(), anyString())).thenReturn(sr); - when(searchRepository.fetchTargetTypes(anyString(), anyString(), anyString(), anyString(), anyBoolean())).thenReturn(tTypeList); - when(searchRepository.fetchDistributionForTargetType(anyString(), anyString(), anyString(), anyString(), anyBoolean())).thenReturn(distMap ); - ReflectionTestUtils.setField(service, "searchRepository", searchRepository); - - SearchResult result = service.search(incomingCrit); - assertTrue(result.getTotal()==1); - } - -} +package com.tmobile.pacman.api.asset.service; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyBoolean; + +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.http.StatusLine; +import org.apache.http.util.EntityUtils; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.test.util.ReflectionTestUtils; + +import com.tmobile.pacman.api.asset.domain.ResponseWithFieldsByTargetType; +import com.tmobile.pacman.api.asset.domain.SearchCriteria; +import com.tmobile.pacman.api.asset.domain.SearchResult; +import com.tmobile.pacman.api.asset.repository.AssetRepository; +import com.tmobile.pacman.api.asset.repository.PacmanRedshiftRepository; +import com.tmobile.pacman.api.asset.repository.SearchRepository; +import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; +import com.tmobile.pacman.api.commons.repo.PacmanRdsRepository; +import com.tmobile.pacman.api.commons.utils.PacHttpUtils; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ PacHttpUtils.class, EntityUtils.class, Response.class, RestClient.class }) +public class SearchServiceTest { + + @Mock + ElasticSearchRepository elasticSearchRepository; + + @Mock + RestClient restClient; + + @Mock + StatusLine sl; + + @Mock + Response response; + + @Mock + PacmanRdsRepository pacmanRdsRepository; + + @Mock + SearchRepository searchRepository; + + SearchServiceImpl service = new SearchServiceImpl(); + + @Test + public void testgetSearchCategories() throws Exception { + + List categs = service.getSearchCategories("Infra"); + assertTrue(categs.size() == 3); + + categs = service.getSearchCategories("other"); + assertTrue(categs.size() == 2); + + } + + @Test + public void testSearch() throws Exception { + SearchCriteria incomingCrit = new SearchCriteria(); + SearchResult sr = new SearchResult(); + List> dataList = new ArrayList<>(); + Map dataMap1 = new HashMap<>(); + dataMap1.put("_id", "a1"); + dataMap1.put("searchCategory", "Assets"); + dataList.add(dataMap1); + sr.setResults(dataList); + sr.setTotal(1); + + List> tTypeList = new ArrayList<>(); + Map tTypeMap = new HashMap<>(); + tTypeMap.put("fieldName", "snapshot"); + tTypeMap.put("count",(long)1); + tTypeList.add(tTypeMap); + + + Map>> distMap = new HashMap<>(); + List> distList = new ArrayList(); + Map dataMap = new HashMap<>(); + dataMap.put("type", "searchFilterAttribute"); + dataMap.put("fieldName", "low"); + dataMap.put("applied", true); + dataMap.put("groupBy", null); + dataMap.put("count", (long)3); + distList.add(dataMap); + distMap.put("severity", distList); + + + when(searchRepository.fetchSearchResultsAndSetTotal(anyString(), anyString(), anyBoolean(), anyString(), + anyString(), anyObject(), anyInt(), anyInt(), anyObject(), anyString())).thenReturn(sr); + when(searchRepository.fetchTargetTypes(anyString(), anyString(), anyString(), anyString(), anyBoolean())).thenReturn(tTypeList); + when(searchRepository.fetchDistributionForTargetType(anyString(), anyString(), anyString(), anyString(), anyBoolean())).thenReturn(distMap ); + ReflectionTestUtils.setField(service, "searchRepository", searchRepository); + + SearchResult result = service.search(incomingCrit); + assertTrue(result.getTotal()==1); + } + +} diff --git a/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/Constants.java b/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/Constants.java index ea7c14670..9ae17b45d 100644 --- a/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/Constants.java +++ b/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/Constants.java @@ -1,293 +1,294 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ - /** - Copyright (C) 2017 T Mobile Inc - All Rights Reserve - Purpose: - Author :kkumar - Modified Date: Oct 18, 2017 - **/ -package com.tmobile.pacman.api.commons; - -public interface Constants { - - Integer ES_PAGE_SIZE = 10000; - String ES_PAGE_SCROLL_TTL = "2m"; - String ES_DOC_ID_KEY = "_id"; - String ES_DOC_PARENT_KEY = "_parent"; - String ES_DOC_ROUTING_KEY = "_routing"; - String MESSAGE_KEY = "message"; - String FAIL_MESSAGE = "failed"; - String STATUS_KEY = "message"; - String STATUS_SUCCESS = "success"; - String DATA_KEY = "data"; - String TYPE = "type"; - String SUBTYPE = "subtype"; - String LATEST = "latest"; - String TRUE = "true"; - String ISSUE = "issue"; - String RECOMMENDATION = "RECOMMENDATION"; - String CLOSED = "closed"; - String OPEN = "open"; - String RULE_CATEGORY = "ruleCategory"; - String ISSUE_STATUS = "issueStatus"; - String INCLUDE_EXEMPT = "include_exempt"; - String SEVERITY = "severity"; - String NAME = "name"; - String RULEID = "ruleId"; - String POLICYID = "policyId"; - String OPEN_ISSUES = "openIssues"; - String EC2_MANDATORY_TAG_RULE = "PacMan_ec2mandatorytags_version-1_ec2mandatorytags_ec2"; - String EC2_KERNEL_COMPLIANCE_RULE = "PacMan_cloud-kernel-compliance_version-1_Ec2-Kernel-Compliance-Rule_ec2"; - String VULNAR_SEVERITY_LEVEL = "vuln.list.hostAssetVuln.severitylevel"; - String SSL_EXPIRY_RULE = "PacMan_certificate-expiry-policy_version-1_SSLcertificatesexpirywithin45days_cert"; - String KEY = "key"; - String VALUE = "value"; - String PARAMS = "params"; - String RULE_NAME = "ruleName"; - String DISPLAY_NAME = "displayName"; - String ASSETS_SCANNED = "assetsScanned"; - String PASSED = "passed"; - String FAILED = "failed"; - String RULE_DISPAY_NAME = "displayName"; - String RULE_PARAMS = "ruleParams"; - String TARGET_TYPE = "targetType"; - String RESOURCE_TYPE = "resourcetType"; - String POLICY_DESC = "policyDesc"; - String TAGGIG_POLICY = "PacMan_TaggingRule_version-1"; - String TITLE = "title"; - String DESCRIPTION = "description"; - String METRIC_NAME = "metricName"; - String METRIC_VALUE = "metricValue"; - String COUNT = "count"; - String SEVEITY_LEVEL = "severitylevel"; - String DATE = "date"; - String NETWORK_IN = "networkIn"; - String NETWORK_OUT = "networkOut"; - String CPU_UTILIZATION = "cpu-utilization"; - String DISK_READ_IN_BYTES = "diskReadinBytes"; - String DISK_WRITE_IN_BYTES = "diskWriteinBytes"; - String AWS = "aws"; - String RESOURCEID = "_resourceid"; - String AUDIT_DATE = "auditdate"; - String STATUS = "status"; - String DATA_SOURCE = "datasource"; - String DELIMITER = "*"; - String _ID = "_id"; - String ID = "id"; - String EXEMPTED = "exempted"; - String MODIFIED_DATE = "modifiedDate"; - String PAC_DS = "pac_ds"; - String POLICY_VIOLATION = "#violation"; - String CONTRIBUTION = "contribution"; - String COMPLIANCE_PERCENTAGE = "compliance"; - String COMPLIANCE_PERCENT = "compliance_percent"; - String LAST_SCAN = "lastScan"; - String TAGGING_POLICY = "PacMan_TaggingRule_version-1"; - String TAGS_APPLICATION = "tags.Application"; - String MISSING_TAGS = "missingTags"; - String ACCOUNT_ID = "accountid"; - String ACCOUNT_NAME = "accountname"; - String REGION = "region"; - String CREATED_DATE = "createdDate"; - String TAGS_ENVIRONMENT = "tags.Environment"; - String DESC = "desc"; - String POLICY_DISPLAY_NAME = "PolicyName"; - String RULE_DISPLAY_ID = "RuleId"; - String POLICY_DISPLAY_ID = "PolicyId"; - String ISSUE_ID = "IssueId"; - String RESOURCE_DISPLAY_ID = "ResourceId"; - String APPLICATION = "Application"; - String ENVIRONMENT = "Environment"; - String REGION_DISPALY_NAME = "Region"; - String SEVERITY_DISPALY_NAME = "Severity"; - String RULECATEGORY_DISPALY_NAME = "RuleCategory"; - String ACCOUNT_DISPLAYI_D = "AccountId"; - String ACCOUNT_DISPALY_NAME = "AccountName"; - String CREATED_DISPLAY_DATE = "CreatedOn"; - String MODIFIED_DISPLAY_DATE = "ModifiedOn"; - String STATUS_DISPLAY_NAME = "Status"; - String RUNNING = "running"; - String PLATFORM = "platform"; - String STATE_NAME = "statename"; - String WINDOWS = "windows"; - String ONPREM_KERNEL_COMPLIANCE_RULE = "PacMan_onpremisekernelversion_version-1_onpremKernelVersionRule_onpremserver"; - String CLOUD_QUALYS_RULE="PacMan_Ec2InstanceScannedByQualys_version-1_Ec2-instance-scanned-by-qualys-API_ec2"; - String PROJECT_ID = "_projectid"; - String REPOSITORY_ID = "_repositoryid"; - String BRANCH = "branches"; - String INSCOPE = "inScope"; - String DOMAIN = "domain"; - String DOMAIN_NAME = "domainName"; - String ENV = "environment"; - String ASSET_MANDATORY = "Asset group is mandatory"; - String ASSET_GROUP_DOMAIN = "Asset group/Domain is mandatory"; - int TWO_HUNDRED = 200; - Double HUNDRED = 100.00; - String ONPREMSERVER = "onpremserver"; - String EXE_CERT_EXPIRY = "Exception in getCerticatesExpiryByApplication"; - int FOUR = 4; - int START_YEAR = 1900; - int LAST_YEAR = 2100; - int FIVE_THOUSAND = 5000; - int NEG_FIFTEEN = -15; - int NEG_THIRTY = -30; - String RESPONSE = "response"; - String EXE_VULN = "Exception in getVulnerabilitiesDetails"; - int TEN_THOUSAND = 10000; - String CERT_SEARCH = "/cert/_search"; - String BUCKETS = "buckets"; - String EXP_IN_45_DAYS = "expiry45Days"; - String EXP_IN_30_DAYS = "expiry30Days"; - String DOC_COUNT = "doc_count"; - String EXP_IN = "expiringIn"; - String THIRTY = "30"; - String FOURTYFIVE = "45"; - String SSL_CERT_45_DAYS_EXP_RULE = "PacMan_certificate-expiry-policy_version-1_SSLcertificatesexpirywithin45days_cert"; - String SSL_CERT_30_DAYS_EXP_RULE = "PacMan_certificate-expiry-policy_version-1_certificates-expiry-next-30days_cert"; - String VALID_TO = "validto"; - String UNDERSCORE_COUNT = "_count"; - String ISSUE_DETAILS = "issueDetails"; - String SEARCH = "_search"; - String INFRA_AND_PLATFORMS = "Infra & Platforms"; - String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; - String ERROR_IN_US = "error retrieving inventory from ES"; - String SOX = "sox"; - String AGGREGATIONS = "aggregations"; - String KERNEL_VERSION = "kernelVersion"; - String DENOMINATOR = "denominator"; - String NUMERATOR = "numerator"; - String RULE_DESC = "ruleDescription"; - String RESOLUTION = "resolution"; - String CERTIFICATES = "certificates"; - String OUTPUT = "output"; - String MATCH = "match"; - String MUST = "must"; - String DIRECTOR = "director"; - String EXCUTIVE_SPONSOR = "executiveSponsor"; - String UNPATCHED_INSTANCE = "unpatched_instances"; - String NO_DATA_FOUND = "No Data Found"; - String UNPATCHED_INSTANCES = "unpatched_instances"; - String TOTAL_INSTANCES = "total_instances"; - String PATCHING_PERCENTAGE = "patching_percentage"; - String EC2 = "ec2"; - String RULEID_KEYWORD = "ruleId.keyword"; - String POLICY_VERSION = "policyVersion"; - String COMPLIANTPERCENTAGE = "compliantPercentage"; - String TOTAL = "total"; - String ISSUE_REASON = "issueReason"; - String HITS = "hits"; - String DOCID = "_docid"; - int INT_HUNDRED = 100; - String RANGE = "range"; - String AG_STATS = "assetgroup_stats"; - String VULN_INFO = "vulninfo"; - String APPS = "application";; - String SCROLL = "?scroll="; - String SLASH_SCROLL = "/scroll"; - String TAGS_APPS = "tags.Application.keyword"; - String SEVERITY_INFO = "severityInfo"; - String QUALYS_INFO = "qualysinfo"; - String VULN = "vulns"; - String VULNEREBILITIES = "vulnerabilities"; - String AGING = "aging"; - String ZERO = "0"; - String VULN_COUNT = "vulnInstanceCount"; - int THREE = 3; - int FOUR_NOT_THREE = 403; - int TEN = 10; - int FIVE = 5; - int ONE = 1; - int ELEVEN = 11; - String COMPLAINT = "compliant"; - String NON_COMPLIANT = "noncompliant"; - int NINE_THOUSAND_THREE_HUNDRED = 9300; - String NON_COMPLIANT_NUMBER = "nonCompliantNumber"; - String APP_TAG = "appTag"; - String KERNEL_RELEASE = "kernel_release"; - String PATCHED_INSTANCE = "patched_instances"; - String START_DATE = "start_date"; - String END_DATE = "end_date"; - String INSTANCE_ID = "instanceid"; - String PATCHED = "patched"; - String UN_PATCHED = "unpatched"; - String CRITICAL = "critical"; - String MEDIUM = "medium"; - String LOW = "low"; - String HIGH = "high"; - int THOUSAND = 1000; - int SIXTY = 60; - String RESPONSE_CODE = "responseCode"; - String LAST_ACTIONS = "lastActions"; - String SEV_INFO = "severityinfo"; - String ASSETS_AFFECTED = "assetsAffected"; - String CATEGORY = "category"; - String VULN_TYPE = "vulntype"; - String PATCHABLE = "patchable"; - String UNKNOWN = "Unknown"; - String ATTRIBUTES = "attributes"; - String SRC_NAME = "srcname"; - String DOUBLE_ZERO = "0.0"; - String TAGS_ENV = "tags.Environment.keyword"; - int TWO = 2; - String ISSUE_UNDERSCORE = "issue_"; - String HAS_PARENT = "has_parent"; - int THOUSAND_TWENTY_FOUR = 1024; - int TWELVE = 12; - int SIX = 6; - int FOURTEEN = 14; - int SEVEN = 7; - String NOT_ELIGIBLE_PROJECTIONS = "asset group not eligible for projection"; - String CLOUD = "Cloud"; - String ONPREM = "OnPrem"; - String IP_ADDRESS = "ip_address"; - String VPC_ID = "vpcid"; - String SOURCE = "source"; - String ERROR_UNIQUEHOST = "Error in getUniqueHost from ES"; - String ISSUE_COUNT_PER_RULE_AG= "issuecountPerRuleAG"; - String ASSET_COUNT = "assetCount"; - String CONTR_PERCENTAGE = "contributionPercentage"; - String COMP_PERCENTAGE= "compliancePercentage"; - String WORKING="working"; - String EXE_EMAIL_SEND= "Exception in sendTextMail"; - String APP_TAB_DETAILS="appTableDetails"; - String CRITICAL_ISSUE_COUNT="criticalIssuesCount"; - String TOP_APP_COUNT="topAppCount"; - String EMAIL_SERVICE_STARTED ="Execution of Email Service for Asset Group Started"; - String EMAIL_SERVICE_COMPLETED= "Email Service for Asset Group Succeessfully Completed"; - String PATCHING_EXCEPTION = "ServiceException in getPatchingDetails"; - String DISTRIBUTION = "distribution"; - String HIGHEST = "Highest"; - String DIRECTORS = "directors"; - String UNIQUE_QID = "unique-qid"; - String TOTAL_VULN_ASSETS = "totalVulnerableAssets"; - String UNIQUE_VULN_COUNT = "uniqueVulnCount"; - String NOTE_ID = "noteId"; - String SEVERITY_LEVELS = "3,4,5"; - String ACTION = "action"; - String SUB_ACTIONS = "subActions"; - String MATCHING_STRING = "matchingString"; - String FIRST_DISCOVERED_ON = "firstdiscoveredon"; - String SSM_AGENT_RULE="PacMan_SSMAgentCheckRule_version-1_SSMAgentCheckRule_ec2"; - String SERVICE_DNS_NAME="service.dns.name"; - String AUTHORIZATION = "Authorization"; - String BEARER = "bearer"; - String BASIC_AUTH = "basicAuth"; - long MILLIS_ONE_DAY = 86400000; - String STATUS_FAILURE = "fail"; - String ERROR_MESSAGE = "errorMessage"; - String ERROR_DETAILS = "errorDetails"; -} - +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ + /** + Copyright (C) 2017 T Mobile Inc - All Rights Reserve + Purpose: + Author :kkumar + Modified Date: Oct 18, 2017 + **/ +package com.tmobile.pacman.api.commons; + +public interface Constants { + + Integer ES_PAGE_SIZE = 10000; + String ES_PAGE_SCROLL_TTL = "2m"; + String ES_DOC_ID_KEY = "_id"; + String ES_DOC_PARENT_KEY = "_parent"; + String ES_DOC_ROUTING_KEY = "_routing"; + String MESSAGE_KEY = "message"; + String FAIL_MESSAGE = "failed"; + String STATUS_KEY = "message"; + String STATUS_SUCCESS = "success"; + String DATA_KEY = "data"; + String TYPE = "type"; + String SUBTYPE = "subtype"; + String LATEST = "latest"; + String TRUE = "true"; + String ISSUE = "issue"; + String RECOMMENDATION = "RECOMMENDATION"; + String CLOSED = "closed"; + String OPEN = "open"; + String RULE_CATEGORY = "ruleCategory"; + String ISSUE_STATUS = "issueStatus"; + String INCLUDE_EXEMPT = "include_exempt"; + String SEVERITY = "severity"; + String NAME = "name"; + String RULEID = "ruleId"; + String POLICYID = "policyId"; + String OPEN_ISSUES = "openIssues"; + String EC2_MANDATORY_TAG_RULE = "PacMan_ec2mandatorytags_version-1_ec2mandatorytags_ec2"; + String EC2_KERNEL_COMPLIANCE_RULE = "PacMan_cloud-kernel-compliance_version-1_Ec2-Kernel-Compliance-Rule_ec2"; + String VULNAR_SEVERITY_LEVEL = "vuln.list.hostAssetVuln.severitylevel"; + String SSL_EXPIRY_RULE = "PacMan_certificate-expiry-policy_version-1_SSLcertificatesexpirywithin45days_cert"; + String KEY = "key"; + String VALUE = "value"; + String PARAMS = "params"; + String RULE_NAME = "ruleName"; + String DISPLAY_NAME = "displayName"; + String ASSETS_SCANNED = "assetsScanned"; + String PASSED = "passed"; + String FAILED = "failed"; + String RULE_DISPAY_NAME = "displayName"; + String RULE_PARAMS = "ruleParams"; + String TARGET_TYPE = "targetType"; + String RESOURCE_TYPE = "resourcetType"; + String POLICY_DESC = "policyDesc"; + String TAGGIG_POLICY = "PacMan_TaggingRule_version-1"; + String TITLE = "title"; + String DESCRIPTION = "description"; + String METRIC_NAME = "metricName"; + String METRIC_VALUE = "metricValue"; + String COUNT = "count"; + String SEVEITY_LEVEL = "severitylevel"; + String DATE = "date"; + String NETWORK_IN = "networkIn"; + String NETWORK_OUT = "networkOut"; + String CPU_UTILIZATION = "cpu-utilization"; + String DISK_READ_IN_BYTES = "diskReadinBytes"; + String DISK_WRITE_IN_BYTES = "diskWriteinBytes"; + String AWS = "aws"; + String RESOURCEID = "_resourceid"; + String AUDIT_DATE = "auditdate"; + String STATUS = "status"; + String DATA_SOURCE = "datasource"; + String DELIMITER = "*"; + String _ID = "_id"; + String ID = "id"; + String EXEMPTED = "exempted"; + String MODIFIED_DATE = "modifiedDate"; + String PAC_DS = "pac_ds"; + String POLICY_VIOLATION = "#violation"; + String CONTRIBUTION = "contribution"; + String COMPLIANCE_PERCENTAGE = "compliance"; + String COMPLIANCE_PERCENT = "compliance_percent"; + String LAST_SCAN = "lastScan"; + String TAGGING_POLICY = "PacMan_TaggingRule_version-1"; + String TAGS_APPLICATION = "tags.Application"; + String MISSING_TAGS = "missingTags"; + String ACCOUNT_ID = "accountid"; + String ACCOUNT_NAME = "accountname"; + String REGION = "region"; + String CREATED_DATE = "createdDate"; + String TAGS_ENVIRONMENT = "tags.Environment"; + String DESC = "desc"; + String POLICY_DISPLAY_NAME = "PolicyName"; + String RULE_DISPLAY_ID = "RuleId"; + String POLICY_DISPLAY_ID = "PolicyId"; + String ISSUE_ID = "IssueId"; + String RESOURCE_DISPLAY_ID = "ResourceId"; + String APPLICATION = "Application"; + String ENVIRONMENT = "Environment"; + String REGION_DISPALY_NAME = "Region"; + String SEVERITY_DISPALY_NAME = "Severity"; + String RULECATEGORY_DISPALY_NAME = "RuleCategory"; + String ACCOUNT_DISPLAYI_D = "AccountId"; + String ACCOUNT_DISPALY_NAME = "AccountName"; + String CREATED_DISPLAY_DATE = "CreatedOn"; + String MODIFIED_DISPLAY_DATE = "ModifiedOn"; + String STATUS_DISPLAY_NAME = "Status"; + String RUNNING = "running"; + String PLATFORM = "platform"; + String STATE_NAME = "statename"; + String WINDOWS = "windows"; + String ONPREM_KERNEL_COMPLIANCE_RULE = "PacMan_onpremisekernelversion_version-1_onpremKernelVersionRule_onpremserver"; + String CLOUD_QUALYS_RULE="PacMan_Ec2InstanceScannedByQualys_version-1_Ec2-instance-scanned-by-qualys-API_ec2"; + String PROJECT_ID = "_projectid"; + String REPOSITORY_ID = "_repositoryid"; + String BRANCH = "branches"; + String INSCOPE = "inScope"; + String DOMAIN = "domain"; + String DOMAIN_NAME = "domainName"; + String ENV = "environment"; + String ASSET_MANDATORY = "Asset group is mandatory"; + String ASSET_GROUP_DOMAIN = "Asset group/Domain is mandatory"; + int TWO_HUNDRED = 200; + Double HUNDRED = 100.00; + String ONPREMSERVER = "onpremserver"; + String EXE_CERT_EXPIRY = "Exception in getCerticatesExpiryByApplication"; + int FOUR = 4; + int START_YEAR = 1900; + int LAST_YEAR = 2100; + int FIVE_THOUSAND = 5000; + int NEG_FIFTEEN = -15; + int NEG_THIRTY = -30; + String RESPONSE = "response"; + String EXE_VULN = "Exception in getVulnerabilitiesDetails"; + int TEN_THOUSAND = 10000; + String CERT_SEARCH = "/cert/_search"; + String BUCKETS = "buckets"; + String EXP_IN_45_DAYS = "expiry45Days"; + String EXP_IN_30_DAYS = "expiry30Days"; + String DOC_COUNT = "doc_count"; + String EXP_IN = "expiringIn"; + String THIRTY = "30"; + String FOURTYFIVE = "45"; + String SSL_CERT_45_DAYS_EXP_RULE = "PacMan_certificate-expiry-policy_version-1_SSLcertificatesexpirywithin45days_cert"; + String SSL_CERT_30_DAYS_EXP_RULE = "PacMan_certificate-expiry-policy_version-1_certificates-expiry-next-30days_cert"; + String VALID_TO = "validto"; + String UNDERSCORE_COUNT = "_count"; + String ISSUE_DETAILS = "issueDetails"; + String SEARCH = "_search"; + String INFRA_AND_PLATFORMS = "Infra & Platforms"; + String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; + String ERROR_IN_US = "error retrieving inventory from ES"; + String SOX = "sox"; + String AGGREGATIONS = "aggregations"; + String KERNEL_VERSION = "kernelVersion"; + String DENOMINATOR = "denominator"; + String NUMERATOR = "numerator"; + String RULE_DESC = "ruleDescription"; + String RESOLUTION = "resolution"; + String CERTIFICATES = "certificates"; + String OUTPUT = "output"; + String MATCH = "match"; + String MUST = "must"; + String DIRECTOR = "director"; + String EXCUTIVE_SPONSOR = "executiveSponsor"; + String UNPATCHED_INSTANCE = "unpatched_instances"; + String NO_DATA_FOUND = "No Data Found"; + String UNPATCHED_INSTANCES = "unpatched_instances"; + String TOTAL_INSTANCES = "total_instances"; + String PATCHING_PERCENTAGE = "patching_percentage"; + String EC2 = "ec2"; + String RULEID_KEYWORD = "ruleId.keyword"; + String POLICY_VERSION = "policyVersion"; + String COMPLIANTPERCENTAGE = "compliantPercentage"; + String TOTAL = "total"; + String ISSUE_REASON = "issueReason"; + String HITS = "hits"; + String DOCID = "_docid"; + int INT_HUNDRED = 100; + String RANGE = "range"; + String AG_STATS = "assetgroup_stats"; + String VULN_INFO = "vulninfo"; + String APPS = "application";; + String SCROLL = "?scroll="; + String SLASH_SCROLL = "/scroll"; + String TAGS_APPS = "tags.Application.keyword"; + String SEVERITY_INFO = "severityInfo"; + String QUALYS_INFO = "qualysinfo"; + String VULN = "vulns"; + String VULNEREBILITIES = "vulnerabilities"; + String AGING = "aging"; + String ZERO = "0"; + String VULN_COUNT = "vulnInstanceCount"; + int THREE = 3; + int FOUR_NOT_THREE = 403; + int TEN = 10; + int FIVE = 5; + int ONE = 1; + int ELEVEN = 11; + String COMPLAINT = "compliant"; + String NON_COMPLIANT = "noncompliant"; + int NINE_THOUSAND_THREE_HUNDRED = 9300; + String NON_COMPLIANT_NUMBER = "nonCompliantNumber"; + String APP_TAG = "appTag"; + String KERNEL_RELEASE = "kernel_release"; + String PATCHED_INSTANCE = "patched_instances"; + String START_DATE = "start_date"; + String END_DATE = "end_date"; + String INSTANCE_ID = "instanceid"; + String PATCHED = "patched"; + String UN_PATCHED = "unpatched"; + String CRITICAL = "critical"; + String MEDIUM = "medium"; + String LOW = "low"; + String HIGH = "high"; + int THOUSAND = 1000; + int SIXTY = 60; + String RESPONSE_CODE = "responseCode"; + String LAST_ACTIONS = "lastActions"; + String SEV_INFO = "severityinfo"; + String ASSETS_AFFECTED = "assetsAffected"; + String CATEGORY = "category"; + String VULN_TYPE = "vulntype"; + String PATCHABLE = "patchable"; + String UNKNOWN = "Unknown"; + String ATTRIBUTES = "attributes"; + String SRC_NAME = "srcname"; + String DOUBLE_ZERO = "0.0"; + String TAGS_ENV = "tags.Environment.keyword"; + int TWO = 2; + String ISSUE_UNDERSCORE = "issue_"; + String HAS_PARENT = "has_parent"; + int THOUSAND_TWENTY_FOUR = 1024; + int TWELVE = 12; + int SIX = 6; + int FOURTEEN = 14; + int SEVEN = 7; + String NOT_ELIGIBLE_PROJECTIONS = "asset group not eligible for projection"; + String CLOUD = "Cloud"; + String ONPREM = "OnPrem"; + String IP_ADDRESS = "ip_address"; + String VPC_ID = "vpcid"; + String SOURCE = "source"; + String ERROR_UNIQUEHOST = "Error in getUniqueHost from ES"; + String ISSUE_COUNT_PER_RULE_AG= "issuecountPerRuleAG"; + String ASSET_COUNT = "assetCount"; + String CONTR_PERCENTAGE = "contributionPercentage"; + String COMP_PERCENTAGE= "compliancePercentage"; + String WORKING="working"; + String EXE_EMAIL_SEND= "Exception in sendTextMail"; + String APP_TAB_DETAILS="appTableDetails"; + String CRITICAL_ISSUE_COUNT="criticalIssuesCount"; + String TOP_APP_COUNT="topAppCount"; + String EMAIL_SERVICE_STARTED ="Execution of Email Service for Asset Group Started"; + String EMAIL_SERVICE_COMPLETED= "Email Service for Asset Group Succeessfully Completed"; + String PATCHING_EXCEPTION = "ServiceException in getPatchingDetails"; + String DISTRIBUTION = "distribution"; + String HIGHEST = "Highest"; + String DIRECTORS = "directors"; + String UNIQUE_QID = "unique-qid"; + String TOTAL_VULN_ASSETS = "totalVulnerableAssets"; + String UNIQUE_VULN_COUNT = "uniqueVulnCount"; + String NOTE_ID = "noteId"; + String SEVERITY_LEVELS = "3,4,5"; + String ACTION = "action"; + String SUB_ACTIONS = "subActions"; + String MATCHING_STRING = "matchingString"; + String FIRST_DISCOVERED_ON = "firstdiscoveredon"; + String SSM_AGENT_RULE="PacMan_SSMAgentCheckRule_version-1_SSMAgentCheckRule_ec2"; + String SERVICE_DNS_NAME="service.dns.name"; + String AUTHORIZATION = "Authorization"; + String BEARER = "bearer"; + String BASIC_AUTH = "basicAuth"; + long MILLIS_ONE_DAY = 86400000; + String STATUS_FAILURE = "fail"; + String ERROR_MESSAGE = "errorMessage"; + String ERROR_DETAILS = "errorDetails"; + String PROVIDER = "provider"; +} + From 331db72d00a011f5fb7a1361eb2889a99dfc8573 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Wed, 31 Jul 2019 12:55:45 +0530 Subject: [PATCH 12/86] Added few constants --- .../pacman/api/asset/AssetConstants.java | 207 +++++++++--------- 1 file changed, 105 insertions(+), 102 deletions(-) diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/AssetConstants.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/AssetConstants.java index 881c61b92..30cc6e0a2 100644 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/AssetConstants.java +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/AssetConstants.java @@ -1,102 +1,105 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ -package com.tmobile.pacman.api.asset; - -/** - * Constants class where the asset service constants are stored. - */ -public final class AssetConstants { - - private AssetConstants() { - - } - - public static final String FILTER_EXEC_SPONSOR = "executiveSponsor"; - public static final String FILTER_RES_TYPE = "resourceType"; - public static final String FILTER_DIRECTOR = "director"; - public static final String FILTER_APPLICATION = "application"; - public static final String FILTER_ENVIRONMENT = "environment"; - public static final String FILTER_PATCHED = "patched"; - public static final String FILTER_TAGGED = "tagged"; - public static final String FILTER_TAGNAME = "tagName"; - public static final String FILTER_RULEID = "ruleId"; - public static final String FILTER_COMPLIANT = "compliant"; - public static final String FILTER_DOMAIN = "domain"; - public static final String TAG_NOT_FOUND = "Not Found"; - public static final String ERROR_FROM_NEGATIVE = "From should not be a negative number"; - public static final String ERROR_FILTER_ACCEPTS = "Filter accepts only "; - public static final String ASSET_COUNT = "assetcount"; - public static final String ERROR_INSTANCEID = "Asset group/Instance Id is Mandatory"; - public static final String ERROR_FROM_EXCEEDS = "From exceeds the size of list"; - public static final String ERROR_QUALYS_NOT_ENABLED = "Qualys not enabled"; - public static final String ASSETS = "Assets"; - public static final int ZERO = 0; - public static final int FIFTEEN = 15; - public static final int TWENTY = 20; - public static final int TWENTY_FIVE = 25; - public static final int THIRTY = 30; - public static final int FORTY = 40; - public static final int FIFTY = 50; - public static final int SIXTY = 60; - public static final int EIGHT = 8; - public static final int NINE = 9; - public static final String UNDERSCORE_ENTITY = "_entity"; - public static final String ALL = "all"; - public static final String STOPPED = "stopped"; - public static final String STOPPING = "stopping"; - public static final String UNDERSCORE_TYPE = "_type"; - public static final String UNDERSCORE_SOURCE = "_source"; - public static final String RECENTLY_VIEWED_AG = "recentlyViewedAg"; - public static final String UNDERSCORE_LOADDATE = "_loaddate"; - public static final String CREATE_TIME = "createtime"; - public static final String FIRST_DISCOVEREDON = "firstdiscoveredon"; - public static final String UNDERSCORE_DISCOVERY_DATE = "_discoverydate"; - public static final String DISCOVERY_DATE = "discoverydate"; - public static final String CREATION_DATE = "creationdate"; - public static final String UNDERSCORE_ENTITY_TYPE_KEYWORD = "_entitytype.keyword"; - public static final String UNDERSCORE_ENTITY_TYPE = "_entitytype"; - public static final String AWS_EC2 = "aws_ec2"; - public static final String INSTANCEID_KEYWORD = "instanceid.keyword"; - public static final String FALSE = "false"; - public static final String ERROR_FETCHING_FIELDNAMES = "Error while fetching field names "; - public static final String SERVICE_NAME = "serviceName"; - public static final String QUERY = "query"; - public static final String POLICY_VIOLATIONS = "Policy Violations"; - public static final String VULNERABILITIES = "Vulnerabilities"; - public static final String PUBLIC_IP_ADDRESS = "publicipaddress"; - public static final String PRIVATE_IP_ADDRESS = "privateipaddress"; - public static final String RELATED_ASSETS = "RELATED ASSETS"; - public static final String CREATED_BY = "createdBy"; - public static final String EMAIL = "email"; - public static final String USERNAME = "username"; - public static final String TOTAL_COST = "totalCost"; - public static final String MANAGED_BY = "managedBy"; - public static final String FIELDNAME = "fieldName"; - public static final String ERROR_SEARCH = "Error in search "; - public static final String ERROR_GETASSETSBYAG = "Error in getAssetsByAssetGroup "; - public static final String ERROR_COUNT = "Error in count "; - public static final String ERROR_EXEQUTEQUERY = "Error in executeQuery "; - public static final String ERROR_BATCHUPDATE = "Error in batchUpdate "; - public static final String ERROR_GETAPPSBYAG = "Error in getApplicationByAssetGroup "; - public static final String DEBUG_RESPONSEJSON = "Response json is:"; - public static final String ESQUERY_RANGE = ",{ \"range\": {\"date\": {"; - public static final String ESQUERY_RANGE_CLOSE = "}}}]}}}"; - public static final String ESQUERY_CLOSE = "\"}}]}}}"; - public static final String ESQUERY_BULK = "/_bulk?refresh=true"; - public static final String RESPONSE_ERROR = "\"errors\":true"; - -} - +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.api.asset; + +/** + * Constants class where the asset service constants are stored. + */ +public final class AssetConstants { + + private AssetConstants() { + + } + + public static final String FILTER_EXEC_SPONSOR = "executiveSponsor"; + public static final String FILTER_RES_TYPE = "resourceType"; + public static final String FILTER_DIRECTOR = "director"; + public static final String FILTER_APPLICATION = "application"; + public static final String FILTER_ENVIRONMENT = "environment"; + public static final String FILTER_PATCHED = "patched"; + public static final String FILTER_TAGGED = "tagged"; + public static final String FILTER_TAGNAME = "tagName"; + public static final String FILTER_RULEID = "ruleId"; + public static final String FILTER_COMPLIANT = "compliant"; + public static final String FILTER_DOMAIN = "domain"; + public static final String TAG_NOT_FOUND = "Not Found"; + public static final String ERROR_FROM_NEGATIVE = "From should not be a negative number"; + public static final String ERROR_FILTER_ACCEPTS = "Filter accepts only "; + public static final String ASSET_COUNT = "assetcount"; + public static final String ERROR_INSTANCEID = "Asset group/Instance Id is Mandatory"; + public static final String ERROR_FROM_EXCEEDS = "From exceeds the size of list"; + public static final String ERROR_QUALYS_NOT_ENABLED = "Qualys not enabled"; + public static final String ASSETS = "Assets"; + public static final int ZERO = 0; + public static final int FIFTEEN = 15; + public static final int TWENTY = 20; + public static final int TWENTY_FIVE = 25; + public static final int THIRTY = 30; + public static final int FORTY = 40; + public static final int FIFTY = 50; + public static final int SIXTY = 60; + public static final int EIGHT = 8; + public static final int NINE = 9; + public static final String UNDERSCORE_ENTITY = "_entity"; + public static final String ALL = "all"; + public static final String STOPPED = "stopped"; + public static final String STOPPING = "stopping"; + public static final String UNDERSCORE_TYPE = "_type"; + public static final String UNDERSCORE_SOURCE = "_source"; + public static final String RECENTLY_VIEWED_AG = "recentlyViewedAg"; + public static final String UNDERSCORE_LOADDATE = "_loaddate"; + public static final String CREATE_TIME = "createtime"; + public static final String FIRST_DISCOVEREDON = "firstdiscoveredon"; + public static final String UNDERSCORE_DISCOVERY_DATE = "_discoverydate"; + public static final String DISCOVERY_DATE = "discoverydate"; + public static final String CREATION_DATE = "creationdate"; + public static final String UNDERSCORE_ENTITY_TYPE_KEYWORD = "_entitytype.keyword"; + public static final String UNDERSCORE_ENTITY_TYPE = "_entitytype"; + public static final String AWS_EC2 = "aws_ec2"; + public static final String INSTANCEID_KEYWORD = "instanceid.keyword"; + public static final String FALSE = "false"; + public static final String ERROR_FETCHING_FIELDNAMES = "Error while fetching field names "; + public static final String SERVICE_NAME = "serviceName"; + public static final String QUERY = "query"; + public static final String POLICY_VIOLATIONS = "Policy Violations"; + public static final String VULNERABILITIES = "Vulnerabilities"; + public static final String PUBLIC_IP_ADDRESS = "publicipaddress"; + public static final String PRIVATE_IP_ADDRESS = "privateipaddress"; + public static final String RELATED_ASSETS = "RELATED ASSETS"; + public static final String CREATED_BY = "createdBy"; + public static final String EMAIL = "email"; + public static final String USERNAME = "username"; + public static final String TOTAL_COST = "totalCost"; + public static final String MANAGED_BY = "managedBy"; + public static final String FIELDNAME = "fieldName"; + public static final String ERROR_SEARCH = "Error in search "; + public static final String ERROR_GETASSETSBYAG = "Error in getAssetsByAssetGroup "; + public static final String ERROR_COUNT = "Error in count "; + public static final String ERROR_EXEQUTEQUERY = "Error in executeQuery "; + public static final String ERROR_BATCHUPDATE = "Error in batchUpdate "; + public static final String ERROR_GETAPPSBYAG = "Error in getApplicationByAssetGroup "; + public static final String DEBUG_RESPONSEJSON = "Response json is:"; + public static final String ESQUERY_RANGE = ",{ \"range\": {\"date\": {"; + public static final String ESQUERY_RANGE_CLOSE = "}}}]}}}"; + public static final String ESQUERY_CLOSE = "\"}}]}}}"; + public static final String ESQUERY_BULK = "/_bulk?refresh=true"; + public static final String RESPONSE_ERROR = "\"errors\":true"; + public static final String FILTER_CATEGORY = "category"; + public static final String FILTER_GENERAL = "general"; + public static final String FILTER_RECOMMENDATION_ID = "recommendationId"; + +} + From 2870e3dc2682ac16554402bd92c8071398c12d3a Mon Sep 17 00:00:00 2001 From: Kanchana Date: Thu, 1 Aug 2019 11:05:31 +0530 Subject: [PATCH 13/86] Removed cost thing for recommendations for OSS --- .../asset/controller/AssetCostController.java | 232 -------- .../api/asset/service/AssetService.java | 16 - .../api/asset/service/AssetServiceImpl.java | 121 ---- .../pacman/api/asset/service/CostService.java | 523 ------------------ .../controller/AssetCostControllerTest.java | 220 -------- .../api/asset/service/CostServiceTest.java | 193 ------- 6 files changed, 1305 deletions(-) delete mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/AssetCostController.java delete mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CostService.java delete mode 100644 api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetCostControllerTest.java delete mode 100644 api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/CostServiceTest.java diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/AssetCostController.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/AssetCostController.java deleted file mode 100644 index 3a3d952a9..000000000 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/AssetCostController.java +++ /dev/null @@ -1,232 +0,0 @@ -package com.tmobile.pacman.api.asset.controller; - - -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import com.tmobile.pacman.api.asset.domain.ApplicationDetail; -import com.tmobile.pacman.api.asset.domain.ApplicationDetailsResponse; -import com.tmobile.pacman.api.asset.service.AssetService; -import com.tmobile.pacman.api.asset.service.CostService; -import com.tmobile.pacman.api.commons.utils.ResponseUtils; - -@RestController -@PreAuthorize("@securityService.hasPermission(authentication, 'ROLE_USER')") -@CrossOrigin -public class AssetCostController { - - @Autowired - CostService costService; - - @Autowired - private AssetService assetService; - - private static final Log LOGGER = LogFactory.getLog(AssetCostController.class); - - @GetMapping(value = "/v1/costByApplication") - public ResponseEntity getAssetCostByApplication( - @RequestParam(name = "ag", required = true) String assetGroup, - @RequestParam(name = "application", required = false) String application, - @RequestParam(name = "type", required = false) String type, - @RequestParam(name = "quarter", required = false) Integer quarter, - @RequestParam(name = "year", required = false) Integer year, - @RequestParam(name = "month", required = false) Integer month) { - return getAssetCost(assetGroup, type, application, quarter, year, month, false); - } - - @GetMapping(value = "/v1/costByType") - public ResponseEntity getAssetCostByType(@RequestParam(name = "ag", required = true) String assetGroup, - @RequestParam(name = "application", required = false) String application, - @RequestParam(name = "type", required = false) String type, - @RequestParam(name = "quarter", required = false) Integer quarter, - @RequestParam(name = "year", required = false) Integer year, - @RequestParam(name = "month", required = false) Integer month) { - return getAssetCost(assetGroup, type, application, quarter, year, month, true); - } - - @GetMapping(value = "/v1/cost/trend") - public ResponseEntity getAssetCostTrendByType(@RequestParam(name = "ag", required = true) String assetGroup, - @RequestParam(name = "application", required = false) String application, - @RequestParam(name = "type", required = false) String type, - @RequestParam(name = "period", required = true) Period period) { - try { - - ApplicationDetailsResponse appDetailsResponse = null; - appDetailsResponse = assetService.getApplicationDetailsByAssetGroup(assetGroup, null); - List validApplications = appDetailsResponse.getValidApplications(); - List appNameList = new ArrayList<>(); - Iterator it = validApplications.iterator(); - while (it.hasNext()) { - String appName = it.next().getName(); - appNameList.add(appName); - - } - - List tTypeList = new ArrayList<>(); - List> tTypeMapList = assetService.getAllCostTypes(); - Iterator> iter = tTypeMapList.iterator(); - while (iter.hasNext()) { - Map tTypeMap = iter.next(); - tTypeList.add(tTypeMap.get("type").toString()); - } - - if (StringUtils.isNotBlank(application) && !appNameList.contains(application)) { - return ResponseUtils.buildFailureResponse(new Exception("Invalid application entered"), null, null); - } - if (StringUtils.isNotBlank(type) && !tTypeList.contains(type)) { - return ResponseUtils.buildFailureResponse(new Exception("Invalid type entered"), null, null); - } - if (StringUtils.isNotBlank(application)) { - appNameList = Arrays.asList(application); - } - if (StringUtils.isNotBlank(type)) { - tTypeList = Arrays.asList(type); - }else{ - tTypeList = new ArrayList<>(); - } - - - Map response = new LinkedHashMap<>(); - response.put("ag", assetGroup); - if(StringUtils.isNotBlank(type)) { - response.put("type", type); - } - if(StringUtils.isNotBlank(application)) { - assetGroup = application.toLowerCase().replaceAll("[^a-z0-9-_]", ""); - } - List> trendList = costService.getCostTrend(appNameList,tTypeList,period.toString()); - response.put("trend", trendList); - return ResponseUtils.buildSucessResponse(response); - } catch (Exception e) { - return ResponseUtils.buildFailureResponse(e); - } - } - - - public ResponseEntity getAssetCost(@RequestParam(name = "ag", required = true) String assetGroup, - @RequestParam(name = "type", required = false) String type, - @RequestParam(name = "application", required = false) String application, - @RequestParam(name = "quarter", required = false) Integer quarter, - @RequestParam(name = "year", required = false) Integer year, - @RequestParam(name = "month", required = false) Integer month, - @RequestParam(name = "byType", required = false) boolean byType) { - try { - - if (month != null && quarter != null) { - return ResponseUtils.buildFailureResponse( - new Exception("Both quarter AND month cannot be entered together. Enter only one of these."), - null, null); - } - - if(year==null && (month != null || quarter!=null)){ - return ResponseUtils.buildFailureResponse(new Exception("Year is mandatory"), null, - null); - } - - if(year!=null && month == null && quarter==null){ - return ResponseUtils.buildFailureResponse(new Exception("Month or quarter is mandatory a year is entered"), null, - null); - } - - if (quarter != null && (quarter < 1 || quarter > 4)) { - return ResponseUtils.buildFailureResponse(new Exception("Quarter should be one of 1,2,3,4"), null, - null); - } - - if (month != null && (month < 1 || month > 12)) { - return ResponseUtils.buildFailureResponse(new Exception("Month should be a number from 1-12"), null, - null); - } - - if (year!=null && (year < 2019 || year > LocalDate.now().getYear())) { - return ResponseUtils.buildFailureResponse(new Exception("Invalid year entered : Please enter between 2019 - "+LocalDate.now().getYear()), null, null); - } - if (assetService.getAssetGroupInfo(assetGroup).isEmpty()) { - return ResponseUtils.buildFailureResponse(new Exception("Invalid asset group entered"), null, null); - } - - ApplicationDetailsResponse appDetailsResponse = null; - appDetailsResponse = assetService.getApplicationDetailsByAssetGroup(assetGroup, null); - List validApplications = appDetailsResponse.getValidApplications(); - List appNameList = new ArrayList<>(); - Iterator it = validApplications.iterator(); - while (it.hasNext()) { - String appName = it.next().getName(); - appNameList.add(appName); - - } - - List tTypeList = new ArrayList<>(); - List> tTypeMapList = assetService.getAllCostTypes(); - Iterator> iter = tTypeMapList.iterator(); - while (iter.hasNext()) { - Map tTypeMap = iter.next(); - tTypeList.add(tTypeMap.get("type").toString()); - } - - if (StringUtils.isNotBlank(application) && !appNameList.contains(application)) { - return ResponseUtils.buildFailureResponse(new Exception("Invalid application entered"), null, null); - } - if (StringUtils.isNotBlank(type) && !tTypeList.contains(type)) { - return ResponseUtils.buildFailureResponse(new Exception("Invalid type entered"), null, null); - } - if (StringUtils.isNotBlank(application)) { - appNameList = Arrays.asList(application); - } - if (StringUtils.isNotBlank(type)) { - tTypeList = Arrays.asList(type); - }else{ - tTypeList = new ArrayList<>(); - } - - List monthList = new ArrayList<>(); - - if (quarter != null) { - int monthBaseAddendum = (quarter - 1) * 3; - int firstMonth = monthBaseAddendum + 1; - int secondMonth = monthBaseAddendum + 2; - int thirdMonth = monthBaseAddendum + 3; - monthList.add(new Integer(firstMonth).toString()); - monthList.add(new Integer(secondMonth).toString()); - monthList.add(new Integer(thirdMonth).toString()); - } - - if (month != null) { - monthList.add(month + ""); - } - - Map responseMap ; - if (byType) { - responseMap = costService.getCostByType(assetGroup, year, monthList, appNameList, tTypeList); - } else{ - responseMap = costService.getCostByApplication(assetGroup, year, monthList, appNameList, tTypeList, - validApplications); - } - return ResponseUtils.buildSucessResponse(responseMap); - - } catch (Exception e) { - LOGGER.error("Error occured fetching cost info",e); - return ResponseUtils.buildFailureResponse(e, null, null); - } - } -} - -enum Period { - monthly,quarterly; -} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetService.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetService.java index 7d0a582df..5887d91b3 100644 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetService.java +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetService.java @@ -487,21 +487,5 @@ public List> getAssetLists(String assetGroup, Map> getDataTypeInfoByTargetType(String resourceId) throws ServiceException; - /** - * Fetches all application details by asset group name - * - * @param assetGroup - valid assetGroup id - * - * @return ApplicationDetailsResponse - valid and invalid application details list - * @throws DataException, JsonProcessingException - */ - public ApplicationDetailsResponse getApplicationDetailsByAssetGroup(String assetGroup, String applicationName) throws DataException, JsonProcessingException, Exception; - - /** - * Gets the all cost types. - * - * @return the all cost types - */ - List> getAllCostTypes(); } diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetServiceImpl.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetServiceImpl.java index a97972b52..21c7984d8 100644 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetServiceImpl.java +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetServiceImpl.java @@ -958,125 +958,4 @@ public List> getDataTypeInfoByTargetType(String resourceType } return dataTypeList; } - - @Override - public ApplicationDetailsResponse getApplicationDetailsByAssetGroup(String assetGroup, String applicationName) - throws DataException, JsonProcessingException { - List infraValidApplications = repository.getApplicationDetails(); - Map infraValidApplicationMap = infraValidApplications.stream() - .collect(Collectors.toMap(app -> app.getApplicationDetail().getAppTag(), - ApplicationDetailsESResponse::getApplicationDetail)); - - String domain = "Infra & Platforms"; - Map applicationAssetCountMap = this.filterAppAssetCountByApplicationName( - repository.getApplicationAssetCountByAssetGroup(assetGroup, domain), applicationName); - List applications = new ArrayList<>(applicationAssetCountMap.keySet()); - - List validApplications = new ArrayList<>(); - List invalidApplications = new ArrayList<>(); - applications.stream().forEach(application -> { - ApplicationDetail applicationDetail = new ApplicationDetail(); - ApplicationESDetail applicationESDetail = infraValidApplicationMap.get(application); - if (applicationESDetail != null) { - List organizations = Lists.newArrayList(); - String description = StringUtils.EMPTY; - if (applicationESDetail.getDescription() != null) { - description = StringUtils.chomp(applicationESDetail.getDescription()); - } else { - description = application; - } - List> orgDetails = Lists.newArrayList(); - if (applicationESDetail.getOrgInfo() != null) { - orgDetails = applicationESDetail.getOrgInfo(); - } - orgDetails.forEach(orgDetail -> { - Organization organization = new Organization(); - int mgmntLevel = 0; - if (StringUtils.isNotBlank(orgDetail.get("mgmntLevel"))) { - mgmntLevel = Integer.parseInt(orgDetail.get("mgmntLevel")); - organization.setName(orgDetail.get("name")); - switch (mgmntLevel) { - case 1: - organization.setDesignation("EVP"); - break; - case 2: - organization.setDesignation("SVP"); - break; - case 3: - organization.setDesignation("VP"); - break; - case 4: - organization.setDesignation("Sr Director"); - break; - default: - organization.setDesignation("Director"); - break; - } - } else { - if (StringUtils.isNotBlank(orgDetail.get("isOwner"))) { - if (Boolean.parseBoolean(orgDetail.get("isOwner"))) { - organization.setDesignation("Director"); - } - } else { - organization.setDesignation("NA"); - } - } - organizations.add(organization); - }); - String assetGroupId = application.toLowerCase().replaceAll("[^a-z0-9-_]", StringUtils.EMPTY); - applicationDetail.setDescription(description); - applicationDetail.setName(application); - applicationDetail.setOrganization(organizations); - applicationDetail.setAssetGroupId(assetGroupId); - applicationDetail.setTotalResources(applicationAssetCountMap.get(application)); - validApplications.add(applicationDetail); - } else { - applicationDetail.setDescription("NA"); - applicationDetail.setName(application); - applicationDetail.setOrganization(Lists.newArrayList()); - applicationDetail.setAssetGroupId("NA"); - applicationDetail.setTotalResources(applicationAssetCountMap.get(application)); - invalidApplications.add(applicationDetail); - } - - }); - ApplicationDetailsResponse applicationDetailsResponse = new ApplicationDetailsResponse(); - applicationDetailsResponse.setValidApplications(validApplications); - applicationDetailsResponse.setInvalidApplications(invalidApplications); - return applicationDetailsResponse; - } - - /** - * Function for filtering out the asset count by application name if application - * name is present Else return full application list - * - * @param applicationAssetCountMap - * @param applicationName - * @return - * @throws DataException - */ - private Map filterAppAssetCountByApplicationName(Map applicationAssetCountMap, - String applicationName) throws DataException { - if (applicationName == null) { - return applicationAssetCountMap; - } else { - Map filteredMap = new HashMap(); - if (applicationAssetCountMap.containsKey(applicationName)) { - filteredMap.put(applicationName, applicationAssetCountMap.get(applicationName)); - return filteredMap; - } else { - throw new DataException("Invalid Application Name!"); - } - } - } - - /* (non-Javadoc) - * @see com.tmobile.pacman.api.asset.service.AssetService#getAllCostTypes() - */ - @Override - public List> getAllCostTypes() { - - return repository.getAllCostTypes(); - - } } diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CostService.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CostService.java deleted file mode 100644 index 46540219a..000000000 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CostService.java +++ /dev/null @@ -1,523 +0,0 @@ -package com.tmobile.pacman.api.asset.service; - -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.stream.Collectors; - -import javax.annotation.PostConstruct; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; -import com.tmobile.pacman.api.asset.domain.ApplicationDetail; -import com.tmobile.pacman.api.asset.domain.Organization; -import com.tmobile.pacman.api.asset.repository.AssetRepository; -import com.tmobile.pacman.api.asset.repository.CostRepository; -import com.tmobile.pacman.api.commons.Constants; -import com.tmobile.pacman.api.commons.exception.ServiceException; -import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; -import com.tmobile.pacman.api.commons.utils.CommonUtils; - -@Service -public class CostService { - /** The es host. */ - @Value("${elastic-search.host}") - private String esHost; - - /** The es port. */ - @Value("${elastic-search.port}") - private int esPort; - - /** The cost indicator percent. */ - @Value("${cost-indicator.percent}") - private int costIndicatorPercent; - - /** The Constant PROTOCOL. */ - static final String PROTOCOL = "http"; - - /** The es url. */ - private String esUrl; - - /** The elastic search repository. */ - @Autowired - private ElasticSearchRepository elasticSearchRepository; - - @Autowired - private AssetRepository assetRepository; - - @Autowired - private CostRepository costRepository; - - @PostConstruct - void init() { - esUrl = PROTOCOL + "://" + esHost + ":" + esPort; - } - - /** The Constant LOGGER. */ - private static final Log LOGGER = LogFactory.getLog(CostService.class); - - @SuppressWarnings("deprecation") - public Map getCostByType(String assetGroup, Integer year, List monthList, - List appNameList, List tTypeList) throws Exception { - - Integer prevYear = year; - List prevMonthList = new ArrayList<>(); - if(year==null && monthList.isEmpty()){ // Defaulted to latest finalised - Map yearMonth = costRepository.findLatestCostFinalisedMonth(); - if(yearMonth.isEmpty()){ - throw new ServiceException("Could not find cost as year/month to fetch the data can not be determined"); - } - year = yearMonth.get("year"); - monthList.add(yearMonth.get("month")+""); - Integer currMonth = Integer.valueOf(yearMonth.get("month").toString()); - if(currMonth >1 ) { - prevYear = year; - prevMonthList.add(String.valueOf(currMonth-1)+""); - } else { - prevYear = year -1; - prevMonthList.add("12"); - } - } else { - if(monthList.size() > 1) { - if(monthList.contains("1") && monthList.contains("2") && monthList.contains("3")) { - prevYear = year-1; - prevMonthList.add("10"); - prevMonthList.add("11"); - prevMonthList.add("12"); - } else { - for(String month : monthList) { - prevMonthList.add(String.valueOf(Integer.valueOf(month)-1)+""); - } - } - - } else { - if(Integer.valueOf(monthList.get(0)) >1 ) { - prevYear = year; - prevMonthList.add(String.valueOf(Integer.valueOf(monthList.get(0))-1)+""); - } else { - prevYear = year -1; - prevMonthList.add("12"); - } - } - } - Map responseMap = new HashMap<>(); - Map mustFilter = new HashMap<>(); - Map mustTermsFilter = new HashMap<>(); - mustFilter.put("year", year); - mustTermsFilter.put(CommonUtils.convertAttributetoKeyword("application"), filterApps(appNameList)); - if(!tTypeList.isEmpty()){ - mustTermsFilter.put(CommonUtils.convertAttributetoKeyword("costInfo.type"), tTypeList); - } - mustTermsFilter.put("month", monthList); - List> currResult = elasticSearchRepository.getDataFromES("aws-cost", "monthly-cost", mustFilter, - null, null, null, mustTermsFilter); - mustFilter.put("year", prevYear); - mustTermsFilter.put("month", prevMonthList); - List> prevResult = elasticSearchRepository.getDataFromES("aws-cost", "monthly-cost", mustFilter, - null, null, null, mustTermsFilter); - - boolean finalised = true; - for(Map resultMap :currResult){ - finalised = finalised && Boolean.valueOf(resultMap.get("finalised").toString()); - } - List> currCostByTypeMapList = formCostByType(currResult, tTypeList); - List> prevCostByTypeMapList = formCostByType(prevResult, tTypeList); - - findCostIndicatorByType(currCostByTypeMapList, prevCostByTypeMapList); - - LocalDate date1 = LocalDate.of(year, new Integer(monthList.get(0)), 1); - LocalDate start = date1.withDayOfMonth(1); - - LocalDate date2 = LocalDate.of(year, new Integer(monthList.get(monthList.size() - 1)), 1); - LocalDate end = date2.withDayOfMonth(date2.lengthOfMonth()); - - responseMap.put("ag", assetGroup); - responseMap.put("startDate", start.format(DateTimeFormatter.ISO_LOCAL_DATE)); - responseMap.put("endDate", end.format(DateTimeFormatter.ISO_LOCAL_DATE)); - responseMap.put("costByType", currCostByTypeMapList); - responseMap.put("finalised", finalised); - - responseMap.put("year", start.getYear()); - if(start.getMonthValue() == end.getMonth().getValue()){ - responseMap.put("month", start.getMonthValue()); - }else{ - responseMap.put("quarter", ((start.getMonthValue()-1)/3)+1); - } - return responseMap; - - } - - private List> formCostByType(List> result, List tTypeList) { - - Map> typeToAppMap = new HashMap<>(); - for(Map resultMap :result){ - String application = resultMap.get("application").toString(); - String typeCostListJson = resultMap.get("list").toString(); - List> typeCostList = new Gson().fromJson(typeCostListJson, new TypeToken>>() {}.getType()); - typeCostList.stream().filter(typeCost -> tTypeList.isEmpty()?true:tTypeList.contains(typeCost.get("type").toString()) ).forEach(typeCost-> { - String type = typeCost.get("type").toString(); - long cost = Math.round(Double.valueOf(typeCost.get("cost").toString())); - if(cost>0){ - Map appMap = typeToAppMap.get(type); - if(appMap==null){ - appMap = new HashMap<>(); - typeToAppMap.put(type, appMap); - } - Long currCost = appMap.get(application); - currCost = currCost==null?0l:currCost; - appMap.put(application, cost+currCost); - } - }); - } - - List typeList = new ArrayList(typeToAppMap.keySet()); - List> typeDataSource = assetRepository.getDatasourceForCostMapping(typeList); - - List> costByTypeMapList = new ArrayList<>(); - Iterator typeIterator = typeToAppMap.keySet().iterator(); - while (typeIterator.hasNext()) { - String typeValue = typeIterator.next(); - Map typeDataMap = new HashMap<>(); - typeDataMap.put("type", typeValue); - - typeDataMap.put(Constants.PROVIDER, - typeDataSource.stream() - .filter(datasource -> datasource.get(Constants.TYPE).toString().equals(typeValue)) - .findFirst().get().get(Constants.PROVIDER)); - - Map appMap = (typeToAppMap.get(typeValue) != null) - ? ((Map) (typeToAppMap.get(typeValue))) - : new HashMap<>(); - - Double typeCost = appMap.values().stream().mapToDouble(value -> value).sum(); - typeDataMap.put("typeTotalCost", typeCost); - List> appLineItemsMapList = new ArrayList<>(); - typeDataMap.put("applicationLineItems", appLineItemsMapList); - - Iterator appIterator = appMap.keySet().iterator(); - while (appIterator.hasNext()) { - Map appLineItemsMap = new HashMap<>(); - String appName = appIterator.next(); - Long cost = appMap.get(appName); - appLineItemsMap.put("lineItemName", appName); - appLineItemsMap.put("lineItemCost", cost); - appLineItemsMapList.add(appLineItemsMap); - } - - costByTypeMapList.add(typeDataMap); - } - - return costByTypeMapList; - } - - private void findCostIndicatorByType(List> currCostList, List> prevCostList) { - for(Map currCost : currCostList) { - String costIndicator = "NC"; - for(Map prevCost : prevCostList) { - if(currCost.get("type").equals(prevCost.get("type"))) { - Double currTotalCost = Double.valueOf(currCost.get("typeTotalCost").toString()); - Double prevTotalCost = Double.valueOf(prevCost.get("typeTotalCost").toString()); - Double percentage = (currTotalCost-prevTotalCost)/prevTotalCost*100; - if(percentage>0){ - if(percentage>costIndicatorPercent) { - costIndicator = "UP"; - } - } else if(percentage<0){ - costIndicator = "DOWN"; - } - break; - } - } - currCost.put("costTrendIndicator", costIndicator); - } - } - - @SuppressWarnings("deprecation") - public Map getCostByApplication(String assetGroup, Integer year, List monthList, - List appNameList, List tTypeList, List validApplications) - throws Exception { - - Integer prevYear = year; - List prevMonthList = new ArrayList<>(); - if(year==null && monthList.isEmpty()){ // Defaulted to latest finalised - Map yearMonth = costRepository.findLatestCostFinalisedMonth(); - if(yearMonth.isEmpty()){ - throw new ServiceException("Could not find cost as year/month to fetch the data can not be determined"); - } - year = yearMonth.get("year"); - monthList.add(yearMonth.get("month")+""); - Integer currMonth = Integer.valueOf(yearMonth.get("month").toString()); - if(currMonth >1 ) { - prevYear = year; - prevMonthList.add(String.valueOf(currMonth-1)+""); - } else { - prevYear = year -1; - prevMonthList.add("12"); - } - } else { - if(monthList.size() > 1) { - if(monthList.contains("1") && monthList.contains("2") && monthList.contains("3")) { - prevYear = year-1; - prevMonthList.add("10"); - prevMonthList.add("11"); - prevMonthList.add("12"); - } else { - for(String month : monthList) { - prevMonthList.add(String.valueOf(Integer.valueOf(month)-1)+""); - } - } - - } else { - if(Integer.valueOf(monthList.get(0)) >1 ) { - prevYear = year; - prevMonthList.add(String.valueOf(Integer.valueOf(monthList.get(0))-1)+""); - } else { - prevYear = year -1; - prevMonthList.add("12"); - } - } - } - - Map responseMap = new HashMap<>(); - Map mustFilter = new HashMap<>(); - Map mustTermsFilter = new HashMap<>(); - mustFilter.put("year", year); - mustTermsFilter.put(CommonUtils.convertAttributetoKeyword("application"), filterApps(appNameList)); - if(!tTypeList.isEmpty()){ - mustTermsFilter.put(CommonUtils.convertAttributetoKeyword("costInfo.type"), tTypeList); - } - mustTermsFilter.put("month", monthList); - List> currResult = elasticSearchRepository.getDataFromES("aws-cost", "monthly-cost", mustFilter, - null, null, null, mustTermsFilter); - - mustFilter.put("year", prevYear); - mustTermsFilter.put("month", prevMonthList); - List> prevResult = elasticSearchRepository.getDataFromES("aws-cost", "monthly-cost", mustFilter, - null, null, null, mustTermsFilter); - - boolean finalised = true; - for(Map resultMap :currResult){ - finalised = finalised && Boolean.valueOf(resultMap.get("finalised").toString()); - } - - List> currCostByAPPMapList = formCostByApplication(currResult, tTypeList, validApplications); - List> prevCostByAPPMapList = formCostByApplication(prevResult, tTypeList, validApplications); - - findCostIndicatorByApplication(currCostByAPPMapList,prevCostByAPPMapList); - - LocalDate date1 = LocalDate.of(year, new Integer(monthList.get(0)), 1); - LocalDate start = date1.withDayOfMonth(1); - - LocalDate date2 = LocalDate.of(year, new Integer(monthList.get(monthList.size() - 1)), 1); - LocalDate end = date2.withDayOfMonth(date2.lengthOfMonth()); - - - responseMap.put("ag", assetGroup); - responseMap.put("finalised", finalised); - responseMap.put("startDate", start.format(DateTimeFormatter.ISO_LOCAL_DATE)); - responseMap.put("endDate", end.format(DateTimeFormatter.ISO_LOCAL_DATE)); - responseMap.put("costByApplication", currCostByAPPMapList); - - responseMap.put("year", start.getYear()); - if(start.getMonthValue() == end.getMonth().getValue()){ - responseMap.put("month", start.getMonthValue()); - }else{ - responseMap.put("quarter", ((start.getMonthValue()-1)/3)+1); - } - - return responseMap; - } - -private List> formCostByApplication(List> result, List tTypeList, List validApplications) { - - Map> appToTypeMap = new HashMap<>(); - for(Map resultMap :result){ - String appllcation = resultMap.get("application").toString(); - String typeCostListJson = resultMap.get("list").toString(); - List> typeCostList = new Gson().fromJson(typeCostListJson, new TypeToken>>() {}.getType()); - if(!typeCostList.isEmpty()){ - typeCostList.stream().filter(typeCost -> tTypeList.isEmpty()?true:tTypeList.contains(typeCost.get("type").toString()) ).forEach(typeCost-> { - String type = typeCost.get("type").toString(); - long cost = Math.round(Double.valueOf(typeCost.get("cost").toString())); - Map typeMap = appToTypeMap.get(appllcation); - if(typeMap==null){ - typeMap = new HashMap<>(); - appToTypeMap.put(appllcation, typeMap); - } - Long currCost = typeMap.get(type); - currCost = currCost==null?0l:currCost; - typeMap.put(type, cost+currCost); - - }); - }else{ - Map typeMap = new HashMap<>(); - typeMap.put("", 0l); - appToTypeMap.put(appllcation, typeMap); - } - - } - - List> costByApplicationMapList = new ArrayList<>(); - Iterator appIterator = appToTypeMap.keySet().iterator(); - while (appIterator.hasNext()) { - String appValue = appIterator.next(); - Map applicationDataMap = new HashMap<>(); - applicationDataMap.put("name", appValue); - List orgList = getOrganization(appValue, validApplications); - if (null != orgList && !orgList.isEmpty()) { - applicationDataMap.put("organization", orgList); - } - - Map typeMap = (appToTypeMap.get(appValue) != null) - ? ( (appToTypeMap.get(appValue))) - : new HashMap<>(); - - Long applicationCost = typeMap.values().stream().mapToLong(value -> value).sum(); - applicationDataMap.put("applicationTotalCost", applicationCost); - List> typeLineItemsMapList = new ArrayList<>(); - applicationDataMap.put("typeLineItems", typeLineItemsMapList); - - Iterator typeIterator = typeMap.keySet().iterator(); - while (typeIterator.hasNext()) { - Map typeLineItemsMap = new HashMap<>(); - String typeName = typeIterator.next(); - Long cost = typeMap.get(typeName); - if(cost>0){ - typeLineItemsMap.put("lineItemName", typeName); - typeLineItemsMap.put("lineItemCost", cost); - typeLineItemsMapList.add(typeLineItemsMap); - } - } - - costByApplicationMapList.add(applicationDataMap); - } - return costByApplicationMapList; - } - - private void findCostIndicatorByApplication(List> currCostList, List> prevCostList) { - for(Map currCost : currCostList) { - String costIndicator = "NC"; - for(Map prevCost : prevCostList) { - if(currCost.get("name").equals(prevCost.get("name"))) { - Double currTotalCost = Double.valueOf(currCost.get("applicationTotalCost").toString()); - Double prevTotalCost = Double.valueOf(prevCost.get("applicationTotalCost").toString()); - Double percentage = (currTotalCost-prevTotalCost)/prevTotalCost*100; - if(percentage>0){ - if(percentage>5) { - costIndicator = "UP"; - } - } else { - costIndicator = "DOWN"; - } - break; - } - } - currCost.put("costTrendIndicator", costIndicator); - } - } - - private List getOrganization(String appName, List validApplications) { - Iterator appDetailIterator = validApplications.iterator(); - while (appDetailIterator.hasNext()) { - ApplicationDetail appDetail = appDetailIterator.next(); - if (appName.equals(appDetail.getName())) { - return appDetail.getOrganization(); - } - } - return null; - } - - - private List filterApps(List apps){ - List masterList = costRepository.fetchApplicationMasterList(); - if(masterList.isEmpty()){ - return apps; - }else{ - return apps.stream().filter(masterList::contains).collect(Collectors.toList()); - } - } - - @SuppressWarnings("unchecked") - public List> getCostTrend(List appNameList, List tTypeList, String period) throws Exception { - - List> trendList = new ArrayList<>(); - - if(tTypeList.isEmpty()) { - trendList.addAll(costRepository.getCostAggs(appNameList)); - } else { - trendList.addAll(costRepository.getCostAggsWithTT(appNameList, tTypeList)); - } - sortByYearAndMonth(trendList,"month"); - if("monthly".equals(period)) { - return trendList; - } else { - Map yearMap = new HashMap<>(); - for(Map trend : trendList) { - if(!yearMap.isEmpty() && yearMap.containsKey(trend.get("year").toString())) { - Map quarterMap = (Map) yearMap.get(trend.get("year").toString()); - int quarter = ((Integer.valueOf(trend.get("month").toString())-1) / 3)+1; - if(quarterMap.containsKey(quarter)) { - Map costMap = (Map) quarterMap.get(quarter); - costMap.put("cost", Double.valueOf(costMap.get("cost").toString()) + Double.valueOf(trend.get("cost").toString())); - costMap.put("costStatus", trend.get("costStatus")); - quarterMap.put(quarter, costMap); - } else { - Map costMap = new HashMap<>(); - costMap.put("cost", trend.get("cost")); - costMap.put("costStatus", trend.get("costStatus")); - quarterMap.put(quarter, costMap); - } - } else { - Map quarterMap = new HashMap<>(); - Map costMap = new HashMap<>(); - costMap.put("cost", trend.get("cost")); - costMap.put("costStatus", trend.get("costStatus")); - quarterMap.put(((Integer.valueOf(trend.get("month").toString())-1) / 3)+1, costMap); - yearMap.put(trend.get("year").toString(), quarterMap); - } - } - - trendList = new ArrayList<>(); - - - for(Entry year : yearMap.entrySet()) { - for(Entry quarter : ((Map)year.getValue()).entrySet()) { - Map trend = new HashMap<>(); - trend.put("year", year.getKey()); - trend.put("quarter", quarter.getKey()); - Map cost = (Map)quarter.getValue(); - trend.put("cost", cost.get("cost")); - trend.put("costStatus", cost.get("costStatus")); - trendList.add(trend); - } - } - sortByYearAndMonth(trendList,"quarter"); - return trendList; - } - } - - private void sortByYearAndMonth(List> trendList, String compartor) { - Comparator> comp1 = (m1, m2) -> Integer.compare( - new Integer(m1.get("year").toString()), new Integer(m2.get("year").toString())); - Collections.sort(trendList, comp1); - - Comparator> comp2 = (m1, m2) -> Integer.compare( - new Integer(m1.get(compartor).toString()), new Integer(m2.get(compartor).toString())); - Collections.sort(trendList, comp2); - } -} - - diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetCostControllerTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetCostControllerTest.java deleted file mode 100644 index 937b0f0db..000000000 --- a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/controller/AssetCostControllerTest.java +++ /dev/null @@ -1,220 +0,0 @@ -package com.tmobile.pacman.api.asset.controller; - -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyList; -import static org.mockito.Matchers.anyString; -import static org.powermock.api.mockito.PowerMockito.when; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.util.ReflectionTestUtils; - -import com.google.common.collect.Lists; -import com.tmobile.pacman.api.asset.domain.ApplicationDetail; -import com.tmobile.pacman.api.asset.domain.ApplicationDetailsResponse; -import com.tmobile.pacman.api.asset.domain.Organization; -import com.tmobile.pacman.api.asset.service.AssetService; -import com.tmobile.pacman.api.asset.service.CostService; -import com.tmobile.pacman.api.commons.utils.ResponseUtils; - -@RunWith(PowerMockRunner.class) -@PrepareForTest({ ResponseUtils.class }) -public class AssetCostControllerTest { - - @Mock - CostService costService; - - @Mock - AssetService assetService; - - AssetCostController controller = new AssetCostController(); - - @SuppressWarnings("unchecked") - @Test - public void getAssetCostByApplicationTest() throws Exception { - Map agInfo = new HashMap<>(); - agInfo.put("count","1"); - when(assetService.getAssetGroupInfo(anyString())).thenReturn(agInfo); - ReflectionTestUtils.setField(controller, "assetService", assetService); - ApplicationDetailsResponse applications = buildApplicationDetails(); - when(assetService.getApplicationDetailsByAssetGroup(anyString(), anyString())).thenReturn(applications); - when(assetService.getAllCostTypes()).thenReturn(buildCostTypes()); - when(costService.getCostByApplication(anyString(), anyInt(), anyList(), anyList(), anyList(), anyList())).thenReturn(new HashMap<>()); - ReflectionTestUtils.setField(controller, "costService", costService); - ResponseEntity responseObj0 = controller.getAssetCostByApplication("assetGroupId123", null, null, null, null, null); - assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); - - responseObj0 = controller.getAssetCostByApplication("assetGroupId123", "name123", null, null, null, null); - assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); - - responseObj0 = controller.getAssetCostByApplication("assetGroupId123", null, "type1", null, null, null); - assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); - - responseObj0 = controller.getAssetCostByApplication("assetGroupId123", null, null , 1, 2019, null); - assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); - - responseObj0 = controller.getAssetCostByApplication("assetGroupId123", null, null , null, 2019, 1); - assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); - } - - @Test - public void getAssetCostByApplicationTest_Failed() throws Exception { - - ResponseEntity responseObj0 = controller.getAssetCostByApplication("assetGroupId123", null, null, 1, null, 5); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - ResponseEntity responseObj1 = controller.getAssetCostByApplication("assetGroupId123", null, null, 1, null, null); - assertTrue(responseObj1.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - ResponseEntity responseObj2 = controller.getAssetCostByApplication("assetGroupId123", null, null, null, 2019, null); - assertTrue(responseObj2.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - ResponseEntity responseObj3 = controller.getAssetCostByApplication("assetGroupId123", null, null, null, null, 5); - assertTrue(responseObj3.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - ResponseEntity responseObj4 = controller.getAssetCostByApplication("assetGroupId123", null, null, 5, 2019, null); - assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - responseObj4 = controller.getAssetCostByApplication("assetGroupId123", null, null, 0, 2019, null); - assertTrue(responseObj4.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - ResponseEntity responseObj5 = controller.getAssetCostByApplication("assetGroupId123", null, null, null, 2019, 13); - assertTrue(responseObj5.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - responseObj5 = controller.getAssetCostByApplication("assetGroupId123", null, null, null, 2019, 0); - assertTrue(responseObj5.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - ResponseEntity responseObj6 = controller.getAssetCostByApplication("assetGroupId123", null, null, 1, 2017, null); - assertTrue(responseObj6.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - when(assetService.getAssetGroupInfo(anyString())).thenReturn(new HashMap<>()); - ReflectionTestUtils.setField(controller, "assetService", assetService); - ResponseEntity responseObj9 = controller.getAssetCostByApplication("assetGroupId123", null, null, null, null, null); - assertTrue(responseObj9.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - Map agInfo = new HashMap<>(); - agInfo.put("count","1"); - when(assetService.getAssetGroupInfo(anyString())).thenReturn(agInfo); - ReflectionTestUtils.setField(controller, "assetService", assetService); - ApplicationDetailsResponse applications = buildApplicationDetails(); - when(assetService.getApplicationDetailsByAssetGroup(anyString(), anyString())).thenReturn(applications); - - ResponseEntity responseObj7 = controller.getAssetCostByApplication("assetGroupId123", "test", null, null, null, null); - assertTrue(responseObj7.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - ResponseEntity responseObj8 = controller.getAssetCostByApplication("assetGroupId123", null, "test", null, null, null); - assertTrue(responseObj8.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - } - - @SuppressWarnings("unchecked") - @Test - public void getAssetCostByApplicationTest_Exception() throws Exception { - Map agInfo = new HashMap<>(); - agInfo.put("count","1"); - when(assetService.getAssetGroupInfo(anyString())).thenReturn(agInfo); - ReflectionTestUtils.setField(controller, "assetService", assetService); - ApplicationDetailsResponse applications = buildApplicationDetails(); - when(assetService.getApplicationDetailsByAssetGroup(anyString(), anyString())).thenReturn(applications); - when(assetService.getAllCostTypes()).thenReturn(buildCostTypes()); - when(costService.getCostByApplication(anyString(), anyInt(), anyList(), anyList(), anyList(), anyList())).thenThrow(new Exception()); - ReflectionTestUtils.setField(controller, "costService", costService); - ResponseEntity responseObj0 = controller.getAssetCostByApplication("assetGroupId123", null, null, null, null, null); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - } - - @SuppressWarnings("unchecked") - @Test - public void getAssetCostByTypeTest() throws Exception { - Map agInfo = new HashMap<>(); - agInfo.put("count","1"); - when(assetService.getAssetGroupInfo(anyString())).thenReturn(agInfo); - ReflectionTestUtils.setField(controller, "assetService", assetService); - ApplicationDetailsResponse applications = buildApplicationDetails(); - when(assetService.getApplicationDetailsByAssetGroup(anyString(), anyString())).thenReturn(applications); - when(assetService.getAllCostTypes()).thenReturn(buildCostTypes()); - when(costService.getCostByType(anyString(), anyInt(), anyList(), anyList(), anyList())).thenReturn(new HashMap<>()); - ReflectionTestUtils.setField(controller, "costService", costService); - ResponseEntity responseObj0 = controller.getAssetCostByType("assetGroupId123", null, null, null, null, null); - assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); - - } - - private ApplicationDetailsResponse buildApplicationDetails() - { - Organization organization = new Organization(); - organization.setDesignation("designation123"); - organization.setName("name123"); - ApplicationDetail applicationDetail = new ApplicationDetail(); - applicationDetail.setAssetGroupId("assetGroupId123"); - applicationDetail.setDescription("description123"); - applicationDetail.setName("name123"); - applicationDetail.setOrganization(Lists.newArrayList(organization)); - ApplicationDetailsResponse applicationDetailsResponse = new ApplicationDetailsResponse(); - applicationDetailsResponse.setInvalidApplications(Lists.newArrayList(applicationDetail)); - applicationDetailsResponse.setValidApplications(Lists.newArrayList(applicationDetail)); - return applicationDetailsResponse; - } - - private List> buildCostTypes() { - List> costTypes = new ArrayList<>(); - Map costType = new HashMap<>(); - costType.put("type", "type1"); - costTypes.add(costType); - return costTypes; - } - - @SuppressWarnings("unchecked") - @Test - public void getAssetCostTrendByTypeTest() throws Exception { - - ApplicationDetailsResponse applications = buildApplicationDetails(); - when(assetService.getApplicationDetailsByAssetGroup(anyString(), anyString())).thenReturn(applications); - ReflectionTestUtils.setField(controller, "assetService", assetService); - when(assetService.getAllCostTypes()).thenReturn(buildCostTypes()); - when(costService.getCostTrend(anyList(), anyList(), anyString())).thenReturn(new ArrayList<>()); - ReflectionTestUtils.setField(controller, "costService", costService); - ResponseEntity responseObj0 = controller.getAssetCostTrendByType("assetGroupId123", null, null, Period.monthly); - assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); - - responseObj0 = controller.getAssetCostTrendByType("assetGroupId123", "name123", null, Period.monthly); - assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); - - responseObj0 = controller.getAssetCostTrendByType("assetGroupId123", null, "type1", Period.quarterly); - assertTrue(responseObj0.getStatusCode() == HttpStatus.OK); - - } - - @SuppressWarnings("unchecked") - @Test - public void getAssetCostTrendByTypeTest_Failed() throws Exception { - - ResponseEntity responseObj7 = controller.getAssetCostTrendByType("assetGroupId123", "test", null, Period.monthly); - assertTrue(responseObj7.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - ResponseEntity responseObj8 = controller.getAssetCostTrendByType("assetGroupId123", null, "test", Period.monthly); - assertTrue(responseObj8.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - ApplicationDetailsResponse applications = buildApplicationDetails(); - when(assetService.getApplicationDetailsByAssetGroup(anyString(), anyString())).thenReturn(applications); - ReflectionTestUtils.setField(controller, "assetService", assetService); - when(assetService.getAllCostTypes()).thenReturn(buildCostTypes()); - when(costService.getCostTrend(anyList(), anyList(), anyString())).thenThrow(new Exception()); - ReflectionTestUtils.setField(controller, "costService", costService); - ResponseEntity responseObj0 = controller.getAssetCostTrendByType("assetGroupId123", null, null, Period.monthly); - assertTrue(responseObj0.getStatusCode() == HttpStatus.EXPECTATION_FAILED); - - } -} diff --git a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/CostServiceTest.java b/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/CostServiceTest.java deleted file mode 100644 index dd67bcb44..000000000 --- a/api/pacman-api-asset/src/test/java/com/tmobile/pacman/api/asset/service/CostServiceTest.java +++ /dev/null @@ -1,193 +0,0 @@ -package com.tmobile.pacman.api.asset.service; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.anyString; -import static org.powermock.api.mockito.PowerMockito.when; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.powermock.modules.junit4.PowerMockRunner; -import org.springframework.test.util.ReflectionTestUtils; - -import com.tmobile.pacman.api.asset.domain.ApplicationDetail; -import com.tmobile.pacman.api.asset.repository.AssetRepository; -import com.tmobile.pacman.api.asset.repository.CostRepository; -import com.tmobile.pacman.api.commons.Constants; -import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; - -@RunWith(PowerMockRunner.class) -public class CostServiceTest { - - @Mock - ElasticSearchRepository elasticSearchRepository; - - @Mock - AssetService assetService; - - @Mock - CostRepository costRepository; - - @Mock - AssetRepository assetRepository; - - @InjectMocks - CostService costService; - - @SuppressWarnings({ "deprecation", "unchecked" }) - @Test - public void getCostByTypeTest() throws Exception { - Map yearMonth = new HashMap<>(); - yearMonth.put("month", 5); - yearMonth.put("year", 2019); - when(costRepository.findLatestCostFinalisedMonth()).thenReturn(yearMonth); - when(costRepository.fetchApplicationMasterList()).thenReturn(new ArrayList<>()); - ReflectionTestUtils.setField(costService, "costRepository", costRepository); - when(elasticSearchRepository.getDataFromES(anyString(),anyString(),anyObject(),anyObject(),anyObject(),anyObject(),anyObject())).thenReturn(getCurrentCost(),getPreviousCost()); - List> typeDataSource = new ArrayList<>(); - Map dataSource = new HashMap<>(); - dataSource.put(Constants.TYPE, Constants.TYPE); - dataSource.put(Constants.PROVIDER, "aws"); - typeDataSource.add(dataSource); - when(assetRepository.getDatasourceForCostMapping(anyObject())).thenReturn(typeDataSource); - - assertTrue(costService.getCostByType("ag", 2019, Arrays.asList("4"), Arrays.asList("app"), Arrays.asList("type")).size() == 7); - assertTrue(costService.getCostByType("ag", null, new ArrayList<>(), Arrays.asList("app"), Arrays.asList("type")).size() == 7); - assertTrue(costService.getCostByType("ag", 2019, Arrays.asList("2","3"), Arrays.asList("app"), Arrays.asList("type")).size() == 7); - assertTrue(costService.getCostByType("ag", 2019, Arrays.asList("1","2","3"), Arrays.asList("app"), Arrays.asList("type")).size() == 7); - assertTrue(costService.getCostByType("ag", 2019, Arrays.asList("1"), Arrays.asList("app"), Arrays.asList("type")).size() == 7); - } - - @Test - public void getCostByTypeTest_Exception() throws Exception { - when(costRepository.findLatestCostFinalisedMonth()).thenReturn(new HashMap<>()); - assertThatThrownBy(() -> costService.getCostByType("ag", null, new ArrayList<>(), Arrays.asList("app"), Arrays.asList("type"))) - .isInstanceOf(Exception.class); - } - - @SuppressWarnings({ "deprecation", "unchecked" }) - @Test - public void getCostByApplicationTest() throws Exception { - Map yearMonth = new HashMap<>(); - yearMonth.put("month", 5); - yearMonth.put("year", 2019); - when(costRepository.findLatestCostFinalisedMonth()).thenReturn(yearMonth); - when( costRepository.fetchApplicationMasterList()).thenReturn(Arrays.asList("app")); - ReflectionTestUtils.setField(costService, "costRepository", costRepository); - when(elasticSearchRepository.getDataFromES(anyString(),anyString(),anyObject(),anyObject(),anyObject(),anyObject(),anyObject())).thenReturn(getCurrentCost(),getPreviousCost()); - - assertTrue(costService.getCostByApplication("ag", 2019, Arrays.asList("4"), Arrays.asList("app"), Arrays.asList("type"), getValidApplications()).size() == 7); - assertTrue(costService.getCostByApplication("ag", null, new ArrayList<>(), Arrays.asList("app"), Arrays.asList("type"), getValidApplications()).size() == 7); - assertTrue(costService.getCostByApplication("ag", 2019, Arrays.asList("2","3"), Arrays.asList("app"), Arrays.asList("type"), getValidApplications()).size() == 7); - assertTrue(costService.getCostByApplication("ag", 2019, Arrays.asList("1","2","3"), Arrays.asList("app"), Arrays.asList("type"), getValidApplications()).size() == 7); - assertTrue(costService.getCostByApplication("ag", 2019, Arrays.asList("1"), Arrays.asList("app"), Arrays.asList("type"), getValidApplications()).size() == 7); - } - - @Test - public void getCostByApplicationTest_Exception() throws Exception { - when(costRepository.findLatestCostFinalisedMonth()).thenReturn(new HashMap<>()); - assertThatThrownBy(() -> costService.getCostByApplication("ag", null, new ArrayList<>(), Arrays.asList("app"), Arrays.asList("type"), getValidApplications())) - .isInstanceOf(Exception.class); - } - - @Test - public void getCostTrendTest() throws Exception { - - when(costRepository.getCostAggs(anyObject())).thenReturn(getCostTrend()); - assertTrue(costService.getCostTrend(Arrays.asList("app"), new ArrayList<>(), "monthly").size() == 5); - - when(costRepository.getCostAggsWithTT(anyObject(), anyObject())).thenReturn(getCostTrend()); - assertTrue(costService.getCostTrend(Arrays.asList("app"), Arrays.asList("type"), "quarterly").size() == 2); - } - - private List> getCurrentCost() { - - List> currentCost = new ArrayList<>(); - Map cost = new HashMap<>(); - cost.put("application", "app"); - cost.put("month", 4.0); - cost.put("year", 2019.0); - cost.put("finalised", "false"); - cost.put("totalCost", 44942.096); - List> typeCost = new ArrayList<>(); - Map type = new HashMap<>(); - type.put("cost", 44942.096); - type.put("type", "type"); - typeCost.add(type); - cost.put("list",typeCost); - currentCost.add(cost); - return currentCost; - } - - private List> getPreviousCost() { - - List> previousCost = new ArrayList<>(); - Map cost = new HashMap<>(); - cost.put("application", "app"); - cost.put("month", 4.0); - cost.put("year", 2019.0); - cost.put("finalised", "false"); - cost.put("totalCost", 44942.096); - List> typeCost = new ArrayList<>(); - Map type = new HashMap<>(); - type.put("cost", 44942.096); - type.put("type", "type"); - typeCost.add(type); - cost.put("list",typeCost); - previousCost.add(cost); - return previousCost; - } - - private List getValidApplications() { - List validApplications = new ArrayList<>(); - ApplicationDetail app = new ApplicationDetail(); - app.setName("app"); - validApplications.add(app); - return validApplications; - } - - private List> getCostTrend() { - - List> costTrend = new ArrayList<>(); - Map trend = new HashMap<>(); - trend.put("month", 1); - trend.put("year", 2019); - trend.put("cost", 57221); - trend.put("finalised", true); - costTrend.add(trend); - trend = new HashMap<>(); - trend.put("month", 2); - trend.put("year", 2019); - trend.put("cost", 50138); - trend.put("finalised", true); - costTrend.add(trend); - trend = new HashMap<>(); - trend.put("month", 3); - trend.put("year", 2019); - trend.put("cost", 44942); - trend.put("finalised", true); - costTrend.add(trend); - trend = new HashMap<>(); - trend.put("month", 4); - trend.put("year", 2019); - trend.put("cost", 37134); - trend.put("finalised", false); - costTrend.add(trend); - trend = new HashMap<>(); - trend.put("month", 5); - trend.put("year", 2019); - trend.put("cost", 6517); - trend.put("finalised", false); - costTrend.add(trend); - return costTrend; - } -} From bedb2f42ac6aadc833ccd52347627687746dc984 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Thu, 1 Aug 2019 11:06:21 +0530 Subject: [PATCH 14/86] job name is added --- .../java/com/tmobile/cso/pacbot/recommendation/Main.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/Main.java b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/Main.java index 590ed192b..29e6ac941 100644 --- a/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/Main.java +++ b/jobs/recommendation-enricher/src/main/java/com/tmobile/cso/pacbot/recommendation/Main.java @@ -62,7 +62,10 @@ public static void main(String[] args) { * @return the map */ public static Map shipData(Map params) { - String jobName = System.getProperty("jobName"); + String jobName = params.get("jobName"); + if(jobName.isEmpty()){ + jobName = "aws-recommendations-collector"; + } List> errorList = new ArrayList<>(); try { MainUtil.setup(params); From edd91f33fdc8ba33d1fb8e75ae2d1dcf8598f061 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Thu, 1 Aug 2019 15:36:13 +0530 Subject: [PATCH 15/86] Health notifications changes --- .../CloudNotificationsController.java | 186 + .../CloudNotificationsRepository.java | 20 + .../CloudNotificationsRepositoryImpl.java | 838 +++++ .../service/CloudNotificationService.java | 16 + .../service/CloudNotificationServiceImpl.java | 46 + .../tmobile/pacman/api/commons/Constants.java | 3 + .../commons/repo/ElasticSearchRepository.java | 3255 +++++++++-------- .../pacman/api/commons/utils/CommonUtils.java | 724 ++-- .../pacman-cloud-notifications/pom.xml | 263 ++ .../tmobile/pacman/common/AutoFixAction.java | 140 +- .../pacman/common/PacmanSdkConstants.java | 6 + .../pacman/commons/autofix/AutoFixPlan.java | 178 + .../pacman/commons/autofix/PlanItem.java | 109 + .../pacman/commons/autofix/Status.java | 72 + .../autofix/manager/AutoFixManager.java | 224 +- .../autofix/manager/AutoFixPlanManager.java | 268 ++ .../autofix/manager/NextStepManager.java | 20 +- .../pacman/dto/AutoFixTransaction.java | 17 +- .../impl/ElasticSearchDataInterface.java | 81 + .../impl/ElasticSearchDataPublisher.java | 34 +- .../impl/ElasticSearchDataReader.java | 106 + .../com/tmobile/pacman/util/MailUtils.java | 2 +- .../manager/AutoFixPlanManagerTest.java | 73 + 23 files changed, 4565 insertions(+), 2116 deletions(-) create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/CloudNotificationsController.java create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/CloudNotificationsRepository.java create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/CloudNotificationsRepositoryImpl.java create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CloudNotificationService.java create mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CloudNotificationServiceImpl.java create mode 100644 jobs/pacman-cloud-notifications/target/classes/META-INF/maven/com.tmobile.pacman.cloud/pacman-cloud-notifications/pom.xml create mode 100644 jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/AutoFixPlan.java create mode 100644 jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/PlanItem.java create mode 100644 jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/Status.java create mode 100644 jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/AutoFixPlanManager.java create mode 100644 jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/publisher/impl/ElasticSearchDataInterface.java create mode 100644 jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/publisher/impl/ElasticSearchDataReader.java create mode 100644 jobs/pacman-rule-engine-2.0/src/test/java/com/tmobile/pacman/commons/autofix/manager/AutoFixPlanManagerTest.java diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/CloudNotificationsController.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/CloudNotificationsController.java new file mode 100644 index 000000000..731405ac6 --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/controller/CloudNotificationsController.java @@ -0,0 +1,186 @@ +/** + * + */ +package com.tmobile.pacman.api.asset.controller; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.google.common.base.Strings; +import com.tmobile.pacman.api.asset.AssetConstants; +import com.tmobile.pacman.api.asset.domain.Request; +import com.tmobile.pacman.api.asset.domain.ResponseWithCount; +import com.tmobile.pacman.api.asset.service.CloudNotificationService; +import com.tmobile.pacman.api.commons.Constants; +import com.tmobile.pacman.api.commons.utils.CommonUtils; +import com.tmobile.pacman.api.commons.utils.ResponseUtils; + +import io.swagger.annotations.ApiOperation; + +/** + * The controller layer which has methods to return list of cloud notifications. + * + */ +@RestController +@PreAuthorize("@securityService.hasPermission(authentication, 'ROLE_USER')") +@CrossOrigin +public class CloudNotificationsController { + + @Autowired + CloudNotificationService cloudService; + + private static final Log LOGGER = LogFactory.getLog(AssetListController.class); + + /** + * Fetches the Cloud Notifications for the rule id passed in the filter. + * + * @param request This request expects assetGroup and ruleId as mandatory + * attributes. API returns all the CIS assets associated with the + * assetGroup with matching filters. + * + * @return cloud Notifications by asset group. + */ + + @ApiOperation(httpMethod = "POST", value = "Get the list of Cloud Notifications by a asset Group. Mandatory Filter -'Global Notifications'") + @PostMapping(value = "/v1/cloud/notifications") + public ResponseEntity getlistOfCloudNotifications(@RequestBody(required = true) Request request, @RequestParam(name = "global", required = true) boolean globalNotifier ) { + + String assetGroup = request.getAg(); + if (Strings.isNullOrEmpty(assetGroup)) { + return ResponseUtils.buildFailureResponse(new Exception(Constants.ASSET_MANDATORY)); + } + + int from = request.getFrom(); + int size = request.getSize(); + if (from < 0) { + return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.ERROR_FROM_NEGATIVE)); + } + + String searchText = request.getSearchtext(); + Map filter = request.getFilter(); + List> masterList; + + try { + masterList = cloudService.getNotifications(assetGroup, filter, globalNotifier, size, from); + } catch (Exception e) { + LOGGER.error("Error in getlistOfCloudNotifications ", e); + return ResponseUtils.buildFailureResponse(e); + } + return formResponseWithCount(masterList, from, size, searchText); + } + + /** + * Method returns the list with count based on the from and size. + * + * @param masterList + * @param from + * @param size + * @param searchText + * + * @return ResponseEntity + */ + @SuppressWarnings("unchecked") + private ResponseEntity formResponseWithCount(List> masterList, int from, int size, + String searchText) { + try { + List> masterDetailList = (List>) CommonUtils + .filterMatchingCollectionElements(masterList, searchText, true); + if (masterDetailList.isEmpty()) { + return ResponseUtils + .buildSucessResponse(new ResponseWithCount(new ArrayList>(), 0)); + } + + if (from >= masterDetailList.size()) { + return ResponseUtils.buildFailureResponse(new Exception(AssetConstants.ERROR_FROM_EXCEEDS)); + } + + int endIndex = 0; + + if (size == 0) { + size = masterDetailList.size(); + } + + if ((from + size) > masterDetailList.size()) { + endIndex = masterDetailList.size(); + } else { + endIndex = from + size; + } + + List> subDetailList = masterDetailList.subList(from, endIndex); + return ResponseUtils.buildSucessResponse(new ResponseWithCount(subDetailList, masterDetailList.size())); + } catch (Exception e) { + LOGGER.error("Exception in formResponseWithCount ",e); + return ResponseUtils.buildFailureResponse(e); + } + } + + @GetMapping(value = "/v1/cloud/notifications/summary") + public ResponseEntity getCloudNotificationsSummary(@RequestParam(name = "ag", required = true) String assetGroup , + @RequestParam(name = "global", required = true) boolean globalNotifier, + @RequestParam(name = "resourceId", required = false) String resourceId, + @RequestParam(name = "eventStatus", required = false) String eventStatus) { + try { + return ResponseUtils.buildSucessResponse(cloudService.getCloudNotificationsSummary(assetGroup, globalNotifier, resourceId, eventStatus)); + } catch (Exception e) { + LOGGER.error("Error in getCloudNotificationsSummary "+ e); + return ResponseUtils.buildFailureResponse(e); + } + } + + @GetMapping(value = "/v1/cloud/notifications/detail") + public ResponseEntity getCloudNotificationDetail(@RequestParam(name = "eventArn", required = true) String eventArn, + @RequestParam(name = "global", required = true) boolean globalNotifier, + @RequestParam(name = "ag", required = true) String assetGroup) { + try { + return ResponseUtils.buildSucessResponse(cloudService.getCloudNotificationDetail(eventArn,globalNotifier, assetGroup)); + } catch (Exception e) { + LOGGER.error("Error in getCloudNotificationDetail "+ e); + return ResponseUtils.buildFailureResponse(e); + } + } + + @GetMapping(value = "/v1/cloud/notifications/info") + public ResponseEntity getCloudNotificationInfo(@RequestParam(name = "eventArn", required = true) String eventArn, + @RequestParam(name = "global", required = true) boolean globalNotifier, + @RequestParam(name = "ag", required = true) String assetGroup) { + try { + return ResponseUtils.buildSucessResponse(cloudService.getCloudNotificationInfo(eventArn,globalNotifier, assetGroup)); + } catch (Exception e) { + LOGGER.error("Error in getCloudNotificationInfo "+ e); + return ResponseUtils.buildFailureResponse(e); + } + } + + @ApiOperation(httpMethod = "POST", value = "Autofix plan details") + @PostMapping(value = "/v1/autofix/notifications/detail") + public ResponseEntity getAutofixProjectionDetail(@RequestBody(required = true) Request request) { + try { + String assetGroup = request.getAg(); + Map filter = request.getFilter(); + if (Strings.isNullOrEmpty(assetGroup)) { + return ResponseUtils.buildFailureResponse(new Exception(Constants.ASSET_MANDATORY)); + } + if (filter.isEmpty()) { + return ResponseUtils.buildFailureResponse(new Exception(Constants.FILTER_MANDATORY)); + } + return ResponseUtils.buildSucessResponse(cloudService.getAutofixProjectionDetail(assetGroup, filter)); + } catch (Exception e) { + LOGGER.error("Error in getAutofixProjectionDetail "+ e); + return ResponseUtils.buildFailureResponse(e); + } + } + +} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/CloudNotificationsRepository.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/CloudNotificationsRepository.java new file mode 100644 index 000000000..41783a670 --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/CloudNotificationsRepository.java @@ -0,0 +1,20 @@ +package com.tmobile.pacman.api.asset.repository; + +import java.util.List; +import java.util.Map; + +import org.springframework.stereotype.Repository; + +/** + * This is the Cloud Notifications Repository layer which makes call to RDS DB as well as ElasticSearch + */ +@Repository +public interface CloudNotificationsRepository { + + public List> getNotifications(String assetGroup, Map filter, boolean globalNotifier, int size, int from); + public List> getCloudNotificationsSummary(String assetGroup, boolean globalNotifier, String resourceId, String eventStatus); + public List> getCloudNotificationDetail(String eventArn, boolean globalNotifier, String assetGroup); + public Map getCloudNotificationInfo(String eventArn, boolean globalNotifier, String assetGroup); + public Map getAutofixProjectionDetail(String assetGroup, Map filter); + +} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/CloudNotificationsRepositoryImpl.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/CloudNotificationsRepositoryImpl.java new file mode 100644 index 000000000..e4c6c828c --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/CloudNotificationsRepositoryImpl.java @@ -0,0 +1,838 @@ +package com.tmobile.pacman.api.asset.repository; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Repository; +import org.springframework.util.CollectionUtils; + +import com.google.common.base.Strings; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.tmobile.pacman.api.asset.AssetConstants; +import com.tmobile.pacman.api.commons.Constants; +import com.tmobile.pacman.api.commons.exception.DataException; +import com.tmobile.pacman.api.commons.repo.ElasticSearchRepository; +import com.tmobile.pacman.api.commons.repo.PacmanRdsRepository; +import com.tmobile.pacman.api.commons.utils.CommonUtils; +import com.tmobile.pacman.api.commons.utils.PacHttpUtils; + +/** + * Implemented class for CloudNotificationsRepository and all its method + */ +@Repository +public class CloudNotificationsRepositoryImpl implements CloudNotificationsRepository { + + @Autowired + ElasticSearchRepository esRepository; + + @Autowired + PacmanRdsRepository rdsRepository; + + private static final Log LOGGER = LogFactory.getLog(CloudNotificationsRepositoryImpl.class); + private static final String _SEARCH = "_search"; + private static final String HITS = "hits"; + private static final String ERROR_IN_US = "error retrieving inventory from ES"; + @Value("${elastic-search.host}") + private String esHost; + @Value("${elastic-search.port}") + private int esPort; + private String TYPE = "cloud_notification"; + private String INDEX = "cloud_notifications"; + private String AUTOFIXTYPE = "autofixplan"; + final static String protocol = "http"; + private String esUrl; + private static final String _SOURCE = "_source"; + private static final String _COUNT = "_count"; + List> notifications = new ArrayList<>(); + String autoFixQuery = ""; + + @PostConstruct + void init() { + esUrl = protocol + "://" + esHost + ":" + esPort; + } + + @Override + public List> getNotifications(String assetGroup, Map filter, + boolean globalNotifier, int size, int from) { + LOGGER.info("Inside getNotifications"); + notifications = new ArrayList<>(); + try { + + if (globalNotifier) { + getCloudNotifications(INDEX, TYPE, filter, size, from).forEach(notification -> { + notifications.add(notification); + }); + } else { + + String eventCat = filter.get(Constants.EVENTCATEGORY); + String resourceId = filter.get(Constants.RESOURCEID); + if ((filter.isEmpty() || filter.containsValue("Autofix") || Strings.isNullOrEmpty(eventCat)) && (Strings.isNullOrEmpty(resourceId)) ) { + getAutofixProjections(assetGroup, AUTOFIXTYPE, filter).forEach(autofix -> { + notifications.add(autofix); + }); + } + + getCloudNotifications(assetGroup, TYPE, filter, size, from).forEach(notification -> { + notifications.add(notification); + }); + } + } catch (Exception e) { + LOGGER.error("Error in getNotifications", e); + } + LOGGER.info("Exiting getNotifications"); + return notifications.stream().distinct().collect(Collectors.toList()); + } + + + @Override + public List> getCloudNotificationDetail(String eventArn, boolean globalNotifier, + String assetGroup) { + LOGGER.info("Inside getCloudNotificationDetail"); + List> detail = new ArrayList<>(); + try { + if (globalNotifier) { + detail = getCloudNotificationDetail(INDEX, TYPE, eventArn); + } else { + detail = getCloudNotificationDetail(assetGroup, TYPE, eventArn); + } + + } catch (Exception e) { + LOGGER.error("Error in getCloudNotificationDetail", e); + } + LOGGER.info("Exiting getCloudNotificationDetail"); + return detail; + } + + @SuppressWarnings({ "deprecation" }) + private List> getAssetsByResourceId(String assetGroupName, String type, String resourceId) { + + List> results = new ArrayList<>(); + String query = "SELECT esIndex, resourceIdVal FROM CloudNotification_mapping WHERE esIndex =\"" + type + "\""; + try { + results = rdsRepository.getDataFromPacman(query); + } catch (Exception exception) { + LOGGER.error("Error in getAssetsByResourceId for getting parent type ", exception); + } + Map mustFilter = new HashMap<>(); + mustFilter.put(CommonUtils.convertAttributetoKeyword((results.get(0).get("resourceIdVal")).toString()), + resourceId); + mustFilter.put(Constants.LATEST, Constants.TRUE); + mustFilter.put(AssetConstants.UNDERSCORE_ENTITY, Constants.TRUE); + Map mustNotFilter = null; + + List> assets = new ArrayList<>(); + try { + if (AssetConstants.ALL.equals(type)) { + try { + Map mustTermsFilter = new HashMap<>(); + assets = esRepository.getDataFromES(assetGroupName, null, mustFilter, null, null, null, + mustTermsFilter); + } catch (Exception e) { + LOGGER.error(AssetConstants.ERROR_GETASSETSBYAG, e); + } + } else { + assets = esRepository.getDataFromES(assetGroupName, (results.get(0).get("esIndex")).toString(), + mustFilter, mustNotFilter, null, null, null); + } + } catch (Exception e) { + LOGGER.error(AssetConstants.ERROR_GETASSETSBYAG, e); + } + return assets; + } + + @SuppressWarnings("unchecked") + public List> getCloudNotificationDetail(String index, String type, String eventArn) + throws DataException { + Gson gson = new GsonBuilder().create(); + String responseDetails = null; + StringBuilder requestBody = null; + List> cloudDetails = null; + List fieldNames = new ArrayList<>(); + List> detail = new ArrayList>(); + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append("/").append(index).append("/").append(type) + .append("/").append(_SEARCH); + String body = "{\"_source\": [\"eventarn\",\"notificationId\",\"latestdescription\", \"type\"], \"query\":{\"bool\":{\"must\":[{\"term\":{\"eventarn.keyword\":\"" + + eventArn + "\"}},{\"term\":{\"latest\":\"true\"}}]}}}"; + requestBody = new StringBuilder(body); + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQueryBuffer.toString(), requestBody.toString()); + } catch (Exception e) { + LOGGER.error(ERROR_IN_US, e); + throw new DataException(e); + } + Map responseMap = (Map) gson.fromJson(responseDetails, Object.class); + if (responseMap.containsKey(HITS)) { + Map hits = (Map) responseMap.get(HITS); + if (hits.containsKey(HITS)) { + cloudDetails = (List>) hits.get(HITS); + List resources = new ArrayList(); + String resourceType = ""; + for (Map cloudDetail : cloudDetails) { + Map sourceMap = (Map) cloudDetail.get("_source"); + if (sourceMap.containsKey("notificationId")) { + resources.add(sourceMap.get("notificationId").toString()); + resourceType = sourceMap.get("type").toString(); + detail.add(getAssetsByResourceId(index, resourceType, resources.get(0).toString()).get(0)); + } + } + } + } + List fieldsToBeSkipped = Arrays.asList(Constants.RESOURCEID, Constants.DOCID, + AssetConstants.UNDERSCORE_ENTITY, Constants._ID, AssetConstants.UNDERSCORE_LOADDATE, + Constants.ES_DOC_PARENT_KEY, Constants.ES_DOC_ROUTING_KEY, AssetConstants.CREATE_TIME, + AssetConstants.FIRST_DISCOVEREDON, AssetConstants.DISCOVERY_DATE, Constants.LATEST, + AssetConstants.CREATION_DATE); + return formGetListResponse(fieldNames, detail, fieldsToBeSkipped); + } + + private List> formGetListResponse(List fieldNames, + List> assetDetails, List fieldsToBeSkipped) { + + List> assetList = new ArrayList<>(); + if (!CollectionUtils.isEmpty(fieldNames)) { + final List fieldNamesCopy = fieldNames; + assetDetails.parallelStream().forEach(assetDetail -> { + Map asset = new LinkedHashMap<>(); + for (String fieldName : fieldNamesCopy) { + if (!assetDetail.containsKey(fieldName)) { + asset.put(fieldName, ""); + } else { + asset.put(fieldName, assetDetail.get(fieldName)); + } + } + synchronized (assetList) { + assetList.add(asset); + } + }); + return assetList; + } else { + assetDetails.parallelStream().forEach(assetDetail -> { + Map asset = new LinkedHashMap<>(); + asset.put(Constants.RESOURCEID, assetDetail.get(Constants.RESOURCEID)); + assetDetail.forEach((key, value) -> { + if (!fieldsToBeSkipped.contains(key)) { + asset.put(key, value); + } + }); + synchronized (assetList) { + assetList.add(asset); + } + }); + return assetList; + } + } + + @Override + @SuppressWarnings("unchecked") + public Map getCloudNotificationInfo(String eventArn, boolean globalNotifier, String assetGroup) { + Map eventMap = new HashMap<>(); + eventMap.put("scheduledChange", "Scheduled Change"); + eventMap.put("accountNotification", "Account Notification"); + eventMap.put("issue", "Issue"); + + String index = ""; + String type = ""; + if (globalNotifier) { + index = INDEX; + type = TYPE; + } else { + index = assetGroup; + type = TYPE; + } + Gson gson = new GsonBuilder().create(); + String responseDetails = null; + StringBuilder requestBody = null; + List> cloudDetails = null; + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append("/").append(index).append("/").append(type) + .append("/").append(_SEARCH); + + String body = "{\"_source\": [\"eventarn\",\"endtime\",\"eventtypecategory\",\"starttime\",\"statuscode\",\"eventtypecode\",\"eventregion\",\"latestdescription\", \"type\"], \"query\":{\"bool\":{\"must\":[{\"term\":{\"eventarn.keyword\":\"" + + eventArn + "\"}},{\"term\":{\"latest\":\"true\"}}]}}}"; + requestBody = new StringBuilder(body); + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQueryBuffer.toString(), requestBody.toString()); + } catch (Exception e) { + LOGGER.error(ERROR_IN_US, e); + try { + throw new DataException(e); + } catch (DataException e1) { + LOGGER.error("ERROR in getCloudNotificationInfo ", e1); + } + } + Map responseMap = (Map) gson.fromJson(responseDetails, Object.class); + Map infoMap = new HashMap(); + if (responseMap.containsKey(HITS)) { + Map hits = (Map) responseMap.get(HITS); + if (hits.containsKey(HITS)) { + cloudDetails = (List>) hits.get(HITS); + for (Map cloudDetail : cloudDetails) { + Map sourceMap = (Map) cloudDetail.get("_source"); + infoMap.put("event", CommonUtils.capitailizeWord(sourceMap.get("eventtypecode").toString())); + infoMap.put("status", sourceMap.get("statuscode")); + infoMap.put("region", sourceMap.get("eventregion")); + infoMap.put("startTime", sourceMap.get("starttime")); + infoMap.put("endTime", sourceMap.get("endtime")); + infoMap.put("eventCategory", eventMap.get(sourceMap.get("eventtypecategory"))); + infoMap.put("eventarn", sourceMap.get("eventarn")); + infoMap.put("latestdescription", eventDescChanges(sourceMap.get("latestdescription").toString())); + } + } + } + return infoMap; + } + + private String eventDescChanges(String description) { + + description = description.replace("*", "
*"); + description = description.replace("?[NL]", "?
"); + if (description.indexOf("https://console.aws.amazon.com/ec2/v2/home?region=us-west-2#Events") > 0) { + description = description.replace("https://console.aws.amazon.com/ec2/v2/home?region=us-west-2#Events", + "https://console.aws.amazon.com/ec2/v2/home?region=us-west-2#Events"); + } + if (description.indexOf( + "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html#schedevents_actions_reboot") > 0) { + description = description.replace( + "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html#schedevents_actions_reboot", + "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html#schedevents_actions_reboot"); + } + if (description.indexOf( + "at https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html") > 0) { + description = description.replace( + "at https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html", + "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html"); + } + if (description.indexOf("https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Stop_Start.html") > 0) { + description = description.replace("https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Stop_Start.html", + "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Stop_Start.html"); + } + if (description.indexOf("https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#Events") > 0) { + description = description.replace("https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#Events", + "https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#Events"); + } + if (description.indexOf("[3] https://github.com/awslabs/aws-vpn-migration-scripts") > 0) { + description = description.replace("[3] https://github.com/awslabs/aws-vpn-migration-scripts", + "https://github.com/awslabs/aws-vpn-migration-scripts"); + } + if (description.indexOf("http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-retirement.html") > 0) { + description = description.replace( + " http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-retirement.html", + "http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-retirement.html"); + } + if (description.indexOf("(https://aws.amazon.com/support)") > 0) { + description = description.replace("(https://aws.amazon.com/support)", + "https://aws.amazon.com/support"); + } + if (description.indexOf("(http://aws.amazon.com/support)") > 0) { + description = description.replace("(http://aws.amazon.com/support)", + "http://aws.amazon.com/support"); + } + if (description.indexOf("http://aws.amazon.com/support") > 0) { + description = description.replace("http://aws.amazon.com/support", + "http://aws.amazon.com/support"); + } + if (description.indexOf("[1] https://console.aws.amazon.com") > 0) { + description = description.replace("[1] https://console.aws.amazon.com", + "https://console.aws.amazon.com"); + } + if (description.indexOf("http://aws.amazon.com/architecture") > 0) { + description = description.replace("http://aws.amazon.com/architecture", + "http://aws.amazon.com/architecture"); + } + if (description.indexOf("https://aws.amazon.com/support") > 0) { + description = description.replace("https://aws.amazon.com/support", + "https://aws.amazon.com/support"); + } + if (description.indexOf("https://aws.amazon.com/premiumsupport/knowledge-center/migrate-classic-vpn-new") > 0) { + description = description.replace( + "https://aws.amazon.com/premiumsupport/knowledge-center/migrate-classic-vpn-new", + "https://aws.amazon.com/premiumsupport/knowledge-center/migrate-classic-vpn-new"); + } + if (description.indexOf( + "https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/using-amazon-mq-securely.html#amazon-mq-vpc-security-groups") > 0) { + description = description.replace( + "https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/using-amazon-mq-securely.html#amazon-mq-vpc-security-groups", + "https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/using-amazon-mq-securely.html#amazon-mq-vpc-security-groups"); + } + if (description.indexOf( + "[3] http://activemq.apache.org/security-advisories.data/CVE-2019-0222-announcement.txt") > 0) { + description = description.replace( + "[3] http://activemq.apache.org/security-advisories.data/CVE-2019-0222-announcement.txt", + "http://activemq.apache.org/security-advisories.data/CVE-2019-0222-announcement.txt"); + } + if (description.indexOf( + "https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/amazon-mq-editing-broker-preferences.html") > 0) { + description = description.replace( + "https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/amazon-mq-editing-broker-preferences.html", + "https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/amazon-mq-editing-broker-preferences.html"); + } + if (description.indexOf("https://docs.aws.amazon.com/vpn/latest/s2svpn/VPC_VPN.html#vpn-categories") > 0) { + description = description.replace( + "https://docs.aws.amazon.com/vpn/latest/s2svpn/VPC_VPN.html#vpn-categories", + "https://docs.aws.amazon.com/vpn/latest/s2svpn/VPC_VPN.html#vpn-categories"); + } + if (description.indexOf("https://nodejs.org/en/blog/release/v6.9.0/") > 0) { + description = description.replace("https://nodejs.org/en/blog/release/v6.9.0/", + "https://nodejs.org/en/blog/release/v6.9.0/"); + } + if (description.indexOf("https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html") > 0) { + description = description.replace( + "https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html", + "https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html"); + } + if (description.indexOf( + "https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/") > 0) { + description = description.replace( + "https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/", + "https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda"); + } + if (description.indexOf( + "https://aws.amazon.com/blogs/compute/upcoming-updates-to-the-aws-lambda-execution-environment/") > 0) { + description = description.replace( + "https://aws.amazon.com/blogs/compute/upcoming-updates-to-the-aws-lambda-execution-environment/", + "https://aws.amazon.com/blogs/compute/upcoming-updates-to-the-aws-lambda-execution-environment"); + } + if (description.indexOf( + "https://aws.amazon.com/blogs/compute/updated-timeframe-for-the-upcoming-aws-lambda-and-aws-lambdaedge-execution-environment-update/") > 0) { + description = description.replace( + "https://aws.amazon.com/blogs/compute/updated-timeframe-for-the-upcoming-aws-lambda-and-aws-lambdaedge-execution-environment-update/", + "https://aws.amazon.com/blogs/compute/updated-timeframe-for-the-upcoming-aws-lambda-and-aws-lambdaedge-execution-environment-update"); + } + + description = description.replace("[1]", "").replace("[2]", "").replace("[3]", "").replace("[4]", "") + .replace("[NL][NL]", "\n\n").replace("(https:", "> getCloudNotifications(String index, String type, Map filter, + int size, int from) throws DataException { + Map eventMap = new HashMap<>(); + eventMap.put("scheduledChange", "Scheduled Change"); + eventMap.put("accountNotification", "Account Notification"); + eventMap.put("issue", "Issue"); + List> notificationsList = new ArrayList>(); + try { + Map eventArnMap = new HashMap(); + eventArnMap = getCloudEventArn(index, type, size, from); + String eventArn = eventArnMap.keySet().stream().collect(Collectors.toList()).stream() + .collect(Collectors.joining("\",\"", "\"", "\"")); + + String body = ""; + String evenCategory = filterkey(filter, Constants.EVENTCATEGORY); + String resourceId = filterkey(filter, Constants.RESOURCEID); + + String eventStatus = filterkey(filter, Constants.EVENTSTATUS); + if(evenCategory.contains("Autofix") && (Strings.isNullOrEmpty(resourceId))) { + getAutofixProjections(index, AUTOFIXTYPE, filter).forEach(autofix -> { + notificationsList.add(autofix); + }); + } + + body = "{\"size\":10000,\"_source\":[\"eventarn\",\"eventtypecode\",\"statuscode\",\"eventregion\",\"starttime\",\"endtime\",\"eventtypecategory\"],\"query\":{\"bool\":{\"must\":[{\"terms\":{\"eventarn.keyword\":[" + + eventArn + "]}},{\"term\":{\"latest\":\"true\"}}"; + if (!Strings.isNullOrEmpty(evenCategory)) { + body = body + ",{\"terms\":{\"eventtypecategory.keyword\":" + evenCategory + "}}"; + } + if (!Strings.isNullOrEmpty(resourceId)) { + body = body + ",{\"terms\":{\"_resourceid.keyword\":" + resourceId + "}}"; + } + if (!Strings.isNullOrEmpty(eventStatus)) { + body = body + ",{\"terms\":{\"statuscode.keyword\":" + eventStatus + "}}"; + } + body = body + "]}},\"sort\":[{\"starttime.keyword\":{\"order\":\"desc\"}}]}}"; + String urlToQuery = esRepository.buildESURL(esUrl, index, type, size, from); + Gson gson = new GsonBuilder().create(); + String responseDetails = null; + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery, new StringBuilder(body).toString()); + } catch (Exception e) { + LOGGER.error("Error in getCloudNotifications", e); + } + Map response = (Map) gson.fromJson(responseDetails, Object.class); + if (response.containsKey(HITS)) { + Map hits = (Map) response.get(HITS); + if (hits.containsKey(HITS)) { + List> hitDetails = (List>) hits.get(HITS); + if (!hitDetails.isEmpty()) { + for (Map hitDetail : hitDetails) { + Map sources = (Map) hitDetail.get(_SOURCE); + Map notifcation = new LinkedHashMap(); + notifcation.put("event", + CommonUtils.capitailizeWord(sources.get("eventtypecode").toString())); + notifcation.put("status", sources.get("statuscode")); + notifcation.put("region", sources.get("eventregion")); + notifcation.put("startTime", sources.get("starttime")); + notifcation.put("endTime", sources.get("endtime")); + if (!index.equalsIgnoreCase("cloud_notifications")) { + notifcation.put("affectedResources", eventArnMap.get(sources.get("eventarn"))); + } + notifcation.put("eventCategory", eventMap.get(sources.get("eventtypecategory"))); + notifcation.put("eventarn", sources.get("eventarn")); + notificationsList.add(notifcation); + } + } + } + } + } catch (Exception e) { + LOGGER.error("Error in getCloudNotifications", e); + } + return notificationsList.stream().distinct().collect(Collectors.toList()); + } + + /* + * (non-Javadoc) + * + * @see com.tmobile.pacman.api.compliance.repository. + * CloudNotificationsRepositoryImpl# getGlobalNotifications(java.lang.String) + */ + @SuppressWarnings("unchecked") + public Map getCloudEventArn(String index, String type, int size, int from) throws DataException { + + Gson gson = new GsonBuilder().create(); + String responseDetails = null; + StringBuilder requestBody = null; + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append("/").append(index).append("/").append(type) + .append("/").append(_SEARCH); + + String body = "{\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}}]}},\"aggs\":{\"name\":{\"terms\":{\"field\":\"eventarn.keyword\",\"size\":1000}}}," + + "\"sort\":[{\"starttime.keyword\":{\"order\":\"desc\"}}]}"; + requestBody = new StringBuilder(body); + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQueryBuffer.toString(), requestBody.toString()); + } catch (Exception e) { + LOGGER.error(ERROR_IN_US, e); + throw new DataException(e); + } + Map response = (Map) gson.fromJson(responseDetails, Map.class); + Map aggregations = (Map) response.get(Constants.AGGREGATIONS); + Map name = (Map) aggregations.get("name"); + List> buckets = (List>) name.get(Constants.BUCKETS); + + return buckets.parallelStream().filter(buket -> buket.get("doc_count") != null) + .collect(Collectors.toMap(buket -> buket.get("key").toString(), buket -> buket.get("doc_count"), + (oldValue, newValue) -> newValue)); + } + + @SuppressWarnings("unchecked") + private long getTotalDocCount(String index, String type, String requestBody) { + StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append(index).append("/").append(type) + .append("/").append(_SEARCH); + String responseDetails = null; + Gson gson = new GsonBuilder().create(); + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), requestBody); + Map response = (Map) gson.fromJson(responseDetails, Map.class); + Map aggregations = (Map) response.get(Constants.AGGREGATIONS); + Map name = (Map) aggregations.get("name"); + List> buckets = (List>) name.get(Constants.BUCKETS); + return (long) (buckets.size()); + } catch (Exception e) { + LOGGER.error("Error in getTotalDocCount", e); + return 0; + } + } + + /** + * Gets the type count. + * + * @param indexName the index name + * @param type the type + * @return the type count + */ + private int getAutoFixSummary(String indexName, String type) { + + StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append(indexName).append("/").append(type) + .append("/").append(_COUNT).append("?filter_path=count"); + String requestBody = "{}"; + String responseDetails = null; + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), requestBody); + JsonParser jsonParser = new JsonParser(); + JsonObject resultJson = (JsonObject) jsonParser.parse(responseDetails); + return resultJson.get("count").getAsInt(); + } catch (Exception e) { + LOGGER.error("Error in getTotalDocCount", e); + return 0; + } + } + + @SuppressWarnings("unchecked") + public List> getAutofixProjections(String index, String type, Map filter) + throws DataException { + List> autofixPlanList = new ArrayList>(); + try { + StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append(index).append("/").append(type) + .append("/").append(_SEARCH); + String body = ""; + body = "{\"size\":10000,\"_source\":[\"docId\",\"planItems\",\"ruleId\",\"issueId\",\"resourceId\",\"resourceType\"]}"; + Gson gson = new GsonBuilder().create(); + String responseDetails = null; + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), new StringBuilder(body).toString()); + } catch (Exception e) { + LOGGER.error("Error in getAutofixProjections", e); + } + Map response = (Map) gson.fromJson(responseDetails, Object.class); + if (response.containsKey(HITS)) { + Map hits = (Map) response.get(HITS); + if (hits.containsKey(HITS)) { + List> hitDetails = (List>) hits.get(HITS); + if (!hitDetails.isEmpty()) { + for (Map hitDetail : hitDetails) { + Map sources = (Map) hitDetail.get(_SOURCE); + Map notifcation = new LinkedHashMap(); + notifcation.put("event", "Aws "+ sources.get("resourceType")+ " Autofix"); + notifcation.put("eventCategory", "Autofix"); + notifcation.put("eventarn", sources.get("resourceId")); + Object planStatus = sources.get("planStatus"); + List> planitems = (List>) sources.get("planItems"); + + if(planitems!=null && !planitems.isEmpty()) { + + notifcation.put("startTime", planitems.get(0).get("plannedActionTime")); + notifcation.put("endTime", planitems.get(planitems.size()-1).get("plannedActionTime")); + + if(planStatus==null) { + planStatus = planitems.get(planitems.size()-1).get("status"); + } + + } + if(planStatus!=null) { + notifcation.put("status",planStatus.toString().toLowerCase()); + + }else { + notifcation.put("status","unknown"); + } + notifcation.put("affectedResources", 1); + autofixPlanList.add(notifcation); + } + } + } + } + Comparator> comp = (m1, m2) -> LocalDate + .parse(m2.get("endTime").toString().substring(0, 10), DateTimeFormatter.ISO_DATE) + .compareTo(LocalDate.parse(m1.get("endTime").toString().substring(0, 10), DateTimeFormatter.ISO_DATE)); + Collections.sort(autofixPlanList, comp); + } catch (Exception e) { + LOGGER.error("Error in getAutofixProjections", e); + } + return autofixPlanList; + } + + @SuppressWarnings("unchecked") + public Map getAutofixProjectionDetail(String ag, Map filter) { + Map autofixPlanDet = new LinkedHashMap(); + autoFixQuery = ""; + try { + StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append(ag).append("/").append(AUTOFIXTYPE) + .append("/").append(_SEARCH); + filter.entrySet().forEach(autofix->{ + autoFixQuery = "{\"size\":1,\"_source\":[\"docId\",\"planItems\",\"ruleId\",\"issueId\",\"resourceId\",\"resourceType\"],\"query\":{\"match\":{\"" + +autofix.getKey()+".keyword"+"\":\"" + +autofix.getValue()+"\"}}}"; + }); + Gson gson = new GsonBuilder().create(); + String responseDetails = null; + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), new StringBuilder(autoFixQuery).toString()); + } catch (Exception e) { + LOGGER.error("Error in getAutofixProjectionDetail", e); + } + Map response = (Map) gson.fromJson(responseDetails, Object.class); + if (response.containsKey(HITS)) { + Map hits = (Map) response.get(HITS); + if (hits.containsKey(HITS)) { + List> hitDetails = (List>) hits.get(HITS); + if (!hitDetails.isEmpty()) { + for (Map hitDetail : hitDetails) { + Map sources = (Map) hitDetail.get(_SOURCE); + autofixPlanDet.put("event", "Aws "+ sources.get("resourceType")+ " Autofix"); + + autofixPlanDet.put("eventCategory", "Autofix"); + autofixPlanDet.put("eventarn", sources.get("resourceId")); + autofixPlanDet.put("planItems", sources.get("planItems")); + autofixPlanDet.put("issueId", sources.get("issueId")); + autofixPlanDet.put("resourceId", sources.get("resourceId")); + autofixPlanDet.put("ruleId", sources.get("ruleId")); + autofixPlanDet.put("resourceType", sources.get("resourceType")); + List> planitems = (List>) sources.get("planItems"); + planitems.get(0).entrySet().forEach(item -> { + if ("plannedActionTime".equalsIgnoreCase(item.getKey())) { + autofixPlanDet.put("startTime", item.getValue()); + } + if ("status".equalsIgnoreCase(item.getKey())) { + autofixPlanDet.put("status", item.getValue().toString().toLowerCase()); + } + }); + planitems.get(3).entrySet().forEach(item -> { + if ("plannedActionTime".equalsIgnoreCase(item.getKey())) { + autofixPlanDet.put("endTime", item.getValue()); + } + if ("status".equalsIgnoreCase(item.getKey())) { + autofixPlanDet.put("status", item.getValue().toString().toLowerCase()); + } + }); + + List> ruleDetails = new ArrayList>(); + try { + ruleDetails = rdsRepository.getDataFromPacman("SELECT displayName, policyId FROM cf_RuleInstance WHERE ruleId =\""+sources.get("ruleId")+"\""); + autofixPlanDet.put("ruleName", ruleDetails.get(0).get("displayName")); + } catch (Exception exception) { + LOGGER.error("Error in getAutofixProjectionDetail for getting rule displayName " , exception); + } + try { + autofixPlanDet.put("ruleDescription", rdsRepository.queryForString("select policyDesc from cf_Policy WHERE policyId =\""+ruleDetails.get(0).get("policyId")+"\"")); + } catch (Exception exception) { + LOGGER.error("Error in getAutofixProjectionDetail for getting rule description " , exception); + } + } + } + } + } + } catch (Exception e) { + LOGGER.error("Error in getAutofixProjectionDetail", e); + } + return autofixPlanDet; + } + + private String filterkey(Map filter, String keyText) { + String searchterm = ""; + if (filter.containsKey(keyText) + && StringUtils.isNotBlank(filter.get(keyText))) { + searchterm = "["; + String[] splitted = filter.get(keyText).split(","); + for (String _categoryList : splitted) { + searchterm = searchterm + "\"" + _categoryList + "\","; + } + searchterm = StringUtils.substring(searchterm, 0, searchterm.length() - 1); + searchterm = searchterm + "]"; + } + return searchterm; + } + + @Override + @SuppressWarnings("unchecked") + public List> getCloudNotificationsSummary(String assetGroup, boolean globalNotifier, + String resourceId, String eventStatus) { + LOGGER.info("Inside getCloudNotificationsSummary"); + List> summaryList = new ArrayList<>(); + try { + Map countMap = new HashMap<>(); + if (globalNotifier && Strings.isNullOrEmpty(resourceId) && Strings.isNullOrEmpty(resourceId)) { + countMap.put("globalNotificationsCount", getTotalDocCount("cloud_notifications", "cloud_notification", + "{\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}}]}},\"aggs\":{\"name\":{\"terms\":{\"field\":\"eventarn.keyword\",\"size\":1000}}}}")); + countMap.put("evnetIssuesCount", getTotalDocCount("cloud_notifications", "cloud_notification", + "{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}},{\"match\": {\"eventtypecategory.keyword\": \"issue\"}}]}},\"aggs\":{\"name\":{\"terms\":{\"field\":\"eventarn.keyword\",\"size\":1000}}}}")); + countMap.put("eventscheduledCount", getTotalDocCount("cloud_notifications", "cloud_notification", + "{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}},{\"match\": {\"eventtypecategory.keyword\": \"scheduledChange\"}}]}},\"aggs\":{\"name\":{\"terms\":{\"field\":\"eventarn.keyword\",\"size\":1000}}}}")); + countMap.put("eventNotificationCount", getTotalDocCount("cloud_notifications", "cloud_notification", + "{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}},{\"match\": {\"eventtypecategory.keyword\": \"accountNotification\"}}]}},\"aggs\":{\"name\":{\"terms\":{\"field\":\"eventarn.keyword\",\"size\":1000}}}}")); + countMap.put("autofixCount", 0); + summaryList.add(countMap); + } else { + if(!Strings.isNullOrEmpty(resourceId) && !Strings.isNullOrEmpty(resourceId) && !globalNotifier) { + String body = "{\"size\": 1,\"_source\":\"eventtypecategory\",\"query\":{\"bool\":{\"must\":[{\"term\":{\"_resourceid.keyword\":\"" + + resourceId +"\"}},{\"term\":{\"statuscode.keyword\":\"" + + eventStatus +"\"}}]}}}"; + StringBuilder urlToQuery = new StringBuilder(esUrl).append("/").append(assetGroup).append("/").append(TYPE) + .append("/").append(_SEARCH); + Gson gson = new GsonBuilder().create(); + String responseDetails = null; + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), new StringBuilder(body).toString()); + } catch (Exception e) { + LOGGER.error("Error in getAutofixProjectionDetail", e); + } + Map response = (Map) gson.fromJson(responseDetails, Object.class); + if (response.containsKey(HITS)) { + Map hits = (Map) response.get(HITS); + if (hits.containsKey(HITS)) { + List> hitDetails = (List>) hits.get(HITS); + if (!hitDetails.isEmpty()) { + for (Map hitDetail : hitDetails) { + Map sources = (Map) hitDetail.get(_SOURCE); + String eventType = sources.get("eventtypecategory").toString(); + switch (eventType) { + case "scheduledChange": + countMap.put("globalNotificationsCount", 0); + countMap.put("evnetIssuesCount", 0); + countMap.put("eventscheduledCount", sources.size()); + countMap.put("eventNotificationCount", 0); + countMap.put("autofixCount", 0); + summaryList.add(countMap); + break; + case "issue": + countMap.put("globalNotificationsCount", 0); + countMap.put("evnetIssuesCount", sources.size()); + countMap.put("eventscheduledCount", 0); + countMap.put("eventNotificationCount", 0); + countMap.put("autofixCount", 0); + summaryList.add(countMap); + break; + case "accountNotification": + countMap.put("globalNotificationsCount", 0); + countMap.put("evnetIssuesCount", 0); + countMap.put("eventscheduledCount", 0); + countMap.put("eventNotificationCount", sources.size()); + countMap.put("autofixCount", 0); + summaryList.add(countMap); + break; + default: + } + } + } + } + } + } else if(!Strings.isNullOrEmpty(resourceId) && !Strings.isNullOrEmpty(resourceId) && globalNotifier) { + countMap.put("globalNotificationsCount", 0); + countMap.put("evnetIssuesCount", 0); + countMap.put("eventscheduledCount", 0); + countMap.put("eventNotificationCount", 0); + countMap.put("autofixCount", 0); + summaryList.add(countMap); + } else { + countMap.put("globalNotificationsCount", getTotalDocCount("cloud_notifications", "cloud_notification", + "{\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}}]}},\"aggs\":{\"name\":{\"terms\":{\"field\":\"eventarn.keyword\",\"size\":1000}}}}")); + countMap.put("evnetIssuesCount", getTotalDocCount(assetGroup, "cloud_notification", + "{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}},{\"match\": {\"eventtypecategory.keyword\": \"issue\"}}]}},\"aggs\":{\"name\":{\"terms\":{\"field\":\"eventarn.keyword\",\"size\":1000}}}}")); + countMap.put("eventscheduledCount", getTotalDocCount(assetGroup, "cloud_notification", + "{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}},{\"match\": {\"eventtypecategory.keyword\": \"scheduledChange\"}}]}},\"aggs\":{\"name\":{\"terms\":{\"field\":\"eventarn.keyword\",\"size\":1000}}}}")); + countMap.put("eventNotificationCount", getTotalDocCount(assetGroup, "cloud_notification", + "{\"size\":0,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":true}},{\"match\": {\"eventtypecategory.keyword\": \"accountNotification\"}}]}},\"aggs\":{\"name\":{\"terms\":{\"field\":\"eventarn.keyword\",\"size\":1000}}}}")); + countMap.put("autofixCount", getAutoFixSummary(assetGroup, "autofixplan")); + summaryList.add(countMap); + } + } + } catch (Exception e) { + LOGGER.error("Error in getCloudNotificationsSummary", e); + } + LOGGER.info("Exiting getCloudNotificationsSummary"); + return summaryList; + } +} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CloudNotificationService.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CloudNotificationService.java new file mode 100644 index 000000000..e7ff5868a --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CloudNotificationService.java @@ -0,0 +1,16 @@ +package com.tmobile.pacman.api.asset.service; + +import java.util.List; +import java.util.Map; + +/** + * This is the main interface for cloud notifications service which contains business logics and method calls to repository + */ +public interface CloudNotificationService { + + public List> getNotifications(String assetGroup, Map filter, boolean globalNotifier, int size, int from); + public List> getCloudNotificationsSummary(String assetGroup, boolean globalNotifier, String resourceId, String eventStatus); + public List> getCloudNotificationDetail(String eventArn, boolean globalNotifier, String assetGroup); + public Map getCloudNotificationInfo(String eventArn, boolean globalNotifier, String assetGroup); + public Map getAutofixProjectionDetail(String assetGroup, Map filter); +} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CloudNotificationServiceImpl.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CloudNotificationServiceImpl.java new file mode 100644 index 000000000..ef6cca5b0 --- /dev/null +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/CloudNotificationServiceImpl.java @@ -0,0 +1,46 @@ +package com.tmobile.pacman.api.asset.service; + +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.tmobile.pacman.api.asset.repository.CloudNotificationsRepository; + +/** + * Implemented class for CloudNotificationService and all its method + */ +@Service +public class CloudNotificationServiceImpl implements CloudNotificationService { + + @Autowired + private CloudNotificationsRepository repository; + + @Override + public List> getNotifications(String assetGroup, Map filter, + boolean globalNotifier, int size, int from) { + return repository.getNotifications(assetGroup, filter, globalNotifier, size, from); + } + + @Override + public List> getCloudNotificationsSummary(String assetGroup, boolean globalNotifier, String resourceId, String eventStatus) { + return repository.getCloudNotificationsSummary(assetGroup, globalNotifier, resourceId, eventStatus); + } + + @Override + public List> getCloudNotificationDetail(String eventArn, boolean globalNotifier, String assetGroup) { + return repository.getCloudNotificationDetail(eventArn, globalNotifier, assetGroup); + } + + @Override + public Map getCloudNotificationInfo(String eventArn, boolean globalNotifier, String assetGroup) { + return repository.getCloudNotificationInfo(eventArn, globalNotifier, assetGroup); + } + + @Override + public Map getAutofixProjectionDetail(String assetGroup, Map filter) { + return repository.getAutofixProjectionDetail(assetGroup, filter); + } + +} diff --git a/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/Constants.java b/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/Constants.java index 9ae17b45d..048e2b292 100644 --- a/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/Constants.java +++ b/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/Constants.java @@ -290,5 +290,8 @@ public interface Constants { String ERROR_MESSAGE = "errorMessage"; String ERROR_DETAILS = "errorDetails"; String PROVIDER = "provider"; + String EVENTCATEGORY = "eventtypecategory"; + String EVENTSTATUS = "eventstatus"; + String FILTER_MANDATORY = "Filter is mandatory, pass the resourceid/docid/issueid/planid"; } diff --git a/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/repo/ElasticSearchRepository.java b/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/repo/ElasticSearchRepository.java index c8e2bacb2..223d3526e 100644 --- a/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/repo/ElasticSearchRepository.java +++ b/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/repo/ElasticSearchRepository.java @@ -1,1619 +1,1636 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ -/** - Copyright (C) 2017 T Mobile Inc - All Rights Reserve - Purpose: - Author :kkumar - Modified Date: Oct 17, 2017 - - **/ -package com.tmobile.pacman.api.commons.repo; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.PostConstruct; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Repository; - -import com.google.common.base.Strings; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.tmobile.pacman.api.commons.Constants; -import com.tmobile.pacman.api.commons.utils.CommonUtils; -import com.tmobile.pacman.api.commons.utils.PacHttpUtils; - -@Repository -public class ElasticSearchRepository implements Constants { - - /** - * - */ - private static final String AVG = "avg"; - /** - * - */ - private static final String SUM = "sum"; - /** - * - */ - private static final String SUM_NETWORK_OUT = "Sum-NetworkOut"; - /** - * - */ - private static final String SUM_NETWORK_IN = "Sum-NetworkIn"; - /** - * - */ - private static final String AVG_CPU_UTILIZATION = "Avg-CPU-Utilization"; - /** - * - */ - private static final String NO_RECORDS_FOUND = "No records found!"; - /** - * - */ - private static final String HITS = "hits"; - /** - * - */ - private static final String ORDER = "order"; - /** - * - */ - private static final String EC2_UTILIZATION = "ec2_utilization"; - /** - * - */ - private static final String AGGS = "aggs"; - /** - * - */ - private static final String FORWARD_SLASH = "/"; - /** - * - */ - private static final String _COUNT = "_count"; - /** - * - */ - private static final String MATCH_PHRASE_PREFIX = "match_phrase_prefix"; - /** - * - */ - private static final String _ALL = "_all"; - /** - * - */ - private static final String MATCH = "match"; - /** - * - */ - private static final String MINIMUM_SHOULD_MATCH = "minimum_should_match"; - /** - * - */ - private static final String BOOL = "bool"; - /** - * - */ - private static final String SHOULD = "should"; - /** - * - */ - private static final String MUST_NOT = "must_not"; - /** - * - */ - private static final String MUST = "must"; - /** - * - */ - private static final String RANGE = "range"; - /** - * - */ - private static final String TERM = "term"; - /** - * - */ - private static final String TERMS = "terms"; - /** - * - */ - private static final String ERROR_RETRIEVING_INVENTORY_FROM_ES = "error retrieving inventory from ES"; - /** - * - */ - private static final String HAS_PARENT = "has_parent"; - /** - * - */ - private static final String HAS_CHILD = "has_child"; - /** - * - */ - private static final String _SOURCE = "_source"; - /** - * - */ - private static final String SORT = "sort"; - /** - * - */ - private static final String QUERY = "query"; - /** - * - */ - private static final String SIZE = "size"; - /** - * - */ - private static final String _SEARCH = "_search"; - @Value("${elastic-search.host}") - private String esHost; - @Value("${elastic-search.port}") - private int esPort; - - final static String protocol = "http"; - - private String esUrl; - - private static final Log LOGGER = LogFactory.getLog(ElasticSearchRepository.class); - - @PostConstruct - void init() { - esUrl = protocol + "://" + esHost + ":" + esPort; - } - - /** - * - * @param dataSource - * @param targetType - * @param mustFilter - * @param mustNotFilter - * @param shouldFilter - * @param fields - * @return - * @throws Exception - * @deprecated - */ - @SuppressWarnings("unchecked") - @Deprecated - public List> getDataFromES(String dataSource, String targetType, Map mustFilter, - final Map mustNotFilter, final HashMultimap shouldFilter, - List fields, Map mustTermsFilter) throws Exception { - - Long totalDocs = getTotalDocumentCountForIndexAndType(dataSource, targetType, mustFilter, mustNotFilter, - shouldFilter, null, mustTermsFilter); - // if filter is not null apply filter, this can be a multi value filter - // also if from and size are -1 -1 send all the data back and do not - // paginate - StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(dataSource); - if (!Strings.isNullOrEmpty(targetType)) { - urlToQueryBuffer.append(FORWARD_SLASH).append(targetType); - } - urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); - - String urlToQuery = urlToQueryBuffer.toString(); - // paginate for breaking the response into smaller chunks - Map requestBody = new HashMap(); - requestBody.put(SIZE, ES_PAGE_SIZE); - if (totalDocs < ES_PAGE_SIZE) { - requestBody.put(SIZE, totalDocs); - } - requestBody.put(QUERY, buildQuery(mustFilter, mustNotFilter, shouldFilter, null, mustTermsFilter,null)); - requestBody.put(_SOURCE, fields); - Gson serializer = new GsonBuilder().disableHtmlEscaping().create(); - String request = serializer.toJson(requestBody); - - return prepareResultsUsingScroll(0, totalDocs, urlToQuery, request); - } - - /** - * - * @param dataSource - * @param targetType - * @param mustFilter - * @param mustNotFilter - * @param shouldFilter - * @param fields - * @return - * @throws Exception - */ - @SuppressWarnings("unchecked") - public List> getSortedDataFromES(String dataSource, String targetType, - Map mustFilter, final Map mustNotFilter, - final HashMultimap shouldFilter, List fields, Map mustTermsFilter, - List> sortFieldMapList) throws Exception { - - Long totalDocs = getTotalDocumentCountForIndexAndType(dataSource, targetType, mustFilter, mustNotFilter, - shouldFilter, null, mustTermsFilter); - // if filter is not null apply filter, this can be a multi value filter - // also if from and size are -1 -1 send all the data back and do not - // paginate - StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(dataSource); - if (!Strings.isNullOrEmpty(targetType)) { - urlToQueryBuffer.append(FORWARD_SLASH).append(targetType); - } - urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); - - String urlToQuery = urlToQueryBuffer.toString(); - // paginate for breaking the response into smaller chunks - Map requestBody = new HashMap(); - requestBody.put(SIZE, ES_PAGE_SIZE); - if (totalDocs < ES_PAGE_SIZE) { - requestBody.put(SIZE, totalDocs); - } - requestBody.put(QUERY, buildQuery(mustFilter, mustNotFilter, shouldFilter, null, mustTermsFilter,null)); - - if (null != sortFieldMapList && !sortFieldMapList.isEmpty()) { - requestBody.put(SORT, sortFieldMapList); - } - requestBody.put(_SOURCE, fields); - Gson serializer = new GsonBuilder().disableHtmlEscaping().create(); - String request = serializer.toJson(requestBody); - - return prepareResultsUsingScroll(0, totalDocs, urlToQuery, request); - } - - /** - * - * @param from - * @param size - * @param urlToQuery - * @param request - * @return - * @throws Exception - */ - private List> prepareResultsUsingScroll(long from, long size, String urlToQuery, String request) - throws Exception { - String scrollId = null; - List> results = new ArrayList<>(); - - urlToQuery = urlToQuery + "?scroll=" + ES_PAGE_SCROLL_TTL; - - String urlToScroll = new StringBuilder(esUrl).append(FORWARD_SLASH).append(_SEARCH).append("/scroll") - .toString(); - - for (int index = 0; index <= ((from + size) / ES_PAGE_SIZE); index++) { - String responseDetails = null; - try { - if (!Strings.isNullOrEmpty(scrollId)) { - request = buildScrollRequest(scrollId, ES_PAGE_SCROLL_TTL); - urlToQuery = urlToScroll; - } - responseDetails = PacHttpUtils.doHttpPost(urlToQuery, request); - scrollId = processResponseAndSendTheScrollBack(responseDetails, results); - } catch (Exception e) { - LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); - throw e; - } - - } - - int to = (int) (from + size); - if (to > results.size()) { - to = results.size(); // If the size passed is greater than actual - // size.. - } - results = results.subList((int) from, to); - return results; - } - - /** - * - * @param distributionName - * @param size - * @return - */ - private Map buildAggs(String distributionName, int size) { - Map name = new HashMap(); - if (!Strings.isNullOrEmpty(distributionName)) { - Map terms = new HashMap(); - Map termDetails = new HashMap(); - termDetails.put("field", distributionName); - if (size > 0) { - termDetails.put(SIZE, size); - } - terms.put(TERMS, termDetails); - name.put("name", terms); - } - return name; - } - - /** - * - * @param filter - * @return elastic search query details - */ - public Map buildQuery(final Map mustFilter, final Map mustNotFilter, - final HashMultimap shouldFilter, final String searchText, - final Map mustTermsFilter,Map> matchPhrasePrefix) { - - Map queryFilters = Maps.newHashMap(); - Map boolFilters = Maps.newHashMap(); - - Map hasChildObject = null; - Map hasParentObject = null; - - if (isNotNullOrEmpty(mustFilter)) { - if (mustFilter.containsKey(HAS_CHILD)) { - hasChildObject = (Map) mustFilter.get(HAS_CHILD); - mustFilter.remove(HAS_CHILD); - } - if (mustFilter.containsKey(HAS_PARENT)) { - hasParentObject = (Map) mustFilter.get(HAS_PARENT); - mustFilter.remove(HAS_PARENT); - } - } - - if (isNotNullOrEmpty(mustFilter) && (!Strings.isNullOrEmpty(searchText))) { - - List> must = getFilter(mustFilter, mustTermsFilter,matchPhrasePrefix); - Map match = Maps.newHashMap(); - Map all = Maps.newHashMap(); - // If the string is enclosed in quotes, do a match phrase instead of - // match - if (searchText.startsWith("\"") && searchText.endsWith("\"")) { - all.put(_ALL, searchText.substring(1, searchText.length() - 1)); - match.put(MATCH_PHRASE_PREFIX, all); - } else { - all.put(_ALL, searchText); - match.put(MATCH, all); - } - must.add(match); - boolFilters.put(MUST, must); - } else if (isNotNullOrEmpty(mustFilter)) { - boolFilters.put(MUST, getFilter(mustFilter, mustTermsFilter,matchPhrasePrefix)); - } - - if (isNotNullOrEmpty(mustFilter)) { - - Map hasChildMap = Maps.newHashMap(); - Map hasParentMap = Maps.newHashMap(); - - List> must = (List>) boolFilters.get(MUST); - - if (null != hasChildObject) { - hasChildMap.put(HAS_CHILD, hasChildObject); - must.add(hasChildMap); - } - if (null != hasParentObject) { - hasParentMap.put(HAS_PARENT, hasParentObject); - must.add(hasParentMap); - } - - } - - if (isNotNullOrEmpty(mustNotFilter)) { - - boolFilters.put(MUST_NOT, getFilter(mustNotFilter, null,null)); - } - if (isNotNullOrEmpty(shouldFilter)) { - - boolFilters.put(SHOULD, getFilter(shouldFilter)); - boolFilters.put(MINIMUM_SHOULD_MATCH, 1); - } - queryFilters.put(BOOL, boolFilters); - return queryFilters; - } - - /** - * - * @param shouldFilter - * @return - */ - private boolean isNotNullOrEmpty(HashMultimap shouldFilter) { - - return shouldFilter != null && shouldFilter.size() > 0; - } - - /** - * - * @param collection - * @return - */ - private boolean isNotNullOrEmpty(Map collection) { - - return collection != null && collection.size() > 0; - } - - /** - * - * @param mustfilter - * @return - */ - private List> getFilter(final Map mustfilter, - final Map mustTerms, - Map> matchPhrasePrefix) { - List> finalFilter = Lists.newArrayList(); - for (Map.Entry entry : mustfilter.entrySet()) { - Map term = Maps.newHashMap(); - Map termDetails = Maps.newHashMap(); - termDetails.put(entry.getKey(), entry.getValue()); - if (RANGE.equals(entry.getKey())) { - term.put(RANGE, entry.getValue()); - } else { - term.put(TERM, termDetails); - } - finalFilter.add(term); - } - if (mustTerms != null && !mustTerms.isEmpty()) { - if (mustTerms.size() == 1) { - Map term = Maps.newHashMap(); - term.put(TERMS, mustTerms); - finalFilter.add(term); - } else { - mustTerms.forEach((key, value) -> { - Map innerMustTermsMap = new HashMap<>(); - innerMustTermsMap.put(key, value); - Map term = Maps.newHashMap(); - term.put(TERMS, innerMustTermsMap); - finalFilter.add(term); - }); - } - } - - if (matchPhrasePrefix != null && !matchPhrasePrefix.isEmpty()) { - - for (Map.Entry> entry : matchPhrasePrefix - .entrySet()) { - List infoList = new ArrayList(); - infoList.add(entry.getValue()); - - for (Object val : entry.getValue()) { - Map map = new HashMap(); - Map matchPhrasePrefixMap = Maps - .newHashMap(); - map.put(entry.getKey(), val); - matchPhrasePrefixMap.put("match_phrase_prefix", map); - finalFilter.add(matchPhrasePrefixMap); - } - - } - } - - return finalFilter; - } - - /** - * - * @param filter - * @return - */ - private List> getFilter(final HashMultimap filter) { - List> finalFilter = Lists.newArrayList(); - for (Map.Entry entry : filter.entries()) { - Map term = Maps.newHashMap(); - Map termDetails = Maps.newHashMap(); - termDetails.put(entry.getKey(), entry.getValue()); - term.put(TERM, termDetails); - finalFilter.add(term); - } - return finalFilter; - } - - /** - * - * @param scrollId - * @param esPageScrollTtl - * @return - */ - public String buildScrollRequest(String scrollId, String esPageScrollTtl) { - Map requestBody = new HashMap(); - requestBody.put("scroll", ES_PAGE_SCROLL_TTL); - requestBody.put("scroll_id", scrollId); - Gson serializer = new GsonBuilder().create(); - return serializer.toJson(requestBody); - } - - /** - * - * @param responseDetails - * @param results - * @return - */ - public String processResponseAndSendTheScrollBack(String responseDetails, List> results) { - Gson serializer = new GsonBuilder().create(); - Map response = (Map) serializer.fromJson(responseDetails, Object.class); - if (response.containsKey(HITS)) { - Map hits = (Map) response.get(HITS); - if (hits.containsKey(HITS)) { - List> hitDetails = (List>) hits.get(HITS); - for (Map hitDetail : hitDetails) { - Map sources = (Map) hitDetail.get(_SOURCE); - sources.put(ES_DOC_ID_KEY, hitDetail.get(ES_DOC_ID_KEY)); - sources.put(ES_DOC_PARENT_KEY, hitDetail.get(ES_DOC_PARENT_KEY)); - sources.put(ES_DOC_ROUTING_KEY, hitDetail.get(ES_DOC_ROUTING_KEY)); - results.add(CommonUtils.flatNestedMap(null, sources)); - } - } - } - return (String) response.get("_scroll_id"); - } - - /** - * - * @param elastic - * search url - * @param index - * name - * @param type - * name - * @param shouldFilter - * @param mustNotFilter - * @param filters - * @return elastic search count - */ - @SuppressWarnings("unchecked") - public long getTotalDocumentCountForIndexAndType(String index, String type, Map mustFilter, - Map mustNotFilter, HashMultimap shouldFilter, String searchText, - Map mustTermsFilter) throws Exception { - - String urlToQuery = buildCountURL(esUrl, index, type); - - Map requestBody = new HashMap(); - Map matchFilters = Maps.newHashMap(); - if (mustFilter == null) { - matchFilters.put("match_all", new HashMap()); - } else { - matchFilters.putAll(mustFilter); - } - if (null != mustFilter) { - requestBody.put(QUERY, buildQuery(matchFilters, mustNotFilter, shouldFilter, searchText, mustTermsFilter,null)); - } else { - requestBody.put(QUERY, matchFilters); - } - String responseDetails = null; - Gson gson = new GsonBuilder().create(); - try { - - String requestJson = gson.toJson(requestBody, Object.class); - responseDetails = PacHttpUtils.doHttpPost(urlToQuery, requestJson); - Map response = (Map) gson.fromJson(responseDetails, Object.class); - return (long) (Double.parseDouble(response.get(COUNT).toString())); - } catch (Exception e) { - LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); - throw e; - } - } - - /** - * - * @param url - * @param index - * @param type - * @return - */ - private String buildCountURL(String url, String index, String type) { - - StringBuilder urlToQuery = new StringBuilder(url).append(FORWARD_SLASH).append(index); - if (!Strings.isNullOrEmpty(type)) { - urlToQuery.append(FORWARD_SLASH).append(type); - } - urlToQuery.append(FORWARD_SLASH).append(_COUNT); - return urlToQuery.toString(); - } - - /** - * - * @param index - * @param type - * @param mustFilter - * @param mustNotFilter - * @param shouldFilter - * @param aggsFilter - * @param size - * @param mustTermsFilter - * @return - * @throws Exception - */ - public Map getTotalDistributionForIndexAndType(String index, String type, - Map mustFilter, Map mustNotFilter, - HashMultimap shouldFilter, String aggsFilter, int size, Map mustTermsFilter) - throws Exception { - - String urlToQuery = buildAggsURL(esUrl, index, type); - Map requestBody = new HashMap(); - Map matchFilters = Maps.newHashMap(); - Map distribution = new HashMap(); - if (mustFilter == null) { - matchFilters.put("match_all", new HashMap()); - } else { - matchFilters.putAll(mustFilter); - } - if (null != mustFilter) { - requestBody.put(QUERY, buildQuery(matchFilters, mustNotFilter, shouldFilter, null, mustTermsFilter,null)); - requestBody.put(AGGS, buildAggs(aggsFilter, size)); - - if (!Strings.isNullOrEmpty(aggsFilter)) { - requestBody.put(SIZE, "0"); - } - - } else { - requestBody.put(QUERY, matchFilters); - } - String responseDetails = null; - Gson gson = new GsonBuilder().create(); - - try { - String requestJson = gson.toJson(requestBody, Object.class); - responseDetails = PacHttpUtils.doHttpPost(urlToQuery, requestJson); - Map response = (Map) gson.fromJson(responseDetails, Map.class); - Map aggregations = (Map) response.get(AGGREGATIONS); - Map name = (Map) aggregations.get(NAME); - List> buckets = (List>) name.get(BUCKETS); - - for (int i = 0; i < buckets.size(); i++) { - Map bucket = buckets.get(i); - distribution.put(bucket.get("key").toString(), ((Double) bucket.get("doc_count")).longValue()); - } - - } catch (Exception e) { - LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); - throw e; - } - return distribution; - } - - /** - * - * @param url - * @param index - * @param type - * @return - */ - private String buildAggsURL(String url, String index, String type) { - - StringBuilder urlToQuery = new StringBuilder(url).append(FORWARD_SLASH).append(index); - if (!Strings.isNullOrEmpty(type)) { - urlToQuery.append(FORWARD_SLASH).append(type); - } - urlToQuery.append(FORWARD_SLASH).append("_search/?size=0"); - return urlToQuery.toString(); - } - - /** - * - * @param asseGroup - * @return - * @throws Exception - */ - public List> getUtilizationByAssetGroup(String asseGroup) throws Exception { - String urlToQuery = buildAggsURL(esUrl, asseGroup, EC2_UTILIZATION); - Map requestBody = new HashMap(); - Map cpuUtilizationDetails = new HashMap(); - Map cpuUtilization = new HashMap(); - Map range = new HashMap(); - Map must = new HashMap(); - Map bool = new HashMap(); - Map aggs = new HashMap(); - Map histogram = new HashMap(); - Map histogramDetails = new HashMap(); - Map avgValuesperDay = new HashMap(); - List> utilizationList = new ArrayList>(); - Map utilization = null; - Map field = null; - Map sum = null; - Map avg = null; - // must Query formate - cpuUtilizationDetails.put("gte", "now-30d"); - cpuUtilizationDetails.put("lte", "now-1d"); - cpuUtilizationDetails.put("format", "yyyy-MM-dd HH:mm:ss"); - cpuUtilization.put("#Datetime-CPU-Utilization", cpuUtilizationDetails); - range.put(RANGE, cpuUtilization); - must.put(MUST, range); - bool.put(BOOL, must); - // Aggs Query foramte - - field = new HashMap(); - avg = new HashMap(); - field.put("field", AVG_CPU_UTILIZATION); - avg.put(AVG, field); - aggs.put(AVG_CPU_UTILIZATION, avg); - - field = new HashMap(); - sum = new HashMap(); - field.put("field", SUM_NETWORK_IN); - sum.put(SUM, field); - aggs.put("Avg-NetworkIn", sum); - - field = new HashMap(); - sum = new HashMap(); - field.put("field", SUM_NETWORK_OUT); - sum.put(SUM, field); - aggs.put("Avg-NetworkOut", sum); - - field = new HashMap(); - sum = new HashMap(); - field.put("field", "Sum-DiskReadBytes"); - sum.put(SUM, field); - aggs.put("Avg-DiskReadinBytes", sum); - - field = new HashMap(); - sum = new HashMap(); - field.put("field", "Sum-DiskWriteBytes"); - sum.put(SUM, field); - aggs.put("Avg-DiskWriteinBytes", sum); - - field = new HashMap(); - field.put("_key", "desc"); - histogramDetails.put("field", "#Datetime-CPU-Utilization"); - histogramDetails.put("interval", "day"); - histogramDetails.put("format", "yyyy-MM-dd HH:mm:ss"); - histogramDetails.put(ORDER, field); - histogram.put("date_histogram", histogramDetails); - histogram.put(AGGS, aggs); - avgValuesperDay.put("avg-values-per-day", histogram); - - requestBody.put(QUERY, bool); - requestBody.put(AGGS, avgValuesperDay); - requestBody.put(SIZE, 0); - - Gson gson = new GsonBuilder().create(); - - try { - String request = gson.toJson(requestBody, Object.class); - String responseDetails = null; - - responseDetails = PacHttpUtils.doHttpPost(urlToQuery, request); - - JsonParser parser = new JsonParser(); - JsonObject responseDetailsjson = parser.parse(responseDetails).getAsJsonObject(); - responseDetailsjson.get("aggregations"); - Object aggregations = responseDetailsjson.get("aggregations"); - String aggregationsstr = aggregations.toString(); - parser = new JsonParser(); - JsonObject aggregationsjson = (JsonObject) parser.parse(aggregationsstr); - Object avgvalues = aggregationsjson.get("avg-values-per-day"); - String avgvaluestr = avgvalues.toString(); - parser = new JsonParser(); - JsonObject avgvaluesjson = (JsonObject) parser.parse(avgvaluestr); - Object bucketObj = avgvaluesjson.get(BUCKETS); - String bucketstr = bucketObj.toString(); - parser = new JsonParser(); - JsonArray buckets = parser.parse(bucketstr).getAsJsonArray(); - - for (JsonElement jsonElement : buckets) { - utilization = new HashMap(); - - JsonObject bucketdetails = jsonElement.getAsJsonObject(); - utilization.put(DATE, bucketdetails.get("key_as_string").getAsString()); - - Object cpuUtilizationObj = bucketdetails.get(AVG_CPU_UTILIZATION); - String cpuUtilizationStr = cpuUtilizationObj.toString(); - parser = new JsonParser(); - JsonObject cpuUtilizationjson = (JsonObject) parser.parse(cpuUtilizationStr); - if (!cpuUtilizationjson.get("value").isJsonNull()) { - utilization.put(CPU_UTILIZATION, cpuUtilizationjson.get("value").getAsDouble()); - } else { - utilization.put(CPU_UTILIZATION, 0); - } - Object networkInUtilizationObj = bucketdetails.get("Avg-NetworkIn"); - String networkInUtilizationStr = networkInUtilizationObj.toString(); - parser = new JsonParser(); - JsonObject networkInUtilizationjson = (JsonObject) parser.parse(networkInUtilizationStr); - if (!networkInUtilizationjson.get("value").isJsonNull()) { - utilization.put(NETWORK_IN, networkInUtilizationjson.get("value").getAsLong()); - } else { - utilization.put(NETWORK_IN, 0); - } - Object networkOutUtilizationObj = bucketdetails.get("Avg-NetworkOut"); - String networkOutUtilizationStr = networkOutUtilizationObj.toString(); - parser = new JsonParser(); - JsonObject networkOutUtilizationjson = (JsonObject) parser.parse(networkOutUtilizationStr); - if (!networkOutUtilizationjson.get("value").isJsonNull()) { - utilization.put(NETWORK_OUT, networkOutUtilizationjson.get("value").getAsLong()); - } else { - utilization.put(NETWORK_OUT, 0); - } - Object diskReadUtilizationObj = bucketdetails.get("Avg-DiskReadinBytes"); - String diskReadUtilizationStr = diskReadUtilizationObj.toString(); - parser = new JsonParser(); - JsonObject diskReadUtilizationjson = (JsonObject) parser.parse(diskReadUtilizationStr); - if (!diskReadUtilizationjson.get("value").isJsonNull()) { - utilization.put(DISK_READ_IN_BYTES, diskReadUtilizationjson.get("value").getAsLong()); - } else { - utilization.put(DISK_READ_IN_BYTES, 0); - } - Object diskRWriteUtilizationObj = bucketdetails.get("Avg-DiskWriteinBytes"); - String diskRWriteUtilizationStr = diskRWriteUtilizationObj.toString(); - parser = new JsonParser(); - JsonObject diskRWriteUtilizationjson = (JsonObject) parser.parse(diskRWriteUtilizationStr); - if (!diskRWriteUtilizationjson.get("value").isJsonNull()) { - utilization.put(DISK_WRITE_IN_BYTES, diskRWriteUtilizationjson.get("value").getAsLong()); - } else { - utilization.put(DISK_WRITE_IN_BYTES, 0); - } - utilizationList.add(utilization); - } - return utilizationList; - - } catch (Exception e) { - LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); - throw e; - } - } - - /** - * - * @param dataSource - * @param targetType - * @param mustFilter - * @param mustNotFilter - * @param shouldFilter - * @param fields - * @param from - * @param size - * @param searchText - * @param mustTermsFilter - * @return - * @throws Exception - * @deprecated - */ - @Deprecated - public List> getDataFromESBySize(String dataSource, String targetType, - final Map mustFilter, final Map mustNotFilter, - final HashMultimap shouldFilter, List fields, int from, int size, String searchText, - final Map mustTermsFilter) throws Exception { - if (size <= 0) { - size = (int) getTotalDocumentCountForIndexAndType(dataSource, targetType, mustFilter, mustNotFilter, null, - searchText, mustTermsFilter); - } - StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(dataSource); - if (!Strings.isNullOrEmpty(targetType)) { - urlToQueryBuffer.append(FORWARD_SLASH).append(targetType); - } - urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); - - String urlToQuery = urlToQueryBuffer.toString(); - - Map requestBody = new HashMap(); - requestBody.put(SIZE, ES_PAGE_SIZE); - if ((from + size) < ES_PAGE_SIZE) { - requestBody.put(SIZE, (from + size)); - } - requestBody.put(QUERY, buildQuery(mustFilter, mustNotFilter, shouldFilter, searchText, mustTermsFilter,null)); - requestBody.put(_SOURCE, fields); - Gson serializer = new GsonBuilder().create(); - String request = serializer.toJson(requestBody); - return prepareResultsUsingScroll(from, size, urlToQuery, request); - - } - - /** - * - * @param dataSource - * @param targetType - * @param mustFilter - * @param mustNotFilter - * @param shouldFilter - * @param fields - * @param from - * @param size - * @param searchText - * @param mustTermsFilter - * @param sortFieldMapList - * @return - * @throws Exception - */ - public List> getSortedDataFromESBySize(String dataSource, String targetType, - final Map mustFilter, final Map mustNotFilter, - final HashMultimap shouldFilter, List fields, int from, int size, String searchText, - final Map mustTermsFilter, List> sortFieldMapList) throws Exception { - if (size <= 0) { - size = (int) getTotalDocumentCountForIndexAndType(dataSource, targetType, mustFilter, mustNotFilter, null, - searchText, mustTermsFilter); - } - StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(dataSource); - if (!Strings.isNullOrEmpty(targetType)) { - urlToQueryBuffer.append(FORWARD_SLASH).append(targetType); - } - urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); - - String urlToQuery = urlToQueryBuffer.toString(); - - Map requestBody = new HashMap(); - requestBody.put(SIZE, ES_PAGE_SIZE); - if ((from + size) < ES_PAGE_SIZE) { - requestBody.put(SIZE, (from + size)); - } - requestBody.put(QUERY, buildQuery(mustFilter, mustNotFilter, shouldFilter, searchText, mustTermsFilter,null)); - - if (null != sortFieldMapList && !sortFieldMapList.isEmpty()) { - requestBody.put(SORT, sortFieldMapList); - } - requestBody.put(_SOURCE, fields); - Gson serializer = new GsonBuilder().create(); - String request = serializer.toJson(requestBody); - return prepareResultsUsingScroll(from, size, urlToQuery, request); - } - - /** - * - * @param dataSource - * @param targetType - * @param id - * @param routing - * @param parent - * @param partialDocument - * @return - * @throws Exception - */ - @SuppressWarnings("unchecked") - public Boolean updatePartialDataToES(String dataSource, String targetType, String id, String routing, String parent, - Map partialDocument) throws Exception { - try { - StringBuilder esQueryUrl = new StringBuilder(esUrl); - if (!Strings.isNullOrEmpty(dataSource) && !Strings.isNullOrEmpty(targetType)) { - esQueryUrl.append(FORWARD_SLASH).append(dataSource).append(FORWARD_SLASH).append(targetType); - esQueryUrl.append(FORWARD_SLASH).append(id).append(FORWARD_SLASH).append("_update"); - if (!Strings.isNullOrEmpty(routing) && !Strings.isNullOrEmpty(parent)) { - esQueryUrl.append("?routing=").append(routing).append("&parent=").append(parent); - } - Map documentToUpdate = Maps.newHashMap(); - documentToUpdate.put("doc", partialDocument); - Gson serializer = new GsonBuilder().create(); - String request = serializer.toJson(documentToUpdate); - String responseDetails = PacHttpUtils.doHttpPost(esQueryUrl.toString(), request); - Map response = (Map) serializer.fromJson(responseDetails, Object.class); - return ("updated".equalsIgnoreCase(response.get("result").toString()) - || "noop".equalsIgnoreCase(response.get("result").toString())); - } - } catch (Exception exception) { - LOGGER.error("error while updatePartialDataToES",exception); - return false; - } - return false; - } - - /** - * - * @param dataSource - * @param routing - * @param data - * @return - */ - @SuppressWarnings("unchecked") - public Boolean saveExceptionDataToES(String dataSource, String routing, Map data) { - try { - StringBuilder esQueryUrl = new StringBuilder(esUrl); - if (!Strings.isNullOrEmpty(dataSource)) { - esQueryUrl.append(FORWARD_SLASH).append(dataSource).append("/issue_").append(data.get(TARGET_TYPE)) - .append("_exception"); - if (!Strings.isNullOrEmpty(routing)) { - esQueryUrl.append("?routing=").append(routing); - Gson serializer = new GsonBuilder().create(); - String request = serializer.toJson(data); - String responseDetails = PacHttpUtils.doHttpPost(esQueryUrl.toString(), request); - Map response = (Map) serializer.fromJson(responseDetails, - Object.class); - if (response.get("result").toString().equalsIgnoreCase("created")) { - return true; - } else { - return false; - } - } - } - } catch (Exception exception) { - return false; - } - return false; - } - - /** - * - * @param index - * @param type - * @param mustFilter - * @param mustNotFilter - * @param shouldFilter - * @param aggsFilter - * @return - */ - public Map getTotalDistributionForIndexAndTypeBySize(String index, String type, - Map mustFilter, Map mustNotFilter, - HashMultimap shouldFilter, String aggsFilter, int size, int from, String searchText) - throws Exception { - - StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(index); - if (!Strings.isNullOrEmpty(type)) { - urlToQueryBuffer.append(FORWARD_SLASH).append(type); - } - urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); - if (size > 0 && from >= 0) { - urlToQueryBuffer.append("?").append("size=").append(size).append("&").append("from=").append(from); - } - - String urlToQuery = urlToQueryBuffer.toString(); - Map requestBody = new HashMap(); - Map matchFilters = Maps.newHashMap(); - Map distribution = new HashMap(); - if (mustFilter == null) { - matchFilters.put("match_all", new HashMap()); - } else { - matchFilters.putAll(mustFilter); - } - if (null != mustFilter) { - requestBody.put(QUERY, buildQuery(matchFilters, mustNotFilter, shouldFilter, searchText, null,null)); - requestBody.put(AGGS, buildAggs(aggsFilter, size)); - - } else { - requestBody.put(QUERY, matchFilters); - } - String responseDetails = null; - Gson gson = new GsonBuilder().create(); - - try { - String requestJson = gson.toJson(requestBody, Object.class); - responseDetails = PacHttpUtils.doHttpPost(urlToQuery, requestJson); - Map response = (Map) gson.fromJson(responseDetails, Map.class); - Map aggregations = (Map) response.get(AGGREGATIONS); - Map name = (Map) aggregations.get(NAME); - List> buckets = (List>) name.get(BUCKETS); - for (int i = 0; i < buckets.size(); i++) { - Map bucket = buckets.get(i); - distribution.put(bucket.get("key").toString(), ((Double) bucket.get("doc_count")).longValue()); - } - - } catch (Exception e) { - LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); - throw e; - } - return distribution; - } - - /** - * - * @param index - * @param type - * @param mustFilter - * @param mustNotFilter - * @param shouldFilter - * @param dateFieldName - * @param interval - * @return - * @throws Exception - */ - public Map getDateHistogramForIndexAndTypeByInterval(String index, String type, - Map mustFilter, Map mustNotFilter, - HashMultimap shouldFilter, String dateFieldName, String interval) throws Exception { - - String urlToQuery = buildAggsURL(esUrl, index, type); - Map requestBody = new HashMap(); - Map matchFilters = Maps.newHashMap(); - Map distribution = new HashMap(); - if (mustFilter == null) { - matchFilters.put("match_all", new HashMap()); - } else { - matchFilters.putAll(mustFilter); - } - if (null != dateFieldName && null != interval) { - - requestBody.put(AGGS, buildHistogramAggs(dateFieldName, interval)); - - } - if (!matchFilters.isEmpty()) { - requestBody.put(QUERY, buildQuery(matchFilters, mustNotFilter, shouldFilter, null, null,null)); - } - String responseDetails = null; - Gson gson = new GsonBuilder().create(); - - try { - String requestJson = gson.toJson(requestBody, Object.class); - responseDetails = PacHttpUtils.doHttpPost(urlToQuery, requestJson); - Map response = (Map) gson.fromJson(responseDetails, Map.class); - Map aggregations = (Map) response.get("aggregations"); - - Map name = (Map) aggregations.get("name"); - List> buckets = (List>) name.get("buckets"); - - for (int i = 0; i < buckets.size(); i++) { - Map bucket = buckets.get(i); - distribution.put(bucket.get("key_as_string").toString(), - ((Double) bucket.get("doc_count")).longValue()); - } - - } catch (Exception e) { - LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); - throw e; - } - return distribution; - } - - /** - * - * @param dateFieldName - * @param interval - * @return - */ - private Map buildHistogramAggs(String dateFieldName, String interval) { - - Map agg = new HashMap(); - Map name = new HashMap(); - Map histogram = new HashMap(); - - if (!Strings.isNullOrEmpty(dateFieldName)) { - - histogram.put("field", dateFieldName); - histogram.put("interval", interval); - } - name.put("date_histogram", histogram); - agg.put("name", name); - return agg; - - } - - /** - * - * @param index - * @param type - * @param filter - * @param mustNotFilter - * @param shouldFilter - * @param aggsFilter - * @return - */ - public Map getAccountsByMultiAggs(String index, String type, Map filter, - Map mustNotFilter, HashMultimap shouldFilter, - Map aggsFilter, int size) throws Exception { - - StringBuilder requestBody = null; - StringBuilder urlToQuery = null; - Map matchFilters = Maps.newHashMap(); - Map distribution = new HashMap(); - if (filter == null) { - matchFilters.put("match_all", new HashMap()); - } else { - matchFilters.putAll(filter); - } - if (null != filter) { - urlToQuery = new StringBuilder(esUrl).append(FORWARD_SLASH).append(index); - urlToQuery.append(FORWARD_SLASH).append(_SEARCH); - - requestBody = new StringBuilder("{\"aggs\":{\"accountid\":{\"terms\":{\"field\":\""); - requestBody.append("accountid.keyword"); - requestBody.append("\",\"size\":" + size + "}," - + "\"aggs\":{\"accountname\":{\"terms\":{\"field\":\"accountname.keyword\",\"size\":" + size - + "}}}}}}"); - - } - - String responseDetails = null; - Gson gson = new GsonBuilder().create(); - - try { - responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), requestBody.toString()); - Map response = (Map) gson.fromJson(responseDetails, Map.class); - Map aggregations = (Map) response.get("aggregations"); - Map name = (Map) aggregations.get("accountid"); - List> buckets = (List>) name.get("buckets"); - - for (int i = 0; i < buckets.size(); i++) { - Map bucket = buckets.get(i); - Map accName = (Map) bucket.get("accountname"); - List> bucketsName = (List>) accName.get("buckets"); - for (int j = 0; j < bucketsName.size(); j++) { - Map bucketAccName = bucketsName.get(j); - distribution.put(bucket.get("key").toString(), bucketAccName.get("key").toString()); - } - } - - } catch (Exception e) { - LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); - throw e; - } - return distribution; - } - - /** - * - * @param dataSource - * @param targetType - * @param mustFilter - * @param mustNotFilter - * @param shouldFilter - * @param fields - * @param from - * @param size - * @param searchText - * @param mustTermsFilter - * @return - * @throws Exception - */ - public List> getDetailsFromESBySize(String dataSource, String targetType, - final Map mustFilter, final Map mustNotFilter, - final HashMultimap shouldFilter, List fields, int from, int size, String searchText, - final Map mustTermsFilter) throws Exception { - - StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(dataSource); - if (!Strings.isNullOrEmpty(targetType)) { - urlToQueryBuffer.append(FORWARD_SLASH).append(targetType); - } - urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); - if (size > 0 && from >= 0) { - urlToQueryBuffer.append("?").append("size=").append(size).append("&").append("from=").append(from); - } - String urlToQuery = urlToQueryBuffer.toString(); - List> results = new ArrayList>(); - - Map requestBody = new HashMap(); - Map> auditDate = new HashMap>(); - Map order = new HashMap(); - order.put(ORDER, "desc"); - auditDate.put("auditdate", order); - List>> list = new ArrayList>>(); - list.add(auditDate); - requestBody.put(SORT, list); - if (size > 0) { - requestBody.put(SIZE, size); - } - - requestBody.put(QUERY, buildQuery(mustFilter, mustNotFilter, shouldFilter, searchText, mustTermsFilter,null)); - requestBody.put(_SOURCE, fields); - Gson serializer = new GsonBuilder().create(); - String request = serializer.toJson(requestBody); - String responseDetails = null; - try { - responseDetails = PacHttpUtils.doHttpPost(urlToQuery, request); - serializer = new GsonBuilder().create(); - Map response = (Map) serializer.fromJson(responseDetails, Object.class); - if (response.containsKey(HITS)) { - Map hits = (Map) response.get(HITS); - if (hits.containsKey(HITS)) { - List> hitDetails = (List>) hits.get(HITS); - if (!hitDetails.isEmpty()) { - for (Map hitDetail : hitDetails) { - Map sources = (Map) hitDetail.get(_SOURCE); - results.add(CommonUtils.flatNestedLinkedHashMap(null, sources)); - - } - } else { - throw new RuntimeException(NO_RECORDS_FOUND); - } - } - } - } catch (Exception e) { - LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); - throw e; - } - return results; - } - - /** - * - * @param dataSource - * @param targetType - * @param mustFilter - * @param mustNotFilter - * @param shouldFilter - * @param fields - * @param mustTermsFilter - * @param mustNotTermsFilter - * @param mustNotWildCardFilter - * @return - * @throws Exception - * @deprecated - */ - @SuppressWarnings("unchecked") - @Deprecated - public List> getDataFromESWithMustNotTermsFilter(String dataSource, String targetType, - Map mustFilter, final Map mustNotFilter, - final HashMultimap shouldFilter, List fields, Map mustTermsFilter, - Map mustNotTermsFilter, Map mustNotWildCardFilter) throws Exception { - - Long totalDocs = getTotalDocumentCountForIndexAndTypeWithMustNotTermsFilter(dataSource, targetType, mustFilter, - mustNotFilter, shouldFilter, null, mustTermsFilter, mustNotTermsFilter, mustNotWildCardFilter); - // if filter is not null apply filter, this can be a multi value filter - // also if from and size are -1 -1 send all the data back and do not - // paginate - StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(dataSource); - if (!Strings.isNullOrEmpty(targetType)) { - urlToQueryBuffer.append(FORWARD_SLASH).append(targetType); - } - urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); - - String urlToQuery = urlToQueryBuffer.toString(); - // paginate for breaking the response into smaller chunks - Map requestBody = new HashMap(); - - requestBody.put(SIZE, ES_PAGE_SIZE); - if (totalDocs < ES_PAGE_SIZE) { - requestBody.put(SIZE, totalDocs); - } - - requestBody.put(QUERY, buildQueryForMustTermsFilter(mustFilter, mustNotFilter, shouldFilter, null, - mustTermsFilter, mustNotTermsFilter, mustNotWildCardFilter)); - requestBody.put(_SOURCE, fields); - Gson serializer = new GsonBuilder().create(); - String request = serializer.toJson(requestBody); - return prepareResultsUsingScroll(0, totalDocs, urlToQuery, request); - } - - /** - * - * @param dataSource - * @param targetType - * @param mustFilter - * @param mustNotFilter - * @param shouldFilter - * @param fields - * @param mustTermsFilter - * @param mustNotTermsFilter - * @param mustNotWildCardFilter - * @param sortFieldMapList - * @return - * @throws Exception - */ - @SuppressWarnings("unchecked") - public List> getSortedDataFromESWithMustNotTermsFilter(String dataSource, String targetType, - Map mustFilter, final Map mustNotFilter, - final HashMultimap shouldFilter, List fields, Map mustTermsFilter, - Map mustNotTermsFilter, Map mustNotWildCardFilter, - List> sortFieldMapList) throws Exception { - - Long totalDocs = getTotalDocumentCountForIndexAndTypeWithMustNotTermsFilter(dataSource, targetType, mustFilter, - mustNotFilter, shouldFilter, null, mustTermsFilter, mustNotTermsFilter, mustNotWildCardFilter); - // if filter is not null apply filter, this can be a multi value filter - // also if from and size are -1 -1 send all the data back and do not - // paginate - StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(dataSource); - if (!Strings.isNullOrEmpty(targetType)) { - urlToQueryBuffer.append(FORWARD_SLASH).append(targetType); - } - urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); - - String urlToQuery = urlToQueryBuffer.toString(); - // paginate for breaking the response into smaller chunks - Map requestBody = new HashMap(); - - requestBody.put(SIZE, ES_PAGE_SIZE); - if (totalDocs < ES_PAGE_SIZE) { - requestBody.put(SIZE, totalDocs); - } - - requestBody.put(QUERY, buildQueryForMustTermsFilter(mustFilter, mustNotFilter, shouldFilter, null, - mustTermsFilter, mustNotTermsFilter, mustNotWildCardFilter)); - - if (null != sortFieldMapList && !sortFieldMapList.isEmpty()) { - requestBody.put(SORT, sortFieldMapList); - } - - requestBody.put(_SOURCE, fields); - Gson serializer = new GsonBuilder().create(); - String request = serializer.toJson(requestBody); - return prepareResultsUsingScroll(0, totalDocs, urlToQuery, request); - } - - /** - * - * @param index - * @param type - * @param mustFilter - * @param mustNotFilter - * @param shouldFilter - * @param searchText - * @param mustTermsFilter - * @param mustNotTermsFilter - * @param mustNotWildCardFilter - * @return - * @throws Exception - */ - public long getTotalDocumentCountForIndexAndTypeWithMustNotTermsFilter(String index, String type, - Map mustFilter, Map mustNotFilter, - HashMultimap shouldFilter, String searchText, Map mustTermsFilter, - Map mustNotTermsFilter, Map mustNotWildCardFilter) throws Exception { - - String urlToQuery = buildCountURL(esUrl, index, type); - - Map requestBody = new HashMap(); - Map matchFilters = Maps.newHashMap(); - if (mustFilter == null) { - matchFilters.put("match_all", new HashMap()); - } else { - matchFilters.putAll(mustFilter); - } - if (null != mustFilter) { - requestBody.put(QUERY, buildQueryForMustTermsFilter(matchFilters, mustNotFilter, shouldFilter, searchText, - mustTermsFilter, mustNotTermsFilter, mustNotWildCardFilter)); - } else { - requestBody.put(QUERY, matchFilters); - } - String responseDetails = null; - Gson gson = new GsonBuilder().create(); - try { - - String requestJson = gson.toJson(requestBody, Object.class); - responseDetails = PacHttpUtils.doHttpPost(urlToQuery, requestJson); - Map response = (Map) gson.fromJson(responseDetails, Object.class); - return (long) (Double.parseDouble(response.get(COUNT).toString())); - } catch (Exception e) { - LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); - throw e; - } - } - - /** - * - * @param filter - * @return elastic search query details - */ - private Map buildQueryForMustTermsFilter(final Map mustFilter, - final Map mustNotFilter, final HashMultimap shouldFilter, - final String searchText, final Map mustTermsFilter, - final Map mustNotTermsFilter, final Map mustNotWildCardFilter) { - Map queryFilters = Maps.newHashMap(); - Map boolFilters = Maps.newHashMap(); - - Map hasChildObject = null; - Map hasParentObject = null; - - if (isNotNullOrEmpty(mustFilter)) { - if (mustFilter.containsKey(HAS_CHILD)) { - hasChildObject = (Map) mustFilter.get(HAS_CHILD); - mustFilter.remove(HAS_CHILD); - } - if (mustFilter.containsKey(HAS_PARENT)) { - hasParentObject = (Map) mustFilter.get(HAS_PARENT); - mustFilter.remove(HAS_PARENT); - } - } - - if (isNotNullOrEmpty(mustFilter) && (!Strings.isNullOrEmpty(searchText))) { - - List> must = getFilter(mustFilter, mustTermsFilter,null); - Map match = Maps.newHashMap(); - Map all = Maps.newHashMap(); - all.put(_ALL, searchText); - match.put(MATCH, all); - must.add(match); - boolFilters.put(MUST, must); - } else if (isNotNullOrEmpty(mustFilter)) { - boolFilters.put(MUST, getFilter(mustFilter, mustTermsFilter,null)); - } - - if (isNotNullOrEmpty(mustFilter)) { - - Map hasChildMap = Maps.newHashMap(); - Map hasParentMap = Maps.newHashMap(); - - List> must = (List>) boolFilters.get(MUST); - - if (null != hasChildObject) { - hasChildMap.put(HAS_CHILD, hasChildObject); - must.add(hasChildMap); - } - if (null != hasParentObject) { - hasParentMap.put(HAS_PARENT, hasParentObject); - must.add(hasParentMap); - } - - } - - if (isNotNullOrEmpty(mustNotFilter)) { - - boolFilters.put(MUST_NOT, getFilterWithWildCard(mustNotFilter, mustNotTermsFilter, mustNotWildCardFilter)); - } - if (isNotNullOrEmpty(shouldFilter)) { - boolFilters.put(SHOULD, getFilter(shouldFilter)); - boolFilters.put(MINIMUM_SHOULD_MATCH, 1); - } - queryFilters.put(BOOL, boolFilters); - return queryFilters; - } - - /** - * - * @param mustfilter - * @return - */ - private List> getFilterWithWildCard(final Map mustfilter, - final Map mustTerms, final Map wildCardFilter) { - - List> finalFilter = Lists.newArrayList(); - Map wildCardMap = Maps.newHashMap(); - for (Map.Entry entry : mustfilter.entrySet()) { - Map term = Maps.newHashMap(); - Map termDetails = Maps.newHashMap(); - termDetails.put(entry.getKey(), entry.getValue()); - if (RANGE.equals(entry.getKey())) { - term.put(RANGE, entry.getValue()); - } else { - term.put(TERM, termDetails); - } - finalFilter.add(term); - } - - if (isNotNullOrEmpty(wildCardFilter)) { - wildCardMap.put("wildcard", wildCardFilter); - finalFilter.add(wildCardMap); - } - - if (mustTerms != null && !mustTerms.isEmpty()) { - Map term = Maps.newHashMap(); - term.put(TERMS, mustTerms); - finalFilter.add(term); - } - return finalFilter; - } - - /** - * - * @param elastic - * search url - * @param index - * name - * @param type - * name - * @param shouldFilter - * @param mustNotFilter - * @param filters - * @return elastic search count - */ - @SuppressWarnings("unchecked") - public long getTotalDistributionForIndexAndTypeWithMatchPhrase(String index, String type, - Map mustFilter, Map mustNotFilter, - HashMultimap shouldFilter, String searchText, - Map mustTermsFilter, - Map> matchPhrasePrefix) throws Exception { - - String urlToQuery = buildCountURL(esUrl, index, type); - - Map requestBody = new HashMap(); - Map matchFilters = Maps.newHashMap(); - if (mustFilter == null) { - matchFilters.put("match_all", new HashMap()); - } else { - matchFilters.putAll(mustFilter); - } - if (null != mustFilter) { - requestBody.put( - QUERY, - buildQuery(matchFilters, mustNotFilter, shouldFilter, - searchText, mustTermsFilter, matchPhrasePrefix)); - } else { - requestBody.put(QUERY, matchFilters); - } - String responseDetails = null; - Gson gson = new GsonBuilder().create(); - try { - - String requestJson = gson.toJson(requestBody, Object.class); - responseDetails = PacHttpUtils.doHttpPost(urlToQuery, requestJson); - Map response = (Map) gson.fromJson( - responseDetails, Object.class); - return (long) (Double.parseDouble(response.get(COUNT).toString())); - } catch (Exception e) { - LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); - throw e; - } - } - -} +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +/** + Copyright (C) 2017 T Mobile Inc - All Rights Reserve + Purpose: + Author :kkumar + Modified Date: Oct 17, 2017 + + **/ +package com.tmobile.pacman.api.commons.repo; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.PostConstruct; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Repository; + +import com.google.common.base.Strings; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.tmobile.pacman.api.commons.Constants; +import com.tmobile.pacman.api.commons.utils.CommonUtils; +import com.tmobile.pacman.api.commons.utils.PacHttpUtils; + +@Repository +public class ElasticSearchRepository implements Constants { + + /** + * + */ + private static final String AVG = "avg"; + /** + * + */ + private static final String SUM = "sum"; + /** + * + */ + private static final String SUM_NETWORK_OUT = "Sum-NetworkOut"; + /** + * + */ + private static final String SUM_NETWORK_IN = "Sum-NetworkIn"; + /** + * + */ + private static final String AVG_CPU_UTILIZATION = "Avg-CPU-Utilization"; + /** + * + */ + private static final String NO_RECORDS_FOUND = "No records found!"; + /** + * + */ + private static final String HITS = "hits"; + /** + * + */ + private static final String ORDER = "order"; + /** + * + */ + private static final String EC2_UTILIZATION = "ec2_utilization"; + /** + * + */ + private static final String AGGS = "aggs"; + /** + * + */ + private static final String FORWARD_SLASH = "/"; + /** + * + */ + private static final String _COUNT = "_count"; + /** + * + */ + private static final String MATCH_PHRASE_PREFIX = "match_phrase_prefix"; + /** + * + */ + private static final String _ALL = "_all"; + /** + * + */ + private static final String MATCH = "match"; + /** + * + */ + private static final String MINIMUM_SHOULD_MATCH = "minimum_should_match"; + /** + * + */ + private static final String BOOL = "bool"; + /** + * + */ + private static final String SHOULD = "should"; + /** + * + */ + private static final String MUST_NOT = "must_not"; + /** + * + */ + private static final String MUST = "must"; + /** + * + */ + private static final String RANGE = "range"; + /** + * + */ + private static final String TERM = "term"; + /** + * + */ + private static final String TERMS = "terms"; + /** + * + */ + private static final String ERROR_RETRIEVING_INVENTORY_FROM_ES = "error retrieving inventory from ES"; + /** + * + */ + private static final String HAS_PARENT = "has_parent"; + /** + * + */ + private static final String HAS_CHILD = "has_child"; + /** + * + */ + private static final String _SOURCE = "_source"; + /** + * + */ + private static final String SORT = "sort"; + /** + * + */ + private static final String QUERY = "query"; + /** + * + */ + private static final String SIZE = "size"; + /** + * + */ + private static final String _SEARCH = "_search"; + @Value("${elastic-search.host}") + private String esHost; + @Value("${elastic-search.port}") + private int esPort; + + final static String protocol = "http"; + + private String esUrl; + + private static final Log LOGGER = LogFactory.getLog(ElasticSearchRepository.class); + + @PostConstruct + void init() { + esUrl = protocol + "://" + esHost + ":" + esPort; + } + + /** + * + * @param dataSource + * @param targetType + * @param mustFilter + * @param mustNotFilter + * @param shouldFilter + * @param fields + * @return + * @throws Exception + * @deprecated + */ + @SuppressWarnings("unchecked") + @Deprecated + public List> getDataFromES(String dataSource, String targetType, Map mustFilter, + final Map mustNotFilter, final HashMultimap shouldFilter, + List fields, Map mustTermsFilter) throws Exception { + + Long totalDocs = getTotalDocumentCountForIndexAndType(dataSource, targetType, mustFilter, mustNotFilter, + shouldFilter, null, mustTermsFilter); + // if filter is not null apply filter, this can be a multi value filter + // also if from and size are -1 -1 send all the data back and do not + // paginate + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(dataSource); + if (!Strings.isNullOrEmpty(targetType)) { + urlToQueryBuffer.append(FORWARD_SLASH).append(targetType); + } + urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); + + String urlToQuery = urlToQueryBuffer.toString(); + // paginate for breaking the response into smaller chunks + Map requestBody = new HashMap(); + requestBody.put(SIZE, ES_PAGE_SIZE); + if (totalDocs < ES_PAGE_SIZE) { + requestBody.put(SIZE, totalDocs); + } + requestBody.put(QUERY, buildQuery(mustFilter, mustNotFilter, shouldFilter, null, mustTermsFilter,null)); + requestBody.put(_SOURCE, fields); + Gson serializer = new GsonBuilder().disableHtmlEscaping().create(); + String request = serializer.toJson(requestBody); + + return prepareResultsUsingScroll(0, totalDocs, urlToQuery, request); + } + + /** + * + * @param dataSource + * @param targetType + * @param mustFilter + * @param mustNotFilter + * @param shouldFilter + * @param fields + * @return + * @throws Exception + */ + @SuppressWarnings("unchecked") + public List> getSortedDataFromES(String dataSource, String targetType, + Map mustFilter, final Map mustNotFilter, + final HashMultimap shouldFilter, List fields, Map mustTermsFilter, + List> sortFieldMapList) throws Exception { + + Long totalDocs = getTotalDocumentCountForIndexAndType(dataSource, targetType, mustFilter, mustNotFilter, + shouldFilter, null, mustTermsFilter); + // if filter is not null apply filter, this can be a multi value filter + // also if from and size are -1 -1 send all the data back and do not + // paginate + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(dataSource); + if (!Strings.isNullOrEmpty(targetType)) { + urlToQueryBuffer.append(FORWARD_SLASH).append(targetType); + } + urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); + + String urlToQuery = urlToQueryBuffer.toString(); + // paginate for breaking the response into smaller chunks + Map requestBody = new HashMap(); + requestBody.put(SIZE, ES_PAGE_SIZE); + if (totalDocs < ES_PAGE_SIZE) { + requestBody.put(SIZE, totalDocs); + } + requestBody.put(QUERY, buildQuery(mustFilter, mustNotFilter, shouldFilter, null, mustTermsFilter,null)); + + if (null != sortFieldMapList && !sortFieldMapList.isEmpty()) { + requestBody.put(SORT, sortFieldMapList); + } + requestBody.put(_SOURCE, fields); + Gson serializer = new GsonBuilder().disableHtmlEscaping().create(); + String request = serializer.toJson(requestBody); + + return prepareResultsUsingScroll(0, totalDocs, urlToQuery, request); + } + + /** + * + * @param from + * @param size + * @param urlToQuery + * @param request + * @return + * @throws Exception + */ + private List> prepareResultsUsingScroll(long from, long size, String urlToQuery, String request) + throws Exception { + String scrollId = null; + List> results = new ArrayList<>(); + + urlToQuery = urlToQuery + "?scroll=" + ES_PAGE_SCROLL_TTL; + + String urlToScroll = new StringBuilder(esUrl).append(FORWARD_SLASH).append(_SEARCH).append("/scroll") + .toString(); + + for (int index = 0; index <= ((from + size) / ES_PAGE_SIZE); index++) { + String responseDetails = null; + try { + if (!Strings.isNullOrEmpty(scrollId)) { + request = buildScrollRequest(scrollId, ES_PAGE_SCROLL_TTL); + urlToQuery = urlToScroll; + } + responseDetails = PacHttpUtils.doHttpPost(urlToQuery, request); + scrollId = processResponseAndSendTheScrollBack(responseDetails, results); + } catch (Exception e) { + LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); + throw e; + } + + } + + int to = (int) (from + size); + if (to > results.size()) { + to = results.size(); // If the size passed is greater than actual + // size.. + } + results = results.subList((int) from, to); + return results; + } + + /** + * + * @param distributionName + * @param size + * @return + */ + private Map buildAggs(String distributionName, int size) { + Map name = new HashMap(); + if (!Strings.isNullOrEmpty(distributionName)) { + Map terms = new HashMap(); + Map termDetails = new HashMap(); + termDetails.put("field", distributionName); + if (size > 0) { + termDetails.put(SIZE, size); + } + terms.put(TERMS, termDetails); + name.put("name", terms); + } + return name; + } + + /** + * + * @param filter + * @return elastic search query details + */ + public Map buildQuery(final Map mustFilter, final Map mustNotFilter, + final HashMultimap shouldFilter, final String searchText, + final Map mustTermsFilter,Map> matchPhrasePrefix) { + + Map queryFilters = Maps.newHashMap(); + Map boolFilters = Maps.newHashMap(); + + Map hasChildObject = null; + Map hasParentObject = null; + + if (isNotNullOrEmpty(mustFilter)) { + if (mustFilter.containsKey(HAS_CHILD)) { + hasChildObject = (Map) mustFilter.get(HAS_CHILD); + mustFilter.remove(HAS_CHILD); + } + if (mustFilter.containsKey(HAS_PARENT)) { + hasParentObject = (Map) mustFilter.get(HAS_PARENT); + mustFilter.remove(HAS_PARENT); + } + } + + if (isNotNullOrEmpty(mustFilter) && (!Strings.isNullOrEmpty(searchText))) { + + List> must = getFilter(mustFilter, mustTermsFilter,matchPhrasePrefix); + Map match = Maps.newHashMap(); + Map all = Maps.newHashMap(); + // If the string is enclosed in quotes, do a match phrase instead of + // match + if (searchText.startsWith("\"") && searchText.endsWith("\"")) { + all.put(_ALL, searchText.substring(1, searchText.length() - 1)); + match.put(MATCH_PHRASE_PREFIX, all); + } else { + all.put(_ALL, searchText); + match.put(MATCH, all); + } + must.add(match); + boolFilters.put(MUST, must); + } else if (isNotNullOrEmpty(mustFilter)) { + boolFilters.put(MUST, getFilter(mustFilter, mustTermsFilter,matchPhrasePrefix)); + } + + if (isNotNullOrEmpty(mustFilter)) { + + Map hasChildMap = Maps.newHashMap(); + Map hasParentMap = Maps.newHashMap(); + + List> must = (List>) boolFilters.get(MUST); + + if (null != hasChildObject) { + hasChildMap.put(HAS_CHILD, hasChildObject); + must.add(hasChildMap); + } + if (null != hasParentObject) { + hasParentMap.put(HAS_PARENT, hasParentObject); + must.add(hasParentMap); + } + + } + + if (isNotNullOrEmpty(mustNotFilter)) { + + boolFilters.put(MUST_NOT, getFilter(mustNotFilter, null,null)); + } + if (isNotNullOrEmpty(shouldFilter)) { + + boolFilters.put(SHOULD, getFilter(shouldFilter)); + boolFilters.put(MINIMUM_SHOULD_MATCH, 1); + } + queryFilters.put(BOOL, boolFilters); + return queryFilters; + } + + /** + * + * @param shouldFilter + * @return + */ + private boolean isNotNullOrEmpty(HashMultimap shouldFilter) { + + return shouldFilter != null && shouldFilter.size() > 0; + } + + /** + * + * @param collection + * @return + */ + private boolean isNotNullOrEmpty(Map collection) { + + return collection != null && collection.size() > 0; + } + + /** + * + * @param mustfilter + * @return + */ + private List> getFilter(final Map mustfilter, + final Map mustTerms, + Map> matchPhrasePrefix) { + List> finalFilter = Lists.newArrayList(); + for (Map.Entry entry : mustfilter.entrySet()) { + Map term = Maps.newHashMap(); + Map termDetails = Maps.newHashMap(); + termDetails.put(entry.getKey(), entry.getValue()); + if (RANGE.equals(entry.getKey())) { + term.put(RANGE, entry.getValue()); + } else { + term.put(TERM, termDetails); + } + finalFilter.add(term); + } + if (mustTerms != null && !mustTerms.isEmpty()) { + if (mustTerms.size() == 1) { + Map term = Maps.newHashMap(); + term.put(TERMS, mustTerms); + finalFilter.add(term); + } else { + mustTerms.forEach((key, value) -> { + Map innerMustTermsMap = new HashMap<>(); + innerMustTermsMap.put(key, value); + Map term = Maps.newHashMap(); + term.put(TERMS, innerMustTermsMap); + finalFilter.add(term); + }); + } + } + + if (matchPhrasePrefix != null && !matchPhrasePrefix.isEmpty()) { + + for (Map.Entry> entry : matchPhrasePrefix + .entrySet()) { + List infoList = new ArrayList(); + infoList.add(entry.getValue()); + + for (Object val : entry.getValue()) { + Map map = new HashMap(); + Map matchPhrasePrefixMap = Maps + .newHashMap(); + map.put(entry.getKey(), val); + matchPhrasePrefixMap.put("match_phrase_prefix", map); + finalFilter.add(matchPhrasePrefixMap); + } + + } + } + + return finalFilter; + } + + /** + * + * @param filter + * @return + */ + private List> getFilter(final HashMultimap filter) { + List> finalFilter = Lists.newArrayList(); + for (Map.Entry entry : filter.entries()) { + Map term = Maps.newHashMap(); + Map termDetails = Maps.newHashMap(); + termDetails.put(entry.getKey(), entry.getValue()); + term.put(TERM, termDetails); + finalFilter.add(term); + } + return finalFilter; + } + + /** + * + * @param scrollId + * @param esPageScrollTtl + * @return + */ + public String buildScrollRequest(String scrollId, String esPageScrollTtl) { + Map requestBody = new HashMap(); + requestBody.put("scroll", ES_PAGE_SCROLL_TTL); + requestBody.put("scroll_id", scrollId); + Gson serializer = new GsonBuilder().create(); + return serializer.toJson(requestBody); + } + + /** + * + * @param responseDetails + * @param results + * @return + */ + public String processResponseAndSendTheScrollBack(String responseDetails, List> results) { + Gson serializer = new GsonBuilder().create(); + Map response = (Map) serializer.fromJson(responseDetails, Object.class); + if (response.containsKey(HITS)) { + Map hits = (Map) response.get(HITS); + if (hits.containsKey(HITS)) { + List> hitDetails = (List>) hits.get(HITS); + for (Map hitDetail : hitDetails) { + Map sources = (Map) hitDetail.get(_SOURCE); + sources.put(ES_DOC_ID_KEY, hitDetail.get(ES_DOC_ID_KEY)); + sources.put(ES_DOC_PARENT_KEY, hitDetail.get(ES_DOC_PARENT_KEY)); + sources.put(ES_DOC_ROUTING_KEY, hitDetail.get(ES_DOC_ROUTING_KEY)); + results.add(CommonUtils.flatNestedMap(null, sources)); + } + } + } + return (String) response.get("_scroll_id"); + } + + /** + * + * @param elastic + * search url + * @param index + * name + * @param type + * name + * @param shouldFilter + * @param mustNotFilter + * @param filters + * @return elastic search count + */ + @SuppressWarnings("unchecked") + public long getTotalDocumentCountForIndexAndType(String index, String type, Map mustFilter, + Map mustNotFilter, HashMultimap shouldFilter, String searchText, + Map mustTermsFilter) throws Exception { + + String urlToQuery = buildCountURL(esUrl, index, type); + + Map requestBody = new HashMap(); + Map matchFilters = Maps.newHashMap(); + if (mustFilter == null) { + matchFilters.put("match_all", new HashMap()); + } else { + matchFilters.putAll(mustFilter); + } + if (null != mustFilter) { + requestBody.put(QUERY, buildQuery(matchFilters, mustNotFilter, shouldFilter, searchText, mustTermsFilter,null)); + } else { + requestBody.put(QUERY, matchFilters); + } + String responseDetails = null; + Gson gson = new GsonBuilder().create(); + try { + + String requestJson = gson.toJson(requestBody, Object.class); + responseDetails = PacHttpUtils.doHttpPost(urlToQuery, requestJson); + Map response = (Map) gson.fromJson(responseDetails, Object.class); + return (long) (Double.parseDouble(response.get(COUNT).toString())); + } catch (Exception e) { + LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); + throw e; + } + } + + /** + * + * @param url + * @param index + * @param type + * @return + */ + private String buildCountURL(String url, String index, String type) { + + StringBuilder urlToQuery = new StringBuilder(url).append(FORWARD_SLASH).append(index); + if (!Strings.isNullOrEmpty(type)) { + urlToQuery.append(FORWARD_SLASH).append(type); + } + urlToQuery.append(FORWARD_SLASH).append(_COUNT); + return urlToQuery.toString(); + } + + /** + * + * @param index + * @param type + * @param mustFilter + * @param mustNotFilter + * @param shouldFilter + * @param aggsFilter + * @param size + * @param mustTermsFilter + * @return + * @throws Exception + */ + public Map getTotalDistributionForIndexAndType(String index, String type, + Map mustFilter, Map mustNotFilter, + HashMultimap shouldFilter, String aggsFilter, int size, Map mustTermsFilter) + throws Exception { + + String urlToQuery = buildAggsURL(esUrl, index, type); + Map requestBody = new HashMap(); + Map matchFilters = Maps.newHashMap(); + Map distribution = new HashMap(); + if (mustFilter == null) { + matchFilters.put("match_all", new HashMap()); + } else { + matchFilters.putAll(mustFilter); + } + if (null != mustFilter) { + requestBody.put(QUERY, buildQuery(matchFilters, mustNotFilter, shouldFilter, null, mustTermsFilter,null)); + requestBody.put(AGGS, buildAggs(aggsFilter, size)); + + if (!Strings.isNullOrEmpty(aggsFilter)) { + requestBody.put(SIZE, "0"); + } + + } else { + requestBody.put(QUERY, matchFilters); + } + String responseDetails = null; + Gson gson = new GsonBuilder().create(); + + try { + String requestJson = gson.toJson(requestBody, Object.class); + responseDetails = PacHttpUtils.doHttpPost(urlToQuery, requestJson); + Map response = (Map) gson.fromJson(responseDetails, Map.class); + Map aggregations = (Map) response.get(AGGREGATIONS); + Map name = (Map) aggregations.get(NAME); + List> buckets = (List>) name.get(BUCKETS); + + for (int i = 0; i < buckets.size(); i++) { + Map bucket = buckets.get(i); + distribution.put(bucket.get("key").toString(), ((Double) bucket.get("doc_count")).longValue()); + } + + } catch (Exception e) { + LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); + throw e; + } + return distribution; + } + + /** + * + * @param url + * @param index + * @param type + * @return + */ + private String buildAggsURL(String url, String index, String type) { + + StringBuilder urlToQuery = new StringBuilder(url).append(FORWARD_SLASH).append(index); + if (!Strings.isNullOrEmpty(type)) { + urlToQuery.append(FORWARD_SLASH).append(type); + } + urlToQuery.append(FORWARD_SLASH).append("_search/?size=0"); + return urlToQuery.toString(); + } + + /** + * + * @param asseGroup + * @return + * @throws Exception + */ + public List> getUtilizationByAssetGroup(String asseGroup) throws Exception { + String urlToQuery = buildAggsURL(esUrl, asseGroup, EC2_UTILIZATION); + Map requestBody = new HashMap(); + Map cpuUtilizationDetails = new HashMap(); + Map cpuUtilization = new HashMap(); + Map range = new HashMap(); + Map must = new HashMap(); + Map bool = new HashMap(); + Map aggs = new HashMap(); + Map histogram = new HashMap(); + Map histogramDetails = new HashMap(); + Map avgValuesperDay = new HashMap(); + List> utilizationList = new ArrayList>(); + Map utilization = null; + Map field = null; + Map sum = null; + Map avg = null; + // must Query formate + cpuUtilizationDetails.put("gte", "now-30d"); + cpuUtilizationDetails.put("lte", "now-1d"); + cpuUtilizationDetails.put("format", "yyyy-MM-dd HH:mm:ss"); + cpuUtilization.put("#Datetime-CPU-Utilization", cpuUtilizationDetails); + range.put(RANGE, cpuUtilization); + must.put(MUST, range); + bool.put(BOOL, must); + // Aggs Query foramte + + field = new HashMap(); + avg = new HashMap(); + field.put("field", AVG_CPU_UTILIZATION); + avg.put(AVG, field); + aggs.put(AVG_CPU_UTILIZATION, avg); + + field = new HashMap(); + sum = new HashMap(); + field.put("field", SUM_NETWORK_IN); + sum.put(SUM, field); + aggs.put("Avg-NetworkIn", sum); + + field = new HashMap(); + sum = new HashMap(); + field.put("field", SUM_NETWORK_OUT); + sum.put(SUM, field); + aggs.put("Avg-NetworkOut", sum); + + field = new HashMap(); + sum = new HashMap(); + field.put("field", "Sum-DiskReadBytes"); + sum.put(SUM, field); + aggs.put("Avg-DiskReadinBytes", sum); + + field = new HashMap(); + sum = new HashMap(); + field.put("field", "Sum-DiskWriteBytes"); + sum.put(SUM, field); + aggs.put("Avg-DiskWriteinBytes", sum); + + field = new HashMap(); + field.put("_key", "desc"); + histogramDetails.put("field", "#Datetime-CPU-Utilization"); + histogramDetails.put("interval", "day"); + histogramDetails.put("format", "yyyy-MM-dd HH:mm:ss"); + histogramDetails.put(ORDER, field); + histogram.put("date_histogram", histogramDetails); + histogram.put(AGGS, aggs); + avgValuesperDay.put("avg-values-per-day", histogram); + + requestBody.put(QUERY, bool); + requestBody.put(AGGS, avgValuesperDay); + requestBody.put(SIZE, 0); + + Gson gson = new GsonBuilder().create(); + + try { + String request = gson.toJson(requestBody, Object.class); + String responseDetails = null; + + responseDetails = PacHttpUtils.doHttpPost(urlToQuery, request); + + JsonParser parser = new JsonParser(); + JsonObject responseDetailsjson = parser.parse(responseDetails).getAsJsonObject(); + responseDetailsjson.get("aggregations"); + Object aggregations = responseDetailsjson.get("aggregations"); + String aggregationsstr = aggregations.toString(); + parser = new JsonParser(); + JsonObject aggregationsjson = (JsonObject) parser.parse(aggregationsstr); + Object avgvalues = aggregationsjson.get("avg-values-per-day"); + String avgvaluestr = avgvalues.toString(); + parser = new JsonParser(); + JsonObject avgvaluesjson = (JsonObject) parser.parse(avgvaluestr); + Object bucketObj = avgvaluesjson.get(BUCKETS); + String bucketstr = bucketObj.toString(); + parser = new JsonParser(); + JsonArray buckets = parser.parse(bucketstr).getAsJsonArray(); + + for (JsonElement jsonElement : buckets) { + utilization = new HashMap(); + + JsonObject bucketdetails = jsonElement.getAsJsonObject(); + utilization.put(DATE, bucketdetails.get("key_as_string").getAsString()); + + Object cpuUtilizationObj = bucketdetails.get(AVG_CPU_UTILIZATION); + String cpuUtilizationStr = cpuUtilizationObj.toString(); + parser = new JsonParser(); + JsonObject cpuUtilizationjson = (JsonObject) parser.parse(cpuUtilizationStr); + if (!cpuUtilizationjson.get("value").isJsonNull()) { + utilization.put(CPU_UTILIZATION, cpuUtilizationjson.get("value").getAsDouble()); + } else { + utilization.put(CPU_UTILIZATION, 0); + } + Object networkInUtilizationObj = bucketdetails.get("Avg-NetworkIn"); + String networkInUtilizationStr = networkInUtilizationObj.toString(); + parser = new JsonParser(); + JsonObject networkInUtilizationjson = (JsonObject) parser.parse(networkInUtilizationStr); + if (!networkInUtilizationjson.get("value").isJsonNull()) { + utilization.put(NETWORK_IN, networkInUtilizationjson.get("value").getAsLong()); + } else { + utilization.put(NETWORK_IN, 0); + } + Object networkOutUtilizationObj = bucketdetails.get("Avg-NetworkOut"); + String networkOutUtilizationStr = networkOutUtilizationObj.toString(); + parser = new JsonParser(); + JsonObject networkOutUtilizationjson = (JsonObject) parser.parse(networkOutUtilizationStr); + if (!networkOutUtilizationjson.get("value").isJsonNull()) { + utilization.put(NETWORK_OUT, networkOutUtilizationjson.get("value").getAsLong()); + } else { + utilization.put(NETWORK_OUT, 0); + } + Object diskReadUtilizationObj = bucketdetails.get("Avg-DiskReadinBytes"); + String diskReadUtilizationStr = diskReadUtilizationObj.toString(); + parser = new JsonParser(); + JsonObject diskReadUtilizationjson = (JsonObject) parser.parse(diskReadUtilizationStr); + if (!diskReadUtilizationjson.get("value").isJsonNull()) { + utilization.put(DISK_READ_IN_BYTES, diskReadUtilizationjson.get("value").getAsLong()); + } else { + utilization.put(DISK_READ_IN_BYTES, 0); + } + Object diskRWriteUtilizationObj = bucketdetails.get("Avg-DiskWriteinBytes"); + String diskRWriteUtilizationStr = diskRWriteUtilizationObj.toString(); + parser = new JsonParser(); + JsonObject diskRWriteUtilizationjson = (JsonObject) parser.parse(diskRWriteUtilizationStr); + if (!diskRWriteUtilizationjson.get("value").isJsonNull()) { + utilization.put(DISK_WRITE_IN_BYTES, diskRWriteUtilizationjson.get("value").getAsLong()); + } else { + utilization.put(DISK_WRITE_IN_BYTES, 0); + } + utilizationList.add(utilization); + } + return utilizationList; + + } catch (Exception e) { + LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); + throw e; + } + } + + /** + * + * @param dataSource + * @param targetType + * @param mustFilter + * @param mustNotFilter + * @param shouldFilter + * @param fields + * @param from + * @param size + * @param searchText + * @param mustTermsFilter + * @return + * @throws Exception + * @deprecated + */ + @Deprecated + public List> getDataFromESBySize(String dataSource, String targetType, + final Map mustFilter, final Map mustNotFilter, + final HashMultimap shouldFilter, List fields, int from, int size, String searchText, + final Map mustTermsFilter) throws Exception { + if (size <= 0) { + size = (int) getTotalDocumentCountForIndexAndType(dataSource, targetType, mustFilter, mustNotFilter, null, + searchText, mustTermsFilter); + } + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(dataSource); + if (!Strings.isNullOrEmpty(targetType)) { + urlToQueryBuffer.append(FORWARD_SLASH).append(targetType); + } + urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); + + String urlToQuery = urlToQueryBuffer.toString(); + + Map requestBody = new HashMap(); + requestBody.put(SIZE, ES_PAGE_SIZE); + if ((from + size) < ES_PAGE_SIZE) { + requestBody.put(SIZE, (from + size)); + } + requestBody.put(QUERY, buildQuery(mustFilter, mustNotFilter, shouldFilter, searchText, mustTermsFilter,null)); + requestBody.put(_SOURCE, fields); + Gson serializer = new GsonBuilder().create(); + String request = serializer.toJson(requestBody); + return prepareResultsUsingScroll(from, size, urlToQuery, request); + + } + + /** + * + * @param dataSource + * @param targetType + * @param mustFilter + * @param mustNotFilter + * @param shouldFilter + * @param fields + * @param from + * @param size + * @param searchText + * @param mustTermsFilter + * @param sortFieldMapList + * @return + * @throws Exception + */ + public List> getSortedDataFromESBySize(String dataSource, String targetType, + final Map mustFilter, final Map mustNotFilter, + final HashMultimap shouldFilter, List fields, int from, int size, String searchText, + final Map mustTermsFilter, List> sortFieldMapList) throws Exception { + if (size <= 0) { + size = (int) getTotalDocumentCountForIndexAndType(dataSource, targetType, mustFilter, mustNotFilter, null, + searchText, mustTermsFilter); + } + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(dataSource); + if (!Strings.isNullOrEmpty(targetType)) { + urlToQueryBuffer.append(FORWARD_SLASH).append(targetType); + } + urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); + + String urlToQuery = urlToQueryBuffer.toString(); + + Map requestBody = new HashMap(); + requestBody.put(SIZE, ES_PAGE_SIZE); + if ((from + size) < ES_PAGE_SIZE) { + requestBody.put(SIZE, (from + size)); + } + requestBody.put(QUERY, buildQuery(mustFilter, mustNotFilter, shouldFilter, searchText, mustTermsFilter,null)); + + if (null != sortFieldMapList && !sortFieldMapList.isEmpty()) { + requestBody.put(SORT, sortFieldMapList); + } + requestBody.put(_SOURCE, fields); + Gson serializer = new GsonBuilder().create(); + String request = serializer.toJson(requestBody); + return prepareResultsUsingScroll(from, size, urlToQuery, request); + } + + /** + * + * @param dataSource + * @param targetType + * @param id + * @param routing + * @param parent + * @param partialDocument + * @return + * @throws Exception + */ + @SuppressWarnings("unchecked") + public Boolean updatePartialDataToES(String dataSource, String targetType, String id, String routing, String parent, + Map partialDocument) throws Exception { + try { + StringBuilder esQueryUrl = new StringBuilder(esUrl); + if (!Strings.isNullOrEmpty(dataSource) && !Strings.isNullOrEmpty(targetType)) { + esQueryUrl.append(FORWARD_SLASH).append(dataSource).append(FORWARD_SLASH).append(targetType); + esQueryUrl.append(FORWARD_SLASH).append(id).append(FORWARD_SLASH).append("_update"); + if (!Strings.isNullOrEmpty(routing) && !Strings.isNullOrEmpty(parent)) { + esQueryUrl.append("?routing=").append(routing).append("&parent=").append(parent); + } + Map documentToUpdate = Maps.newHashMap(); + documentToUpdate.put("doc", partialDocument); + Gson serializer = new GsonBuilder().create(); + String request = serializer.toJson(documentToUpdate); + String responseDetails = PacHttpUtils.doHttpPost(esQueryUrl.toString(), request); + Map response = (Map) serializer.fromJson(responseDetails, Object.class); + return ("updated".equalsIgnoreCase(response.get("result").toString()) + || "noop".equalsIgnoreCase(response.get("result").toString())); + } + } catch (Exception exception) { + LOGGER.error("error while updatePartialDataToES",exception); + return false; + } + return false; + } + + /** + * + * @param dataSource + * @param routing + * @param data + * @return + */ + @SuppressWarnings("unchecked") + public Boolean saveExceptionDataToES(String dataSource, String routing, Map data) { + try { + StringBuilder esQueryUrl = new StringBuilder(esUrl); + if (!Strings.isNullOrEmpty(dataSource)) { + esQueryUrl.append(FORWARD_SLASH).append(dataSource).append("/issue_").append(data.get(TARGET_TYPE)) + .append("_exception"); + if (!Strings.isNullOrEmpty(routing)) { + esQueryUrl.append("?routing=").append(routing); + Gson serializer = new GsonBuilder().create(); + String request = serializer.toJson(data); + String responseDetails = PacHttpUtils.doHttpPost(esQueryUrl.toString(), request); + Map response = (Map) serializer.fromJson(responseDetails, + Object.class); + if (response.get("result").toString().equalsIgnoreCase("created")) { + return true; + } else { + return false; + } + } + } + } catch (Exception exception) { + return false; + } + return false; + } + + /** + * + * @param index + * @param type + * @param mustFilter + * @param mustNotFilter + * @param shouldFilter + * @param aggsFilter + * @return + */ + public Map getTotalDistributionForIndexAndTypeBySize(String index, String type, + Map mustFilter, Map mustNotFilter, + HashMultimap shouldFilter, String aggsFilter, int size, int from, String searchText) + throws Exception { + + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(index); + if (!Strings.isNullOrEmpty(type)) { + urlToQueryBuffer.append(FORWARD_SLASH).append(type); + } + urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); + if (size > 0 && from >= 0) { + urlToQueryBuffer.append("?").append("size=").append(size).append("&").append("from=").append(from); + } + + String urlToQuery = urlToQueryBuffer.toString(); + Map requestBody = new HashMap(); + Map matchFilters = Maps.newHashMap(); + Map distribution = new HashMap(); + if (mustFilter == null) { + matchFilters.put("match_all", new HashMap()); + } else { + matchFilters.putAll(mustFilter); + } + if (null != mustFilter) { + requestBody.put(QUERY, buildQuery(matchFilters, mustNotFilter, shouldFilter, searchText, null,null)); + requestBody.put(AGGS, buildAggs(aggsFilter, size)); + + } else { + requestBody.put(QUERY, matchFilters); + } + String responseDetails = null; + Gson gson = new GsonBuilder().create(); + + try { + String requestJson = gson.toJson(requestBody, Object.class); + responseDetails = PacHttpUtils.doHttpPost(urlToQuery, requestJson); + Map response = (Map) gson.fromJson(responseDetails, Map.class); + Map aggregations = (Map) response.get(AGGREGATIONS); + Map name = (Map) aggregations.get(NAME); + List> buckets = (List>) name.get(BUCKETS); + for (int i = 0; i < buckets.size(); i++) { + Map bucket = buckets.get(i); + distribution.put(bucket.get("key").toString(), ((Double) bucket.get("doc_count")).longValue()); + } + + } catch (Exception e) { + LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); + throw e; + } + return distribution; + } + + /** + * + * @param index + * @param type + * @param mustFilter + * @param mustNotFilter + * @param shouldFilter + * @param dateFieldName + * @param interval + * @return + * @throws Exception + */ + public Map getDateHistogramForIndexAndTypeByInterval(String index, String type, + Map mustFilter, Map mustNotFilter, + HashMultimap shouldFilter, String dateFieldName, String interval) throws Exception { + + String urlToQuery = buildAggsURL(esUrl, index, type); + Map requestBody = new HashMap(); + Map matchFilters = Maps.newHashMap(); + Map distribution = new HashMap(); + if (mustFilter == null) { + matchFilters.put("match_all", new HashMap()); + } else { + matchFilters.putAll(mustFilter); + } + if (null != dateFieldName && null != interval) { + + requestBody.put(AGGS, buildHistogramAggs(dateFieldName, interval)); + + } + if (!matchFilters.isEmpty()) { + requestBody.put(QUERY, buildQuery(matchFilters, mustNotFilter, shouldFilter, null, null,null)); + } + String responseDetails = null; + Gson gson = new GsonBuilder().create(); + + try { + String requestJson = gson.toJson(requestBody, Object.class); + responseDetails = PacHttpUtils.doHttpPost(urlToQuery, requestJson); + Map response = (Map) gson.fromJson(responseDetails, Map.class); + Map aggregations = (Map) response.get("aggregations"); + + Map name = (Map) aggregations.get("name"); + List> buckets = (List>) name.get("buckets"); + + for (int i = 0; i < buckets.size(); i++) { + Map bucket = buckets.get(i); + distribution.put(bucket.get("key_as_string").toString(), + ((Double) bucket.get("doc_count")).longValue()); + } + + } catch (Exception e) { + LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); + throw e; + } + return distribution; + } + + /** + * + * @param dateFieldName + * @param interval + * @return + */ + private Map buildHistogramAggs(String dateFieldName, String interval) { + + Map agg = new HashMap(); + Map name = new HashMap(); + Map histogram = new HashMap(); + + if (!Strings.isNullOrEmpty(dateFieldName)) { + + histogram.put("field", dateFieldName); + histogram.put("interval", interval); + } + name.put("date_histogram", histogram); + agg.put("name", name); + return agg; + + } + + /** + * + * @param index + * @param type + * @param filter + * @param mustNotFilter + * @param shouldFilter + * @param aggsFilter + * @return + */ + public Map getAccountsByMultiAggs(String index, String type, Map filter, + Map mustNotFilter, HashMultimap shouldFilter, + Map aggsFilter, int size) throws Exception { + + StringBuilder requestBody = null; + StringBuilder urlToQuery = null; + Map matchFilters = Maps.newHashMap(); + Map distribution = new HashMap(); + if (filter == null) { + matchFilters.put("match_all", new HashMap()); + } else { + matchFilters.putAll(filter); + } + if (null != filter) { + urlToQuery = new StringBuilder(esUrl).append(FORWARD_SLASH).append(index); + urlToQuery.append(FORWARD_SLASH).append(_SEARCH); + + requestBody = new StringBuilder("{\"aggs\":{\"accountid\":{\"terms\":{\"field\":\""); + requestBody.append("accountid.keyword"); + requestBody.append("\",\"size\":" + size + "}," + + "\"aggs\":{\"accountname\":{\"terms\":{\"field\":\"accountname.keyword\",\"size\":" + size + + "}}}}}}"); + + } + + String responseDetails = null; + Gson gson = new GsonBuilder().create(); + + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery.toString(), requestBody.toString()); + Map response = (Map) gson.fromJson(responseDetails, Map.class); + Map aggregations = (Map) response.get("aggregations"); + Map name = (Map) aggregations.get("accountid"); + List> buckets = (List>) name.get("buckets"); + + for (int i = 0; i < buckets.size(); i++) { + Map bucket = buckets.get(i); + Map accName = (Map) bucket.get("accountname"); + List> bucketsName = (List>) accName.get("buckets"); + for (int j = 0; j < bucketsName.size(); j++) { + Map bucketAccName = bucketsName.get(j); + distribution.put(bucket.get("key").toString(), bucketAccName.get("key").toString()); + } + } + + } catch (Exception e) { + LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); + throw e; + } + return distribution; + } + + /** + * + * @param dataSource + * @param targetType + * @param mustFilter + * @param mustNotFilter + * @param shouldFilter + * @param fields + * @param from + * @param size + * @param searchText + * @param mustTermsFilter + * @return + * @throws Exception + */ + public List> getDetailsFromESBySize(String dataSource, String targetType, + final Map mustFilter, final Map mustNotFilter, + final HashMultimap shouldFilter, List fields, int from, int size, String searchText, + final Map mustTermsFilter) throws Exception { + + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(dataSource); + if (!Strings.isNullOrEmpty(targetType)) { + urlToQueryBuffer.append(FORWARD_SLASH).append(targetType); + } + urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); + if (size > 0 && from >= 0) { + urlToQueryBuffer.append("?").append("size=").append(size).append("&").append("from=").append(from); + } + String urlToQuery = urlToQueryBuffer.toString(); + List> results = new ArrayList>(); + + Map requestBody = new HashMap(); + Map> auditDate = new HashMap>(); + Map order = new HashMap(); + order.put(ORDER, "desc"); + auditDate.put("auditdate", order); + List>> list = new ArrayList>>(); + list.add(auditDate); + requestBody.put(SORT, list); + if (size > 0) { + requestBody.put(SIZE, size); + } + + requestBody.put(QUERY, buildQuery(mustFilter, mustNotFilter, shouldFilter, searchText, mustTermsFilter,null)); + requestBody.put(_SOURCE, fields); + Gson serializer = new GsonBuilder().create(); + String request = serializer.toJson(requestBody); + String responseDetails = null; + try { + responseDetails = PacHttpUtils.doHttpPost(urlToQuery, request); + serializer = new GsonBuilder().create(); + Map response = (Map) serializer.fromJson(responseDetails, Object.class); + if (response.containsKey(HITS)) { + Map hits = (Map) response.get(HITS); + if (hits.containsKey(HITS)) { + List> hitDetails = (List>) hits.get(HITS); + if (!hitDetails.isEmpty()) { + for (Map hitDetail : hitDetails) { + Map sources = (Map) hitDetail.get(_SOURCE); + results.add(CommonUtils.flatNestedLinkedHashMap(null, sources)); + + } + } else { + throw new RuntimeException(NO_RECORDS_FOUND); + } + } + } + } catch (Exception e) { + LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); + throw e; + } + return results; + } + + /** + * + * @param dataSource + * @param targetType + * @param mustFilter + * @param mustNotFilter + * @param shouldFilter + * @param fields + * @param mustTermsFilter + * @param mustNotTermsFilter + * @param mustNotWildCardFilter + * @return + * @throws Exception + * @deprecated + */ + @SuppressWarnings("unchecked") + @Deprecated + public List> getDataFromESWithMustNotTermsFilter(String dataSource, String targetType, + Map mustFilter, final Map mustNotFilter, + final HashMultimap shouldFilter, List fields, Map mustTermsFilter, + Map mustNotTermsFilter, Map mustNotWildCardFilter) throws Exception { + + Long totalDocs = getTotalDocumentCountForIndexAndTypeWithMustNotTermsFilter(dataSource, targetType, mustFilter, + mustNotFilter, shouldFilter, null, mustTermsFilter, mustNotTermsFilter, mustNotWildCardFilter); + // if filter is not null apply filter, this can be a multi value filter + // also if from and size are -1 -1 send all the data back and do not + // paginate + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(dataSource); + if (!Strings.isNullOrEmpty(targetType)) { + urlToQueryBuffer.append(FORWARD_SLASH).append(targetType); + } + urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); + + String urlToQuery = urlToQueryBuffer.toString(); + // paginate for breaking the response into smaller chunks + Map requestBody = new HashMap(); + + requestBody.put(SIZE, ES_PAGE_SIZE); + if (totalDocs < ES_PAGE_SIZE) { + requestBody.put(SIZE, totalDocs); + } + + requestBody.put(QUERY, buildQueryForMustTermsFilter(mustFilter, mustNotFilter, shouldFilter, null, + mustTermsFilter, mustNotTermsFilter, mustNotWildCardFilter)); + requestBody.put(_SOURCE, fields); + Gson serializer = new GsonBuilder().create(); + String request = serializer.toJson(requestBody); + return prepareResultsUsingScroll(0, totalDocs, urlToQuery, request); + } + + /** + * + * @param dataSource + * @param targetType + * @param mustFilter + * @param mustNotFilter + * @param shouldFilter + * @param fields + * @param mustTermsFilter + * @param mustNotTermsFilter + * @param mustNotWildCardFilter + * @param sortFieldMapList + * @return + * @throws Exception + */ + @SuppressWarnings("unchecked") + public List> getSortedDataFromESWithMustNotTermsFilter(String dataSource, String targetType, + Map mustFilter, final Map mustNotFilter, + final HashMultimap shouldFilter, List fields, Map mustTermsFilter, + Map mustNotTermsFilter, Map mustNotWildCardFilter, + List> sortFieldMapList) throws Exception { + + Long totalDocs = getTotalDocumentCountForIndexAndTypeWithMustNotTermsFilter(dataSource, targetType, mustFilter, + mustNotFilter, shouldFilter, null, mustTermsFilter, mustNotTermsFilter, mustNotWildCardFilter); + // if filter is not null apply filter, this can be a multi value filter + // also if from and size are -1 -1 send all the data back and do not + // paginate + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append(FORWARD_SLASH).append(dataSource); + if (!Strings.isNullOrEmpty(targetType)) { + urlToQueryBuffer.append(FORWARD_SLASH).append(targetType); + } + urlToQueryBuffer.append(FORWARD_SLASH).append(_SEARCH); + + String urlToQuery = urlToQueryBuffer.toString(); + // paginate for breaking the response into smaller chunks + Map requestBody = new HashMap(); + + requestBody.put(SIZE, ES_PAGE_SIZE); + if (totalDocs < ES_PAGE_SIZE) { + requestBody.put(SIZE, totalDocs); + } + + requestBody.put(QUERY, buildQueryForMustTermsFilter(mustFilter, mustNotFilter, shouldFilter, null, + mustTermsFilter, mustNotTermsFilter, mustNotWildCardFilter)); + + if (null != sortFieldMapList && !sortFieldMapList.isEmpty()) { + requestBody.put(SORT, sortFieldMapList); + } + + requestBody.put(_SOURCE, fields); + Gson serializer = new GsonBuilder().create(); + String request = serializer.toJson(requestBody); + return prepareResultsUsingScroll(0, totalDocs, urlToQuery, request); + } + + /** + * + * @param index + * @param type + * @param mustFilter + * @param mustNotFilter + * @param shouldFilter + * @param searchText + * @param mustTermsFilter + * @param mustNotTermsFilter + * @param mustNotWildCardFilter + * @return + * @throws Exception + */ + public long getTotalDocumentCountForIndexAndTypeWithMustNotTermsFilter(String index, String type, + Map mustFilter, Map mustNotFilter, + HashMultimap shouldFilter, String searchText, Map mustTermsFilter, + Map mustNotTermsFilter, Map mustNotWildCardFilter) throws Exception { + + String urlToQuery = buildCountURL(esUrl, index, type); + + Map requestBody = new HashMap(); + Map matchFilters = Maps.newHashMap(); + if (mustFilter == null) { + matchFilters.put("match_all", new HashMap()); + } else { + matchFilters.putAll(mustFilter); + } + if (null != mustFilter) { + requestBody.put(QUERY, buildQueryForMustTermsFilter(matchFilters, mustNotFilter, shouldFilter, searchText, + mustTermsFilter, mustNotTermsFilter, mustNotWildCardFilter)); + } else { + requestBody.put(QUERY, matchFilters); + } + String responseDetails = null; + Gson gson = new GsonBuilder().create(); + try { + + String requestJson = gson.toJson(requestBody, Object.class); + responseDetails = PacHttpUtils.doHttpPost(urlToQuery, requestJson); + Map response = (Map) gson.fromJson(responseDetails, Object.class); + return (long) (Double.parseDouble(response.get(COUNT).toString())); + } catch (Exception e) { + LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); + throw e; + } + } + + /** + * + * @param filter + * @return elastic search query details + */ + private Map buildQueryForMustTermsFilter(final Map mustFilter, + final Map mustNotFilter, final HashMultimap shouldFilter, + final String searchText, final Map mustTermsFilter, + final Map mustNotTermsFilter, final Map mustNotWildCardFilter) { + Map queryFilters = Maps.newHashMap(); + Map boolFilters = Maps.newHashMap(); + + Map hasChildObject = null; + Map hasParentObject = null; + + if (isNotNullOrEmpty(mustFilter)) { + if (mustFilter.containsKey(HAS_CHILD)) { + hasChildObject = (Map) mustFilter.get(HAS_CHILD); + mustFilter.remove(HAS_CHILD); + } + if (mustFilter.containsKey(HAS_PARENT)) { + hasParentObject = (Map) mustFilter.get(HAS_PARENT); + mustFilter.remove(HAS_PARENT); + } + } + + if (isNotNullOrEmpty(mustFilter) && (!Strings.isNullOrEmpty(searchText))) { + + List> must = getFilter(mustFilter, mustTermsFilter,null); + Map match = Maps.newHashMap(); + Map all = Maps.newHashMap(); + all.put(_ALL, searchText); + match.put(MATCH, all); + must.add(match); + boolFilters.put(MUST, must); + } else if (isNotNullOrEmpty(mustFilter)) { + boolFilters.put(MUST, getFilter(mustFilter, mustTermsFilter,null)); + } + + if (isNotNullOrEmpty(mustFilter)) { + + Map hasChildMap = Maps.newHashMap(); + Map hasParentMap = Maps.newHashMap(); + + List> must = (List>) boolFilters.get(MUST); + + if (null != hasChildObject) { + hasChildMap.put(HAS_CHILD, hasChildObject); + must.add(hasChildMap); + } + if (null != hasParentObject) { + hasParentMap.put(HAS_PARENT, hasParentObject); + must.add(hasParentMap); + } + + } + + if (isNotNullOrEmpty(mustNotFilter)) { + + boolFilters.put(MUST_NOT, getFilterWithWildCard(mustNotFilter, mustNotTermsFilter, mustNotWildCardFilter)); + } + if (isNotNullOrEmpty(shouldFilter)) { + boolFilters.put(SHOULD, getFilter(shouldFilter)); + boolFilters.put(MINIMUM_SHOULD_MATCH, 1); + } + queryFilters.put(BOOL, boolFilters); + return queryFilters; + } + + /** + * + * @param mustfilter + * @return + */ + private List> getFilterWithWildCard(final Map mustfilter, + final Map mustTerms, final Map wildCardFilter) { + + List> finalFilter = Lists.newArrayList(); + Map wildCardMap = Maps.newHashMap(); + for (Map.Entry entry : mustfilter.entrySet()) { + Map term = Maps.newHashMap(); + Map termDetails = Maps.newHashMap(); + termDetails.put(entry.getKey(), entry.getValue()); + if (RANGE.equals(entry.getKey())) { + term.put(RANGE, entry.getValue()); + } else { + term.put(TERM, termDetails); + } + finalFilter.add(term); + } + + if (isNotNullOrEmpty(wildCardFilter)) { + wildCardMap.put("wildcard", wildCardFilter); + finalFilter.add(wildCardMap); + } + + if (mustTerms != null && !mustTerms.isEmpty()) { + Map term = Maps.newHashMap(); + term.put(TERMS, mustTerms); + finalFilter.add(term); + } + return finalFilter; + } + + /** + * + * @param elastic + * search url + * @param index + * name + * @param type + * name + * @param shouldFilter + * @param mustNotFilter + * @param filters + * @return elastic search count + */ + @SuppressWarnings("unchecked") + public long getTotalDistributionForIndexAndTypeWithMatchPhrase(String index, String type, + Map mustFilter, Map mustNotFilter, + HashMultimap shouldFilter, String searchText, + Map mustTermsFilter, + Map> matchPhrasePrefix) throws Exception { + + String urlToQuery = buildCountURL(esUrl, index, type); + + Map requestBody = new HashMap(); + Map matchFilters = Maps.newHashMap(); + if (mustFilter == null) { + matchFilters.put("match_all", new HashMap()); + } else { + matchFilters.putAll(mustFilter); + } + if (null != mustFilter) { + requestBody.put( + QUERY, + buildQuery(matchFilters, mustNotFilter, shouldFilter, + searchText, mustTermsFilter, matchPhrasePrefix)); + } else { + requestBody.put(QUERY, matchFilters); + } + String responseDetails = null; + Gson gson = new GsonBuilder().create(); + try { + + String requestJson = gson.toJson(requestBody, Object.class); + responseDetails = PacHttpUtils.doHttpPost(urlToQuery, requestJson); + Map response = (Map) gson.fromJson( + responseDetails, Object.class); + return (long) (Double.parseDouble(response.get(COUNT).toString())); + } catch (Exception e) { + LOGGER.error(ERROR_RETRIEVING_INVENTORY_FROM_ES, e); + throw e; + } + } + + /** + * + * @param url + * @param index + * @param type + * @return + */ + public String buildESURL(String url, String index, String type, int size, int from) { + + StringBuilder urlToQuery = new StringBuilder(url).append(FORWARD_SLASH).append(index); + if (!Strings.isNullOrEmpty(type)) { + urlToQuery.append(FORWARD_SLASH).append(type); + } + urlToQuery.append(FORWARD_SLASH).append(_SEARCH); + return urlToQuery.toString(); + } + +} diff --git a/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/utils/CommonUtils.java b/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/utils/CommonUtils.java index 2200f5035..1e9518063 100644 --- a/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/utils/CommonUtils.java +++ b/commons/pac-api-commons/src/main/java/com/tmobile/pacman/api/commons/utils/CommonUtils.java @@ -1,351 +1,373 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ -/** - Copyright (C) 2017 T Mobile Inc - All Rights Reserve - Purpose: - Author :kkumar - Modified Date: Oct 18, 2017 - -**/ -package com.tmobile.pacman.api.commons.utils; - -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -import com.google.common.base.Strings; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -public class CommonUtils { - - - - /** - * - */ - private CommonUtils() { - // hide the implicit public constructor - } - - /** - * - * @param notation - * @return nestedMap - */ - @SuppressWarnings("unchecked") - public static Map flatNestedMap(String notation, Map nestedMap) { - Map flatNestedMap = new HashMap(); - String prefixKey = notation != null ? notation + "." : ""; - for (Map.Entry entry : nestedMap.entrySet()) { - if (entry.getValue() instanceof String || entry.getValue() instanceof Long || entry.getValue() instanceof Integer || entry.getValue() instanceof Float || entry.getValue() instanceof Double) { - flatNestedMap.put(prefixKey + entry.getKey(), entry.getValue()); - } - if (entry.getValue() instanceof Map) { - flatNestedMap.putAll(flatNestedMap(prefixKey + entry.getKey(), (Map) entry.getValue())); - } - if (entry.getValue() instanceof ArrayList) { - Gson gson = new Gson(); - flatNestedMap.put("list",gson.toJson(entry.getValue())); - - } - } - return flatNestedMap; - } - - /** - * - * @param e - * @return - */ - public static String buildErrorResponse(Exception e){ - return "{\"status\" : \"failed\"}"; - } - /** - * - * @param attributeName - * @return - */ - public static String convertAttributetoKeyword(String attributeName){ - return attributeName + ".keyword"; - } - - /** - * - * @param notation - * @param nestedMap - * @return - */ - @SuppressWarnings("unchecked") - public static LinkedHashMap flatNestedLinkedHashMap(String notation, Map nestedMap) { - LinkedHashMap flatNestedMap = new LinkedHashMap(); - String prefixKey = notation != null ? notation + "." : ""; - for (Map.Entry entry : nestedMap.entrySet()) { - if (entry.getValue() instanceof String || entry.getValue() instanceof Long || entry.getValue() instanceof Integer || entry.getValue() instanceof Float || entry.getValue() instanceof Double) { - flatNestedMap.put(prefixKey + entry.getKey(), entry.getValue()); - } - if (entry.getValue() instanceof Map) { - flatNestedMap.putAll(flatNestedMap(prefixKey + entry.getKey(), (Map) entry.getValue())); - } - if (entry.getValue() instanceof ArrayList) { - Gson gson = new Gson(); - flatNestedMap.put("list",gson.toJson(entry.getValue())); - - } - } - return flatNestedMap; - } - - /* - * This function can remove/retain elements from collections if it matches - * certain criteria. The collections could be deeply nested within the - * incoming java object. The removal/retaining is done only if the json - * object, that matched the criteria, is a part of a collection. Other json - * objects will be left alone if the match is true. - * - * - * The first arg is obvious, it is the java obj itself. This will be - * converted to json , processed, and then converted back to a java object - * and the incoming object gets replaced with this. - * - * The second arg is a colon separate key:value. For e.g. if you want to - * remove/retain all elements of a particular key provided it matches with a - * particular value, the matchTerm would be "issue:open". While it parses - * the json tree, if it encounters any key with the value "issue" and if its - * value is "open", then this particular element will be removed/retained. - * - * If you simply give the value alone without the key and the colon, it will - * match ALL elements whose value matches this term, irrespective of the key - * of the element. Use this keyless approach, only if you are sure of what - * you are doing. - * - * By default, this function will 'remove' matched elements. But if you pass - * the third arg as true, this behaviour will flip. We will then 'retain' - * only the matched elements and will remove everything else. - * - * - */ - /** - * @param obj - * @param pattern - * @param retainInsteadOfFilter - * @return - */ - public static Object filterMatchingCollectionElements(Object obj, String pattern, boolean retainInsteadOfFilter) { - JsonElement jsonElement = new GsonBuilder().create().toJsonTree(obj); - - boolean exact=false; - - if (!Strings.isNullOrEmpty(pattern) && pattern.startsWith("\"")&&pattern.endsWith("\"")) { - //If the user enters search term enclosed in double quotes, - //we take that as an 'exact' search rather than a 'like' search - exact=true; - //Strip off the quotes now. We will use the search term within. - pattern = pattern.substring(1,Math.max(1,pattern.length()-1)); - } - - doRecursiveJsonMatch(jsonElement, pattern, retainInsteadOfFilter,exact); - - obj = new GsonBuilder().create().fromJson(jsonElement, Object.class); - - return obj; - - } - - /** - * - * @param jsonElement - * @param pattern - * @param retainInsteadOfFilter - * @param exact - * @return - */ - protected static boolean doRecursiveJsonMatch(JsonElement jsonElement, String pattern, boolean retainInsteadOfFilter,boolean exact) { - - String jsonKeyMatchTerm = ""; - String jsonValueMatchTerm = ""; - - boolean skipKeyMatch = false; - - if (!Strings.isNullOrEmpty(pattern)) { - int colonPosition = pattern.indexOf(":"); - int length = pattern.length(); - - if (colonPosition == -1) { - // If colon is not there, then we assume that the incoming - // string is the value term. - // The keys will not be matched, any key would qualify as a - // candidate. Only the values will be matched. - jsonValueMatchTerm = pattern; - skipKeyMatch = true; - } else { - // key will be to the left of colon in the incoming pattern - jsonKeyMatchTerm = pattern.substring(0, colonPosition); - - // value will be to the right of colon in the incoming pattern - jsonValueMatchTerm = pattern.substring(colonPosition + 1, length); - } - } else {// We definitely need a pattern. Pattern is the sine qua non of - // this function. - return false; - } - - // Dead end. Can't parse this branch further from here. Return. - if (jsonElement.isJsonNull()) { - return false; - } - - // If array, then pick each element from the array, treat it as a - // separate json object and make a recursive call - if (jsonElement.isJsonArray()) { - JsonArray jsonArray = (JsonArray) jsonElement; - Iterator jsonArrayItr = jsonArray.iterator(); - - while (jsonArrayItr.hasNext()) { - JsonElement jsonArrayElement = jsonArrayItr.next(); - boolean remove = doRecursiveJsonMatch(jsonArrayElement, pattern, retainInsteadOfFilter,exact); - // If the remove flag comes is true, then this means that the - // current - // element in the collection needs to be removed - if (remove) { - jsonArrayItr.remove(); - } - } - - } - - // This means that we are not dealing with an array, and we are dealing - // with a json k-v pair. The key will be a string, but the value need - // not be a primitive type. The value could be another inner JSON - // object or even an array. - if (jsonElement.isJsonObject()) { - - boolean removeThisObjectEntirely = false; - - JsonObject jsonObj = (JsonObject) jsonElement; - - Iterator jsonKeyItr = jsonObj.keySet().iterator(); - - while (jsonKeyItr.hasNext()) { - String key = jsonKeyItr.next(); - - Object valueObj = jsonObj.get(key); - // If the value is not a primitive value, and is another inner - // JSON object or JSON array, then make a recursive call - if ((valueObj instanceof JsonObject) || (valueObj instanceof JsonArray)) { - doRecursiveJsonMatch((JsonElement) valueObj, pattern, retainInsteadOfFilter,exact); - } else { - - // if the skipKeyMatch is true, they keyMatched will always - // be true. Why bother about matching keys? - boolean keyMatched = skipKeyMatch || jsonKeyMatchTerm.equals(key); - boolean valueMatched = false; - - //Exact match versus Like match - if(exact) { - valueMatched = jsonValueMatchTerm.equalsIgnoreCase(jsonObj.get(key).getAsString()); - }else { - String lowercasedvalue = jsonObj.get(key).getAsString().toLowerCase(); - String jsonValueMatchTermLowerCased = jsonValueMatchTerm.toLowerCase(); - valueMatched = lowercasedvalue.contains(jsonValueMatchTermLowerCased); - } - - boolean match = keyMatched && valueMatched; - - // If there is a match, then the decision can be taken - // immediately if we need to remove/retain. This is the - // reason why both two out of the three if conditions below - // with 'match' as true,have a 'break' statement. - - // But if we have a negative match, then we should iterate - // through all k-v pairs of the json object. Only then can - // we take the remove/retain decision. This is the reason, - // the if condition below for negative match does not have a - // 'break' - if (retainInsteadOfFilter && !match) { - removeThisObjectEntirely = true; - - } - - // Tf any of the k-v pairs match, and the option is - // 'retain', then flip the switch 'removeThisObjectEntirely' - // back to false - if (retainInsteadOfFilter && match) { - removeThisObjectEntirely = false; - break; - } - - // If we are in 'filter' mode, and we have a match, remove! - if (!retainInsteadOfFilter && match) { - removeThisObjectEntirely = true; - break; - } - - } - - } - // If we have reached here and the flag 'removeThisObjectEntirely' - // is true, this means that this object needs to be removed for - // sure. But only if this object is part of a collection. So if the - // call to this function came from inside a collection iteration, - // then the caller should ideally watch out for the return of this - // function,and remove this object from the collection, if the - // return value is true - if (removeThisObjectEntirely) { - return true; - } - } - return false; - - } - - /** - * - * @return - */ - public static SSLContext createNoSSLContext() { - SSLContext ssl_ctx = null; - try { - ssl_ctx = SSLContext.getInstance("TLS"); - } catch (NoSuchAlgorithmException e) { - } - TrustManager[] trust_mgr = new TrustManager[] { - new X509TrustManager() { - public X509Certificate[] getAcceptedIssuers() { return null; } - public void checkClientTrusted(X509Certificate[] certs, String t) { } - public void checkServerTrusted(X509Certificate[] certs, String t) { } - } - }; - try { - ssl_ctx.init(null, trust_mgr, new SecureRandom()); - } catch (KeyManagementException e) { - } - return ssl_ctx; - } -} +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +/** + Copyright (C) 2017 T Mobile Inc - All Rights Reserve + Purpose: + Author :kkumar + Modified Date: Oct 18, 2017 + +**/ +package com.tmobile.pacman.api.commons.utils; + +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import com.google.common.base.Strings; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +public class CommonUtils { + + + + /** + * + */ + private CommonUtils() { + // hide the implicit public constructor + } + + /** + * + * @param notation + * @return nestedMap + */ + @SuppressWarnings("unchecked") + public static Map flatNestedMap(String notation, Map nestedMap) { + Map flatNestedMap = new HashMap(); + String prefixKey = notation != null ? notation + "." : ""; + for (Map.Entry entry : nestedMap.entrySet()) { + if (entry.getValue() instanceof String || entry.getValue() instanceof Long || entry.getValue() instanceof Integer || entry.getValue() instanceof Float || entry.getValue() instanceof Double) { + flatNestedMap.put(prefixKey + entry.getKey(), entry.getValue()); + } + if (entry.getValue() instanceof Map) { + flatNestedMap.putAll(flatNestedMap(prefixKey + entry.getKey(), (Map) entry.getValue())); + } + if (entry.getValue() instanceof ArrayList) { + Gson gson = new Gson(); + flatNestedMap.put("list",gson.toJson(entry.getValue())); + + } + } + return flatNestedMap; + } + + /** + * + * @param e + * @return + */ + public static String buildErrorResponse(Exception e){ + return "{\"status\" : \"failed\"}"; + } + /** + * + * @param attributeName + * @return + */ + public static String convertAttributetoKeyword(String attributeName){ + return attributeName + ".keyword"; + } + + /** + * + * @param notation + * @param nestedMap + * @return + */ + @SuppressWarnings("unchecked") + public static LinkedHashMap flatNestedLinkedHashMap(String notation, Map nestedMap) { + LinkedHashMap flatNestedMap = new LinkedHashMap(); + String prefixKey = notation != null ? notation + "." : ""; + for (Map.Entry entry : nestedMap.entrySet()) { + if (entry.getValue() instanceof String || entry.getValue() instanceof Long || entry.getValue() instanceof Integer || entry.getValue() instanceof Float || entry.getValue() instanceof Double) { + flatNestedMap.put(prefixKey + entry.getKey(), entry.getValue()); + } + if (entry.getValue() instanceof Map) { + flatNestedMap.putAll(flatNestedMap(prefixKey + entry.getKey(), (Map) entry.getValue())); + } + if (entry.getValue() instanceof ArrayList) { + Gson gson = new Gson(); + flatNestedMap.put("list",gson.toJson(entry.getValue())); + + } + } + return flatNestedMap; + } + + /* + * This function can remove/retain elements from collections if it matches + * certain criteria. The collections could be deeply nested within the + * incoming java object. The removal/retaining is done only if the json + * object, that matched the criteria, is a part of a collection. Other json + * objects will be left alone if the match is true. + * + * + * The first arg is obvious, it is the java obj itself. This will be + * converted to json , processed, and then converted back to a java object + * and the incoming object gets replaced with this. + * + * The second arg is a colon separate key:value. For e.g. if you want to + * remove/retain all elements of a particular key provided it matches with a + * particular value, the matchTerm would be "issue:open". While it parses + * the json tree, if it encounters any key with the value "issue" and if its + * value is "open", then this particular element will be removed/retained. + * + * If you simply give the value alone without the key and the colon, it will + * match ALL elements whose value matches this term, irrespective of the key + * of the element. Use this keyless approach, only if you are sure of what + * you are doing. + * + * By default, this function will 'remove' matched elements. But if you pass + * the third arg as true, this behaviour will flip. We will then 'retain' + * only the matched elements and will remove everything else. + * + * + */ + /** + * @param obj + * @param pattern + * @param retainInsteadOfFilter + * @return + */ + public static Object filterMatchingCollectionElements(Object obj, String pattern, boolean retainInsteadOfFilter) { + JsonElement jsonElement = new GsonBuilder().create().toJsonTree(obj); + + boolean exact=false; + + if (!Strings.isNullOrEmpty(pattern) && pattern.startsWith("\"")&&pattern.endsWith("\"")) { + //If the user enters search term enclosed in double quotes, + //we take that as an 'exact' search rather than a 'like' search + exact=true; + //Strip off the quotes now. We will use the search term within. + pattern = pattern.substring(1,Math.max(1,pattern.length()-1)); + } + + doRecursiveJsonMatch(jsonElement, pattern, retainInsteadOfFilter,exact); + + obj = new GsonBuilder().create().fromJson(jsonElement, Object.class); + + return obj; + + } + + /** + * + * @param jsonElement + * @param pattern + * @param retainInsteadOfFilter + * @param exact + * @return + */ + protected static boolean doRecursiveJsonMatch(JsonElement jsonElement, String pattern, boolean retainInsteadOfFilter,boolean exact) { + + String jsonKeyMatchTerm = ""; + String jsonValueMatchTerm = ""; + + boolean skipKeyMatch = false; + + if (!Strings.isNullOrEmpty(pattern)) { + int colonPosition = pattern.indexOf(":"); + int length = pattern.length(); + + if (colonPosition == -1) { + // If colon is not there, then we assume that the incoming + // string is the value term. + // The keys will not be matched, any key would qualify as a + // candidate. Only the values will be matched. + jsonValueMatchTerm = pattern; + skipKeyMatch = true; + } else { + // key will be to the left of colon in the incoming pattern + jsonKeyMatchTerm = pattern.substring(0, colonPosition); + + // value will be to the right of colon in the incoming pattern + jsonValueMatchTerm = pattern.substring(colonPosition + 1, length); + } + } else {// We definitely need a pattern. Pattern is the sine qua non of + // this function. + return false; + } + + // Dead end. Can't parse this branch further from here. Return. + if (jsonElement.isJsonNull()) { + return false; + } + + // If array, then pick each element from the array, treat it as a + // separate json object and make a recursive call + if (jsonElement.isJsonArray()) { + JsonArray jsonArray = (JsonArray) jsonElement; + Iterator jsonArrayItr = jsonArray.iterator(); + + while (jsonArrayItr.hasNext()) { + JsonElement jsonArrayElement = jsonArrayItr.next(); + boolean remove = doRecursiveJsonMatch(jsonArrayElement, pattern, retainInsteadOfFilter,exact); + // If the remove flag comes is true, then this means that the + // current + // element in the collection needs to be removed + if (remove) { + jsonArrayItr.remove(); + } + } + + } + + // This means that we are not dealing with an array, and we are dealing + // with a json k-v pair. The key will be a string, but the value need + // not be a primitive type. The value could be another inner JSON + // object or even an array. + if (jsonElement.isJsonObject()) { + + boolean removeThisObjectEntirely = false; + + JsonObject jsonObj = (JsonObject) jsonElement; + + Iterator jsonKeyItr = jsonObj.keySet().iterator(); + + while (jsonKeyItr.hasNext()) { + String key = jsonKeyItr.next(); + + Object valueObj = jsonObj.get(key); + // If the value is not a primitive value, and is another inner + // JSON object or JSON array, then make a recursive call + if ((valueObj instanceof JsonObject) || (valueObj instanceof JsonArray)) { + doRecursiveJsonMatch((JsonElement) valueObj, pattern, retainInsteadOfFilter,exact); + } else { + + // if the skipKeyMatch is true, they keyMatched will always + // be true. Why bother about matching keys? + boolean keyMatched = skipKeyMatch || jsonKeyMatchTerm.equals(key); + boolean valueMatched = false; + + //Exact match versus Like match + if(exact) { + valueMatched = jsonValueMatchTerm.equalsIgnoreCase(jsonObj.get(key).getAsString()); + }else { + String lowercasedvalue = jsonObj.get(key).getAsString().toLowerCase(); + String jsonValueMatchTermLowerCased = jsonValueMatchTerm.toLowerCase(); + valueMatched = lowercasedvalue.contains(jsonValueMatchTermLowerCased); + } + + boolean match = keyMatched && valueMatched; + + // If there is a match, then the decision can be taken + // immediately if we need to remove/retain. This is the + // reason why both two out of the three if conditions below + // with 'match' as true,have a 'break' statement. + + // But if we have a negative match, then we should iterate + // through all k-v pairs of the json object. Only then can + // we take the remove/retain decision. This is the reason, + // the if condition below for negative match does not have a + // 'break' + if (retainInsteadOfFilter && !match) { + removeThisObjectEntirely = true; + + } + + // Tf any of the k-v pairs match, and the option is + // 'retain', then flip the switch 'removeThisObjectEntirely' + // back to false + if (retainInsteadOfFilter && match) { + removeThisObjectEntirely = false; + break; + } + + // If we are in 'filter' mode, and we have a match, remove! + if (!retainInsteadOfFilter && match) { + removeThisObjectEntirely = true; + break; + } + + } + + } + // If we have reached here and the flag 'removeThisObjectEntirely' + // is true, this means that this object needs to be removed for + // sure. But only if this object is part of a collection. So if the + // call to this function came from inside a collection iteration, + // then the caller should ideally watch out for the return of this + // function,and remove this object from the collection, if the + // return value is true + if (removeThisObjectEntirely) { + return true; + } + } + return false; + + } + + /** + * + * @return + */ + public static SSLContext createNoSSLContext() { + SSLContext ssl_ctx = null; + try { + ssl_ctx = SSLContext.getInstance("TLS"); + } catch (NoSuchAlgorithmException e) { + } + TrustManager[] trust_mgr = new TrustManager[] { + new X509TrustManager() { + public X509Certificate[] getAcceptedIssuers() { return null; } + public void checkClientTrusted(X509Certificate[] certs, String t) { } + public void checkServerTrusted(X509Certificate[] certs, String t) { } + } + }; + try { + ssl_ctx.init(null, trust_mgr, new SecureRandom()); + } catch (KeyManagementException e) { + } + return ssl_ctx; + } + // If previous character is space and current + // character is not space then it shows that + // current letter is the starting of the word + /** + * @param str input String + * @return string with capital case + */ + public static String capitailizeWord(String mainStr) { + + String str = mainStr.replaceAll("_", " ").toLowerCase(); + StringBuffer s = new StringBuffer(); + + char ch = ' '; + for (int i = 0; i < str.length(); i++) { + if (ch == ' ' && str.charAt(i) != ' ') + s.append(Character.toUpperCase(str.charAt(i))); + else + s.append(str.charAt(i)); + ch = str.charAt(i); + } + return s.toString().trim(); + } +} diff --git a/jobs/pacman-cloud-notifications/target/classes/META-INF/maven/com.tmobile.pacman.cloud/pacman-cloud-notifications/pom.xml b/jobs/pacman-cloud-notifications/target/classes/META-INF/maven/com.tmobile.pacman.cloud/pacman-cloud-notifications/pom.xml new file mode 100644 index 000000000..522c85fdf --- /dev/null +++ b/jobs/pacman-cloud-notifications/target/classes/META-INF/maven/com.tmobile.pacman.cloud/pacman-cloud-notifications/pom.xml @@ -0,0 +1,263 @@ + + 4.0.0 + + com.tmobile.pacman.cloud + pacman-cloud-notifications + 0.0.1-SNAPSHOT + jar + + pacman-cloud-notifications + Cloud Notification service + + + UTF-8 + 1.8 + 1.6.4 + + + + org.powermock + powermock-api-mockito + ${powermock.version} + test + + + + org.powermock + powermock-module-junit4 + ${powermock.version} + test + + + + org.powermock + powermock-module-junit4 + ${powermock.version} + test + + + + org.mockito + mockito-core + 1.10.19 + test + + + org.springframework + spring-context + 4.3.8.RELEASE + + + org.springframework + spring-test + 5.0.8.RELEASE + test + + + com.google.guava + guava + 19.0 + + + org.apache.logging.log4j + log4j-api + 2.9.0 + + + org.apache.logging.log4j + log4j-core + 2.9.0 + + + org.elasticsearch + elasticsearch + 5.6.2 + + + org.elasticsearch.client + transport + 5.6.2 + + + + com.google.code.gson + gson + 2.8.1 + + + + commons-collections + commons-collections + 3.2.2 + + + org.apache.commons + commons-lang3 + 3.1 + + + com.tmobile.pacman + batch-commons + 1.0.0-SNAPSHOT + provided + + + com.amazonaws + aws-java-sdk-s3 + + + com.amazonaws + aws-java-sdk-rds + + + com.amazonaws + aws-java-sdk-events + + + com.amazonaws + aws-java-sdk-cloudwatch + + + com.amazonaws + aws-java-sdk-dynamodb + + + com.amazonaws + aws-java-sdk-cloudtrail + + + com.amazonaws + aws-java-sdk-core + + + com.amazonaws + + aws-java-sdk-elasticloadbalancingv2 + + + + com.amazonaws + aws-java-sdk-ec2 + + + com.amazonaws + aws-java-sdk-ses + + + com.amazonaws + aws-java-sdk-kms + + + com.amazonaws + aws-lambda-java-core + + + com.amazonaws + aws-java-sdk-iam + + + com.amazonaws + aws-java-sdk-config + + + com.amazonaws + aws-java-sdk-route53 + + + com.amazonaws + aws-java-sdk-sts + + + com.amazonaws + aws-java-sdk-api-gateway + + + com.amazonaws + aws-java-sdk-lambda + + + com.amazonaws + aws-java-sdk-guardduty + + + com.amazonaws + + aws-java-sdk-elasticloadbalancing + + + + + + org.apache.httpcomponents + httpclient + 4.5.3 + + + org.elasticsearch.client + rest + 5.3.0 + + + com.fasterxml.jackson.core + jackson-databind + 2.8.7 + + + mysql + mysql-connector-java + 5.1.17 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + 1.8 + 1.8 + + + + maven-assembly-plugin + + + build-a + + + jar-with-dependencies + + pacman-cloud-notifications + + package + + single + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.6.201602180812 + + + + prepare-agent + + + + report + test + + report + + + + + + + \ No newline at end of file diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/common/AutoFixAction.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/common/AutoFixAction.java index 61259a8a0..037273847 100644 --- a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/common/AutoFixAction.java +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/common/AutoFixAction.java @@ -1,70 +1,70 @@ -/******************************************************************************* - * Copyright 2018 T Mobile, 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. - ******************************************************************************/ - -package com.tmobile.pacman.common; - -// TODO: Auto-generated Javadoc -/** - * The Enum AutoFixAction. - * - * @author kkumar - */ -public enum AutoFixAction { - - /** The email. */ - EMAIL("email"), - /** The autofix action email. */ - AUTOFIX_ACTION_EMAIL("autofixEmail"), - /** The autofix action fix. */ - AUTOFIX_ACTION_FIX("autofixAction"), - /** The autofix action tag. */ - AUTOFIX_ACTION_TAG( - "autofixTag"), - /** The autofix action backup. */ - AUTOFIX_ACTION_BACKUP("autofixBackup"), - /** The autofix action email remind exception expiry. */ - AUTOFIX_ACTION_EMAIL_REMIND_EXCEPTION_EXPIRY( - "remindExceptionExpiry"), - /** The autofix action exempted. */ - AUTOFIX_ACTION_EXEMPTED("autofixExempted"), - /** The do nothing. */ - DO_NOTHING("doNothing"), -/** unable to determine */ -UNABLE_TO_DETERMINE("unableToDetermine"); - - - /** The action. */ - String action; - - /** - * Instantiates a new auto fix action. - * - * @param action the action - */ - AutoFixAction(String action) { - this.action = action; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Enum#toString() - */ - @Override - public String toString() { - return this.action.toString(); - } -} +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ + +package com.tmobile.pacman.common; + +// TODO: Auto-generated Javadoc +/** + * The Enum AutoFixAction. + * + * @author kkumar + */ +public enum AutoFixAction { + + /** The email. */ + EMAIL("email"), + /** The autofix action email. */ + AUTOFIX_ACTION_EMAIL("autofixEmail"), + /** The autofix action fix. */ + AUTOFIX_ACTION_FIX("autofixAction"), + /** The autofix action tag. */ + AUTOFIX_ACTION_TAG( + "autofixTag"), + /** The autofix action backup. */ + AUTOFIX_ACTION_BACKUP("autofixBackup"), + /** The autofix action email remind exception expiry. */ + AUTOFIX_ACTION_EMAIL_REMIND_EXCEPTION_EXPIRY( + "remindExceptionExpiry"), + /** The autofix action exempted. */ + AUTOFIX_ACTION_EXEMPTED("autofixExempted"), + /** The do nothing. */ + DO_NOTHING("doNothing"), +/** unable to determine */ +UNABLE_TO_DETERMINE("unableToDetermine"), CREATE_AUTO_FIX_PLAN("createAutoFixPlan"), SUSPEND_AUTO_FIX_PLAN("suspendAutoFixPlan"), SYNC_AUTO_FIX_PLAN("syncAutoFixPlan"); + + + /** The action. */ + String action; + + /** + * Instantiates a new auto fix action. + * + * @param action the action + */ + AutoFixAction(String action) { + this.action = action; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Enum#toString() + */ + @Override + public String toString() { + return this.action.toString(); + } +} diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/common/PacmanSdkConstants.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/common/PacmanSdkConstants.java index 394539351..5c4f9ddce 100644 --- a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/common/PacmanSdkConstants.java +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/common/PacmanSdkConstants.java @@ -599,5 +599,11 @@ public interface PacmanSdkConstants extends com.tmobile.pacman.commons.PacmanSdk /** The app elb arn attribute name. */ String APP_ELB_ARN_ATTRIBUTE_NAME="resourceDisplayId"; + + /** The autofix blacklist accounts prefix. */ + String AUTOFIX_BLACKLIST_ACCOUNTS_PREFIX = "autofix.blacklist.accounts."; + + /** The pac monitor slack user. */ + String PAC_MONITOR_SLACK_USER = "pacman.monitoring.slack.user"; } diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/AutoFixPlan.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/AutoFixPlan.java new file mode 100644 index 000000000..8a73dff96 --- /dev/null +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/AutoFixPlan.java @@ -0,0 +1,178 @@ +/** + Copyright (C) 2017 T Mobile Inc - All Rights Reserve + Purpose: + Author :kkumar28 + Modified Date: Jun 19, 2019 + +**/ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.commons.autofix; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @author kkumar28 + * + */ +public class AutoFixPlan implements Serializable , PropertyChangeListener { + + /** + * + */ + private static final long serialVersionUID = 1L; + private List planItems; + private String planId; + private String ruleId; + private String issueId; + private String resourceId; + private String docId; // system wide unique id of the resource + private String resourceType; + private Status planStatus; + /*this property will be used to monitor the state of line items , when all the line items are completed, plan status + * should also update*/ + private transient final PropertyChangeSupport pcs; // transient is required else Gson will throw StackOverflow Exception while serializing the plan for posting + + /** + * + */ + private AutoFixPlan() { + super(); + pcs = new PropertyChangeSupport(this); + this.pcs.addPropertyChangeListener("planItems", this); + planItems = new ArrayList<>(); + } + + /** + * + * @param planId + * @param ruleId + * @param issueId + * @param resourceId + */ + public AutoFixPlan(String ruleId, String issueId, String resourceId,String docId,String resourceType) { + this(); + this.planId = issueId; + this.ruleId = ruleId; + this.issueId = issueId; + this.resourceId = resourceId; + this.docId=docId; + this.resourceType=resourceType; + this.planStatus = Status.SCHEDULED; + } + + + /** + * + * @param index + * @return + */ + public Boolean markPlanItemStatus(Integer index,Status status){ + Optional pi = this.getPlanItems().stream().filter(item->item.getIndex().equals(index)).findFirst(); + if(pi.isPresent()) { + pi.get().setStatus(status); + } + this.pcs.firePropertyChange("planItems", "", status); + return Status.COMPLETED.equals(pi.get().getStatus()); + + } + + /** + * + * @param pi + * @return + */ + public Boolean addPlanItem(PlanItem pi){ + return planItems.add(pi); + } + + public List getPlanItems() { + return planItems; + } + + public String getPlanId() { + return planId; + } + + /** + * + * @param index + * @return + */ + public PlanItem getPlanItemByIndex(Integer index){ + return planItems.get(index); + } + + public String getRuleId() { + return ruleId; + } + + public void setRuleId(String ruleId) { + this.ruleId = ruleId; + } + + public String getIssueId() { + return issueId; + } + + public void setIssueId(String issueId) { + this.issueId = issueId; + } + + public String getResourceId() { + return resourceId; + } + + public void setResourceId(String resourceId) { + this.resourceId = resourceId; + } + + public String getResourceType() { + return resourceType; + } + + public String getDocId() { + return docId; + } + + public Status getPlanStatus() { + return planStatus; + } + + public void setPlanStatus(Status planStatus) { + this.planStatus = planStatus; + } + + /* (non-Javadoc) + * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) + * this method will set the final plan status if all the plan items are completed. + */ + @Override + public void propertyChange(PropertyChangeEvent evt) { + List pItems = this.planItems.stream().filter(planItem->!planItem.getStatus().equals(Status.COMPLETED)).collect(Collectors.toList()); + if(!(pItems.size()>0)){ + this .planStatus=Status.COMPLETED; + } + +} +} diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/PlanItem.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/PlanItem.java new file mode 100644 index 000000000..ecf203abd --- /dev/null +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/PlanItem.java @@ -0,0 +1,109 @@ +/** + Copyright (C) 2017 T Mobile Inc - All Rights Reserve + Purpose: + Author :kkumar28 + Modified Date: Jun 19, 2019 + +**/ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.commons.autofix; + +import java.io.Serializable; + +import com.tmobile.pacman.common.AutoFixAction; + +/** + * @author kkumar28 + * + */ +public class PlanItem implements Serializable { + + + /** + * + */ + private static final long serialVersionUID = 1L; + Integer index; + private AutoFixAction action; + private String plannedActionTime; + private Status status; + private String actualActiontime; + + /** + * + */ + public PlanItem() { + } + + /** + * + * @param action + * @param triggerTime + */ + public PlanItem(Integer index ,AutoFixAction action, String plannedActionTime,Status status) { + super(); + this.index = index; + this.action = action; + this.plannedActionTime = plannedActionTime; + this.status=status; + } + + /** + * + * @return + */ + public AutoFixAction getAction() { + return action; + } + /** + * + * @param action + */ + public void setAction(AutoFixAction action) { + this.action = action; + } + + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + public Integer getIndex() { + return index; + } + + public String getPlannedActionTime() { + return plannedActionTime; + } + + public void setPlannedActionTime(String plannedActionTime) { + this.plannedActionTime = plannedActionTime; + } + + public String getActualActiontime() { + return actualActiontime; + } + + public void setActualActiontime(String actualActiontime) { + this.actualActiontime = actualActiontime; + } + +} diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/Status.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/Status.java new file mode 100644 index 000000000..b35ed71d4 --- /dev/null +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/Status.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +/** + Copyright (C) 2017 T Mobile Inc - All Rights Reserve + Purpose: + Author :kkumar28 + Modified Date: Apr 3, 2018 + +**/ +/* + *Copyright 2016-2017 T Mobile, Inc. or its affiliates. All Rights Reserved. + * + *Licensed under the Amazon Software License (the "License"). You may not use + * this file except in compliance with the License. A copy of the License is located at + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.tmobile.pacman.commons.autofix; + +// TODO: Auto-generated Javadoc +/** + * The Enum AutoFixAction. + * + * @author kkumar28 + */ +public enum Status { + + RESCHEDULED("rescheduled"), + SCHEDULED("scheduled"), + COMPLETED("completed"), + CLOSED("closed"), SUSPENDED("suspended"); + + /** + * + */ + String status; + + /** + * Instantiates a new auto fix action. + * + * @param action the action + */ + Status(String status) { + this.status = status; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Enum#toString() + */ + @Override + public String toString() { + return this.status.toString(); + } +} diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/AutoFixManager.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/AutoFixManager.java index 7eeaf6333..0b44b76b7 100644 --- a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/AutoFixManager.java +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/AutoFixManager.java @@ -1,19 +1,25 @@ /******************************************************************************* * Copyright 2018 T Mobile, 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. ******************************************************************************/ - +/** + Copyright (C) 2017 T Mobile Inc - All Rights Reserve + Purpose: + Author :kkumar28 + Modified Date: Sep 26, 2017 + +**/ package com.tmobile.pacman.commons.autofix.manager; import java.lang.reflect.InvocationTargetException; @@ -44,13 +50,16 @@ import com.tmobile.pacman.common.AutoFixAction; import com.tmobile.pacman.common.PacmanSdkConstants; import com.tmobile.pacman.commons.AWSService; +import com.tmobile.pacman.commons.autofix.AutoFixPlan; import com.tmobile.pacman.commons.autofix.FixResult; +import com.tmobile.pacman.commons.autofix.Status; import com.tmobile.pacman.commons.aws.clients.AWSClientManager; import com.tmobile.pacman.commons.aws.clients.impl.AWSClientManagerImpl; import com.tmobile.pacman.commons.exception.UnableToCreateClientException; import com.tmobile.pacman.dto.AutoFixTransaction; import com.tmobile.pacman.dto.IssueException; import com.tmobile.pacman.dto.ResourceOwner; +import com.tmobile.pacman.integrations.slack.SlackMessageRelay; import com.tmobile.pacman.publisher.impl.ElasticSearchDataPublisher; import com.tmobile.pacman.service.ExceptionManager; import com.tmobile.pacman.service.ExceptionManagerImpl; @@ -63,7 +72,7 @@ /** * The Class AutoFixManager. * - * @author kkumar + * @author kkumar28 */ public class AutoFixManager { @@ -120,6 +129,7 @@ public Map performAutoFixs(Map ruleParam, ResourceOwner resourceOwner = null; String resourceId = null; String targetType = null; + String parentDocId = null; String annotationId = null; String exceptionExpiryDate = null; Class fixClass = null; @@ -141,6 +151,7 @@ public Map performAutoFixs(Map ruleParam, Integer resourceOwnerNotFoundCounter = 0; Integer didNothingCounter = 0; Integer backupConfigCounter = 0; + Integer autoFixPlanCreatedCounter=0; String executionId = ruleParam.get(PacmanSdkConstants.EXECUTION_ID); String transactionId = null; @@ -149,6 +160,7 @@ public Map performAutoFixs(Map ruleParam, MDC.put("ruleId", ruleParam.get(PacmanSdkConstants.RULE_ID)); String type = "autofix"; + logger.info("autoFixmanager start"); // check fix exists for rule try { @@ -169,22 +181,25 @@ public Map performAutoFixs(Map ruleParam, autoFixStats.put("auto-fix-error", "error finding fix class - >" + e.getMessage()); return autoFixStats; } - - try { - existingIssues = getOpenAndExcepmtedAnnotationForRule(ruleParam); + existingIssues = getOpenAndExcepmtedAnnotationForRule(ruleParam); } catch (Exception e) { logger.error("unable to get open issue for rule" + ruleId); autoFixStats.put("auto-fix-error", "unable to get open issue for rule" + ruleId + "-- >" + e.getMessage()); return autoFixStats; } - + int count = 0; + AutoFixPlanManager autoFixPlanManager = new AutoFixPlanManager(); + AutoFixPlan autoFixPlan=null; for (Map annotation : existingIssues) { List addDetailsToLogTrans = new ArrayList<>(); + logger.debug("display issue count {}",count++); targetType = annotation.get("targetType"); resourceId =annotation.get("_resourceid"); + parentDocId = annotation.get(PacmanSdkConstants.DOC_ID); transactionId = CommonUtils.getUniqueIdForString(resourceId); - annotationId = annotation.get(PacmanSdkConstants.ES_DOC_ID_KEY); // this + autoFixPlan=null; + annotationId = annotation.get(PacmanSdkConstants.ES_DOC_ID_KEY); // this // will // be // used @@ -195,16 +210,16 @@ public Map performAutoFixs(Map ruleParam, // for // the // resource - targetType = getTargetTypeAlias(targetType); - + //targetType = getTargetTypeAlias(targetType); + // commenting this , as alias is only used to create client, so using the function directly below - serviceType = AWSService.valueOf(targetType.toUpperCase()); + serviceType = AWSService.valueOf(getTargetTypeAlias(targetType).toUpperCase()); // create client - if(isAccountWhiteListedForAutoFix(annotation.get(PacmanSdkConstants.ACCOUNT_ID),ruleParam.get(PacmanSdkConstants.RULE_ID))){ - clientMap = getAWSClient(targetType, annotation, CommonUtils.getPropValue(PacmanSdkConstants.AUTO_FIX_ROLE_NAME)); + if(!isAccountBlackListedForAutoFix(annotation.get(PacmanSdkConstants.ACCOUNT_ID),ruleParam.get(PacmanSdkConstants.RULE_ID))){ + clientMap = getAWSClient(getTargetTypeAlias(targetType), annotation, CommonUtils.getPropValue(PacmanSdkConstants.AUTO_FIX_ROLE_NAME)); }else{ - logger.info("Account id is not whitelisted {}" , annotation.get(PacmanSdkConstants.ACCOUNT_ID)); + logger.info("Account id is blacklisted {}" , annotation.get(PacmanSdkConstants.ACCOUNT_ID)); continue; } logger.debug(String.format("processing for %s " , resourceId)); @@ -216,18 +231,28 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) } logger.debug(String.format("not exempted by conditions --> %s " , resourceId)); + try{ + autoFixPlan = autoFixPlanManager.getAutoFixPalnForResource(resourceId, ruleParam); // find plan associates with resource and issue + }catch (Exception e) { + logger.debug("no plan found for resource {}",resourceId); + } + if(null!=autoFixPlan){ + logger.debug("got autofix plan with id" + autoFixPlan.getPlanId()); + } + + // if resource is exempted tag the resource String issueStatus = annotation.get("issueStatus"); // find resource owner resourceOwner = ownerService.findResourceOwnerByIdAndType(resourceId, serviceType); - autoFixAction = nextStepManager.getNextStep(ruleParam.get(PacmanSdkConstants.RULE_ID),normalizeResourceId(resourceId, serviceType,annotation),resourceId, clientMap, serviceType); + // the following method will also trigger a auto fix plan creation if no action is taken on resource yet + autoFixAction = nextStepManager.getNextStep(ruleParam,normalizeResourceId(resourceId, serviceType,annotation),resourceId, clientMap, serviceType); if(AutoFixAction.UNABLE_TO_DETERMINE==autoFixAction){ autoFixTrans.add(new AutoFixTransaction(AutoFixAction.UNABLE_TO_DETERMINE, resourceId,ruleId, - executionId, transactionId, "unable to determine the next set of action , not processing for this pass",type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION))); + executionId, transactionId, "unable to determine the next set of action , not processing for this pass",type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION),parentDocId)); continue; } - if (PacmanSdkConstants.ISSUE_STATUS_EXEMPTED_VALUE.equals(issueStatus)) { try { // get the exception @@ -236,15 +261,22 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) // notify resource owner about exemption if he was already // notified for violation // check the next step - exceptionExpiryDate = getMaxExceptionExpiry(annotationId, resourceId, exemptedResourcesForRule, individuallyExcemptedIssues); - + try{ + if(autoFixPlan!=null && !Status.SUSPENDED.equals(autoFixPlan.getPlanStatus())) // suspend if not already suspended + autoFixPlanManager.suspendPlan(autoFixPlan,ruleParam); + logger.debug(String.format("auto fix plan suspended for plan # --> %s",autoFixPlan.getPlanId())); + autoFixTrans.add(new AutoFixTransaction(AutoFixAction.SUSPEND_AUTO_FIX_PLAN, resourceId,ruleId, executionId, + transactionId, "auto fix plan suspended with id" + autoFixPlan.getPlanId(),type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION),parentDocId)); + }catch(Exception e) { + logger.error("unable to sync plna status , while resource is exempted, will try in next pass",e); + } if (AutoFixAction.AUTOFIX_ACTION_FIX == autoFixAction) { Map pacTag = createPacTag(exceptionExpiryDate); taggingManager.tagResource(normalizeResourceId(resourceId, serviceType,annotation), clientMap, serviceType, pacTag); autoFixTrans.add(new AutoFixTransaction(AutoFixAction.AUTOFIX_ACTION_TAG, resourceId,ruleId, - executionId, transactionId, "resource tagged",type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION))); + executionId, transactionId, "resource tagged",type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION),parentDocId)); resourcesTaggedCounter++; // this means this resource was exempted after sending // the violation emails and exempted afterwards @@ -253,7 +285,6 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) logger.error(String.format("unable to send email to %s" ,resourceOwner.toString())); } } - // should be removed for deployment // throw new Exception("in case you run it by mistake it // will tag all buckets , hence checking in with this guard @@ -266,7 +297,20 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) } } else { try { - + // if issue is not exempted create auto fix plan + try{ + if(null==autoFixPlan && !nextStepManager.isSilentFixEnabledForRule(ruleId)){ + autoFixPlan = autoFixPlanManager.createPlan(ruleId, annotation.get(PacmanSdkConstants.ANNOTATION_PK), resourceId, + annotation.get(PacmanSdkConstants.DOC_ID), targetType, NextStepManager.getMaxNotifications(ruleId), NextStepManager.getAutoFixDelay(ruleId)); + autoFixPlanManager.publishPlan(ruleParam, autoFixPlan);autoFixPlanCreatedCounter++; + logger.debug("auto fix plan published with id {} " , autoFixPlan.getPlanId()); + autoFixTrans.add(new AutoFixTransaction(AutoFixAction.CREATE_AUTO_FIX_PLAN, resourceId,ruleId, executionId, + transactionId, "auto fix plan created with id" + autoFixPlan.getPlanId(),type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION),parentDocId)); + } + }catch (Exception e) { + logger.error(String.format("unable to create autofix plan for %s,%s,%s,%s,%s",ruleId, annotation.get(PacmanSdkConstants.ANNOTATION_PK), resourceId, annotation.get(PacmanSdkConstants.DOC_ID), targetType),e); + } + logger.debug(String.format("found the resource Owner %s" , resourceOwner.toString())); if (Strings.isNullOrEmpty(resourceOwner.getEmailId()) && !Strings.isNullOrEmpty(resourceOwner.getName()) @@ -290,8 +334,6 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) resourceOwner .setEmailId(CommonUtils.getPropValue(PacmanSdkConstants.ORPHAN_RESOURCE_OWNER_EMAIL)); } - - } catch (Exception e) { logger.error(String.format("unable to find the resource owner for %s " , resourceId)); resourceOwner = new ResourceOwner("CSO", @@ -302,13 +344,13 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) if (AutoFixAction.DO_NOTHING == autoFixAction) { didNothingCounter++; autoFixTrans.add(new AutoFixTransaction(AutoFixAction.DO_NOTHING, resourceId,ruleId, executionId, - transactionId, "waiting for 24 hours before fixing the violation",type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION))); + transactionId, "waiting for 24 hours before fixing the violation",type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION),parentDocId)); continue; } if (AutoFixAction.AUTOFIX_ACTION_EMAIL == autoFixAction - && isAccountWhiteListedForAutoFix(annotation.get(PacmanSdkConstants.ACCOUNT_ID), ruleId)) { + && !isAccountBlackListedForAutoFix(annotation.get(PacmanSdkConstants.ACCOUNT_ID), ruleId)) { long autofixExpiring=nextStepManager.getAutoFixExpirationTimeInHours(ruleParam.get(PacmanSdkConstants.RULE_ID),resourceId); /*ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("America/Los_Angeles")).plusHours(Integer.parseInt(CommonUtils.getPropValue(PacmanSdkConstants.PAC_AUTO_FIX_DELAY_KEY +"."+ ruleParam.get(PacmanSdkConstants.RULE_ID))));*/ @@ -316,20 +358,30 @@ && isAccountWhiteListedForAutoFix(annotation.get(PacmanSdkConstants.ACCOUNT_ID), String expiringTime = zonedDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); if (!MailUtils.sendAutoFixNotification(ruleParam, resourceOwner, targetType, resourceId, expiringTime, AutoFixAction.AUTOFIX_ACTION_EMAIL,addDetailsToLogTrans,annotation)) { - logger.error(String.format("unable to send email to %s" , resourceOwner.toString())); + String msg = String.format("unable to send email to %s for vulnerable resource %s, hence skipping this pass" , resourceOwner.toString(),resourceId); + logger.error(msg); + new SlackMessageRelay().sendMessage(CommonUtils.getPropValue(PacmanSdkConstants.PAC_MONITOR_SLACK_USER), msg); continue; // notification was not sent, skip further // execution } logger.debug(String.format("email sent to %s" , resourceOwner.toString())); autoFixTrans.add(new AutoFixTransaction(AutoFixAction.AUTOFIX_ACTION_EMAIL, resourceId,ruleId, executionId, - transactionId, "email sent to " + resourceOwner.getEmailId(),type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION))); + transactionId, "email sent to " + resourceOwner.getEmailId(),type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION),parentDocId)); notificationSentCounter++; try { - nextStepManager.postFixAction(resourceId, AutoFixAction.EMAIL); + nextStepManager.postFixAction(resourceId, AutoFixAction.EMAIL); + try{ + if(null==autoFixPlan && !nextStepManager.isSilentFixEnabledForRule(ruleId)){ + autoFixPlanManager.synchronizeAndRepublishAutoFixPlan(autoFixPlan,resourceId, ruleParam); + autoFixTrans.add(new AutoFixTransaction(AutoFixAction.SYNC_AUTO_FIX_PLAN, resourceId,ruleId, executionId, + transactionId, "auto fix plan synchronized with id" + autoFixPlan.getPlanId(),type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION),parentDocId)); + } + }catch(Exception e){ + logger.error(String.format("unable to syn plan for %s" , resourceId),e); + } } catch (Exception e) { logger.error(String.format("unable to post email action for %s ", resourceId)); } - fixResults.add(new FixResult(PacmanSdkConstants.STATUS_SUCCESS_CODE, String.format("email sent to owner of resource %s" , resourceId))); continue; @@ -344,13 +396,13 @@ && isAccountWhiteListedForAutoFix(annotation.get(PacmanSdkConstants.ACCOUNT_ID), continue; } autoFixTrans.add(new AutoFixTransaction(AutoFixAction.AUTOFIX_ACTION_BACKUP, resourceId,ruleId, - executionId, transactionId, "resource aconfig backedup",type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION))); + executionId, transactionId, "resource aconfig backedup",type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION),parentDocId)); backupConfigCounter++; FixResult result = (FixResult) executeMethod.invoke(fixObject, annotation, clientMap, ruleParam); fixResults .add(result); autoFixTrans.add(new AutoFixTransaction(AutoFixAction.AUTOFIX_ACTION_FIX, resourceId,ruleId, - executionId, transactionId, result.toString(),type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION))); + executionId, transactionId, result.toString(),type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION),parentDocId)); if (!nextStepManager.isSilentFixEnabledForRule(ruleId)){ if(null!=addDetailsToTransactionLogMethod){ @@ -358,7 +410,17 @@ && isAccountWhiteListedForAutoFix(annotation.get(PacmanSdkConstants.ACCOUNT_ID), } MailUtils.sendAutoFixNotification(ruleParam, resourceOwner, targetType, resourceId, "", AutoFixAction.AUTOFIX_ACTION_FIX,addDetailsToLogTrans,annotation); - logger.debug(String.format("autofixed the resource %s and email sent to %s", + nextStepManager.postFixAction(resourceId, AutoFixAction.AUTOFIX_ACTION_FIX); + try{ + if(null==autoFixPlan && !nextStepManager.isSilentFixEnabledForRule(ruleId)){ + autoFixPlanManager.synchronizeAndRepublishAutoFixPlan(autoFixPlan, resourceId,ruleParam); + autoFixTrans.add(new AutoFixTransaction(AutoFixAction.SYNC_AUTO_FIX_PLAN, resourceId,ruleId, executionId, + transactionId, "auto fix plan synchronized with id" + autoFixPlan.getPlanId(),type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION),parentDocId)); + } + }catch(Exception e){ + logger.error(String.format("unable to syn plan for %s" , resourceId),e); + } + logger.debug(String.format("autofixed the resource %s and email sent to %s and plan synchronized", resourceId, resourceOwner.toString())); } // if(annotation.get("policyId").equalsIgnoreCase("PacMan_ApplicationTagsShouldBeValid_version-1")){ @@ -390,6 +452,8 @@ && isAccountWhiteListedForAutoFix(annotation.get(PacmanSdkConstants.ACCOUNT_ID), } // if issue open }// for + + autoFixPlanManager.releaseResourfes(); //Silent fix send Digest email if(!silentautoFixTrans.isEmpty() && nextStepManager.isSilentFixEnabledForRule(ruleId)){ @@ -410,11 +474,30 @@ && isAccountWhiteListedForAutoFix(annotation.get(PacmanSdkConstants.ACCOUNT_ID), autoFixStats.put("resourceOwnerNotFound", resourceOwnerNotFoundCounter); autoFixStats.put("didNothingCounter", didNothingCounter); autoFixStats.put("backupConfigCounter", backupConfigCounter); - + autoFixStats.put("autoFixPlanCreatedCounter", autoFixPlanCreatedCounter); + logger.info("autoFixmanager end"); return autoFixStats; } + /** + * return the right id needed for operation + * @param resourceId + * @param serviceType + * @param annotation + * @return + */ +private String normalizeResourceId(String resourceId, AWSService serviceType, Map annotation) { + + switch(serviceType){ + + case ELB_APP: + return annotation.get(PacmanSdkConstants.APP_ELB_ARN_ATTRIBUTE_NAME); + default: + return resourceId; + } +} + /** * @param targetType * @return @@ -457,7 +540,16 @@ private Method findIsFixCandidateMethod(Object fixObject, Method isFixCandidateM */ private boolean isAFixCandidate(Method isFixCandidateMethod, Object fixObject, String resourceId, String targetType, Map clientMap, Map ruleParam, Map annotation) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { - return null==isFixCandidateMethod?true:(Boolean)isFixCandidateMethod.invoke(fixObject, resourceId, targetType, clientMap, ruleParam,annotation); + try{ + Boolean isFixCandidate = null==isFixCandidateMethod?true:(Boolean)isFixCandidateMethod.invoke(fixObject, resourceId, targetType, clientMap, ruleParam,annotation); + logger.debug("is fix candidate ==> " + isFixCandidate); + return isFixCandidate; + + }catch(Exception e){ + logger.error("error executing is fix candidate ",e); + return Boolean.FALSE; + } + } /** @@ -618,6 +710,26 @@ private Date getResourceCreatedDate(final String resourceId, String resourceType } } +// /** +// * Checks if is account white listed for auto fix. +// * +// * @param account the account +// * @param ruleId the rule id +// * @return true, if is account white listed for auto fix +// */ +// private boolean isAccountWhiteListedForAutoFix(String account, String ruleId) { +// try { +// String whitelistStr = CommonUtils +// .getPropValue(PacmanSdkConstants.AUTOFIX_WHITELIST_ACCOUNTS_PREFIX + ruleId); +// List whitelist = Arrays.asList(whitelistStr.split("\\s*,\\s*")); +// return whitelist.contains(account); +// } catch (Exception e) { +// logger.error(String.format("%s account assumed not whitelisted for autofix for ruleId %s" ,account, ruleId)); +// return Boolean.FALSE; +// } +// } + + /** * Checks if is account white listed for auto fix. * @@ -625,17 +737,20 @@ private Date getResourceCreatedDate(final String resourceId, String resourceType * @param ruleId the rule id * @return true, if is account white listed for auto fix */ - private boolean isAccountWhiteListedForAutoFix(String account, String ruleId) { + private boolean isAccountBlackListedForAutoFix(String account, String ruleId) { try { - String whitelistStr = CommonUtils - .getPropValue(PacmanSdkConstants.AUTOFIX_WHITELIST_ACCOUNTS_PREFIX + ruleId); - List whitelist = Arrays.asList(whitelistStr.split("\\s*,\\s*")); - return whitelist.contains(account); + String blacklistStr = CommonUtils + .getPropValue(PacmanSdkConstants.AUTOFIX_BLACKLIST_ACCOUNTS_PREFIX + ruleId); + List blacklist = Arrays.asList(blacklistStr.split("\\s*,\\s*")); + return blacklist.contains(account); } catch (Exception e) { - logger.error(String.format("account not whitelisted for autofix for ruleId %s" , ruleId)); - return Boolean.FALSE; + logger.error(String.format("%s account is assumed blacklisted for autofix for ruleId %s" ,account, ruleId)); + return Boolean.TRUE; // be defensive , if not able to figure out , assume blacklist } } + + + /** * Gets the open and excepmted annotation for rule. @@ -706,26 +821,5 @@ public static void main(String[] args) throws Exception { AutoFixManager autoFixManager = new AutoFixManager(); autoFixManager.performAutoFixs(ruleParam, excemptedResourcesForRule, individuallyExcemptedIssues); - } - - /** - * return the right id needed for operation - * - * @param resourceId - * @param serviceType - * @param annotation - * @return - */ - private String normalizeResourceId(String resourceId,AWSService serviceType, Map annotation) { - - switch (serviceType) { - - case ELB_APP: - return annotation - .get(PacmanSdkConstants.APP_ELB_ARN_ATTRIBUTE_NAME); - default: - return resourceId; - } - } } diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/AutoFixPlanManager.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/AutoFixPlanManager.java new file mode 100644 index 000000000..e97112701 --- /dev/null +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/AutoFixPlanManager.java @@ -0,0 +1,268 @@ +/** + Copyright (C) 2017 T Mobile Inc - All Rights Reserve + Purpose: + Author :kkumar28 + Modified Date: Jun 19, 2019 + +**/ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.commons.autofix.manager; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.IntStream; + +import org.joda.time.DateTime; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.tmobile.pacman.common.AutoFixAction; +import com.tmobile.pacman.common.PacmanSdkConstants; +import com.tmobile.pacman.commons.autofix.AutoFixPlan; +import com.tmobile.pacman.commons.autofix.PlanItem; +import com.tmobile.pacman.commons.autofix.Status; +import com.tmobile.pacman.publisher.impl.ElasticSearchDataPublisher; +import com.tmobile.pacman.publisher.impl.ElasticSearchDataReader; +import com.tmobile.pacman.util.CommonUtils; + +/** + * @author kkumar28 + * This class will be used to manage auto fix plan + * A typical plan looks like a series of notifications followed by an auto fix action + */ +public class AutoFixPlanManager{ + + + /** + * + */ + private static final String AUTO_FIX_PLAN_TYPE = "autofixplan"; + /** + * + */ + private static final Logger logger = LoggerFactory.getLogger(AutoFixPlanManager.class); + + + + private ElasticSearchDataPublisher dp; + + private ElasticSearchDataReader dr; + + + /* (non-Javadoc) + * @see java.lang.Object#finalize() + */ + @Override + protected void finalize() throws Throwable { + dp.close(); + super.finalize(); + } + + /** + * + * @param ruleId + * @param issueId + * @param resourceId : id of the resource as specified in cloud + * @param docId id of the resource as specified in pacbot es index + * @param resourceType + * @param numberOfNotificatons + * @param waitTimeBeforeAutoFix + * @return + */ + public AutoFixPlan createPlan(String ruleId, String issueId, String resourceId,String docId, String resourceType,int numberOfNotificatons, int waitTimeBeforeAutoFix) + { + AutoFixPlan autoFixPlan = createTransientPlan(ruleId, issueId, resourceId,docId,resourceType,numberOfNotificatons, waitTimeBeforeAutoFix); + return autoFixPlan; + } + + + /** + * + * @param numberOfNotificatons + * @param waitTimeBeforeAutoFix + * @return AutoFixPlan + */ + public AutoFixPlan createTransientPlan(String ruleId, String issueId, String resourceId,String docId,String resourceType,int numberOfNotificatons, int waitTimeBeforeAutoFix) + { + AutoFixPlan autoFixPlan = new AutoFixPlan(ruleId, issueId, resourceId,docId,resourceType); + IntStream.range(0, numberOfNotificatons).forEach( + index->{ + autoFixPlan.addPlanItem(new PlanItem(index,AutoFixAction.AUTOFIX_ACTION_EMAIL,new DateTime().plusHours(index*(waitTimeBeforeAutoFix/numberOfNotificatons)).toDateTimeISO().toString(),Status.SCHEDULED)); + } + ); + autoFixPlan.addPlanItem(new PlanItem(numberOfNotificatons,AutoFixAction.AUTOFIX_ACTION_FIX, new DateTime().plusHours(numberOfNotificatons*(waitTimeBeforeAutoFix/numberOfNotificatons)).toDateTimeISO().toString(),Status.SCHEDULED)); + return autoFixPlan; + } + + /** + * + * @param plan + * @throws MalformedURLException + */ + public void publishPlan(Map ruleParam,AutoFixPlan plan) throws MalformedURLException{ + if(dp==null){ + dp = new ElasticSearchDataPublisher(); + } + dp.postDocAsChildOfType(plan, plan.getPlanId(), ruleParam, AUTO_FIX_PLAN_TYPE, plan.getResourceType(), plan.getDocId()); + } + + /** + * + * @param planId + * @param itemIndex + * @throws Exception + */ + public void updatePlanItemStatusAndPublish(String planId,int itemIndex,Map ruleParam , String parentId, Status status) throws Exception{ + AutoFixPlan plan = getAutoFixPlan(CommonUtils.getIndexNameFromRuleParam(ruleParam), AUTO_FIX_PLAN_TYPE, planId,parentId); + //1: getPlan() + //2: Update item at itemIndex + plan.markPlanItemStatus(itemIndex,status); + // publish plan again + publishPlan(ruleParam, plan); + } + + + /** + * + * @param planId + * @param itemIndex + * @throws Exception + */ + public AutoFixPlan updatePlanItemStatus(AutoFixPlan plan,Integer itemIndex,Status status){ + plan.markPlanItemStatus(itemIndex,status); + return plan; + } + + + /** + * + * @param resourceId + * @return + * @throws Exception + * @throws IOException + */ + public AutoFixPlan getAutoFixPalnForResource(String resourceId,Map ruleParam) throws IOException, Exception{ + AutoFixPlan plan = getAutoFixPlan(resourceId,ElasticSearchDataPublisher.getIndexName(ruleParam)); + return plan; + } + + + /** + * @param resourceId + * @param indexNameFromRuleParam + * @return + * @throws Exception + * @throws IOException + */ + private AutoFixPlan getAutoFixPlan(String resourceId, String indexNameFromRuleParam) throws IOException, Exception { + + if(dr==null) { + dr = new ElasticSearchDataReader(); + } + String doc =dr.searchDocument(indexNameFromRuleParam,AUTO_FIX_PLAN_TYPE,resourceId); + Gson gson = new Gson(); + return gson.fromJson(doc, AutoFixPlan.class); + } + + + /** + * + * @param index + * @param type + * @param planId + * @param parentId + * @return + * @throws Exception + */ + private AutoFixPlan getAutoFixPlan(String index, String type, String planId , String parentId) throws Exception{ + String doc = new ElasticSearchDataReader().getDocumentById(index, type, planId,parentId); + Gson gson = new Gson(); + return gson.fromJson(doc, AutoFixPlan.class); + } + + + /** + * + * @param resourceId + * @return + * @throws Exception + * @throws IOException + */ + private AutoFixPlan synchronizeAutoFixPlan(AutoFixPlan plan,String resourceId,Map ruleParam) throws IOException, Exception{ + + String url = CommonUtils.getPropValue(PacmanSdkConstants.RESOURCE_GET_LASTACTION); + url = url.concat("?resourceId=").concat(resourceId); + String response=null; + try{ + response = CommonUtils.doHttpGet(url); + }catch (Exception e) { + logger.error("uable to call API",e); + throw e; + } + Map resourceDetailsMap = (Map) CommonUtils.deSerializeToObject(response); + List lastActions = (List) resourceDetailsMap.get("lastActions"); + + // update the plan + int index = 0; + for(String action : lastActions){ + updatePlanItemStatus(plan, index++, Status.COMPLETED); + } + // return updated plan + return plan; + } + + /** + * @param resourceId + * @param ruleParam + * @throws Exception + * @throws IOException + */ + public void suspendPlan(AutoFixPlan plan, Map ruleParam) throws IOException, Exception { + plan.setPlanStatus(Status.SUSPENDED); + publishPlan(ruleParam, plan); + } + + /** + * + * @param resourceId + * @return + * @throws Exception + * @throws IOException + */ + public void synchronizeAndRepublishAutoFixPlan(AutoFixPlan plan,String resourceId , Map ruleParam) throws IOException, Exception{ + if(null==plan) + { + String msg = "null plan"; + logger.error(msg); + throw new Exception(msg); + } + AutoFixPlan syncPlan = synchronizeAutoFixPlan(plan,resourceId,ruleParam); + if(syncPlan!=null) { + publishPlan(ruleParam, syncPlan); + } + } + + + public void releaseResourfes(){ + if(this.dp!=null) dp.close(); + if(this.dr!=null) dr.close(); + } +} diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/NextStepManager.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/NextStepManager.java index bf97d722c..395dabac1 100644 --- a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/NextStepManager.java +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/NextStepManager.java @@ -73,13 +73,18 @@ public NextStepManager() { * * @param ruleId the rule id * @param resourceId the resource id + * @param resourceId * @param clientMap the client map * @param serviceType the service type * @return the next step */ @SuppressWarnings("unchecked") - public AutoFixAction getNextStep(String ruleId , String normalizedResourceId,String resourceId, Map clientMap, AWSService serviceType) { + public AutoFixAction getNextStep(Map ruleParam , String normalizedResourceId, String resourceId, Map clientMap, + AWSService serviceType) { + + String ruleId = ruleParam.get(PacmanSdkConstants.RULE_ID); + try { //silent fix can only be aplied to tagging rules , where exception does not makes much sense @@ -104,13 +109,13 @@ public AutoFixAction getNextStep(String ruleId , String normalizedResourceId,Str } Map resourceDetailsMap = (Map) CommonUtils.deSerializeToObject(response); Double responseCode = Double.valueOf((resourceDetailsMap.get("responseCode").toString())); - long autoFixDelay = getAutoFixDelay(ruleId); + int autoFixDelay = getAutoFixDelay(ruleId); int maxEmails = getMaxNotifications(ruleId); List lastActions = (List) resourceDetailsMap.get("lastActions"); if(CollectionUtils.isNullOrEmpty(lastActions)){ - //no action taken yet, as silent fix is not enabled , first action should be email + //no action taken yet, and silent fix is not enabled , first action should be email return AutoFixAction.AUTOFIX_ACTION_EMAIL; }else{ Collections.sort(lastActions);//sort based on date and find the first action time @@ -141,12 +146,13 @@ public AutoFixAction getNextStep(String ruleId , String normalizedResourceId,Str } } + /** * default or rule specific # of notifications * @param ruleId * @return */ - private int getMaxNotifications(String ruleId) { + public static int getMaxNotifications(String ruleId) { String ruleSpecificValue = CommonUtils.getPropValue(PacmanSdkConstants.AUTOFIX_MAX_EMAILS + "." + ruleId); if(Strings.isNullOrEmpty(ruleSpecificValue)){ @@ -182,15 +188,15 @@ private long getNextActionTime(int maxEmails, long autoFixDelay, int noOfActions * @param ruleId * @return */ - public static long getAutoFixDelay(String ruleId) { - long delay = 24;// to be safe this is initialized with 24 and not 0 , though this will be overridden by config property + public static int getAutoFixDelay(String ruleId) { + Integer delay = 24;// to be safe this is initialized with 24 and not 0 , though this will be overridden by config property try{ String delayForRule = CommonUtils.getPropValue(new StringBuilder(PacmanSdkConstants.PAC_AUTO_FIX_DELAY_KEY).append(".").append(ruleId).toString()); if(Strings.isNullOrEmpty(delayForRule)){ //get default delay delayForRule = CommonUtils.getPropValue(new StringBuilder(PacmanSdkConstants.PAC_AUTO_FIX_DELAY_KEY).append(".").append(PacmanSdkConstants.PAC_DEFAULT).toString()); } - delay = Long.parseLong(delayForRule); + delay = Integer.parseInt(delayForRule); }catch (NumberFormatException nfe) { logger.error("unable to find delay param will not execute fix"); throw nfe; diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/dto/AutoFixTransaction.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/dto/AutoFixTransaction.java index 36437f68a..bfaf26aaa 100644 --- a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/dto/AutoFixTransaction.java +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/dto/AutoFixTransaction.java @@ -26,7 +26,19 @@ public class AutoFixTransaction { /** The allocation Id. */ private String allocationId; - private String attachedSg; + /** The parent doc id. */ + private String parentDocId; + + public String getParentDocId() { + return parentDocId; +} + +public void setParentDocId(String parentDocId) { + this.parentDocId = parentDocId; +} + + +private String attachedSg; private String detachedSg; public String getAttachedSg() { @@ -228,7 +240,7 @@ public AutoFixTransaction() { * @param region */ public AutoFixTransaction(AutoFixAction action, String resourceId, String ruleId, String executionId, String transactionId, - String desc,String type,String targetType,String issueId,String accountId,String region) { + String desc,String type,String targetType,String issueId,String accountId,String region,String parentDocId) { super(); this.transationTime = CommonUtils.getCurrentDateStringWithFormat(PacmanSdkConstants.PAC_TIME_ZONE, PacmanSdkConstants.DATE_FORMAT); @@ -243,6 +255,7 @@ public AutoFixTransaction(AutoFixAction action, String resourceId, String ruleId this.issueId=issueId; this.accountId=accountId; this.region=region; + this.parentDocId=parentDocId; } /** diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/publisher/impl/ElasticSearchDataInterface.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/publisher/impl/ElasticSearchDataInterface.java new file mode 100644 index 000000000..2f784ce08 --- /dev/null +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/publisher/impl/ElasticSearchDataInterface.java @@ -0,0 +1,81 @@ +/** + Copyright (C) 2017 T Mobile Inc - All Rights Reserve + Purpose: + Author :kkumar28 + Modified Date: Jul 2, 2019 + +**/ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.publisher.impl; + +import java.io.IOException; +import java.net.MalformedURLException; + +import org.apache.http.HttpHost; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestHighLevelClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tmobile.pacman.commons.autofix.manager.NextStepManager; +import com.tmobile.pacman.util.ESUtils; + +/** + * @author kkumar28 + * + */ +public class ElasticSearchDataInterface implements AutoCloseable{ + + + + private static final Logger logger = LoggerFactory.getLogger(ElasticSearchDataInterface.class); + + + /** The client. */ + protected RestHighLevelClient client; + + /** rest client will be used to create RestHighLevelClient. */ + protected RestClient restClient; + + + /** + * Instantiates a new elastic search data publisher. + * @throws MalformedURLException + */ + public ElasticSearchDataInterface() throws MalformedURLException { + restClient = RestClient.builder(new HttpHost(ESUtils.getESHost(), ESUtils.getESPort())).build(); + client = new RestHighLevelClient(restClient); + } + + + /* (non-Javadoc) + * @see java.lang.AutoCloseable#close() + */ + @Override + public void close(){ + if(null!=restClient) + try { + restClient.close(); + } catch (IOException e) { + logger.error("error closing rest client" ,e); + } + + client = null; + } + + +} diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/publisher/impl/ElasticSearchDataPublisher.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/publisher/impl/ElasticSearchDataPublisher.java index d94385a0c..b3d5068d6 100644 --- a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/publisher/impl/ElasticSearchDataPublisher.java +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/publisher/impl/ElasticSearchDataPublisher.java @@ -36,6 +36,7 @@ import com.google.gson.Gson; import com.tmobile.pacman.common.AutoFixAction; import com.tmobile.pacman.common.PacmanSdkConstants; +import com.tmobile.pacman.commons.autofix.AutoFixPlan; import com.tmobile.pacman.dto.AutoFixTransaction; import com.tmobile.pacman.util.CommonUtils; import com.tmobile.pacman.util.ESUtils; @@ -187,7 +188,7 @@ private String getDocId(AutoFixTransaction autoFixTransaction) { * @param ruleParam * @return */ - private String getIndexName(Map ruleParam) { + public static String getIndexName(Map ruleParam) { return ruleParam.get(PacmanSdkConstants.DATA_SOURCE_KEY).replace("_all", "") + "_" + ruleParam.get(PacmanSdkConstants.TARGET_TYPE); @@ -219,4 +220,35 @@ public void close(){ client = null; } + /** + * + * @return + */ + public Boolean postDocAsChildOfType(AutoFixPlan plan,String docId,Map ruleParam, String planTypeName, String parentType,String parentId ){ + + logger.debug("posting the plan to ES plan id = {}" , plan.getPlanId()); + Gson gson = new Gson(); + if(!ESUtils.isValidType(ESUtils.getEsUrl(),getIndexName(ruleParam),planTypeName)){ + try { + ESUtils.createMappingWithParent(ESUtils.getEsUrl(),getIndexName(ruleParam),planTypeName, parentType); + } catch (Exception e) { + logger.error("uanble to create child type"); + } + } + + IndexRequest indexRequest = new IndexRequest(getIndexName(ruleParam), planTypeName, docId); + indexRequest.source(gson.toJson(plan),XContentType.JSON); + indexRequest.parent(parentId); + try { + client.index(indexRequest); + } catch (IOException e) { + logger.error("error indexing autofix plan",e); + return false; + } + logger.debug("postes the plan to ES plan id = {}" , plan.getPlanId()); + + return true; + } + + } diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/publisher/impl/ElasticSearchDataReader.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/publisher/impl/ElasticSearchDataReader.java new file mode 100644 index 000000000..eb531e126 --- /dev/null +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/publisher/impl/ElasticSearchDataReader.java @@ -0,0 +1,106 @@ +/** + Copyright (C) 2017 T Mobile Inc - All Rights Reserve + Purpose: + Author :kkumar28 + Modified Date: Jul 2, 2019 + +**/ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.publisher.impl; + +import java.io.IOException; +import java.net.MalformedURLException; + +import org.elasticsearch.action.get.GetRequest; +import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.search.SearchHits; +import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.tmobile.pacman.commons.autofix.AutoFixPlan; +import com.tmobile.pacman.util.ESUtils; + + +/** + * @author kkumar28 + * + */ +public class ElasticSearchDataReader extends ElasticSearchDataInterface { + + + + /** + * @throws MalformedURLException + * + */ + public ElasticSearchDataReader() throws Exception { + super(); + } + + + private static final Logger logger = LoggerFactory.getLogger(ElasticSearchDataReader.class); + + + /** + * + * @param index + * @param type + * @param id + * @return + * @throws IOException + */ + public String getDocumentById(String index,String type, String id,String parentId) throws IOException{ + GetRequest req = new GetRequest(index,type,id); + req.routing(parentId); + GetResponse response = client.get(req); + return response.getSourceAsString(); + } + + + /** + * @param indexNameFromRuleParam + * @param autoFixPlanType + * @param resourceId + * @return + * @throws IOException + */ + public String searchDocument(String indexNameFromRuleParam, String autoFixPlanType, String resourceId) throws IOException { + + SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); + sourceBuilder.query(QueryBuilders.termQuery(ESUtils.convertAttributetoKeyword("resourceId"), resourceId)); + SearchRequest searchRequest = new SearchRequest(indexNameFromRuleParam); + searchRequest.types(autoFixPlanType); + searchRequest.source(sourceBuilder); + + logger.debug("searching auto fix plan with query " ,searchRequest.toString()); + + SearchResponse response = client.search(searchRequest); + SearchHits hits = response.getHits(); + if(RestStatus.OK==response.status() && hits.totalHits>0){ + return hits.getAt(0).getSourceAsString(); + }else{ + throw new IOException(String.format("no plan found for resource %s",resourceId)); + } + } + +} diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/util/MailUtils.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/util/MailUtils.java index e30be6697..721086a09 100644 --- a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/util/MailUtils.java +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/util/MailUtils.java @@ -133,7 +133,7 @@ public static boolean sendAutoFixNotification(Map ruleParam, fin } String warning = CommonUtils.getPropValue(PacmanSdkConstants.EMAIL_WARNING_MESSAGE_PREFIX + ruleParam.get(PacmanSdkConstants.RULE_ID)); - Long autoFixDealy = NextStepManager.getAutoFixDelay(ruleParam.get(PacmanSdkConstants.RULE_ID)); + Integer autoFixDealy = NextStepManager.getAutoFixDelay(ruleParam.get(PacmanSdkConstants.RULE_ID)); if(autoFixDealy!=null){ warning = warning.replace("{days}", "" + Math.toIntExact(autoFixDealy/24)); } diff --git a/jobs/pacman-rule-engine-2.0/src/test/java/com/tmobile/pacman/commons/autofix/manager/AutoFixPlanManagerTest.java b/jobs/pacman-rule-engine-2.0/src/test/java/com/tmobile/pacman/commons/autofix/manager/AutoFixPlanManagerTest.java new file mode 100644 index 000000000..12bdd8093 --- /dev/null +++ b/jobs/pacman-rule-engine-2.0/src/test/java/com/tmobile/pacman/commons/autofix/manager/AutoFixPlanManagerTest.java @@ -0,0 +1,73 @@ +/** + Copyright (C) 2017 T Mobile Inc - All Rights Reserve + Purpose: + Author :kkumar28 + Modified Date: Jun 19, 2019 + +**/ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.commons.autofix.manager; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.tmobile.pacman.common.AutoFixAction; +import com.tmobile.pacman.commons.autofix.AutoFixPlan; +import com.tmobile.pacman.commons.autofix.PlanItem; + +/** + * @author kkumar28 + * + */ + +@RunWith(PowerMockRunner.class) +public class AutoFixPlanManagerTest { + + + final static Integer numberOfNotifications = 4; + + @Test + public void testcreateTransientPlanNotNull(){ + AutoFixPlan plan = new AutoFixPlanManager().createPlan( "ruleId", "issueId", "resourceId","docId","resourcetype", numberOfNotifications, 48); + assertNotNull(plan); + } + + + @Test + public void testcreateTransientPlanVerify(){ + + AutoFixPlan plan = new AutoFixPlanManager().createPlan( "ruleId", "issueId", "resourceId","docId","resourcetype", numberOfNotifications, 48); + assertEquals(numberOfNotifications.intValue(),plan.getPlanItems().size() - 1); // reducing by one as one of them will be action and not notification signal + } + + @Test + public void testcreateTransientPlanVerifyAction(){ + AutoFixPlan plan = new AutoFixPlanManager().createPlan( "ruleId", "issueId", "resourceId","docId","resourcetype", numberOfNotifications, 48); + List items = plan.getPlanItems().stream().filter(obj->obj.getAction().equals(AutoFixAction.AUTOFIX_ACTION_FIX)).collect(Collectors.toList()); + assertTrue(items.get(0).getAction().equals(AutoFixAction.AUTOFIX_ACTION_FIX)); + } + + +} From d2780f6aaad1fe51131e6c6a38a86f089f7a94f6 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Thu, 1 Aug 2019 17:32:47 +0530 Subject: [PATCH 16/86] Removed unused classes --- .../api/asset/domain/ApplicationDetail.java | 62 ------------------- .../domain/ApplicationDetailsESResponse.java | 18 ------ .../domain/ApplicationDetailsResponse.java | 29 --------- .../api/asset/domain/ApplicationESDetail.java | 57 ----------------- .../pacman/api/asset/domain/Organization.java | 27 -------- .../api/asset/repository/AssetRepository.java | 25 -------- .../asset/repository/AssetRepositoryImpl.java | 43 ------------- .../api/asset/service/AssetService.java | 2 - .../api/asset/service/AssetServiceImpl.java | 9 --- 9 files changed, 272 deletions(-) delete mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetail.java delete mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsESResponse.java delete mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsResponse.java delete mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationESDetail.java delete mode 100644 api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/Organization.java diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetail.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetail.java deleted file mode 100644 index 681d9abfe..000000000 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetail.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.tmobile.pacman.api.asset.domain; - -import java.util.List; - -public class ApplicationDetail -{ - private String name; - private String description; - private List organization; - private String assetGroupId; - private Long totalResources; - - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } - - public String getDescription() - { - return description; - } - - public void setDescription(String description) - { - this.description = description; - } - - public List getOrganization() - { - return organization; - } - - public void setOrganization(List organization) - { - this.organization = organization; - } - - public String getAssetGroupId() - { - return assetGroupId; - } - - public void setAssetGroupId(String assetGroupId) - { - this.assetGroupId = assetGroupId; - } - - public Long getTotalResources() - { - return totalResources; - } - - public void setTotalResources(Long totalResources) - { - this.totalResources = totalResources; - } -} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsESResponse.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsESResponse.java deleted file mode 100644 index 8611dea69..000000000 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsESResponse.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.tmobile.pacman.api.asset.domain; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -@JsonIgnoreProperties(ignoreUnknown = true) -public class ApplicationDetailsESResponse { - - private ApplicationESDetail _source; - - public void set_source(ApplicationESDetail _source) { - this._source = _source; - } - - public ApplicationESDetail getApplicationDetail() { - return _source; - } -} - diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsResponse.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsResponse.java deleted file mode 100644 index 1349a8d1e..000000000 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationDetailsResponse.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.tmobile.pacman.api.asset.domain; - -import java.util.List; - -public class ApplicationDetailsResponse -{ - private List validApplications; - private List invalidApplications; - - public List getValidApplications() - { - return validApplications; - } - - public void setValidApplications(List validApplications) - { - this.validApplications = validApplications; - } - - public List getInvalidApplications() - { - return invalidApplications; - } - - public void setInvalidApplications(List invalidApplications) - { - this.invalidApplications = invalidApplications; - } -} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationESDetail.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationESDetail.java deleted file mode 100644 index 784bf78f2..000000000 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/ApplicationESDetail.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.tmobile.pacman.api.asset.domain; - -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -@JsonIgnoreProperties(ignoreUnknown = true) -public class ApplicationESDetail { - private String director; - private String description; - private List> _orgInfo; - private String executiveSponsor; - private String appTag; - - public String getDirector() { - return director; - } - - public void setDirector(String director) { - this.director = director; - } - - public String getDescription() { - return StringUtils.chomp(description); - } - - public void setDescription(String description) { - this.description = description; - } - - public void set_orgInfo(List> _orgInfo) { - this._orgInfo = _orgInfo; - } - - public List> getOrgInfo() { - return _orgInfo; - } - - public String getExecutiveSponsor() { - return executiveSponsor; - } - - public void setExecutiveSponsor(String executiveSponsor) { - this.executiveSponsor = executiveSponsor; - } - - public String getAppTag() { - return appTag; - } - - public void setAppTag(String appTag) { - this.appTag = appTag; - } -} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/Organization.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/Organization.java deleted file mode 100644 index fad1e1cc3..000000000 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/domain/Organization.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.tmobile.pacman.api.asset.domain; - -public class Organization -{ - private String name; - private String designation; - - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } - - public String getDesignation() - { - return designation; - } - - public void setDesignation(String designation) - { - this.designation = designation; - } -} diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepository.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepository.java index d9daf65a1..8a3228af2 100644 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepository.java +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepository.java @@ -21,8 +21,6 @@ import org.springframework.stereotype.Repository; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.tmobile.pacman.api.asset.domain.ApplicationDetailsESResponse; import com.tmobile.pacman.api.asset.model.DefaultUserAssetGroup; import com.tmobile.pacman.api.commons.exception.DataException; import com.tmobile.pacman.api.commons.exception.NoDataFoundException; @@ -519,27 +517,4 @@ public List> getAssetLists(String assetGroup, Map getApplicationAssetCountByAssetGroup(String assetGroupName, String domain) throws DataException; - /** - * Fetches all application details by asset group name - * - * @param applications - valid list of applications - * - * @return List - valid and invalid application details list - * @throws DataException, JsonProcessingException - */ - public List getApplicationDetails() throws JsonProcessingException, DataException; - - /** - * Get the datasource for the given type list - * @param typeList - * @return - */ - public List> getDatasourceForCostMapping(List typeList); - - /** - * Gets the all cost types. - * - * @return the all cost types - */ - List> getAllCostTypes(); } diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepositoryImpl.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepositoryImpl.java index be6907f5b..7896889fd 100644 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepositoryImpl.java +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/repository/AssetRepositoryImpl.java @@ -55,7 +55,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Strings; import com.google.common.collect.HashMultimap; -import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; @@ -64,7 +63,6 @@ import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; import com.tmobile.pacman.api.asset.AssetConstants; -import com.tmobile.pacman.api.asset.domain.ApplicationDetailsESResponse; import com.tmobile.pacman.api.asset.domain.ResourceResponse; import com.tmobile.pacman.api.asset.domain.ResourceResponse.Source; import com.tmobile.pacman.api.asset.model.DefaultUserAssetGroup; @@ -2384,46 +2382,5 @@ public Map getApplicationAssetCountByAssetGroup(String assetGroupN return applicationMap; } - - @Override - public List getApplicationDetails() throws JsonProcessingException, DataException { - String esQuery = "{\"size\":10000,\"query\":{\"bool\":{\"must\":[{\"term\":{\"latest\":\"true\"}}]}},\"_source\":[\"appTag\",\"description\",\"director\",\"executiveSponsor\",\"_orgInfo\"]}"; - String responseJson = StringUtils.EMPTY; - String url = esUrl + "/aws_apps" + "/apps/_search"; - try { - responseJson = PacHttpUtils.doHttpPost(url, esQuery); - } catch (Exception e) { - LOGGER.error("Error in getting application details", e); - throw new DataException("Error in getting application details"); - } - if (!StringUtils.isBlank(responseJson)) { - JsonParser jsonParser = new JsonParser(); - JsonObject resultJson = jsonParser.parse(responseJson).getAsJsonObject(); - JsonObject hitsJson = jsonParser.parse(resultJson.get("hits").toString()).getAsJsonObject(); - Type type = new TypeToken>() { - }.getType(); - return new Gson().fromJson(hitsJson.getAsJsonObject().get("hits").toString(), type); - } - return Lists.newArrayList(); - } - - @Override - public List> getDatasourceForCostMapping(List typeList) { - String targetTypeQuery = typeList.stream().map(targettype -> "\"" + targettype.trim() + "\"") - .collect(Collectors.joining(",")); - String query = "select distinct type as " + Constants.TYPE + ", datasource as " + Constants.PROVIDER - + " from Cost_Mappings"; - if (!CollectionUtils.isEmpty(typeList)) { - query += " WHERE type IN (" + targetTypeQuery + ")"; - } - return rdsRepository.getDataFromPacman(query); - } - - @Override - public List> getAllCostTypes() { - String query = "select distinct type as type from Cost_Mappings"; - return rdsRepository.getDataFromPacman(query); - - } } diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetService.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetService.java index 5887d91b3..aada77a97 100644 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetService.java +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetService.java @@ -19,8 +19,6 @@ import java.util.List; import java.util.Map; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.tmobile.pacman.api.asset.domain.ApplicationDetailsResponse; import com.tmobile.pacman.api.asset.domain.ResponseWithFieldsByTargetType; import com.tmobile.pacman.api.asset.model.DefaultUserAssetGroup; import com.tmobile.pacman.api.commons.exception.DataException; diff --git a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetServiceImpl.java b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetServiceImpl.java index 21c7984d8..7986ba53c 100644 --- a/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetServiceImpl.java +++ b/api/pacman-api-asset/src/main/java/com/tmobile/pacman/api/asset/service/AssetServiceImpl.java @@ -17,10 +17,6 @@ import java.io.IOException; import java.time.LocalDate; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.google.common.collect.Lists; - import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; @@ -51,11 +47,6 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.tmobile.pacman.api.asset.AssetConstants; -import com.tmobile.pacman.api.asset.domain.ApplicationDetail; -import com.tmobile.pacman.api.asset.domain.ApplicationDetailsESResponse; -import com.tmobile.pacman.api.asset.domain.ApplicationDetailsResponse; -import com.tmobile.pacman.api.asset.domain.ApplicationESDetail; -import com.tmobile.pacman.api.asset.domain.Organization; import com.tmobile.pacman.api.asset.domain.ResponseWithFieldsByTargetType; import com.tmobile.pacman.api.asset.model.DefaultUserAssetGroup; import com.tmobile.pacman.api.asset.repository.AssetRepository; From 4cd7b7004cf37d13b20148c8f7f36cad328c78ad Mon Sep 17 00:00:00 2001 From: Sajeer N Date: Fri, 2 Aug 2019 06:39:39 +0530 Subject: [PATCH 17/86] New data enricher job viz AWS Recommendations job has been created as CW rule --- installer/resources/lambda_submit/function.py | 63 ++++++++++++++----- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/installer/resources/lambda_submit/function.py b/installer/resources/lambda_submit/function.py index b51f83273..1342b5b47 100644 --- a/installer/resources/lambda_submit/function.py +++ b/installer/resources/lambda_submit/function.py @@ -47,21 +47,6 @@ class DataCollectorEventRuleLambdaPermission(LambdaPermission): source_arn = DataCollectorEventRule.get_output_attr('arn') -class DataShipperEventRule(CloudWatchEventRuleResource): - name = "aws-redshift-es-data-shipper" - schedule_expression = "cron(0 * * * ? *)" - - DEPENDS_ON = [SubmitJobLambdaFunction, ESDomainPolicy] - - -class DataShipperEventRuleLambdaPermission(LambdaPermission): - statement_id = "AllowExecutionFromDataShipper" - action = "lambda:InvokeFunction" - function_name = SubmitJobLambdaFunction.get_output_attr('function_name') - principal = "events.amazonaws.com" - source_arn = DataShipperEventRule.get_output_attr('arn') - - class DataCollectorCloudWatchEventTarget(CloudWatchEventTargetResource): rule = DataCollectorEventRule.get_output_attr('name') arn = SubmitJobLambdaFunction.get_output_attr('arn') @@ -84,6 +69,21 @@ class DataCollectorCloudWatchEventTarget(CloudWatchEventTargetResource): }) +class DataShipperEventRule(CloudWatchEventRuleResource): + name = "aws-redshift-es-data-shipper" + schedule_expression = "cron(0 * * * ? *)" + + DEPENDS_ON = [SubmitJobLambdaFunction, ESDomainPolicy] + + +class DataShipperEventRuleLambdaPermission(LambdaPermission): + statement_id = "AllowExecutionFromDataShipper" + action = "lambda:InvokeFunction" + function_name = SubmitJobLambdaFunction.get_output_attr('function_name') + principal = "events.amazonaws.com" + source_arn = DataShipperEventRule.get_output_attr('arn') + + class DataShipperCloudWatchEventTarget(CloudWatchEventTargetResource): rule = DataShipperEventRule.get_output_attr('name') arn = SubmitJobLambdaFunction.get_output_attr('arn') @@ -110,3 +110,36 @@ class DataShipperCloudWatchEventTarget(CloudWatchEventTargetResource): 'value': "MjJlMTQ5MjItODdkNy00ZWU0LWE0NzAtZGEwYmIxMGQ0NWQzOmNzcldwYzVwN0pGRjR2RVpCa3dHQ0FoNjdrR1FHd1h2NDZxdWc3djVad3RLZw=="} ] }) + + +class RecommendationsCollectorEventRule(CloudWatchEventRuleResource): + name = "AWS-Recommendations-Collector" + schedule_expression = "cron(0 * * * ? *)" + + DEPENDS_ON = [SubmitJobLambdaFunction] + + +class RecommendationsCollectorEventRuleLambdaPermission(LambdaPermission): + statement_id = "AllowExecutionFromRecommendationsCollectorEvent" + action = "lambda:InvokeFunction" + function_name = SubmitJobLambdaFunction.get_output_attr('function_name') + principal = "events.amazonaws.com" + source_arn = RecommendationsCollectorEventRule.get_output_attr('arn') + + +class RecommendationsCollectorCloudWatchEventTarget(CloudWatchEventTargetResource): + rule = RecommendationsCollectorEventRule.get_output_attr('name') + arn = SubmitJobLambdaFunction.get_output_attr('arn') + target_id = 'RecommendationsCollectorTarget' # Unique identifier + target_input = json.dumps({ + 'jobName': "aws-recommendations-collector", + 'jobUuid': "aws-recommendations-collector", + 'jobType': "jar", + 'jobDesc': "Index trusted advisor checks as recommendations", + 'environmentVariables': [ + ], + 'params': [ + {'encrypt': False, 'key': "package_hint", 'value': "com.tmobile.cso.pacbot"}, + {'encrypt': False, 'key': "config_creds", 'value': "dXNlcjpwYWNtYW4="}, + ] + }) From c0e57c71b8e061d39e971e13684e69c4991a02d2 Mon Sep 17 00:00:00 2001 From: Ritesh Date: Fri, 2 Aug 2019 10:07:45 +0530 Subject: [PATCH 18/86] recommendation L0 and remove bower Dependencies --- webapp/.angular-cli.json | 6 +- webapp/bower.json | 20 - webapp/package.json | 5 +- .../src/app/core/services/workflow.service.ts | 26 +- .../modules/compliance/compliance.module.ts | 6 +- .../recommendations.component.css | 266 ++++++++ .../recommendations.component.html | 108 ++++ .../recommendations.component.spec.ts | 39 ++ .../recommendations.component.ts | 568 ++++++++++++++++++ .../recommand-category.component.css | 33 + .../recommand-category.component.html | 42 ++ .../recommand-category.component.spec.ts | 39 ++ .../recommand-category.component.ts | 452 ++++++++++++++ .../back-navigation.component.css | 58 ++ .../back-navigation.component.html | 17 + .../back-navigation.component.spec.ts | 39 ++ .../back-navigation.component.ts | 54 ++ webapp/src/app/shared/constants/routes.ts | 12 +- .../filtered-selector.component.html | 2 +- .../filtered-selector.component.ts | 33 +- .../generic-page-filter.component.html | 4 +- .../generic-page-filter.component.ts | 89 ++- .../searchable-dropdown.component.html | 8 +- .../searchable-dropdown.component.ts | 177 +++++- .../shared/services/router-utility.service.ts | 21 + webapp/src/app/shared/shared.module.ts | 13 +- .../table-list/table-list.component.css | 214 +++++++ .../table-list/table-list.component.html | 74 +++ .../table-list/table-list.component.spec.ts | 40 ++ .../shared/table-list/table-list.component.ts | 177 ++++++ webapp/src/config/domain-mapping.ts | 12 +- webapp/src/environments/environment.prod.ts | 16 + webapp/src/environments/environment.stg.ts | 16 + webapp/src/environments/environment.ts | 16 + 34 files changed, 2612 insertions(+), 90 deletions(-) delete mode 100644 webapp/bower.json create mode 100644 webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.css create mode 100644 webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.html create mode 100644 webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.spec.ts create mode 100644 webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.ts create mode 100644 webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.css create mode 100644 webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.html create mode 100644 webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.spec.ts create mode 100644 webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.ts create mode 100644 webapp/src/app/shared/back-navigation/back-navigation.component.css create mode 100644 webapp/src/app/shared/back-navigation/back-navigation.component.html create mode 100644 webapp/src/app/shared/back-navigation/back-navigation.component.spec.ts create mode 100644 webapp/src/app/shared/back-navigation/back-navigation.component.ts create mode 100644 webapp/src/app/shared/table-list/table-list.component.css create mode 100644 webapp/src/app/shared/table-list/table-list.component.html create mode 100644 webapp/src/app/shared/table-list/table-list.component.spec.ts create mode 100644 webapp/src/app/shared/table-list/table-list.component.ts diff --git a/webapp/.angular-cli.json b/webapp/.angular-cli.json index 3dbe50f38..584326abc 100644 --- a/webapp/.angular-cli.json +++ b/webapp/.angular-cli.json @@ -20,13 +20,13 @@ "prefix": "app", "styles": [ "styles.css", - "../bower_components/offline/themes/offline-theme-chrome.css", - "../bower_components/offline/themes/offline-language-english.css", + "../node_modules/@bower_components/offline/themes/offline-theme-chrome.css", + "../node_modules/@bower_components/offline/themes/offline-language-english.css", "../node_modules/ag-grid/dist/styles/ag-grid.css", "../node_modules/ag-grid/dist/styles/theme-blue.css" ], "scripts": [ - "../bower_components/offline/offline.js", + "../node_modules/@bower_components/offline/offline.js", "../node_modules/ag-grid/dist/ag-grid.js" ], "environmentSource": "environments/environment.ts", diff --git a/webapp/bower.json b/webapp/bower.json deleted file mode 100644 index ec9fb6aa9..000000000 --- a/webapp/bower.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "pacbot-spa", - "description": "", - "main": "", - "authors": [ - "PacBot Team" - ], - "license": "MIT", - "homepage": "", - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests" - ], - "dependencies": { - "offlinejs-simulate-ui": "^0.1.2" - } -} diff --git a/webapp/package.json b/webapp/package.json index 944bdd300..39361ca7f 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -46,7 +46,10 @@ "ngx-highlight": "0.0.3", "ngx-infinite-scroll": "^0.8.3", "rxjs": "^5.4.2", - "zone.js": "^0.8.14" + "zone.js": "^0.8.14", + "@bower_components/offline": "HubSpot/offline", + "@bower_components/offlinejs-simulate-ui": "craigshoemaker/offlinejs-simulate-ui", + "ngx-select-dropdown": "^1.0.1" }, "devDependencies": { "@angular/cli": "1.6.8", diff --git a/webapp/src/app/core/services/workflow.service.ts b/webapp/src/app/core/services/workflow.service.ts index bbec608ee..b4dc7a55a 100644 --- a/webapp/src/app/core/services/workflow.service.ts +++ b/webapp/src/app/core/services/workflow.service.ts @@ -79,20 +79,6 @@ export class WorkflowService { this.router.navigate([destinationUrlAndParams['url']], {queryParams: destinationUrlAndParams['queryParams']}); } - checkIfFlowExistsCurrently(currentLevel) { - let flowExiststatus = false; - // getLevel(); - this.level = this.getDetailsFromStorage(); - while ( currentLevel >= 0 ) { - if (this.level['level' + currentLevel]) { - flowExiststatus = this.level['level' + currentLevel].length > 0; - } - currentLevel--; - } - - return flowExiststatus; - } - clearAllLevels() { this.level = {}; this.saveToStorage(this.level); @@ -153,4 +139,16 @@ export class WorkflowService { clearDataOfOpenedPageInModule() { this.trackOpenedPageInAModule = {}; } + checkIfFlowExistsCurrently(currentLevel?) { + + const currentPageLevelNumber = this.routerUtilityService.getpageLevel(this.router.routerState.snapshot.root); + + let flowExiststatus = false; + this.level = this.getDetailsFromStorage(); + if (this.level[currentPageLevelNumber]) { + flowExiststatus = this.level[currentPageLevelNumber].length > 0; + } + + return flowExiststatus; + } } diff --git a/webapp/src/app/pacman-features/modules/compliance/compliance.module.ts b/webapp/src/app/pacman-features/modules/compliance/compliance.module.ts index 281e9a118..5d66091e8 100644 --- a/webapp/src/app/pacman-features/modules/compliance/compliance.module.ts +++ b/webapp/src/app/pacman-features/modules/compliance/compliance.module.ts @@ -106,6 +106,8 @@ import { PolicyViolationDescComponent } from './../../secondary-components/polic import { IssueExceptionComponent } from './../../secondary-components/issue-exception/issue-exception.component'; import { PolicyViolationsListComponent } from './policy-violations-list/policy-violations-list.component'; import { IssueListingService } from '../../services/issue-listing.service'; +import { RecommendationsComponent} from '../../modules/compliance/recommendations/recommendations.component'; +import { RecommandCategoryComponent } from '../../secondary-components/recommand-category/recommand-category.component'; @NgModule({ imports: [ @@ -207,7 +209,9 @@ import { IssueListingService } from '../../services/issue-listing.service'; VulnerabilityDetailsComponent, PolicyViolationDescComponent, IssueExceptionComponent, - PolicyViolationsListComponent + PolicyViolationsListComponent, + RecommendationsComponent, + RecommandCategoryComponent ], providers: [ SelectComplianceDropdown, diff --git a/webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.css b/webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.css new file mode 100644 index 000000000..bf47356c6 --- /dev/null +++ b/webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.css @@ -0,0 +1,266 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +.policy-knowledgebase-wrapper { + height: 100%; + justify-content: flex-start; + overflow-y: hidden; + padding-bottom: 2px; +} + +.policy-knowledgebase-content { + margin: 0 1.8em 1.8em; + border-radius: 3px; + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.15); + overflow: hidden; + height: 100%; +} + +.pk-header { + padding-top: 2em; + padding-bottom: 2em; +} + +.pk-top-content { + padding-bottom: 0.5em; + -ms-flex-negative: 0; + flex-shrink: 0; + margin: 0 1.8em; +} + +.tab-list { + margin-right: 1.5em; + letter-spacing: 0.2px; + color: #9b9b9b; + margin-bottom: 0.66em; + padding: 3px; + cursor: pointer; + transition: 0.17s ease; + border-bottom: 2px solid #0000; + opacity: 1; + transform: translate(-3px, -3px); + transition-delay: 0.33s; +} + +.tab-list:hover { + color: #777; +} + +.pk-tabs.loaded { + opacity: 1; + white-space: nowrap; + transform: translate(0px, 0px); +} + +.tabs-container { + min-height: 1em; + flex-wrap: wrap; + flex-shrink: 0; +} + +.tab-list.active { + font-family: ex2-bold; + color: #e20074; + border-bottom: 2px solid #e20074; +} + +.pk-main-content { + padding: 2em 2em; + overflow-y: auto; + overflow-y: overlay; + align-content: flex-start; + position: relative; + height: 100%; + background: #fff; +} + + +.total-count-txt { + font-size: 0.85em; + color: #5a616b; +} + +.summary-heading { + font-size: 1.5em; + text-shadow: 0 0.1px; + position: sticky; + top: 0; + padding: 1em 0.2em 1em; + background-color: #fff; + z-index: 12; + text-transform: capitalize; +} + +.tabs-nav { + color: #000; +} + +.tabs-wrapper { + padding: 0.5em; +} + +.each-summary { + padding: 0.5em; + text-align: center; +} + +.summary-text { + padding: 0.3em 0; +} + +.cost-val { + font-size: 1.2em; + text-shadow: 0 0.1px; +} + +.each-tab { + padding: 1em; + margin: 1.5em; + transition: 0.17s ease; + min-width: 13em; +} + +.each-tab.tab-hover:hover { + cursor: pointer; + border-radius: 3px; + box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.05); + border: 1px solid 0.9px #cccccc; + background-color: #fdfdfd; +} + +.each-tab.tab-hover.active { + cursor: pointer; + border-radius: 3px; + box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.05); + border: 1px solid 0.9px #cccccc; + background-color: #f1f1f1; +} + +.table-wrapper { + padding: 1em 0; + flex-grow: 1 +} + +.total-cost { + background-color: #3f4a59; + border: 1px solid; + border-radius: 1.4em; + padding: 0.5em 1.5em; + letter-spacing: 0.5px; + margin: 0 0.3em; + color: #fff; + line-height: 1.2; + font-size: 1.1em; + max-width: 25em; + text-transform: capitalize; + text-overflow: ellipsis; + min-width: 10em; + white-space: nowrap; + /* opacity: 0; */ + transition: 0.3s ease; +} + +.savings { + background-color: #50c17c; +} + +.total-cost-wrapper { + padding: 1em 0 1.5em; +} + +.height-100 { + height: 100%; +} + +.cost-table-wrapper { + flex-grow: 1; +} + +.filter-selector { + max-height: 0; + overflow: hidden; + padding: 0em 1.5em; + transition: 0.3s ease; +} + +.show-filter-selector { + padding: 0em 1.5em 1.5em; + max-height: 5em; +} + +.total-cost-app { + overflow: hidden; + text-overflow: ellipsis; + white-space: pre; +} + +.opacity { + opacity: 1; +} + +.each-toggle { + color: #777; + padding: 2px 2px 4px; + margin-right: 0.5em; + cursor: pointer; + transition: 0.4s ease; +} + +.each-toggle.active { + color: #ed0274; +} + +.toggle-parent { + width: 2.6em; + height: 1em; + background: #d0d0d0; + margin-right: 0.5em; + border-radius: 0.5em; + border: 1px solid #c1c1c1; + cursor: pointer; +} + +.toggle-slider { + height: 1.4em; + width: 1.4em; + background: #ed0274; + top: 50%; + transition: 0.3s ease; + transform: translateY(-50%); + border: 5px solid #ed0274; + border-radius: 0.8em; + box-shadow: 0 0 4px 0px rgba(0,0,0,0.1); + left: -3px; +} + +.toggle-slider.right { + left: calc(1.1em + 3px); +} + +.toggle-wrap { + padding: 0 0 1em; + flex-shrink: 0; +} + +.help-icon { + vertical-align: text-top; + width: 1em; + cursor: pointer; + transition: 0.2s ease; +} + +.help-icon:hover { + color: magenta; + transform: scale(1.07); +} \ No newline at end of file diff --git a/webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.html b/webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.html new file mode 100644 index 000000000..5d6c18b31 --- /dev/null +++ b/webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.html @@ -0,0 +1,108 @@ + + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+
+
+
Asset-Specific
+
+
+
+
General
+
+
+
+
{{tabs.displayName}} + ({{tabs.recommendations}}) +
+
+
+
+
+ +
+
+ +
+
{{tabs.displayName}}
+
+ +
+
+
+ $ {{tabs.potentialMonthlySavings | number : '1.0-2'}} + {{tabs.recommendations | number : '1.0-2'}} +
+
+ Potential Monthly Savings + Recommendations +
+
+
+
+
+
+ + +
+
+
+ +
+
+
+
+
+
+
{{selectedApplication}} Monthly Cost - $ {{totalCost | number : '1.0-2'}}
+
Potential Monthly Savings - $ {{monthlySavingsTotal | number : '1.0-2'}}
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
\ No newline at end of file diff --git a/webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.spec.ts b/webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.spec.ts new file mode 100644 index 000000000..d9532b65b --- /dev/null +++ b/webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.spec.ts @@ -0,0 +1,39 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { RecommendationsComponent } from './recommendations.component'; + +describe('RecommendationsComponent', () => { + let component: RecommendationsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ RecommendationsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(RecommendationsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.ts b/webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.ts new file mode 100644 index 000000000..14a8d4cf9 --- /dev/null +++ b/webapp/src/app/pacman-features/modules/compliance/recommendations/recommendations.component.ts @@ -0,0 +1,568 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, OnInit, OnDestroy, OnChanges, SimpleChanges } from '@angular/core'; +import { AssetGroupObservableService } from '../../../../core/services/asset-group-observable.service'; +import { Subscription } from 'rxjs/Subscription'; +import { CommonResponseService } from '../../../../shared/services/common-response.service'; +import { environment } from './../../../../../environments/environment'; +import { Router, ActivatedRoute } from '@angular/router'; +import { LoggerService } from '../../../../shared/services/logger.service'; +import { ErrorHandlingService } from '../../../../shared/services/error-handling.service'; +import { RouterUtilityService } from '../../../../shared/services/router-utility.service'; +import { UtilsService } from '../../../../shared/services/utils.service'; +import {RefactorFieldsService} from '../../../../shared/services/refactor-fields.service'; +import { FilterManagementService } from '../../../../shared/services/filter-management.service'; +import {DomainTypeObservableService} from '../../../../core/services/domain-type-observable.service'; +import * as _ from 'lodash'; +@Component({ + selector: 'app-recommendations', + templateUrl: './recommendations.component.html', + styleUrls: ['./recommendations.component.css'], + providers: [CommonResponseService, LoggerService, ErrorHandlingService] +}) +export class RecommendationsComponent implements OnInit, OnChanges, OnDestroy { + selectedAssetGroup: string; + selectedDomain: string; + subscriptionToAssetGroup: Subscription; + domainSubscription: Subscription; + summarySubscription: Subscription; + tableSubscription: Subscription; + costSubscription: Subscription; + currentPageLevel = 0; + tabName = [ + ]; + selectedTabName; + errorVal = { + 'summaryStatus': 0, + 'tableStatus': 0, + 'costStatus': 0, + 'savingsStatus': 0 + }; + summaryActiveTab; + errorMessage = 'apiResponseError'; + tableListData: any = {}; + selectedApplication = 'Total'; + mandatoryfilter; + queryParamsWithoutFilter: any; + isFilterRquiredOnPage = true; + agAndDomain = {}; + appliedFilters = { + queryParamsWithoutFilter: {} /* Stores the query parameter ibject without filter */, + pageLevelAppliedFilters: {} /* Stores the query parameter ibject without filter */ + }; + filterArray = []; /* Stores the page applied filter array */ + monthlySavingsTotal; + FullQueryParams: any; + totalCost = 0; + clearSelectedFilterValue = false; + general = false; + toggleSelected = 'asset'; + constructor(private assetGroupObservableService: AssetGroupObservableService, + private router: Router, + private commonResponseService: CommonResponseService, + private logger: LoggerService, + private activatedRoute: ActivatedRoute, + private errorHandling: ErrorHandlingService, + private filterManagementService: FilterManagementService, + private routerUtilityService: RouterUtilityService, + private utils: UtilsService, + private refactorFieldsService: RefactorFieldsService, + private domainObservableService: DomainTypeObservableService) { + this.subscriptionToAssetGroup = this.assetGroupObservableService.getAssetGroup().subscribe(assetGroupName => { + this.selectedAssetGroup = assetGroupName; + if (assetGroupName) { + this.agAndDomain['ag'] = assetGroupName; + } + }); + this.subscribeToDomain(); + } + + ngOnInit() { + } + + subscribeToDomain() { + this.domainSubscription = this.domainObservableService.getDomainType().subscribe(domain => { + if (domain) { + this.agAndDomain['domain'] = domain; + } + this.currentPageLevel = this.routerUtilityService.getpageLevel(this.router.routerState.snapshot.root); + if (this.currentPageLevel === 0 && this.mandatoryfilter) { + // reset selected filter value on ag change + setTimeout(() => { + this.clearSelectedFilterValue = !this.clearSelectedFilterValue; + this.updateUrlWithNewFilters([]); + }, 50); + } else if (this.currentPageLevel === 1) { + this.routerParam(); + } + this.updateComponent(); + }); + } + + routerParam() { + try { + const currentQueryParams = this.routerUtilityService.getQueryParametersFromSnapshot( + this.router.routerState.snapshot.root + ); + + if (currentQueryParams) { + this.appliedFilters.queryParamsWithoutFilter = JSON.parse( + JSON.stringify(currentQueryParams) + ); + delete this.appliedFilters.queryParamsWithoutFilter['filter']; + + this.appliedFilters.pageLevelAppliedFilters = this.utils.processFilterObj( + currentQueryParams + ); + + this.filterArray = this.filterManagementService.getFilterArray( + this.appliedFilters.pageLevelAppliedFilters + ); + } + } catch (error) { + this.errorMessage = this.errorHandling.handleJavascriptError(error); + this.logger.log('error', error); + } + } + + updateUrlWithNewFilters(filterArr) { + // update mandatoryfilter key if available. + this.mandatoryfilter = filterArr['mandatory']; + delete filterArr['mandatory']; + this.filterArray = filterArr; + this.appliedFilters.pageLevelAppliedFilters = this.utils.arrayToObject( + this.filterArray, + 'filterkey', + 'value' + ); // <-- TO update the queryparam which is passed in the filter of the api + this.appliedFilters.pageLevelAppliedFilters = this.utils.makeFilterObj( + this.appliedFilters.pageLevelAppliedFilters + ); + + /** + * To change the url + * with the deleted filter value along with the other existing paramter(ex-->tv:true) + */ + + const updatedFilters = Object.assign( + this.appliedFilters.pageLevelAppliedFilters, + this.appliedFilters.queryParamsWithoutFilter + ); + + /* + Update url with new filters + */ + this.router + .navigate([], { + relativeTo: this.activatedRoute, + queryParams: updatedFilters, + queryParamsHandling: 'merge' + }) + .then(success => { + this.appliedFilters.pageLevelAppliedFilters = this.utils.processFilterObj( + this.appliedFilters.pageLevelAppliedFilters + ); + if (!this.general && this.selectedApplication !== this.appliedFilters.pageLevelAppliedFilters['tags.Application.keyword']) { + this.updateComponent(); + } + if (this.appliedFilters.pageLevelAppliedFilters['tags.Application.keyword']) { + this.selectedApplication = this.appliedFilters.pageLevelAppliedFilters['tags.Application.keyword']; + } else { + this.selectedApplication = 'Total'; + } + }); + } + + ngOnChanges(changes: SimpleChanges) { + try { + const filterChange = changes['filters']; + if (filterChange) { + const cur = JSON.stringify(filterChange.currentValue); + const prev = JSON.stringify(filterChange.previousValue); + if (cur !== prev) { + this.updateComponent(); + } + } + } catch (error) { + this.logger.log('error', error); + } + } + + updateComponent() { + this.reset(); + this.getSummaryData(); + this.getApplicationCost(); + } + + reset() { + this.summaryActiveTab = ''; + } + + contextChange(val) { + if (this.toggleSelected !== val) { + this.toggleSelected = val; + if (val === 'general') { + this.general = true; + this.clearSelectedFilterValue = !this.clearSelectedFilterValue; + this.updateUrlWithNewFilters([]); + this.updateComponent(); + } else { + this.general = false; + this.updateComponent(); + } + } + } + + toggleSlider() { + if (this.toggleSelected === 'general') { + return 'asset'; + } else { + return 'general'; + } + } + + selectTab(tab) { + this.selectedTabName = tab; + return tab.category; + } + + navigateToTab(category) { + this.changeTab(category); + this.updateUrlCategory(category); + } + + changeTab(category) { + this.tabName.forEach((ele, i) => { + if (ele.category === category) { + this.selectedTabName = this.tabName[i]; + } + }); + } + + updateUrlCategory(category) { + this.appliedFilters.queryParamsWithoutFilter['category'] = category; + const currentQueryParams = this.routerUtilityService.getQueryParametersFromSnapshot( + this.router.routerState.snapshot.root + ); + if (this.appliedFilters.pageLevelAppliedFilters['tags.Application.keyword']) { + this.appliedFilters.pageLevelAppliedFilters = this.utils.makeFilterObj( + this.appliedFilters.pageLevelAppliedFilters + ); + } + this.router + .navigate([], {relativeTo: this.activatedRoute, + queryParams: + { 'ag': currentQueryParams['ag'], + 'domain': currentQueryParams['domain'], + 'category': this.appliedFilters.queryParamsWithoutFilter['category'], + 'filter': this.appliedFilters.pageLevelAppliedFilters['filter'] + } + }) + .then(success => { + }); + } + + navigateTo(category, appVal) { + if (appVal) { + this.updateApplicationFilter(appVal['Application'].text); + } + this.navigateToTab(category); + } + + updateApplicationFilter(appName) { + if (this.filterArray.length && this.filterArray[0].value === appName) { + return; + } + const filterArr = [{ + compareKey: 'tags.application.keyword', + filterkey: 'tags.Application.keyword', + key: 'Application', + value: appName + }]; + this.updateUrlWithNewFilters(filterArr); + } + + getSummaryData() { + try { + if (this.summarySubscription) { + this.summarySubscription.unsubscribe(); + } + const payload = {}; + const queryParam = { + 'ag': this.selectedAssetGroup, + 'general': this.general, + 'application': this.appliedFilters.pageLevelAppliedFilters['tags.Application.keyword'] + }; + this.errorVal.summaryStatus = 0; + this.tabName = []; + const url = environment.recommendationSummary.url; + const method = environment.recommendationSummary.method; + this.summarySubscription = this.commonResponseService.getData(url, method, payload, queryParam).subscribe( + response => { + try { + if (this.utils.checkIfAPIReturnedDataIsEmpty(response)) { + this.errorVal.summaryStatus = -1; + this.errorMessage = 'noDataAvailable'; + } else { + this.errorVal.summaryStatus = 1; + this.processSummary(response); + } + } catch (e) { + this.errorVal.summaryStatus = -1; + this.errorMessage = 'jsError'; + this.logger.log('error', e); + } + }, + error => { + this.errorVal.summaryStatus = -1; + this.errorMessage = 'apiResponseError'; + this.logger.log('error', error); + }); + } catch (error) { + this.logger.log('error', error); + } + } + + processSummary(response) { + let categoryType; + + this.tabName = []; + const summaryTabsColor = { + 'cost_optimizing': '#50c17c', + 'security': '#f58544', + 'performance': '#645ec5', + 'service_limits': '#27b5a4', + 'fault_tolerance': '#289cf7' + }; + const displayOrder = { + 'cost_optimizing': 2, + 'security': 4, + 'performance': 5, + 'service_limits': 6, + 'fault_tolerance': 3 + }; + this.tabName[0] = { + 'category': 'summary', + 'displayName': 'Summary', + 'order': 1 + }; + response.forEach((element) => { + element['displayName'] = this.refactorFieldsService.getDisplayNameForAKey(element['category'].toLocaleLowerCase()) || element['category']; + element['icon'] = '../../../../../assets/icons/recommand_' + element.category + '.svg'; + element['color'] = summaryTabsColor[element.category]; + element['order'] = displayOrder[element.category]; + this.tabName.push(element); + }); + + this.tabName = this.sortData(this.tabName, 'order', 'asc'); + let category; + + if (this.appliedFilters.queryParamsWithoutFilter['category'] || this.selectedTabName) { + + const currentCategory = this.appliedFilters.queryParamsWithoutFilter['category']; + + category = this.checkSelectedCategoryAvailable(currentCategory) ? this.appliedFilters.queryParamsWithoutFilter['category'] : this.selectTab(this.tabName[0]); + + } else if (!this.selectedTabName) { + + this.activatedRoute.queryParams.subscribe(params => { + categoryType = params['category']; + }); + + const selectedTabFromList = this.tabName.find(element => element.category === categoryType); + + if (selectedTabFromList) { + category = this.selectTab(selectedTabFromList); + }else { + category = this.selectTab(this.tabName[0]); + } + } + + this.navigateToTab(category); + this.getApplicationTableData(this.tabName[1]); + } + + getApplicationTableData(selectedTab) { + try { + if (this.summaryActiveTab && this.summaryActiveTab.category === selectedTab.category) { + return; + } else { + this.summaryActiveTab = selectedTab; + } + if (this.tableSubscription) { + this.tableSubscription.unsubscribe(); + } + const payload = {}; + const queryParam = { + 'ag': this.selectedAssetGroup, + 'category': selectedTab.category, + 'general': this.general + }; + this.errorVal.tableStatus = 0; + this.tableListData = {}; + const url = environment.recommendationApplication.url; + const method = environment.recommendationApplication.method; + this.tableSubscription = this.commonResponseService.getData(url, method, payload, queryParam).subscribe( + response => { + try { + if (this.utils.checkIfAPIReturnedDataIsEmpty(response.applications)) { + this.errorVal.tableStatus = -1; + this.errorMessage = 'noDataAvailable'; + } else { + this.errorVal.tableStatus = 1; + this.processTableData(response); + } + } catch (e) { + this.errorVal.tableStatus = -1; + this.errorMessage = 'jsError'; + this.logger.log('error', e); + } + }, + error => { + this.errorVal.tableStatus = -1; + this.errorMessage = 'apiResponseError'; + this.logger.log('error', error); + }); + } catch (error) { + this.logger.log('error', error); + } + } + + processTableData(response) { + const header = Object.keys(response.applications[0]); + this.tableListData['header'] = []; + header.forEach( element => { + this.tableListData['header'].push(this.refactorFieldsService.getDisplayNameForAKey(element.toLocaleLowerCase()) || element); + }); + this.tableListData.detailsView = false; + this.tableListData.searchBar = true; + this.tableListData.getColumnNumWithColor = {0: '#ed0074'}; + this.tableListData.enableSearchandDownload = true; + this.tableListData.firstRowClick = true; + const dataArray = []; + let sortedData; + if (this.tableListData['header'].includes('potential monthly savings')) { + sortedData = this.sortData(response.applications, 'monthlySavings', 'desc'); + } else { + sortedData = this.sortData(response.applications, 'recommendations', 'desc'); + } + sortedData.forEach(element => { + const eachRow = {}; + eachRow['Application'] = { + 'text': element['application'], + 'valText': element['application'] + }; + eachRow['recommendations'] = { + 'text': element['recommendations'], + 'valText': element['recommendations'] + }; + if (element['monthlySavings'] || element['monthlySavings'] === 0) { + eachRow['potential monthly savings'] = { + 'text': '$ ' + element['monthlySavings'].toLocaleString(), + 'valText': element['monthlySavings'] + }; + } else if (this.tableListData['header'].includes('potential monthly savings')) { + eachRow['potential monthly savings'] = { + 'text': '', + 'valText': '' + }; + } + dataArray.push(eachRow); + }); + this.tableListData.tableData = dataArray; + } + + sortData(data, key, sortType) { + return _.orderBy(data, [key], [sortType]); + } + + getmonthlySavings(event) { + this.monthlySavingsTotal = event.val; + this.errorVal.savingsStatus = event.status; + } + + getApplicationCost() { + try { + if (this.costSubscription) { + this.costSubscription.unsubscribe(); + } + this.errorVal.costStatus = 0; + const payload = {}; + const queryParam = { + 'ag': this.selectedAssetGroup + }; + this.totalCost = 0; + if (this.appliedFilters.pageLevelAppliedFilters['tags.Application.keyword']) { + this.selectedApplication = this.appliedFilters.pageLevelAppliedFilters['tags.Application.keyword']; + queryParam['application'] = this.appliedFilters.pageLevelAppliedFilters['tags.Application.keyword']; + } + const url = environment.costApplications.url; + const method = environment.costApplications.method; + this.costSubscription = this.commonResponseService.getData(url, method, payload, queryParam).subscribe( + response => { + const applicationList = response.costByApplication; + try { + this.totalCost = this.processApplicationCost(applicationList); + this.errorVal.costStatus = 1; + } catch (e) { + this.logger.log('error', e); + } + }, + error => { + this.logger.log('error', error); + }); + } catch (error) { + this.logger.log('error', error); + } + } + + processApplicationCost(data) { + return data.reduce(function (a, b) { + return a + b['applicationTotalCost']; + }, 0); + } + + checkSelectedCategoryAvailable(category) { + return _.some(this.tabName, {'category': category }); + } + + showHelpContent(event) { + const widgetId = 'w9'; + const newParams = { widgetId: widgetId }; + this.router.navigate( + ['/pl', { outlets: { helpTextModal: ['help-text'] } }], + { queryParams: newParams, queryParamsHandling: 'merge' } + ); +} + + ngOnDestroy() { + try { + if (this.subscriptionToAssetGroup) { + this.subscriptionToAssetGroup.unsubscribe(); + } + if (this.domainSubscription) { + this.domainSubscription.unsubscribe(); + } + if (this.tableSubscription) { + this.tableSubscription.unsubscribe(); + } + if (this.costSubscription) { + this.costSubscription.unsubscribe(); + } + } catch (error) { + this.logger.log('error', '--- Error while unsubscribing ---'); + } + } +} diff --git a/webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.css b/webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.css new file mode 100644 index 000000000..ae2a9e849 --- /dev/null +++ b/webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.css @@ -0,0 +1,33 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +.tagging-instances-container { + min-height: 15em; + height: 100%; + padding-bottom: 1em; +} + +.tagging-instances-content { + font-size: 1em; + height: 100%; +} + +.tagging-instances-content /deep/ .data-table-wrap .sub-head { + border: solid 0.5px #f0f0f0; +} + +.tagging-instances-content /deep/ .head-cell-wrapper{ + text-align: left; +} + diff --git a/webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.html b/webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.html new file mode 100644 index 000000000..79bd13ed3 --- /dev/null +++ b/webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.html @@ -0,0 +1,42 @@ + + +
+
+ + +
+
\ No newline at end of file diff --git a/webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.spec.ts b/webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.spec.ts new file mode 100644 index 000000000..4c2aec29b --- /dev/null +++ b/webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.spec.ts @@ -0,0 +1,39 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { RecommandCategoryComponent } from './recommand-category.component'; + +describe('RecommandCategoryComponent', () => { + let component: RecommandCategoryComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ RecommandCategoryComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(RecommandCategoryComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.ts b/webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.ts new file mode 100644 index 000000000..cd5172dfb --- /dev/null +++ b/webapp/src/app/pacman-features/secondary-components/recommand-category/recommand-category.component.ts @@ -0,0 +1,452 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, ViewEncapsulation, Input, OnInit, OnChanges, Output, EventEmitter, SimpleChanges, OnDestroy } from '@angular/core'; +import { CommonResponseService } from '../../../shared/services/common-response.service'; +import { Subscription } from 'rxjs/Subscription'; +import { DownloadService } from '../../../shared/services/download.service'; +import { AssetGroupObservableService } from '../../../core/services/asset-group-observable.service'; +import { AutorefreshService } from '../../services/autorefresh.service'; +import { environment } from './../../../../environments/environment'; +import { LoggerService } from '../../../shared/services/logger.service'; +import { ErrorHandlingService } from '../../../shared/services/error-handling.service'; +import {RefactorFieldsService} from '../../../shared/services/refactor-fields.service'; +import {WorkflowService} from '../../../core/services/workflow.service'; +import {ActivatedRoute, Router} from '@angular/router'; +import {UtilsService} from '../../../shared/services/utils.service'; + +@Component({ + selector: 'app-recommand-category', + templateUrl: './recommand-category.component.html', + styleUrls: ['./recommand-category.component.css'], + providers: [CommonResponseService, AutorefreshService], + encapsulation: ViewEncapsulation.None +}) +export class RecommandCategoryComponent implements OnInit, OnChanges, OnDestroy { + public somedata: any; + public outerArr: any; + public allColumns: any; + + selectedAssetGroup: string; + public apiData: any; + public applicationValue: any; + public tableHeaderData: any; + + private subscriptionToAssetGroup: Subscription; + private dataSubscription: Subscription; + private downloadSubscription: Subscription; + + durationParams: any; + autoRefresh: boolean; + totalRows = 0; + bucketNumber = 0; + currentBucket: any = []; + firstPaginator = 1; + popRows: any = ['Download Data']; + lastPaginator: number; + currentPointer = 0; + paginatorSize = 10; + dataTableData: any = []; + errorValue = 0; + searchTxt = ''; + showGenericMessage = false; + @Input() filters: any = {}; + @Input() selectedTab: any = {}; + @Input() general: boolean; + @Output() monthlySavings = new EventEmitter(); + monthlySavingsTotal = 0; + errorMessage = 'apiResponseError'; + columnWhiteList = [ 'recommendation', 'Recommendation For', 'Asset Type', 'potential monthly savings']; + storeRecommendations = { + 'category' : { + 'summary': '', + 'cost_optimizing': '', + 'security': '', + 'performance': '', + 'service_limits': '', + 'fault_tolerance': '' + } + }; + constructor(private commonResponseService: CommonResponseService, + private assetGroupObservableService: AssetGroupObservableService, + private autorefreshService: AutorefreshService, + private downloadService: DownloadService, + private logger: LoggerService, + private errorHandling: ErrorHandlingService, + private refactorFieldsService: RefactorFieldsService, + private workflowService: WorkflowService, + private router: Router, + private utils: UtilsService, + private activatedRoute: ActivatedRoute) { + + + this.subscriptionToAssetGroup = this.assetGroupObservableService.getAssetGroup().subscribe( + assetGroupName => { + this.selectedAssetGroup = assetGroupName; + this.updateComponent(); + }); + this.durationParams = this.autorefreshService.getDuration(); + this.durationParams = parseInt(this.durationParams, 10); + this.autoRefresh = this.autorefreshService.autoRefresh; + } + + + ngOnInit() { + } + + ngOnChanges(changes: SimpleChanges) { + try { + const filterChange = changes['filters']; + const tabChange = changes['selectedTab']; + if (filterChange) { + const cur = JSON.stringify(filterChange.currentValue); + const prev = JSON.stringify(filterChange.previousValue); + if (cur !== prev) { + this.updateComponent(); + } + } + if (tabChange) { + const cur = JSON.stringify(tabChange.currentValue); + const prev = JSON.stringify(tabChange.previousValue); + if (cur !== prev) { + this.updateComponent(); + } + } + } catch (error) { + this.logger.log('error', error); + } + } + + updateComponent() { + + /* All functions variables which are required to be set for component to be reloaded should go here */ + this.outerArr = []; + this.searchTxt = ''; + this.currentBucket = []; + this.dataTableData = []; + this.bucketNumber = 0; + this.firstPaginator = 1; + this.currentPointer = 0; + this.errorValue = 0; + this.showGenericMessage = false; + this.monthlySavings.emit({val: 0, status: 0}); + this.getData(); + } + + getData() { + if (this.selectedAssetGroup !== undefined) { + /* All functions to get data should go here */ + this.columnWhiteList = [ 'recommendation', 'Recommendation For', 'Asset Type', 'potential monthly savings']; + this.getTableData(); + } + } + + handlePopClick(rowText) { + const fileType = 'csv'; + + try { + + let queryParams; + + queryParams = { + 'fileFormat': 'csv', + 'serviceId': 21, + 'fileType': fileType + }; + + const downloadRequest = { + 'ag': this.selectedAssetGroup, + 'filter': { + 'category': this.selectedTab.category, + 'general': this.general + }, + 'from': 0, + 'searchtext': this.searchTxt, + 'size': this.totalRows + }; + if (this.filters['tags.Application.keyword']) { + downloadRequest['filter']['application'] = this.filters['tags.Application.keyword']; + } else if (this.filters['filter'] && this.filters['filter'].includes('Application')) { + let arr = []; + arr = this.filters.filter.split('='); + downloadRequest['filter']['application'] = arr.length > 1 ? arr[1] : ''; + } + + const downloadUrl = environment.download.url; + const downloadMethod = environment.download.method; + + this.downloadService.requestForDownload(queryParams, downloadUrl, downloadMethod, downloadRequest, this.selectedTab.displayName, this.totalRows); + + } catch (error) { + this.logger.log('error', error); + } + } + + getTableData() { + + if (this.dataSubscription) { + this.dataSubscription.unsubscribe(); + } + this.errorValue = 0; + this.dataTableData = []; + this.allColumns = []; + if (this.general) { + this.columnWhiteList.push('recommended'); + } + if (this.general && this.storeRecommendations['category'][this.selectedTab.category]) { + this.errorValue = 1; + const response = this.storeRecommendations['category'][this.selectedTab.category]; + this.dataTableData = response.data.response; + this.processResponse(response); + return; + } + const queryParam = { + 'ag': this.selectedAssetGroup, + 'filter': { + 'category': this.selectedTab.category, + 'general': this.general + }, + 'from': (this.bucketNumber) * this.paginatorSize, + 'searchtext': this.searchTxt, + 'size': this.paginatorSize + }; + if (this.filters['tags.Application.keyword']) { + queryParam['filter']['application'] = this.filters['tags.Application.keyword']; + } else if (this.filters['filter'] && this.filters['filter'].includes('Application')) { + let arr = []; + arr = this.filters.filter.split('='); + queryParam['filter']['application'] = arr.length > 1 ? arr[1] : ''; + } + const url = environment.recommendations.url; + const method = environment.recommendations.method; + + this.dataSubscription = this.commonResponseService.getData(url, method, queryParam, {}).subscribe( + response => { + this.showGenericMessage = false; + try { + this.errorValue = 1; + this.dataTableData = response.data.response; + if (this.general && this.bucketNumber === 0) { + this.storeRecommendations['category'][this.selectedTab.category] = response; + } + this.processResponse(response); + } catch (e) { + this.errorValue = -1; + this.errorMessage = 'jsError'; + } + }, + error => { + this.monthlySavings.emit({val: '', status: 1}); + this.showGenericMessage = true; + this.outerArr = []; + this.errorMessage = 'apiResponseError'; + this.errorValue = -1; + }); + } + + processResponse(response) { + if (this.dataTableData.length === 0) { + this.errorValue = -1; + this.outerArr = []; + this.allColumns = []; + this.totalRows = 0; + this.errorMessage = 'noDataAvailable'; + } + if (response.data.response.length > 0) { + this.totalRows = response.data.total; + this.firstPaginator = (this.bucketNumber * this.paginatorSize) + 1; + this.lastPaginator = (this.bucketNumber * this.paginatorSize) + this.paginatorSize; + + this.currentPointer = this.bucketNumber; + + if (this.lastPaginator > this.totalRows) { + this.lastPaginator = this.totalRows; + } + + const updatedResponse = this.massageData(response.data.response); + if (response.data.totalMonthlySavings) { + this.monthlySavings.emit({val: response.data.totalMonthlySavings, status: 1}); + }else { + this.monthlySavings.emit({val: '', status: 1}); + } + this.currentBucket[this.bucketNumber] = updatedResponse; + this.processData(updatedResponse); + } + } + + massageData(data) { + /* + * the function replaces keys of the table header data to a readable format + */ + const refactoredService = this.refactorFieldsService; + const newData = []; + data.map(function(eachRow) { + const KeysTobeChanged = Object.keys(eachRow); + let newObj = {}; + KeysTobeChanged.forEach(element => { + const elementnew = + refactoredService.getDisplayNameForAKey(element.toLocaleLowerCase()) || element; + newObj = Object.assign(newObj, { [elementnew]: eachRow[element] }); + }); + newData.push(newObj); + }); + return newData; + } + + processData(data) { + try { + let innerArr = {}; + const totalVariablesObj = {}; + let cellObj = {}; + this.outerArr = []; + data.forEach((element, i) => { + delete element['Description']; + if (this.general === false) { + data[i]['Recommendation For'] = element.recommended + ' out of ' + element.total + ' Assets'; + } + }); + const getData = data; + const getCols = Object.keys(getData[0]); + + for ( let row = 0; row < getData.length; row++) { + innerArr = {}; + for ( let col = 0; col < getCols.length; col++) { + if (getCols[col].toLowerCase() === 'recommendation') { + cellObj = { + 'link': 'View Recommendation Details', + 'properties': + { + 'color': '', + 'text-decoration': '' + }, + 'colName': getCols[col], + 'hasPreImg': false, + 'imgLink': '', + 'text': getData[row][getCols[col]], + 'valText': getData[row][getCols[col]] + }; + } else if (getCols[col].toLowerCase() === 'potential monthly savings') { + cellObj = { + 'link': '', + 'properties': + {}, + 'colName': getCols[col], + 'hasPreImg': false, + 'imgLink': '', + 'text': '$ ' + getData[row][getCols[col]].toLocaleString(), + 'valText': getData[row][getCols[col]] + }; + } else if (getCols[col].toLowerCase() === 'recommendation for') { + cellObj = { + 'link': '', + 'properties': + {}, + 'colName': getCols[col], + 'hasPreImg': false, + 'imgLink': '', + 'text': getData[row][getCols[col]], + 'valText': getData[row]['recommended'] + }; + } else { + cellObj = { + 'link': '', + 'properties': { + }, + 'colName': getCols[col], + 'hasPreImg': false, + 'imgLink': '', + 'text': getData[row][getCols[col]], + 'valText': getData[row][getCols[col]] + }; + } + + + innerArr[getCols[col]] = cellObj; + totalVariablesObj[getCols[col]] = ''; + + } + this.outerArr.push(innerArr); + } + if (this.outerArr.length > getData.length) { + const halfLength = this.outerArr.length / 2; + this.outerArr = this.outerArr.splice(halfLength); + } + this.allColumns = Object.keys(totalVariablesObj); + + } catch (error) { + this.errorMessage = this.errorHandling.handleJavascriptError(error); + this.logger.log('error', error); + } + + } + + prevPg() { + this.currentPointer--; + this.processData(this.currentBucket[this.currentPointer]); + this.firstPaginator = (this.currentPointer * this.paginatorSize) + 1; + this.lastPaginator = (this.currentPointer * this.paginatorSize) + this.paginatorSize; + + } + + nextPg() { + + if (this.currentPointer < this.bucketNumber) { + this.currentPointer++; + this.processData(this.currentBucket[this.currentPointer]); + this.firstPaginator = (this.currentPointer * this.paginatorSize) + 1; + this.lastPaginator = (this.currentPointer * this.paginatorSize) + this.paginatorSize; + if (this.lastPaginator > this.totalRows) { + this.lastPaginator = this.totalRows; + } + } else { + this.bucketNumber++; + this.storeRecommendations['category'][this.selectedTab.category] = ''; + this.getData(); + } + + } + searchCalled(search) { + this.searchTxt = search; + } + callNewSearch() { + this.bucketNumber = 0; + this.currentBucket = []; + this.storeRecommendations['category'][this.selectedTab.category] = ''; + this.getData(); + } + + goToDetails(row) { + try { + this.workflowService.addRouterSnapshotToLevel(this.router.routerState.snapshot.root); + if (row.col.toLowerCase() === 'recommendation' && row.row['Recommendation ID'].text.length > 0) { + const eachParams = {'recommendationId': row.row['Recommendation ID'].text, 'name': row.row['recommendation'].text, 'general': this.general}; + this.router.navigate(['pl', {outlets: {details: ['recommendations-detail']}}], { queryParams: eachParams, queryParamsHandling : 'merge'}); + } + } catch (error) { + this.errorMessage = this.errorHandling.handleJavascriptError(error); + this.logger.log('error', error); + } + } + + ngOnDestroy() { + try { + this.subscriptionToAssetGroup.unsubscribe(); + this.dataSubscription.unsubscribe(); + } catch (error) { + this.errorMessage = this.errorHandling.handleJavascriptError(error); + this.errorValue = -1; + } + } + +} diff --git a/webapp/src/app/shared/back-navigation/back-navigation.component.css b/webapp/src/app/shared/back-navigation/back-navigation.component.css new file mode 100644 index 000000000..ce3416cf7 --- /dev/null +++ b/webapp/src/app/shared/back-navigation/back-navigation.component.css @@ -0,0 +1,58 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +.toast-body { + top: 2px; + margin: auto; + max-width: 100%; + background: #37342b; + left: 50%; + transform: translate(-50%, -200%); + padding: 1.3em 1.2em; + z-index: 40; + border-radius: 3px; + box-shadow: 0 0 6px 3px rgba(0,0,0,0.2); + min-height: 3.5em; + transition: 0.4s ease; + color: white; + opacity: 0.93; +} + +.toast-body.active { + transform: translate(-50%, 0%); +} + +.toast-exe { + padding: 0.6em 0.83em; + color: white; + background: #ed0295; + border-radius: 3px; + border: 1px solid #ddd; + cursor: pointer; + font-family: ex2-medium; +} + +.toast-element { + margin: 0 0.66em; +} + +.toast-msg { + font-family: ex2-light; + font-size: 1.1em; + letter-spacing: 0.24px; +} + +.toast-msg:first-letter { + text-transform: uppercase; +} \ No newline at end of file diff --git a/webapp/src/app/shared/back-navigation/back-navigation.component.html b/webapp/src/app/shared/back-navigation/back-navigation.component.html new file mode 100644 index 000000000..f5d7269c5 --- /dev/null +++ b/webapp/src/app/shared/back-navigation/back-navigation.component.html @@ -0,0 +1,17 @@ + + + + +

{{pageTitle}}

\ No newline at end of file diff --git a/webapp/src/app/shared/back-navigation/back-navigation.component.spec.ts b/webapp/src/app/shared/back-navigation/back-navigation.component.spec.ts new file mode 100644 index 000000000..b552dfd3a --- /dev/null +++ b/webapp/src/app/shared/back-navigation/back-navigation.component.spec.ts @@ -0,0 +1,39 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BackNavigationComponent } from './back-navigation.component'; + +describe('BackNavigationComponent', () => { + let component: BackNavigationComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ BackNavigationComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BackNavigationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/webapp/src/app/shared/back-navigation/back-navigation.component.ts b/webapp/src/app/shared/back-navigation/back-navigation.component.ts new file mode 100644 index 000000000..205971ee8 --- /dev/null +++ b/webapp/src/app/shared/back-navigation/back-navigation.component.ts @@ -0,0 +1,54 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, OnInit, Input } from '@angular/core'; +import { WorkflowService } from '../../core/services/workflow.service'; +import { Router } from '@angular/router'; +import { LoggerService } from '../../shared/services/logger.service'; +import { RouterUtilityService } from '../../shared/services/router-utility.service'; + +@Component({ + selector: 'app-back-navigation', + templateUrl: './back-navigation.component.html', + styleUrls: ['./back-navigation.component.css'] +}) +export class BackNavigationComponent implements OnInit { + + public backButtonRequired; + @Input() pageTitle?; + + constructor( + private workflowService: WorkflowService, + private router: Router, + private logger: LoggerService, + private routerUtilityService: RouterUtilityService + ) { + this.backButtonRequired = this.workflowService.checkIfFlowExistsCurrently(); + } + + ngOnInit() { + if (!this.pageTitle) { + this.pageTitle = this.routerUtilityService.getpageTitle(this.router.routerState.snapshot.root); + } + } + + navigateBack() { + try { + this.workflowService.goBackToLastOpenedPageAndUpdateLevel(this.router.routerState.snapshot.root); + } catch (error) { + this.logger.log('error', error); + } + } + +} diff --git a/webapp/src/app/shared/constants/routes.ts b/webapp/src/app/shared/constants/routes.ts index 8ab747945..a714abbd1 100644 --- a/webapp/src/app/shared/constants/routes.ts +++ b/webapp/src/app/shared/constants/routes.ts @@ -68,6 +68,7 @@ import { PluginManagementComponent } from '../../pacman-features/modules/admin/p import { PluginManagementDetailsComponent } from '../../pacman-features/modules/admin/plugin-management-details/plugin-management-details.component'; import { SystemManagementComponent } from '../../pacman-features/modules/admin/system-management/system-management.component'; import { ConfigManagementComponent } from '../../pacman-features/modules/admin/config-management/config-management.component'; +import { RecommendationsComponent} from '../../pacman-features/modules/compliance/recommendations/recommendations.component'; export const COMPLIANCE_ROUTES = [ { @@ -194,7 +195,16 @@ export const COMPLIANCE_ROUTES = [ title: 'Vulnerability Details' }, canActivate: [AuthGuardService] - } + }, + { + path: 'recommendations', + component: RecommendationsComponent, + data: { + title: 'Recommendations', + pageLevel: 0 + }, + canActivate: [AuthGuardService] + }, ]; export const ASSETS_ROUTES = [ diff --git a/webapp/src/app/shared/filtered-selector/filtered-selector.component.html b/webapp/src/app/shared/filtered-selector/filtered-selector.component.html index fa981df14..1beb60179 100644 --- a/webapp/src/app/shared/filtered-selector/filtered-selector.component.html +++ b/webapp/src/app/shared/filtered-selector/filtered-selector.component.html @@ -12,7 +12,7 @@ * limitations under the License. --> -
+
{{arr.key}}: {{arr.value}}
diff --git a/webapp/src/app/shared/filtered-selector/filtered-selector.component.ts b/webapp/src/app/shared/filtered-selector/filtered-selector.component.ts index c1fb7907b..d736ca4f8 100644 --- a/webapp/src/app/shared/filtered-selector/filtered-selector.component.ts +++ b/webapp/src/app/shared/filtered-selector/filtered-selector.component.ts @@ -12,7 +12,7 @@ * limitations under the License. */ -import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { Component, OnInit, OnChanges, Input, Output, EventEmitter, SimpleChanges } from '@angular/core'; import { LoggerService } from '../services/logger.service'; @Component({ @@ -20,7 +20,7 @@ import { LoggerService } from '../services/logger.service'; templateUrl: './filtered-selector.component.html', styleUrls: ['./filtered-selector.component.css'] }) -export class FilteredSelectorComponent implements OnInit { +export class FilteredSelectorComponent implements OnInit, OnChanges { countMandatoryFilter = 0; constructor(private logger: LoggerService) {} @@ -30,13 +30,34 @@ export class FilteredSelectorComponent implements OnInit { @Output() deleteAllFilters = new EventEmitter(); @Output() updateFilterArray = new EventEmitter(); - + @Input() clearSelectedFilterValue; ngOnInit() { + this.updateComponent(); + } + + ngOnChanges(changes: SimpleChanges) { + // clear all filter by default - currenlty used in recommendations to reset on ag change + const toClearValueChange = changes['clearSelectedFilterValue']; + if (toClearValueChange && !toClearValueChange.firstChange) { + const cur = JSON.stringify(toClearValueChange.currentValue); + const prev = JSON.stringify(toClearValueChange.previousValue); + if (cur !== prev) { + this.mandatoryFilter = undefined; + this.countMandatoryFilter = 0; + this.clearAll(this.filteredArray); + } + } else { + this.updateComponent(); + } + } + + updateComponent() { // To show clear All text only when optional filters are present. if (this.mandatoryFilter && this.mandatoryFilter.includes('|')) { this.mandatoryFilter = this.mandatoryFilter.split('|'); } if (this.mandatoryFilter) { + this.countMandatoryFilter = 0; this.filteredArray.forEach(obj => { if (this.mandatoryFilter.includes(obj.filterkey)) { obj['mandatoryFilter'] = true; @@ -77,6 +98,12 @@ export class FilteredSelectorComponent implements OnInit { } else { if (event.clearAll) { this.filteredArray = []; + // Adding again Mandatory filters if found any. + event.array.forEach(obj => { + if (obj.hasOwnProperty('mandatoryFilter')) { + this.filteredArray.push(obj); + } + }); } else { this.filteredArray.splice(event.index, 1); } diff --git a/webapp/src/app/shared/generic-page-filter/generic-page-filter.component.html b/webapp/src/app/shared/generic-page-filter/generic-page-filter.component.html index bca884852..4104a590d 100644 --- a/webapp/src/app/shared/generic-page-filter/generic-page-filter.component.html +++ b/webapp/src/app/shared/generic-page-filter/generic-page-filter.component.html @@ -14,9 +14,9 @@
- +
\ No newline at end of file diff --git a/webapp/src/app/shared/generic-page-filter/generic-page-filter.component.ts b/webapp/src/app/shared/generic-page-filter/generic-page-filter.component.ts index 8a99751cb..b7873589d 100644 --- a/webapp/src/app/shared/generic-page-filter/generic-page-filter.component.ts +++ b/webapp/src/app/shared/generic-page-filter/generic-page-filter.component.ts @@ -12,7 +12,7 @@ * limitations under the License. */ -import { Component, OnInit, Input, Output, EventEmitter, OnDestroy } from '@angular/core'; +import { Component, OnInit, Input, Output, EventEmitter, OnDestroy, OnChanges, SimpleChanges } from '@angular/core'; import {Subscription} from 'rxjs/Subscription'; @@ -29,17 +29,20 @@ import * as _ from 'lodash'; templateUrl: './generic-page-filter.component.html', styleUrls: ['./generic-page-filter.component.css'] }) -export class GenericPageFilterComponent implements OnInit, OnDestroy { - +export class GenericPageFilterComponent implements OnInit, OnDestroy, OnChanges { filterSubscription: Subscription; assetGroupSubscription: Subscription; domainSubscription: Subscription; @Input() filterId; @Input() filterArray; + @Input() selectOnSingleValue?; // check to make filter as selected on single value for second dropdown + @Input() mandatoryFilter: any; // check for any mandatory filter @Output() onFilterValueChange = new EventEmitter(); + @Input() clearSelectedFilterValue? = false; agAndDomain = {}; - + disableFilterTags = true; + dataAvailable = false; filterValues = { filterTypeLabels: [], // contains all filter labels available to show user filterTypeOptions: [], // contians filter id, url to get values corresponsing to that filter @@ -65,6 +68,19 @@ export class GenericPageFilterComponent implements OnInit, OnDestroy { this.init(); } + ngOnChanges(changes: SimpleChanges) { + // clear all value by default - currenlty used in recommendations to reset on ag change + const toClearValueChange = changes['clearSelectedFilterValue']; + if (toClearValueChange && !toClearValueChange.firstChange) { + const cur = JSON.stringify(toClearValueChange.currentValue); + const prev = JSON.stringify(toClearValueChange.previousValue); + if (cur !== prev) { + this.disableFilterTags = false; + this.dataAvailable = false; + } + } + } + subscribeToAssetGroup() { this.assetGroupSubscription = this.assetGroupObservableService.getAssetGroup().subscribe(assetGroup => { if (assetGroup) { @@ -86,7 +102,6 @@ export class GenericPageFilterComponent implements OnInit, OnDestroy { reset() { /* Reset the values */ - } init() { @@ -95,11 +110,24 @@ export class GenericPageFilterComponent implements OnInit, OnDestroy { getFilters() { try { + if (this.filterSubscription) { + this.filterSubscription.unsubscribe(); + } if (this.filterId) { this.filterSubscription = this.filterManagementService.getApplicableFilters(this.filterId) .subscribe(response => { - this.filterValues['filterTypeLabels'] = _.map(response[0].response, 'optionName'); - this.filterValues['filterTypeOptions'] = response[0].response; + this.dataAvailable = true; + const responseData = this.removeMandatoryFilter(response[0].response); + this.filterValues['filterTypeLabels'] = _.map(responseData, 'optionName'); + this.filterValues['filterTypeOptions'] = responseData; + if (this.filterValues['filterTypeLabels'].length === 1) { + this.changeFilterType({ + 'value': this.filterValues['filterTypeLabels'][0] + }); + } + }, + error => { + this.dataAvailable = true; }); } } catch (error) { @@ -109,8 +137,16 @@ export class GenericPageFilterComponent implements OnInit, OnDestroy { changeFilterType(value) { try { + if (this.filterSubscription) { + this.filterSubscription.unsubscribe(); + } + this.dataAvailable = false; + this.filterValues.filterValuesOptions = []; + this.filterValues.filterValuesLabels = []; + this.filterValues.currentSelectedFilterType = {}; + this.disableFilterTags = false; this.filterValues.currentSelectedFilterType = _.find(this.filterValues.filterTypeOptions, { - optionName: value.id + optionName: value.value }); const queryParams = { @@ -119,18 +155,24 @@ export class GenericPageFilterComponent implements OnInit, OnDestroy { }; this.filterSubscription = this.filterManagementService.getValuesForFilterType(this.filterValues.currentSelectedFilterType, queryParams).subscribe(response => { + this.dataAvailable = true; this.filterValues.filterValuesLabels = _.map(response[0].response, 'name'); this.filterValues.filterValuesOptions = response[0].response; + if (this.filterValues.filterValuesOptions.length === 1 && this.selectOnSingleValue) { + this.changeFilterValue(this.filterValues.filterValuesOptions[0], true); + } + }, error => { + this.dataAvailable = true; }); } catch (error) { this.logger.log('error', error); } } - changeFilterValue(value) { + changeFilterValue(value, mandatory?) { try { if (this.filterValues.currentSelectedFilterType) { - const filterTag = _.find(this.filterValues.filterValuesOptions, { name: value.id }); + const filterTag = mandatory ? value : _.find(this.filterValues.filterValuesOptions, { name: value.value }); this.utils.addOrReplaceElement( this.filterArray, { @@ -143,11 +185,12 @@ export class GenericPageFilterComponent implements OnInit, OnDestroy { return el.compareKey === this.filterValues.currentSelectedFilterType['optionValue'].toLowerCase().trim(); } ); - this.filterValues.filterValuesOptions = []; - this.filterValues.filterValuesLabels = []; - this.filterValues.currentSelectedFilterType = {}; } /* Emit value to parent to notify change */ + if (mandatory) { + // provide mandatory key when check is passed to select filter on single value + this.filterArray['mandatory'] = this.filterValues['filterTypeOptions'][0].optionValue; + } this.onFilterValueChange.emit(this.filterArray); this.utils.clickClearDropdown(); } catch (error) { @@ -155,6 +198,23 @@ export class GenericPageFilterComponent implements OnInit, OnDestroy { } } + removeMandatoryFilter(data) { + // remove mandatory filter from filter dropdown + let mandatory = this.mandatoryFilter; + if (mandatory && mandatory.includes('|')) { + mandatory = mandatory.split('|'); + } + if (mandatory) { + const filteredOptionValue = _.map(data, 'optionValue'); + filteredOptionValue.forEach(value => { + if (mandatory.includes(value.trim())) { + data = _.reject(data, {'optionValue': value}); + } + }); + } + return data; + } + ngOnDestroy() { try { if (this.assetGroupSubscription) { @@ -163,6 +223,9 @@ export class GenericPageFilterComponent implements OnInit, OnDestroy { if (this.filterSubscription) { this.filterSubscription.unsubscribe(); } + if (this.domainSubscription) { + this.domainSubscription.unsubscribe(); + } } catch (error) { this.logger.log('error', 'js error - ' + error); } diff --git a/webapp/src/app/shared/searchable-dropdown/searchable-dropdown.component.html b/webapp/src/app/shared/searchable-dropdown/searchable-dropdown.component.html index 4df93c1e0..551124ca1 100644 --- a/webapp/src/app/shared/searchable-dropdown/searchable-dropdown.component.html +++ b/webapp/src/app/shared/searchable-dropdown/searchable-dropdown.component.html @@ -12,8 +12,6 @@ * limitations under the License. --> -
- -
-
-
\ No newline at end of file +
+ +
diff --git a/webapp/src/app/shared/searchable-dropdown/searchable-dropdown.component.ts b/webapp/src/app/shared/searchable-dropdown/searchable-dropdown.component.ts index b70021184..405e6a340 100644 --- a/webapp/src/app/shared/searchable-dropdown/searchable-dropdown.component.ts +++ b/webapp/src/app/shared/searchable-dropdown/searchable-dropdown.component.ts @@ -12,52 +12,187 @@ * limitations under the License. */ -import { Component, OnInit, Input, Output, EventEmitter, OnChanges, SimpleChange, SimpleChanges } from '@angular/core'; +import { Component, OnInit, Input, Output, EventEmitter, OnChanges, SimpleChange, SimpleChanges, } from '@angular/core'; @Component({ selector: 'app-searchable-dropdown', templateUrl: './searchable-dropdown.component.html', styleUrls: ['./searchable-dropdown.component.css'] }) -export class SearchableDropdownComponent implements OnInit { - constructor() {} - +export class SearchableDropdownComponent implements OnInit, OnChanges { @Input() items: any; @Input() placeholder; @Input() firstDD; @Input() initValue; @Input() active = []; - + @Input() disable? = false; @Output() selection = new EventEmitter(); - - private value: any = {}; - private _disabledV = '0'; - private disabled = false; + @Input() displayKey; + @Input() dataAvailable; + @Input() selectOnSingleValue?; + @Input() clearSelectedFilterValue?; + secondDDSelected = false; + placeholderVisible = true; + @Input() dataModel; + config = { + displayKey: 'optionName', // if objects array passed which key to be displayed defaults to description + search: false, // true/false for the search functionlity defaults to false, + height: '25em', // height of the list so that if there are more no of items it can show a scroll defaults to auto. With auto height scroll will never appear + placeholder: this.placeholder, // text to be displayed when no item is selected defaults to Select, + customComparator: () => {}, // a custom function using which user wants to sort the items. default is undefined and Array.sort() will be used in that case, + // limitTo: options.length, // a number thats limits the no of options displayed in the UI similar to angular's limitTo pipe + // moreText: 'more', // text to be displayed whenmore than one items are selected like Option 1 + 5 more + noResultsFound: 'No data available', // text to be displayed when no items are found while searching + searchPlaceholder: 'Search' // label thats displayed in search input, + // searchOnKey: 'name' // key on which search should be performed this will be selective search. if undefined this will be extensive search on all keys + }; ngOnInit() { if (this.initValue) { - this.active[0] = this.initValue; + this.dataModel = this.initValue; + this.placeholderVisible = false; + } + if (this.displayKey) { + this.config.displayKey = this.displayKey; + } + this.setConfig(); + } + + ngOnChanges(changes: SimpleChanges) { + try { + const reset = changes['clearSelectedFilterValue']; + if (reset) { + // reset value having selected by default - currenlty used in recommendations to reset on ag change + const cur = JSON.stringify(reset.currentValue); + const prev = JSON.stringify(reset.previousValue); + if (cur !== prev) { + this.disable = false; + this.clearFilterTagsDropdown(); + this.placeholderVisible = true; + this.updateSelectedValue(this.placeholder, this.firstDD); + this.setConfig(); + } + } else { + this.updateProperties(); + if (!this.firstDD && this.secondDDSelected) { + this.placeholderVisible = true; + this.updateSelectedValue(this.placeholder, this.firstDD); + } + if (this.items.length === 1 && (this.firstDD || this.selectOnSingleValue)) { + this.displayKey ? this.dataModel = this.items[0][this.displayKey] : this.dataModel = this.items[0]; + this.placeholderVisible = false; + this.updateSelectedValue(this.dataModel, this.firstDD); + this.disable = true; + } + } + } catch (error) { + } + } + + public selected(value: any ): void { + // document.getElementsByClassName('search-container')[0].childNodes[1]['value'] = ''; + if (value && value.value) { + this.selection.emit(value); + if (typeof value.value === 'object') { + this.dataModel = value.value[this.displayKey]; + + } else { + this.dataModel = value.value; + } + this.placeholderVisible = false; + this.updateSelectedValue(this.dataModel, this.firstDD); + setTimeout(() => { + if (!this.firstDD && this.secondDDSelected) { + this.placeholderVisible = true; + this.updateSelectedValue(this.placeholder, this.firstDD); + } + }, 100); + } + if (!this.firstDD) { + this.clearFilterTagsDropdown(); + this.secondDDSelected = true; } } - private get disabledV(): string { - return this._disabledV; + updateProperties() { + this.config.placeholder = this.placeholder; + this.config.search = !this.firstDD ? true : false; + if (!this.firstDD && this.secondDDSelected) { + this.dataModel = []; + } + this.setConfig(); + } + + public open(value: any): void { + // document.getElementsByClassName('search-container')[0].odes[1]['value'] = ''; + if (!this.firstDD && this.secondDDSelected) { + this.clearFilterTagsDropdown(); + this.placeholderVisible = true; + this.updateSelectedValue(this.placeholder, this.firstDD); + this.setConfig(); + } } - private set disabledV(value: string) { - this._disabledV = value; - this.disabled = this._disabledV === '1'; + public close(value: any): void { } - public selected(value: any): void { - this.selection.emit(value); + public selectFromDropdown(value: any): void { + if (value.keyCode === 13) { + this.selected({'value': value.target.innerText}); + + } + // this.searchValue = value.target.value; } - public removed(value: any): void {} + public updateSelectedValue(updateValue, firstDD) { + // below code is for search and select value + const selectedDoc = document.getElementsByClassName('ngx-dropdown-button'); + if (firstDD) { + // Commented below code as search is not available in filter type - public typed(value: any): void {} + // for (let j = 0; j < selectedDoc.length; j++) { + // if (selectedDoc[j].nextElementSibling && selectedDoc[j].nextElementSibling.className === 'ngx-dropdown-list-container') { + // const selectedText = selectedDoc[j].childNodes; + // for (let k = 0; k < selectedText.length; k++) { + // if (selectedText[k]['innerHTML']) { + // selectedText[k]['innerHTML'] = updateValue; + // break; + // } + // } + // break; + // } + // } + } else { + const selectedText = selectedDoc[selectedDoc.length - 1].childNodes; + for (let k = 0; k < selectedText.length; k++) { + if (selectedText[k]['innerHTML']) { + selectedText[k]['innerHTML'] = updateValue; + break; + } + } + } + } + + setConfig() { + if (this.items.length > 0) { + this.config.noResultsFound = 'No data available'; + } else { + this.config.noResultsFound = 'Loading...'; + } + if (this.dataAvailable && this.items.length === 0) { + this.config.noResultsFound = 'No results found'; + } + } - public refreshValue(value: any): void { - this.value = value; + clearFilterTagsDropdown() { + setTimeout(function() { + const clear = document.getElementsByClassName( + 'nsdicon-close' + ); + if (clear.length > 0 ) { + const element: HTMLElement = clear[0] as HTMLElement; + element.click(); + } + }, 10); } } diff --git a/webapp/src/app/shared/services/router-utility.service.ts b/webapp/src/app/shared/services/router-utility.service.ts index 0356e3e5c..0b88b3850 100644 --- a/webapp/src/app/shared/services/router-utility.service.ts +++ b/webapp/src/app/shared/services/router-utility.service.ts @@ -126,4 +126,25 @@ export class RouterUtilityService { } return false; } + public getpageLevel(routerSnapshot: ActivatedRouteSnapshot) { + const children = routerSnapshot.children; + let pageLevel = routerSnapshot.data ? routerSnapshot.data['pageLevel'] : ''; + if (children.length > 0) { + const index = children.length - 1; + const child = children[index]; + pageLevel = this.getpageLevel(child); + } + return pageLevel; +} + +public getpageTitle(routerSnapshot: ActivatedRouteSnapshot) { + const children = routerSnapshot.children; + let title = routerSnapshot.data ? routerSnapshot.data['pageTitle'] || routerSnapshot.data['title'] : ''; + if (children.length > 0) { + const index = children.length - 1; + const child = children[index]; + title = this.getpageTitle(child) || title; + } + return title; +} } diff --git a/webapp/src/app/shared/shared.module.ts b/webapp/src/app/shared/shared.module.ts index 26de28256..45fea6d24 100644 --- a/webapp/src/app/shared/shared.module.ts +++ b/webapp/src/app/shared/shared.module.ts @@ -86,6 +86,9 @@ import { FormService } from './services/form.service'; import { LoaderMsgComponent } from './loader-msg/loader-msg.component'; import { GenericModalComponent } from './generic-modal/generic-modal.component'; import { ConfigHistoryDropdownComponent } from './config-history-dropdown/config-history-dropdown.component'; +import { BackNavigationComponent } from './back-navigation/back-navigation.component'; +import { SelectDropDownModule } from 'ngx-select-dropdown'; +import { TableListComponent } from './table-list/table-list.component'; @NgModule({ imports: [ CommonModule, @@ -96,6 +99,7 @@ import { ConfigHistoryDropdownComponent } from './config-history-dropdown/config HttpModule, MatSelectModule, NgDatepickerModule, + SelectDropDownModule, AgGridModule.withComponents( [AgGridTableComponent] ) @@ -149,7 +153,9 @@ import { ConfigHistoryDropdownComponent } from './config-history-dropdown/config LoaderMsgComponent, GenericModalComponent, ConfigHistoryDropdownComponent, - InputModalComponent + InputModalComponent, + BackNavigationComponent, + TableListComponent ], exports: [CommonModule, FormsModule, @@ -203,7 +209,10 @@ import { ConfigHistoryDropdownComponent } from './config-history-dropdown/config LoaderMsgComponent, GenericModalComponent, ConfigHistoryDropdownComponent, - InputModalComponent + InputModalComponent, + BackNavigationComponent, + SelectDropDownModule, + TableListComponent ], providers: [HttpService, UtilsService, RefactorFieldsService, OrderByPipe, SearchFilterPipe, MainRoutingAnimationEventService, AuthGuardService, RouterUtilityService, LoggerService, ErrorHandlingService, FilterManagementService, CommonResponseService, CopytoClipboardService, FormService] }) diff --git a/webapp/src/app/shared/table-list/table-list.component.css b/webapp/src/app/shared/table-list/table-list.component.css new file mode 100644 index 000000000..145109493 --- /dev/null +++ b/webapp/src/app/shared/table-list/table-list.component.css @@ -0,0 +1,214 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +.table-container{ + width: 100% ; + border-collapse: separate; + width: 100%; + border-left: 2em solid #FBFBFB; + border-right: 2em solid #fbfbfb; +} + +.table-heading{ + border-bottom: 1px solid #d6e2f1; + font-size: .84em; +} +.table-heading th{ + border-bottom: 1px solid #d6e2f1; + text-align: initial; + max-width: 30em; + text-overflow: ellipsis; + font-family: ex2-bold; + letter-spacing: .3px; + overflow: hidden; + white-space: nowrap; + text-transform: capitalize; + position: sticky; + top:0; + padding: 2.5em 1.1em .5em; + background: #fbfbfb; +} +.table-heading th:first-child{ + box-shadow: -5px 0 0 0 #fbfbfb; +} +.table-heading th:last-child{ + box-shadow: 5px 0 0 0 #fbfbfb; +} +.container{ + padding-bottom: 1em; + height: 100%; + overflow: auto; +} + +.table-body{ + box-shadow: 0 1px 3px 0 rgba(0,0,0,.15); + background: #fff; +} +.table-body td{ + padding: 1.1em; + text-align: initial; + max-width: 30em; + text-overflow: ellipsis; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + vertical-align: middle; +} +.inner-element{ + transition: .5s; + padding: 2em; + text-overflow: ellipsis; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.inside-table{ + width:100%; +} +.space-element{ + padding:.5em; +} +.expand-element{ + box-shadow: 0px 2px 3px 0 rgba(0,0,0,.15); + border-top: 1px solid #d6e2f1; + background: #fff; + transition: .8s; +} + +.list-sortable-arrow:before, +.list-sortable-arrow:after { + content: ""; + border-width: 0 4px 4px; + border-left: 3px solid transparent; + border-right: 3px solid transparent; + border-style: solid; + border-color: #999 transparent; + visibility: visible; + left: 5px; + top: 50%; + position: absolute; + transition: 0.28s ease; +} + +.list-sortable-arrow:before { + border-top: 0; + border-bottom: 3px solid #999; + margin-top: -4px; +} + +.list-sortable-arrow:after { + border-bottom: 0; + border-top: 3px solid #999; + margin-top: 1px; +} + +.up-arr-shown.list-sortable-arrow:after { + opacity: 0; + visibility: hidden; +} + +.down-arr-shown.list-sortable-arrow:before { + opacity: 0; + visibility: hidden; +} + +.head-cells::selection { + background-color: transparent; +} +.head-cells{ + cursor: pointer; +} +.pk-search-container { + background-color: #eff3f6; + padding: 0.66em 0em .66em 1.6em; + border: 1px solid #eaeaea; + flex-shrink: 0; +} +.input-bar { + padding-right: 1.66em; + position: relative; +} + +.input-bar input { + width: 21.25em; + height: 2.1em; + border-radius: 3px; + background-color: #ffffff; + border: solid 1px #c3cbd7; + padding: 0 1em 0em 2.2em; + font-size: 0.87em; + color: #5a616b; + transition: 0.3s ease; +} + +.input-bar input:focus { + width: 31.25em; +} + +.input-bar input:focus+.search-icon { + transform: rotateZ(360deg); +} +.input-bar input:focus+.search-icon { + transform: rotateZ(360deg); +} + +.search-icon img { + height: 1em; + width: 1em; +} + +.search-icon { + top: 0; + left: 0.5em; + bottom: 0; + margin: auto 0; + pointer-events: none; + transition: 0.3s ease; +} +.input-bar input:focus+.search-icon { + transform: rotateZ(360deg); +} + +.search-icon img { + height: 1em; + width: 1em; +} + +.select-filter-btn { + height: 1em; + width: 1em; + border: 1px solid #e4e4e4; + border-radius: 2px; + margin-right: 0.65em; + cursor: pointer; +} +.right-text{ + padding: 0 2em; + font-size: 1.08em;; +} +.right-number{ + font-family: ex2-bold; +} +.cursor-element{ + cursor: pointer; +} + +.help-icon { + margin-left: 3px; + vertical-align: text-bottom; +} + +.help-icon:hover { + color: magenta; +} diff --git a/webapp/src/app/shared/table-list/table-list.component.html b/webapp/src/app/shared/table-list/table-list.component.html new file mode 100644 index 000000000..ff4aa0e53 --- /dev/null +++ b/webapp/src/app/shared/table-list/table-list.component.html @@ -0,0 +1,74 @@ + +
+
+
+
+ +
+
+
+
+
Total of {{(DataObject.tableData | searchFilter:searchTxt)?.length}} Policies
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + +
+
+ {{list}} + +
+
+ + + {{ (!item[list].text && item[list].text !== 0 && item[list].text !== false) ? 'No Data' : item[list].text }} + +
+

Lorem ipsum, or lipsum as it is sometimes known, is dummy text used in laying out print, graphic or web designs

+
+
+
+
+
+ +
+
+ +
\ No newline at end of file diff --git a/webapp/src/app/shared/table-list/table-list.component.spec.ts b/webapp/src/app/shared/table-list/table-list.component.spec.ts new file mode 100644 index 000000000..71932c4f6 --- /dev/null +++ b/webapp/src/app/shared/table-list/table-list.component.spec.ts @@ -0,0 +1,40 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TableListComponent } from './table-list.component'; + +describe('TableListComponent', () => { + let component: TableListComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ TableListComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TableListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/webapp/src/app/shared/table-list/table-list.component.ts b/webapp/src/app/shared/table-list/table-list.component.ts new file mode 100644 index 000000000..1d03014c3 --- /dev/null +++ b/webapp/src/app/shared/table-list/table-list.component.ts @@ -0,0 +1,177 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import { Component, Input, OnChanges, SimpleChanges, Output, EventEmitter, ViewChild, ElementRef, Renderer, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-table-list', + templateUrl: './table-list.component.html', + styleUrls: ['./table-list.component.css'] +}) + +export class TableListComponent implements OnChanges, OnInit { + + @ViewChild('tableInp') tableInp: ElementRef; + + checkValue = false; + selectedValue; + @Input() DataObject; + @Input() errorValue; + @Input() errorMessage; + @Input() keysToSkip; + @Input() clickableKeys; + @Input() headersWithHelp; + @Input() direction = 0; + @Input() headerColName; + rowIndex = -1; + sortArr: any = []; + header; + currentLength = 0; + searchTxt = ''; + @Output() firstRowClick = new EventEmitter(); + @Output() showHelpContent = new EventEmitter(); + + constructor( + private renderer: Renderer) { + } + + /** + * Toggles the expanded section for each row. + * @param {integer} listItem Index of row that will be expanded. + */ + getToggle(value) { + this.checkValue = !this.checkValue; + this.selectedValue = value; + } + + ngOnInit() { + this.getDataList(); + } + + /** + * List out keys of the object + * @param {object} + * @return {array} Array with object keys. + */ + objectKeys(obj) { + return Object.keys(obj); + } + + /** + * Determines if certain keys from data object should be displayed as a column. + * @param {string} listItem Header name of the column + * @return {boolean} + */ + displayListItem(listItem) { + if (!this.keysToSkip) { return true; } + return this.keysToSkip.includes(listItem) ? false : true; + } + + /** + * Determines if items in table columns should be clickable or not. + * @param {string} listItem Header name of the column + * @return {boolean} + */ + clickableColumn(listItem) { + if (!this.clickableKeys) {return false; } + return this.clickableKeys.includes(listItem); + } + + /** + * Determines if help icon should be shown with table header + * @param {string} headerItem Header name of the column + * @return {boolean} + */ + headerWithHelp(headerItem) { + if (!this.headersWithHelp) {return false; } + return this.headersWithHelp.includes(headerItem); + } + + /** + * Emits out event that help icon is clicked. + * @param {event} event Click event + * @param {string} helpIcon Header name of the column which help icon is clicked. + */ + helpClicked(event, helpIcon) { + event.stopPropagation(); + this.showHelpContent.emit(helpIcon); + } + + /** + * Sorts the table order + * @param {integer} index Index of the column with which the table will be sorted. + * @param {string} header Header of the column with which the table will be sorted. + */ + headerClicked(index, header) { + this.rowIndex = -1; + for (let i = 0; i < this.sortArr.length; i++) { + if (i !== index) { + this.sortArr[i].showUp = undefined; + this.sortArr[i].direction = 0; + } else { + if (this.sortArr[i].direction === 0) { + this.sortArr[i].direction = 1; + } else { + this.sortArr[i].direction = this.sortArr[i].direction * -1; + } + this.direction = this.sortArr[i].direction; + } + } + this.headerColName = header; + } + + getDataList() { + if (this.DataObject.header) { + this.DataObject.header.forEach((element, index) => { + this.sortArr[index] = { + 'showUp': undefined, + 'direction': 0 + }; + }); + } + } + + downloadCsv() { + } + + /** + * Emits out event with the row object after certain cell is clicked. + * @param {object} dataObject Data object that will be emitted. + * @param {string} key Title of column in which item was clicked. + */ + getRuleClick(dataObject, key) { + if (key) { + dataObject.selectedKey = key; + } + this.firstRowClick.emit(dataObject); + } + + ngOnChanges(changes: SimpleChanges) { + + if (this.tableInp) { + this.renderer.invokeElementMethod(this.tableInp.nativeElement, 'focus'); + } + + // const DataChanges = changes['DataObject']; + // if (DataChanges) { + // const cur = JSON.stringify(DataChanges.currentValue); + // const prev = JSON.stringify(DataChanges.previousValue); + // if ((cur !== prev)) { + // this.getDataList(); + // } + // } + } + +} diff --git a/webapp/src/config/domain-mapping.ts b/webapp/src/config/domain-mapping.ts index 64f4bdeb8..eabdb24b7 100644 --- a/webapp/src/config/domain-mapping.ts +++ b/webapp/src/config/domain-mapping.ts @@ -40,12 +40,18 @@ export const DOMAIN_MAPPING = [ }, { 'route': 'issue-listing', - 'sequence': 9 + 'sequence': 1 }, { 'route': 'policy-knowledgebase', - 'sequence': 10 - } + 'sequence': 2 + }, + { + 'route': 'recommendations', + 'sequence': 3, + 'groupBy': 'compliance-dashboard', + 'cloudSpecific': true + }, ] }, { diff --git a/webapp/src/environments/environment.prod.ts b/webapp/src/environments/environment.prod.ts index 311b9c347..a1a380236 100644 --- a/webapp/src/environments/environment.prod.ts +++ b/webapp/src/environments/environment.prod.ts @@ -845,6 +845,22 @@ export const environment = { rollbackConfigProperties: { url: '{{baseUrl}}/admin/config-properties/rollback', method: 'PUT' + }, + recommendationSummary : { + url: '{{baseUrl}}/asset/v1/recommendations/summary', + method: 'GET' + }, + recommendationApplication : { + url: '{{baseUrl}}/asset/v1/recommendations/summaryByApplication', + method: 'GET' + }, + recommendations : { + url: '{{baseUrl}}/asset/v1/recommendations', + method: 'POST' + }, + costApplications : { + url: '{{baseUrl}}/asset/v1/costByApplication', + method: 'GET' } }; diff --git a/webapp/src/environments/environment.stg.ts b/webapp/src/environments/environment.stg.ts index c7da9ef61..128ecb8cb 100644 --- a/webapp/src/environments/environment.stg.ts +++ b/webapp/src/environments/environment.stg.ts @@ -845,5 +845,21 @@ export const environment = { rollbackConfigProperties: { url: '{{baseUrl}}/admin/config-properties/rollback', method: 'PUT' + }, + recommendationSummary : { + url: '{{baseUrl}}/asset/v1/recommendations/summary', + method: 'GET' + }, + recommendationApplication : { + url: '{{baseUrl}}/asset/v1/recommendations/summaryByApplication', + method: 'GET' + }, + recommendations : { + url: '{{baseUrl}}/asset/v1/recommendations', + method: 'POST' + }, + costApplications : { + url: '{{baseUrl}}/asset/v1/costByApplication', + method: 'GET' } }; diff --git a/webapp/src/environments/environment.ts b/webapp/src/environments/environment.ts index a9c29410e..ee5c62c86 100644 --- a/webapp/src/environments/environment.ts +++ b/webapp/src/environments/environment.ts @@ -845,5 +845,21 @@ export const environment = { rollbackConfigProperties: { url: '{{baseUrl}}/admin/config-properties/rollback', method: 'PUT' + }, + recommendationSummary : { + url: '{{baseUrl}}/asset/v1/recommendations/summary', + method: 'GET' + }, + recommendationApplication : { + url: '{{baseUrl}}/asset/v1/recommendations/summaryByApplication', + method: 'GET' + }, + recommendations : { + url: '{{baseUrl}}/asset/v1/recommendations', + method: 'POST' + }, + costApplications : { + url: '{{baseUrl}}/asset/v1/costByApplication', + method: 'GET' } }; From 95e28ac99c9e99c1855d646fd2a7962de618056f Mon Sep 17 00:00:00 2001 From: Kanchana Date: Fri, 2 Aug 2019 11:12:20 +0530 Subject: [PATCH 19/86] Added pom with maven jar plugins --- jobs/pacman-cloud-notifications/pom.xml | 281 +++++++++ .../cloud/CloudNotificationApplication.java | 53 ++ ...otificationDataCollectionOrchestrator.java | 152 +++++ .../pacman/cloud/CloudNotificationJob.java | 69 +++ .../pacman/cloud/config/ConfigManager.java | 126 ++++ .../pacman/cloud/dao/RDSDBManager.java | 106 ++++ .../cloud/es/ElasticSearchRepository.java | 548 ++++++++++++++++++ .../pacman/cloud/exception/DataException.java | 80 +++ .../exception/UnAuthorisedException.java | 41 ++ .../tmobile/pacman/cloud/util/ConfigUtil.java | 99 ++++ .../tmobile/pacman/cloud/util/Constants.java | 153 +++++ .../tmobile/pacman/cloud/util/HttpUtil.java | 185 ++++++ .../com/tmobile/pacman/cloud/util/Util.java | 183 ++++++ jobs/recommendation-enricher/pom.xml | 18 + 14 files changed, 2094 insertions(+) create mode 100644 jobs/pacman-cloud-notifications/pom.xml create mode 100644 jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/CloudNotificationApplication.java create mode 100644 jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/CloudNotificationDataCollectionOrchestrator.java create mode 100644 jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/CloudNotificationJob.java create mode 100644 jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/config/ConfigManager.java create mode 100644 jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/dao/RDSDBManager.java create mode 100644 jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/es/ElasticSearchRepository.java create mode 100644 jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/exception/DataException.java create mode 100644 jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/exception/UnAuthorisedException.java create mode 100644 jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/ConfigUtil.java create mode 100644 jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/Constants.java create mode 100644 jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/HttpUtil.java create mode 100644 jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/Util.java diff --git a/jobs/pacman-cloud-notifications/pom.xml b/jobs/pacman-cloud-notifications/pom.xml new file mode 100644 index 000000000..9f2a17883 --- /dev/null +++ b/jobs/pacman-cloud-notifications/pom.xml @@ -0,0 +1,281 @@ + + 4.0.0 + + com.tmobile.pacman.cloud + pacman-cloud-notifications + 0.0.1-SNAPSHOT + jar + + pacman-cloud-notifications + Cloud Notification service + + + UTF-8 + 1.8 + 1.6.4 + + + + org.powermock + powermock-api-mockito + ${powermock.version} + test + + + + org.powermock + powermock-module-junit4 + ${powermock.version} + test + + + + org.powermock + powermock-module-junit4 + ${powermock.version} + test + + + + org.mockito + mockito-core + 1.10.19 + test + + + org.springframework + spring-context + 4.3.8.RELEASE + + + org.springframework + spring-test + 5.0.8.RELEASE + test + + + com.google.guava + guava + 19.0 + + + org.apache.logging.log4j + log4j-api + 2.9.0 + + + org.apache.logging.log4j + log4j-core + 2.9.0 + + + org.elasticsearch + elasticsearch + 5.6.2 + + + org.elasticsearch.client + transport + 5.6.2 + + + + com.google.code.gson + gson + 2.8.1 + + + + commons-collections + commons-collections + 3.2.2 + + + org.apache.commons + commons-lang3 + 3.1 + + + com.tmobile.pacman + batch-commons + 1.0.0-SNAPSHOT + provided + + + com.amazonaws + aws-java-sdk-s3 + + + com.amazonaws + aws-java-sdk-rds + + + com.amazonaws + aws-java-sdk-events + + + com.amazonaws + aws-java-sdk-cloudwatch + + + com.amazonaws + aws-java-sdk-dynamodb + + + com.amazonaws + aws-java-sdk-cloudtrail + + + com.amazonaws + aws-java-sdk-core + + + com.amazonaws + + aws-java-sdk-elasticloadbalancingv2 + + + + com.amazonaws + aws-java-sdk-ec2 + + + com.amazonaws + aws-java-sdk-ses + + + com.amazonaws + aws-java-sdk-kms + + + com.amazonaws + aws-lambda-java-core + + + com.amazonaws + aws-java-sdk-iam + + + com.amazonaws + aws-java-sdk-config + + + com.amazonaws + aws-java-sdk-route53 + + + com.amazonaws + aws-java-sdk-sts + + + com.amazonaws + aws-java-sdk-api-gateway + + + com.amazonaws + aws-java-sdk-lambda + + + com.amazonaws + aws-java-sdk-guardduty + + + com.amazonaws + + aws-java-sdk-elasticloadbalancing + + + + + + org.apache.httpcomponents + httpclient + 4.5.3 + + + org.elasticsearch.client + rest + 5.3.0 + + + com.fasterxml.jackson.core + jackson-databind + 2.8.7 + + + mysql + mysql-connector-java + 5.1.17 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + 1.8 + 1.8 + + + + maven-assembly-plugin + + + build-a + + + jar-with-dependencies + + pacman-cloud-notifications + + package + + single + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.6.201602180812 + + + + prepare-agent + + + + report + test + + report + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 1.8 + + + install + + + + + + + run + + + + + + + \ No newline at end of file diff --git a/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/CloudNotificationApplication.java b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/CloudNotificationApplication.java new file mode 100644 index 000000000..932a48725 --- /dev/null +++ b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/CloudNotificationApplication.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.cloud; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.StringUtils; + +/** + * The Class CloudNotificationApplication. + */ +@Configuration +@ComponentScan +public class CloudNotificationApplication { + + /** The Constant LOGGER. */ + private static final Logger LOGGER = LoggerFactory.getLogger(CloudNotificationApplication.class); + + /** + * The main method. + * + * @param args the arguments + * @return + */ + @SuppressWarnings("resource") + public static void main(String[] args) { + ApplicationContext context = new AnnotationConfigApplicationContext(CloudNotificationApplication.class); + LOGGER.info("****INVENTORY JOB STARTED RUNNING****"); + // Reads the data from raw-data index, + CloudNotificationDataCollectionOrchestrator dataOrchestrator = context + .getBean(CloudNotificationDataCollectionOrchestrator.class); + dataOrchestrator.orchestrate(); + + } + +} diff --git a/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/CloudNotificationDataCollectionOrchestrator.java b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/CloudNotificationDataCollectionOrchestrator.java new file mode 100644 index 000000000..c84831e6a --- /dev/null +++ b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/CloudNotificationDataCollectionOrchestrator.java @@ -0,0 +1,152 @@ +package com.tmobile.pacman.cloud; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.Map.Entry; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import com.google.gson.Gson; +import com.tmobile.pacman.cloud.config.ConfigManager; +import com.tmobile.pacman.cloud.dao.RDSDBManager; +import com.tmobile.pacman.cloud.es.ElasticSearchRepository; +import com.tmobile.pacman.cloud.exception.DataException; +import com.tmobile.pacman.cloud.util.Constants; +import com.tmobile.pacman.cloud.util.Util; + +@Component +public class CloudNotificationDataCollectionOrchestrator { + + /** The log. */ + private static final Logger LOGGER = LoggerFactory.getLogger(CloudNotificationDataCollectionOrchestrator.class); + + /** Clound Notification Query */ + private String cloudTargetQuery = "select * FROM CloudNotification_mapping"; // { "EC2" }; , "DIRECTCONNECT", "RDS", + // "LAMBDA", "IAM", "VPN", + // "CLOUDFRONT", "S3", "REDSHIFT", "SQS", + // "DYNAMODB", "ELASTICCACHE", "APIGATEWAY", + //"VPC", "KMS", "MQ", "CONFIG", "CLOUDTRAIL" }; + + private static final String CURR_DATE = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").format(new java.util.Date()); + + /** The es type. */ + private static String ESTYPE = "cloud_notification"; + + /** + * Orchestrate. + * + */ + public void orchestrate() { + ExecutorService executor = Executors.newCachedThreadPool(); + executor.execute(() -> { + try { + dataCollection(); + } catch (Exception e) { + LOGGER.error("Exception in startDataCollection " + Util.getStackTrace(e)); + } + }); + executor.shutdown(); + while (!executor.isTerminated()) { + } + } + + /** + * Instantiates a new datacollection orchestrator. + * + * dataCollection method will iterate the targettypes and stores the + * notifications. + * + */ + public void dataCollection() { + + try { + List> outputList = new ArrayList>(); + List> countList = new ArrayList>(); + List> cloudMappings = RDSDBManager.executeQuery(cloudTargetQuery); + List> cloudNotificationObjs = new ArrayList<>(); + + cloudMappings.parallelStream().forEach(cloudMapping -> { + + LOGGER.info("Started Collection for this Target Type**" + cloudMapping.get(Constants.EVENTTYPE)); + List> phdEvents = new ArrayList>(); + try { + phdEvents = ElasticSearchRepository.getPhdEvents(cloudMapping.get(Constants.EVENTTYPE)); + } catch (DataException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + phdEvents.forEach(event -> { + if (event.get(Constants.EVENTARN) != "") { + try { + String phdEntity = ElasticSearchRepository + .getPhdEnityByArn(event.get(Constants.EVENTARN).toString()); + // System.out.println("**Entty**"+phdEntity); + // Get the resources from pacbot + if (phdEntity != null && !"UNKNOWN".equals(phdEntity) && !"AWS_ACCOUNT".equals(phdEntity)) { + + List> resorceDet = ElasticSearchRepository.getPacResourceDet( + cloudMapping.get(Constants.ESINDEX), cloudMapping.get(Constants.RESOURCEIDKEY), + cloudMapping.get(Constants.RESOURCEIDVAL), phdEntity); + if (!resorceDet.isEmpty()) { + resorceDet.forEach(details -> { + LOGGER.info("**Target type**" + cloudMapping.get(Constants.RESOURCEIDKEY)); + LOGGER.info( + "***pac list**" + details.get(cloudMapping.get(Constants.RESOURCEIDVAL)) + + "**DOCID***" + details.get(Constants._DOCID)); + countList.add(details); + + Map notificationObj = new HashMap<>(); + notificationObj.putAll(event); + notificationObj.put("_docid", details.get("_docid")); + notificationObj.put("_resourceid", + details.get(cloudMapping.get(Constants.RESOURCEIDVAL))); + notificationObj.put("latest", true); + notificationObj.put("notificationId", + details.get(cloudMapping.get(Constants.RESOURCEIDVAL))); + notificationObj.put("type", + cloudMapping.get(Constants.ESINDEX).toLowerCase().toString()); + cloudNotificationObjs.add(notificationObj); + }); + } else { + Map sourceMap = event; + sourceMap.put("@id", event.get(Constants.ACCOUNTID).toString() + ":" + + event.get(Constants.EVENTARN).toString()); + outputList.add(sourceMap); + } + + } else { + Map sourceMap = event; + sourceMap.put("@id", event.get(Constants.ACCOUNTID).toString() + ":" + + event.get(Constants.EVENTARN).toString()); + outputList.add(sourceMap); + } + } catch (DataException e) { + LOGGER.error("Error in the cloudNotification" + e.getMessage()); + } + } + }); + }); + if (!cloudNotificationObjs.isEmpty()) { + //cloudNotificationObjs.forEach(System.err::println); + ElasticSearchRepository.uploadDataWithParent(cloudNotificationObjs); + } + // Storing the data + if (!outputList.isEmpty()) { + //outputList.forEach(System.err::println); + LOGGER.info("UPLOADING SECURITYHUB DATA TO ES"); + + ElasticSearchRepository.uploadData("cloud_notifications", ESTYPE, outputList, "@id", false); + } + LOGGER.info("**size**" + countList.size()); + } catch (Exception e) { + LOGGER.error(" FAILED IN SECURITYHUB DATACOLLECTION JOB", Util.getStackTrace(e)); + } + } +} diff --git a/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/CloudNotificationJob.java b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/CloudNotificationJob.java new file mode 100644 index 000000000..84c4d0c2f --- /dev/null +++ b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/CloudNotificationJob.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.cloud; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tmobile.pacman.cloud.util.ConfigUtil; +import com.tmobile.pacman.cloud.util.Constants; +import com.tmobile.pacman.cloud.util.Util; +import com.tmobile.pacman.commons.jobs.PacmanJob; + + +/** + * The Class Cloud Notification enricher. + */ +@PacmanJob(methodToexecute = "execute", jobName = "Cloud-Notification-DataCollection", desc = "Job to collect the cloud data from phd index ", priority = 5) +public class CloudNotificationJob implements Constants { + + /** The Constant LOGGER. */ + private static final Logger LOGGER = LoggerFactory.getLogger(CloudNotificationJob.class); + /** + * The main method. + * @param args + * the arguments + */ + public static void main(String[] args){ + Map params = new HashMap<>(); + Arrays.asList(args).stream().forEach(obj -> { + String[] paramArray = obj.split("[:]"); + params.put(paramArray[0], paramArray[1]); + System.setProperty(paramArray[0], paramArray[1]); + }); + execute(params); + System.exit(0); + } + + /** + * execute. + * @param params the params + * @return + * @return the map + */ + public static void execute(Map params){ + try { + ConfigUtil.setConfigProperties(params); + } catch (Exception e) { + LOGGER.error("Unexpected ERROR in execute method"+Util.getStackTrace(e)); + } + CloudNotificationApplication.main( new String[]{}); + } +} diff --git a/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/config/ConfigManager.java b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/config/ConfigManager.java new file mode 100644 index 000000000..8920b3843 --- /dev/null +++ b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/config/ConfigManager.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.cloud.config; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.tmobile.pacman.cloud.dao.RDSDBManager; +import com.tmobile.pacman.cloud.util.Constants; + + +// TODO: Auto-generated Javadoc +/** + * The Class ConfigManager. + */ +public class ConfigManager { + + /** The Constant log. */ + private static final Logger log = LoggerFactory.getLogger(ConfigManager.class); + + /** The type info. */ + private static Map> typeInfo; + + /** + * Gets the type config. + * + * @param datasoruce + * the datasoruce + * @return the type config + */ + private static Map> getTypeConfig(String datasoruce) { + + String commaSepTargetTypes = System.getProperty(Constants.TARGET_TYPE_INFO); + List targetTypesList = new ArrayList<>(); + if (null != commaSepTargetTypes && !"".equals(commaSepTargetTypes)) { + targetTypesList = Arrays.asList(commaSepTargetTypes.split(",")); + } + String outscopeTypes = System.getProperty(Constants.TARGET_TYPE_OUTSCOPE); + List targetTypesOutScopeList = new ArrayList<>(); + if (null != outscopeTypes && !"".equals(outscopeTypes)) { + targetTypesOutScopeList = Arrays.asList(outscopeTypes.split(",")); + } + + System.out.println("&&&&&"+System.getProperty(Constants.CONFIG_QUERY)); + if (typeInfo == null) { + typeInfo = new HashMap<>(); + List> typeList = RDSDBManager.executeQuery("select targetName,targetConfig from cf_Target where domain ='Infra & Platforms'"); + try{ + for (Map _type : typeList) { + String typeName = _type.get("targetName"); + Map config = new ObjectMapper().readValue(_type.get("targetConfig"),new TypeReference>() {}); + if ( (targetTypesList.isEmpty() || targetTypesList.contains(typeName) ) && !targetTypesOutScopeList.contains(typeName)) { + typeInfo.put(typeName, config); + } + } + } catch (IOException e) { + log.error("Error Fetching config Info" + e); + } + + } + return typeInfo; + } + + /** + * Gets the key for type. + * + * @param ds + * the ds + * @param type + * the type + * @return the key for type + */ + public static String getKeyForType(String ds, String type) { + return getTypeConfig(ds).get(type).get("key"); + + } + + /** + * Gets the id for type. + * + * @param ds + * the ds + * @param type + * the type + * @return the id for type + */ + public static String getIdForType(String ds, String type) { + return getTypeConfig(ds).get(type).get("id"); + + } + + /** + * Gets the types. + * + * @param ds + * the ds + * @return the types + */ + public static Set getTypes(String ds) { + return getTypeConfig(ds).keySet(); + } + +} diff --git a/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/dao/RDSDBManager.java b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/dao/RDSDBManager.java new file mode 100644 index 000000000..acdec5772 --- /dev/null +++ b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/dao/RDSDBManager.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.cloud.dao; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.tmobile.pacman.cloud.util.Constants; +import com.tmobile.pacman.cloud.util.Util; + +/** + * The Class RDSDBManager. + */ +public class RDSDBManager { + + /** The Constant dbURL. */ + private static final String DB_URL = System.getProperty(Constants.RDS_DB_URL); + + /** The Constant dbUserName. */ + private static final String DB_USER_NAME = System.getProperty(Constants.RDS_USER); + + /** The Constant dbPassword. */ + private static final String DB_PASSWORD = System.getProperty(Constants.RDS_PWD); + + /** The Constant LOGGER. */ + private static final Logger LOGGER = LoggerFactory.getLogger(RDSDBManager.class); + + /** + * Instantiates a new RDSDB manager. + */ + private RDSDBManager() { + + } + + /** + * Gets the connection. + * + * @return the connection + * @throws ClassNotFoundException the class not found exception + * @throws SQLException the SQL exception + */ + private static Connection getConnection() throws ClassNotFoundException, SQLException { + + Connection conn = null; + Class.forName(Constants.DBDRIVER); + Properties props = new Properties(); + props.setProperty("user", DB_USER_NAME); + props.setProperty("password", DB_PASSWORD); + conn = DriverManager.getConnection(DB_URL, props); + return conn; + } + + /** + * Execute query. + * + * @param query the query + * @return the list + */ + public static List> executeQuery(String query) { + List> results = new ArrayList<>(); + try (Connection conn = getConnection(); + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(query);) { + ResultSetMetaData rsmd = rs.getMetaData(); + int columnCount = rsmd.getColumnCount(); + Map data; + while (rs.next()) { + data = new LinkedHashMap<>(); + for (int i = 1; i <= columnCount; i++) { + data.put(rsmd.getColumnName(i), rs.getString(i)); + } + results.add(data); + } + } catch (Exception ex) { + ex.printStackTrace(); + LOGGER.error("Error Executing Query", Util.getStackTrace(ex)); + } + return results; + } + +} diff --git a/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/es/ElasticSearchRepository.java b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/es/ElasticSearchRepository.java new file mode 100644 index 000000000..43999c18d --- /dev/null +++ b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/es/ElasticSearchRepository.java @@ -0,0 +1,548 @@ +package com.tmobile.pacman.cloud.es; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collector; +import java.util.stream.Collectors; + +import org.apache.commons.httpclient.HttpStatus; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.ParseException; +import org.apache.http.entity.ContentType; +import org.apache.http.nio.entity.NStringEntity; +import org.apache.http.util.EntityUtils; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; +import com.tmobile.pacman.cloud.exception.DataException; +import com.tmobile.pacman.cloud.util.Constants; +import com.tmobile.pacman.cloud.util.HttpUtil; +import com.tmobile.pacman.cloud.util.Util; + +public class ElasticSearchRepository { + + /** The es host key name. */ + private static final String ES_HOST = System.getProperty(Constants.ELASTIC_SEARCH_HOST); + + /** The es http port. */ + private static final Integer ES_HTTP_PORT = getESPort(System.getProperty(Constants.ELASTIC_SEARCH_PORT)); + + /** The heimdall es host key name. */ + private static final String HEIMDAL_ES_HOS = System.getProperty(Constants.ELASTCIC_SEARCH_HOST_HEIMDALL); + + /** The rest client. */ + private static RestClient restClient; + + /** The Constant PROTOCOL. */ + static final String PROTOCOL = "http"; + + /** The es url. */ + private static String esUrl = PROTOCOL + "://" + ES_HOST + ":" + ES_HTTP_PORT;; + + /** The es type. */ + private static String ESTYPE = "cloud_notification"; + + /** The log. */ + private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchRepository.class); + + /** + * Gets the ES port. + * + * @return the ES port + */ + public static int getESPort(String port) { + try { + return Integer.parseInt(port); + } catch (Exception e) { + return 0; + } + } + + /** + * Gets the rest client. + * + * @return the rest client + */ + private static RestClient getRestClient() { + if (restClient == null) + restClient = RestClient.builder(new HttpHost(ES_HOST, ES_HTTP_PORT)).build(); + return restClient; + + } + + /** + * Gets the phd events by targetType + * + * @param targetType name of the asset group + * @return the phd events by targetType + * @throws DataException when there is error while fetching data from ES + */ + public static List> getPhdEvents(String targetType) throws DataException { + LOGGER.info("****In getPhdEvents*****" + targetType); + String responseDetails = null; + System.out.println(esUrl); + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append("/").append(Constants.AWS_PHD).append("/").append(Constants.PHD).append("/") + .append(Constants._SEARCH); + StringBuilder requestBody = null; + { + String body = "{\"size\":10000,\"query\":{\"bool\":{\"must\":[{\"match\":{\"latest\":\"true\"}},{\"match\":{\"eventservice.keyword\":\"" + + targetType+ "\"}}]}}}"; + + requestBody = new StringBuilder(body); + try { + responseDetails = HttpUtil.doHttpPost(urlToQueryBuffer.toString(), requestBody.toString()); + } catch (Exception e) { + LOGGER.error("failed to fetch phd events in getPhdEvents", Util.getStackTrace(e)); + throw new DataException(e); + } + List> arnList = new ArrayList>(); + String HITS = Constants.HITS; + Gson serializer = new GsonBuilder().create(); + List> iamDetails = null; + Map responseMap = (Map) serializer.fromJson(responseDetails, Object.class); + if (responseMap.containsKey(HITS)) { + Map hits = (Map) responseMap.get(HITS); + if (hits.containsKey(HITS)) { + iamDetails = (List>) hits.get(HITS); + for (Map iamDetail : iamDetails) { + Map sourceMap = (Map) iamDetail.get(Constants._SOURCE); + arnList.add(sourceMap); + } + } + } + return arnList; + } + } + + /** + * Gets the phd entities by phd event Arn + * + * @param phdEventArn name of the asset group + * @return the phd entities by phd event + * @throws DataException when there is error while fetching data from ES + */ + public static String getPhdEnityByArn(String phdEventArn) throws DataException { + LOGGER.info("****In getPhdEnityByArn*****" + phdEventArn); + String responseDetails = null; + System.out.println(esUrl); + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append("/").append(Constants.AWS_PHD).append("/").append(Constants.PHD_ENTITES).append("/") + .append(Constants._SEARCH); + StringBuilder requestBody = null; + { + String body = "{\"size\":10000,\"_source\":[\"entityvalue\"],\"query\":{\"match\":{\"eventarn.keyword\":\"" + + phdEventArn+ "\"}}}"; + + requestBody = new StringBuilder(body); + try { + responseDetails = HttpUtil.doHttpPost(urlToQueryBuffer.toString(), requestBody.toString()); + } catch (Exception e) { + LOGGER.error("failed to fetch phdEntity in getPhdEnityByArn", Util.getStackTrace(e)); + throw new DataException(e); + } + String entity = ""; + String HITS = Constants.HITS; + Gson serializer = new GsonBuilder().create(); + List> iamDetails = null; + Map responseMap = (Map) serializer.fromJson(responseDetails, Object.class); + if (responseMap.containsKey(HITS)) { + Map hits = (Map) responseMap.get(HITS); + if (hits.containsKey(HITS)) { + iamDetails = (List>) hits.get(HITS); + for (Map iamDetail : iamDetails) { + Map sourceMap = (Map) iamDetail.get(Constants._SOURCE); + entity = sourceMap.get("entityvalue").toString(); + } + } + } + return entity; + } + } + + /** + * Gets the Pacbot Resource Details by Phd entity events by targetType + * + * @param index name of the index + * @param type type of the index + * @param resourceKey the keyname of the resource + * @param phdEntity name of the asset group + * @return the resource details by phdEntity + * @throws DataException when there is error while fetching data from ES + */ + public static List> getPacResourceDet(String index, String key, String value, String phdEntity) throws DataException { + LOGGER.info("****In getPacResourceDet*****" + phdEntity); + String responseDetails = null; + System.out.println(esUrl); + StringBuilder urlToQueryBuffer = new StringBuilder(esUrl).append("/").append("aws_"+index).append("/").append(index).append("/") + .append(Constants._SEARCH); + StringBuilder requestBody = null; + { + //String body = "{\"size\":1,\"_source\":[\""+value+"\",\"_docid\"],\"query\":{\"bool\":{\"must\":[{\"match\":{\""+key+"\":\"" + // + phdEntity+ "\"}}]}}}"; + String body = "{\"size\":1,\"_source\":[\""+value+"\",\"_docid\"],\"query\":{\"bool\":{\"must\":[{\"match\":{\""+key+"\":\"" + +phdEntity+"\"}},{\"match\":{\"latest\":true}}]}}}"; + + requestBody = new StringBuilder(body); + try { + responseDetails = HttpUtil.doHttpPost(urlToQueryBuffer.toString(), requestBody.toString()); + } catch (Exception e) { + LOGGER.error("failed to fetch resources in getPacResourceDet", Util.getStackTrace(e)); + throw new DataException(e); + } + List> arnList = new ArrayList>(); + String HITS = Constants.HITS; + Gson serializer = new GsonBuilder().create(); + List> iamDetails = null; + Map responseMap = (Map) serializer.fromJson(responseDetails, Object.class); + if (responseMap.containsKey(HITS)) { + Map hits = (Map) responseMap.get(HITS); + if (hits.containsKey(HITS)) { + iamDetails = (List>) hits.get(HITS); + for (Map iamDetail : iamDetails) { + Map sourceMap = (Map) iamDetail.get(Constants._SOURCE); + arnList.add(sourceMap); + } + } + } + return arnList; + } + } + + /** + * Refresh. + * + * @param index + * the index + */ + public static void refresh(String index) { + try { + Response refrehsResponse = invokeAPI("POST", index + "/" + "_refresh", null); + if (refrehsResponse != null && HttpStatus.SC_OK != refrehsResponse.getStatusLine().getStatusCode()) { + LOGGER.error("Refreshing index %s failed", index, refrehsResponse); + } + } catch (IOException e) { + LOGGER.error("Error in refresh ",e); + } + + } + + + + + /** + * Creates the type. + * + * @param index the index + * @param type the type + * @param parent the parent + */ + public static void createType(String index, String type, String parent) { + if (!typeExists(index, type)) { + String endPoint = index + "/_mapping/" + type; + String payLoad = "{\"_parent\": { \"type\": \"" + parent + "\" } }"; + try { + invokeAPI("PUT", endPoint, payLoad); + } catch (IOException e) { + LOGGER.error("Error createType ", e); + } + } + } + + + /** + * Type exists. + * + * @param indexName + * the index name + * @param type + * the type + * @return true, if successful + */ + private static boolean typeExists(String indexName, String type) { + try { + Response response = invokeAPI("HEAD", indexName + "/_mapping/" + type, null); + if (response != null) { + return response.getStatusLine().getStatusCode() == 200 ? true : false; + } + } catch (IOException e) { + LOGGER.error("Error in typeExists",e); + } + + return false; + } + + + public static void bulkUpload(List errors, String bulkRequest) { + try { + System.out.println("********"+bulkRequest); + Response resp = invokeAPI("POST", "/_bulk?refresh=true", bulkRequest); + + String responseStr = EntityUtils.toString(resp.getEntity()); + if (responseStr.contains("\"errors\":true")) { + LOGGER.error(responseStr); + errors.add(responseStr); + } + } catch (Exception e) { + e.printStackTrace(); + LOGGER.error("Bulk upload failed",e); + errors.add(e.getMessage()); + } + } + + + + /** + * added for uploading Child docs where parent id could be dervied from + * child. + * + * @param index the index + * @param type the type + * @param docs the docs + * @param parentKey the parent key + */ + public static void uploadData(List> docs, String[] parentKey) { + String actionTemplate = "{ \"index\" : { \"_index\" : \"%s\", \"_type\" : \"%s\", \"_parent\" : \"%s\" } }%n"; // added + // _parent + // node + if (null != docs && !docs.isEmpty()) { + StringBuilder bulkRequest = new StringBuilder(); + int i = 0; + for (Map doc : docs) { + String type = doc.get("type").toString(); + String index = "aws_" + type; + LOGGER.info("*********UPLOADING*** {}", type); + StringBuilder _doc = new StringBuilder(new Gson().toJson(doc)); + String parent = Util.concatenate(doc, parentKey, "_"); + bulkRequest.append(String.format(actionTemplate, index, type, parent)); + bulkRequest.append(_doc + "\n"); + i++; + if (i % 1000 == 0 || bulkRequest.toString().getBytes().length / (1024 * 1024) > 5) { + bulkUpload(bulkRequest); + bulkRequest = new StringBuilder(); + } + } + if (bulkRequest.length() > 0) { + bulkUpload(bulkRequest); + } + } + } + + /** + * added for uploading Child docs where parent id could be dervied from + * child. + * + * @param index the index + * @param type the type + * @param docs the docs + * @param parentKey the parent key + */ + public static void uploadDataWithParent(List> docs) { + String actionTemplate = "{ \"index\" : { \"_index\" : \"%s\", \"_type\" : \"%s\", \"_id\" : \"%s\", \"_parent\" : \"%s\" } }%n"; // added + // _parent + // node + String loaddate = new SimpleDateFormat("yyyy-MM-dd HH:mm:00Z").format(new java.util.Date()); + List> updateStatus = new ArrayList>(); + if (null != docs && !docs.isEmpty()) { + StringBuilder bulkRequest = new StringBuilder(); + int i = 0; + LOGGER.info("*********UPLOADING*** {}"); + for (Map doc : docs) { + String type = doc.get(Constants.TYPE).toString(); + String index = "aws_" + type; + Map indexMap = new HashMap(); + String awsType = "aws_"+type; + indexMap.put(Constants.TYPE, ESTYPE); + indexMap.put(Constants.INDEX, awsType); + indexMap.put(Constants.LOADDATE, loaddate); + updateStatus.add(indexMap); + StringBuilder _doc = new StringBuilder(new Gson().toJson(doc)); + createType("aws_" + type, ESTYPE, type); + _doc.deleteCharAt(_doc.length() - 1); + _doc.append(",\"_loaddate\":\"" + loaddate + "\" }"); + String parent = doc.get(Constants._DOCID).toString(); + String idkey = Util.getUniqueID(doc.get(Constants._DOCID).toString() + doc.get(Constants.EVENTARN)); + bulkRequest.append(String.format(actionTemplate, index, ESTYPE, idkey, parent)); + bulkRequest.append(_doc + "\n"); + i++; + if (i % 100 == 0 || bulkRequest.toString().getBytes().length / (1024 * 1024) > 5) { + LOGGER.info("Uploaded {}" + i); + bulkUpload(bulkRequest); + bulkRequest = new StringBuilder(); + } + } + if (bulkRequest.length() > 0) { + LOGGER.info("Uploaded {}" + i); + bulkUpload(bulkRequest); + } + updateStatus = updateStatus.stream().distinct().collect(Collectors.toList()); + updateStatus.parallelStream().forEach(updateMap -> { + LOGGER.info("Updating status"); + refresh(updateMap.get(Constants.INDEX).toString()); + updateLatestStatus(updateMap.get(Constants.INDEX).toString(), updateMap.get(Constants.TYPE).toString(), updateMap.get(Constants.LOADDATE).toString()); + }); + } + + } + + /** + * Bulk upload. + * + * @param bulkRequest the bulk request + */ + private static void bulkUpload(StringBuilder bulkRequest) { + try { + Response resp = invokeAPI("POST", "/_bulk?refresh=true", bulkRequest.toString()); + String responseStr = EntityUtils.toString(resp.getEntity()); + if (responseStr.contains("\"errors\":true")) { + LOGGER.error(responseStr); + } + } catch (ParseException | IOException e) { + LOGGER.error("Error in uploading data", e); + } + } + + + + /** + * Method not used by the entity upload.But to append data to speific index + * + * @param index the index + * @param type the type + * @param docs the docs + * @param idKey the id key + * @param refresh the refresh + */ + public static void uploadData(String index, String type, List> docs, String idKey, + boolean refresh) { + try { + String loaddate = new SimpleDateFormat("yyyy-MM-dd HH:mm:00Z").format(new java.util.Date()); + String actionTemplate = "{ \"index\" : { \"_index\" : \"%s\", \"_type\" : \"%s\", \"_id\" : \"%s\"} }%n"; + String endpoint = "/_bulk"; + if (refresh) { + endpoint = endpoint + "?refresh=true"; + } + LOGGER.info("*********UPLOADING*** {}" + type); + if (null != docs && !docs.isEmpty()) { + StringBuilder bulkRequest = new StringBuilder(); + int i = 0; + for (Map doc : docs) { + + String id = doc.get(idKey).toString(); + StringBuilder _doc = new StringBuilder(createESDoc(doc)); + _doc.deleteCharAt(_doc.length() - 1); + _doc.append(",\"latest\":true,\"_loaddate\":\"" + loaddate + "\" }"); + + if (_doc != null) { + bulkRequest.append(String.format(actionTemplate, index, type, id)); + bulkRequest.append(_doc + "\n"); + } + i++; + if (i % 1000 == 0 || bulkRequest.toString().getBytes().length / (1024 * 1024) > 5) { + LOGGER.info("Uploaded {}" + i); + bulkUpload(endpoint, bulkRequest); + bulkRequest = new StringBuilder(); + } + } + if (bulkRequest.length() > 0) { + LOGGER.info("Uploaded {}" + i); + bulkUpload(endpoint, bulkRequest); + } + LOGGER.info("Updating status"); + refresh(index); + updateLatestStatus(index, type, loaddate); + } + } catch (Exception e) { + e.printStackTrace(); + LOGGER.error(" Some thing failed during uploading the data", Util.getStackTrace(e)); + } + + } + + public static String createESDoc(Map doc) { + ObjectMapper objMapper = new ObjectMapper(); + String docJson = "{}"; + try { + docJson = objMapper.writeValueAsString(doc); + } catch (JsonProcessingException e) { + LOGGER.error(" Some thing got failed in createESDc", Util.getStackTrace(e)); + } + return docJson; + } + + /** + * Bulk upload. + * + * @param endpoint the endpoint + * @param bulkRequest the bulk request + */ + private static void bulkUpload(String endpoint, StringBuilder bulkRequest) { + try { + Response resp = invokeAPI("POST", endpoint, bulkRequest.toString()); + String responseStr = EntityUtils.toString(resp.getEntity()); + if (responseStr.contains("\"errors\":true")) { + LOGGER.info(responseStr); + } + } catch (Exception e) { + LOGGER.error(" Some thing got failed in bulkUpload", Util.getStackTrace(e)); + } + } + + /** + * Invoke API. + * + * @param method the method + * @param endpoint the endpoint + * @param payLoad the pay load + * @return the response + * @throws IOException Signals that an I/O exception has occurred. + */ + public static Response invokeAPI(String method, String endpoint, String payLoad) throws IOException { + String uri = endpoint; + if (!uri.startsWith("/")) { + uri = "/" + uri; + } + HttpEntity entity = null; + if (payLoad != null) + entity = new NStringEntity(payLoad, ContentType.APPLICATION_JSON); + + return getRestClient().performRequest(method, uri, Collections.emptyMap(), entity); + } + + /** + * Update latest status. + * + * @param index + * the index + * @param type + * the type + * @param loaddate + * the loaddate + */ + + public static void updateLatestStatus(String index, String type, String loaddate) { + String updateJson = "{\"script\":{\"inline\": \"ctx._source.latest=false\"},\"query\": {\"bool\": {\"must\": [{ \"match\": {\"latest\":true}}], \"must_not\": [{\"match\": {\"_loaddate.keyword\":\"" + + loaddate + "\"}}]}}}"; + try { + invokeAPI("POST", index + "/" + type + "/" + "_update_by_query", updateJson); + } catch (IOException e) { + LOGGER.error("Error in updateLatestStatus",e); + } + + } +} diff --git a/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/exception/DataException.java b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/exception/DataException.java new file mode 100644 index 000000000..25df19479 --- /dev/null +++ b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/exception/DataException.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +/** + Copyright (C) 2017 T Mobile Inc - All Rights Reserve + Purpose: + Author :kkumar28 + Modified Date: Jun 11, 2018 + +**/ +/* + *Copyright 2016-2017 T Mobile, Inc. or its affiliates. All Rights Reserved. + * + *Licensed under the Amazon Software License (the "License"). You may not use + * this file except in compliance with the License. A copy of the License is located at + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.tmobile.pacman.cloud.exception; + +/** + * @author kkumar28 + * This is the Generic data exception to be thrown when no specific exceptions matches, usually a replacement of Exception class + * when used in Repo class + */ +public class DataException extends Exception { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * + */ + public DataException() { + // TODO Auto-generated constructor stub + } + + + /** + * + */ + public DataException(String msg) { + super(msg); + } + + /** + * + * @param th + */ + public DataException(Throwable th){ + super(th); + } + + /** + * + * @param msg + * @param th + */ + public DataException(String msg,Throwable th){ + super(msg,th); + } + + + +} diff --git a/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/exception/UnAuthorisedException.java b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/exception/UnAuthorisedException.java new file mode 100644 index 000000000..4e60379e1 --- /dev/null +++ b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/exception/UnAuthorisedException.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.cloud.exception; + +/** + * The Class UnAuthorisedException. + */ +public class UnAuthorisedException extends Exception { + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 1L; + + /** + * Instantiates a new un authorised exception. + */ + public UnAuthorisedException() { + } + + /** + * Instantiates a new un authorised exception. + * + * @param msg the msg + */ + public UnAuthorisedException(String msg) { + super(msg); + } + +} diff --git a/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/ConfigUtil.java b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/ConfigUtil.java new file mode 100644 index 000000000..8ba3b300a --- /dev/null +++ b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/ConfigUtil.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.cloud.util; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + + + +/** + * The Class ConfigUtil. + */ +public class ConfigUtil { + + /** The Constant LOGGER. */ + private static final Logger LOGGER = LoggerFactory.getLogger(ConfigUtil.class); + + /** + * Sets the config properties. + * + * @param configCreds the new config properties + * @throws Exception the exception + */ + public static void setConfigProperties(Map params) throws Exception{ + Properties properties = new Properties(); + properties.putAll(System.getProperties()); + properties.putAll(fetchConfigProperties(params)); + System.setProperties(properties); + } + + /** + * Fetch config properties. + * + * @param configCreds the config creds + * @return the map + * @throws Exception the exception + */ + @SuppressWarnings("unchecked") + public static Map fetchConfigProperties(Map params) throws Exception { + Map properties = new HashMap<>(); + String configUrl = System.getenv("CONFIG_URL"); + ObjectMapper objectMapper = new ObjectMapper(); + try { + Map appProps = new HashMap<>(); + Map batchProps = new HashMap<>(); + Map response = objectMapper.readValue(HttpUtil.httpGetMethodWithHeaders(configUrl, Util.getHeader(params.get(Constants.CONFIG_CREDS))), new TypeReference>(){}); + List> propertySources = (List>)response.get("propertySources"); + + for(Map propertySource : propertySources) { + if(params.get("conf_src").contains(propertySource.get(Constants.NAME).toString())) { + appProps.putAll((Map)propertySource.get(Constants.SOURCE)); + } + if(params.get("conf_src").contains(propertySource.get(Constants.NAME).toString())) { + batchProps.putAll((Map)propertySource.get(Constants.SOURCE)); + } + + properties.putAll(appProps); + properties.putAll(batchProps); + + if( !(properties==null || properties.isEmpty())){ properties.forEach((k,v) -> + System.setProperty(k, v)); } + + } + if(params.get(Constants.CONFIG_QUERY)==null){ + System.setProperty(Constants.CONFIG_QUERY, "select targetName,targetConfig from cf_Target where domain ='Infra & Platforms'"); + } + } catch (Exception e) { + LOGGER.error("Error in fetchConfigProperties",e); + throw e; + } + if(properties.isEmpty()){ + throw new Exception("No config properties fetched from "+configUrl); + } + LOGGER.info("Config are feteched from {}",configUrl); + properties.forEach((k,v)-> LOGGER.debug("{} : {} ",k,v)); + return properties; + } +} diff --git a/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/Constants.java b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/Constants.java new file mode 100644 index 000000000..87fda4c66 --- /dev/null +++ b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/Constants.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.cloud.util; + +/** + * The Interface Constants. + */ +public interface Constants { + + /** The rds db url. */ + String RDS_DB_URL = "spring.datasource.url"; + + /** The rds user. */ + String RDS_USER = "spring.datasource.username"; + + /** The rds pwd. */ + String RDS_PWD = "spring.datasource.password"; + + /** The target type info. */ + String TARGET_TYPE_INFO = "targetTypes"; + + /** The config creds. */ + String CONFIG_CREDS = "config_creds"; + + /** The config query. */ + String CONFIG_QUERY = "configquery"; + + /** The config url. */ + String CONFIG_URL = "CONFIG_URL"; + + /** The failed. */ + String FAILED = "failed"; + + /** The error. */ + String ERROR = "error"; + + /** The exception. */ + String EXCEPTION = "exception"; + + /** The error type. */ + String ERROR_TYPE = "type"; + + /** The warn. */ + String WARN = "warn"; + + /** The fatal. */ + String FATAL = "fatal"; + + /** The source. */ + String SOURCE = "source"; + + /** The name. */ + String NAME = "name"; + + /** The JDBC Driver. */ + String DBDRIVER = "com.mysql.jdbc.Driver"; + + /** The elastic search host */ + String ELASTIC_SEARCH_HOST = "elastic-search.host"; + + /** The elastic search host */ + String ELASTIC_SEARCH_PORT = "elastic-search.port"; + + /** The heimdall elastic search host */ + String ELASTCIC_SEARCH_HOST_HEIMDALL = "elastic-search.host-heimdall"; + + /** The heimdall elastic search host */ + String HEIMDALL_ELASTIC_SEARCH_PORT = "elastic-search.port-heimdall"; + + String TARGET_TYPE_OUTSCOPE = "typesNotInScope"; + + String _SEARCH = "_search"; + String AGGREGATIONS = "aggregations"; + String BUCKETS = "buckets"; + String KEY = "key"; + String CIS_COMPLIANCE = "cis-compliance"; + String RAW_DATA = "raw-data"; + String IAMUSER = "iamuser"; + String _SOURCE = "_source"; + String HITS = "hits"; + String AWS = "aws"; + String KMS = "kms"; + + String GROUPNAME = "groupName"; + String SECURITYHUB = "SecurityHub"; + String RULESOURCE = "ruleSource"; + String SECURITYhUB = "securityhub"; + String RULEID = "ruleId"; + String ENTITYTYPE = "entityType"; + String _ENTITYTPE = "_entitytype"; + String AWSACCOUNTID = "AwsAccountId"; + String REGION = "Region"; + String _REGION = "region"; + String RULETITLE = "ruleTitle"; + String UPDATEDAT = "UpdatedAt"; + String MODIFIEDDATE = "modifiedDate"; + String LOADDATE = "loaddate"; + String AWSACCOUNT = "AwsAccount"; + String ID = "Id"; + String ASSETTYPE = "assetType"; + String AWSEC2SECGRP = "AwsEc2SecurityGroup"; + String AWSS3BUCKET = "AwsS3Bucket"; + String AWSKMSKEY = "AwsKmsKey"; + String AWSEC2VPC = "AwsEc2Vpc"; + String ACCOUNT = "account"; + String CLOUDTRAIL = "cloudtrail"; + String VPC = "vpc"; + String S3 = "s3"; + String SG = "sg"; + String SCOREPERCENTAGE = "scorePercentage"; + String _VIOLATEDASSETS = "_violatedAssets"; + String TOTALASSETS = "total_assets"; + String VIOLATEDASSETS = "violated_assets"; + String AG = "ag"; + String _LOADDATE = "_loaddate"; + String SCOREDATA = "scoredata"; + String RESPONSBILITY = "responsbility"; + String GROUPTYPE = "groupType"; + String POLICYID = "policyId"; + + + + String EVENTTYPE = "eventType"; + String AWS_PHD = "aws_phd"; + String PHD = "phd"; + String PHD_ENTITES = "phd_entities"; + String EVENTARN = "eventarn"; + String ESINDEX = "esIndex"; + String RESOURCEIDKEY = "resourceIdKey"; + String RESOURCEIDVAL = "resourceIdVal"; + String _RESOURCEID = "_resourceid"; + String EVENTSERVICE = "eventservice"; + String _DOCID = "_docid"; + String ACCOUNTID = "accountid"; + String TYPE = "type"; + String INDEX = "index"; + + + +} diff --git a/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/HttpUtil.java b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/HttpUtil.java new file mode 100644 index 000000000..19f412729 --- /dev/null +++ b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/HttpUtil.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.cloud.util; + +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Map; + +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.ParseException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.ssl.TrustStrategy; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Strings; +import com.tmobile.pacman.cloud.exception.UnAuthorisedException; + + +/** + * The Class HttpUtil. + */ +public class HttpUtil { + + /** The log. */ + static final Logger LOGGER = LoggerFactory.getLogger(HttpUtil.class); + private static final String CONTENT_TYPE = "Content-Type"; + + /** + * Instantiates a new http util. + */ + private HttpUtil(){ + } + + + + /** + * Post. + * + * @param url the url + * @param requestBody the request body + * @param token the token + * @param tokeType the toke type + * @return the string + * @throws Exception the exception + */ + public static String post(String url, String requestBody,String token,String tokeType) throws Exception { + try { + CloseableHttpClient httpClient = getHttpClient(); + if(httpClient!=null){ + HttpPost httppost = new HttpPost(url); + httppost.setHeader("Content-Type", ContentType.APPLICATION_JSON.toString()); + if(!Strings.isNullOrEmpty(token)){ + httppost.addHeader("Authorization", tokeType+" "+token); + } + httppost.setEntity(new StringEntity(requestBody)); + HttpResponse httpresponse = httpClient.execute(httppost); + if( httpresponse.getStatusLine().getStatusCode()==HttpStatus.SC_UNAUTHORIZED){ + throw new UnAuthorisedException(); + } + return EntityUtils.toString(httpresponse.getEntity()); + } + } catch (Exception e) { + + LOGGER.error("Error getting the data " , e); + throw e; + } + return null; + + } + + /** + * Gets the http client. + * + * @return the http client + */ + private static CloseableHttpClient getHttpClient() { + CloseableHttpClient httpClient = null; + try { + httpClient = HttpClientBuilder.create().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) + .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { + public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { + return true; + } + }).build()).build(); + } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) { + LOGGER.error("Error getting getHttpClient " , e); + } + return httpClient; + } + + /** + * Http get method with headers. + * + * @param url the url + * @param headers the headers + * @return the string + * @throws Exception the exception + */ + public static String httpGetMethodWithHeaders(String url,Map headers) throws Exception { + String json = null; + + HttpGet get = new HttpGet(url); + CloseableHttpClient httpClient = null; + if (headers != null && !headers.isEmpty()) { + for (Map.Entry entry : headers.entrySet()) { + get.setHeader(entry.getKey(), entry.getValue().toString()); + } + } + try { + httpClient = getHttpClient(); + CloseableHttpResponse res = httpClient.execute(get); + if (res.getStatusLine().getStatusCode() == 200) { + json = EntityUtils.toString(res.getEntity()); + } + } finally { + if (httpClient != null) { + httpClient.close(); + } + } + return json; + } + + /** + * + * @param rest + * URL for POST method + * @return String + * @throws Exception + */ + public static String doHttpPost(final String url, final String requestBody) throws Exception { + try { + + HttpClient client = HttpClientBuilder.create().build(); + HttpPost httppost = new HttpPost(url); + httppost.setHeader(CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()); + StringEntity jsonEntity = new StringEntity(requestBody); + httppost.setEntity(jsonEntity); + HttpResponse httpresponse = client.execute(httppost); + int statusCode = httpresponse.getStatusLine().getStatusCode(); + if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_CREATED) { + return EntityUtils.toString(httpresponse.getEntity()); + } else { + LOGGER.error(requestBody); + throw new Exception( + "unable to execute post request because " + httpresponse.getStatusLine().getReasonPhrase()); + } + } catch (ParseException parseException) { + parseException.printStackTrace(); + LOGGER.error("error closing issue" + parseException); + throw parseException; + } catch (Exception exception) { + exception.printStackTrace(); + LOGGER.error("error closing issue" + exception.getMessage()); + throw exception; + } + } +} diff --git a/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/Util.java b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/Util.java new file mode 100644 index 000000000..a6e73d2e1 --- /dev/null +++ b/jobs/pacman-cloud-notifications/src/main/java/com/tmobile/pacman/cloud/util/Util.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.pacman.cloud.util; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.xml.bind.annotation.adapters.HexBinaryAdapter; + +import org.apache.http.entity.ContentType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * The Class Util. + */ +public class Util { + + /** The Constant LOGGER. */ + private static final Logger LOGGER = LoggerFactory.getLogger(Util.class); + + /** + * Instantiates a new util. + */ + private Util(){ + + } + /** + * Gets the stack trace. + * + * @param e + * the e + * @return the stack trace + */ + public static String getStackTrace(Exception e) { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + return sw.toString(); + + } + + /** + * Gets the header. + * + * @param base64Creds the base 64 creds + * @return the header + */ + public static Map getHeader(String base64Creds){ + Map authToken = new HashMap<>(); + authToken.put("Content-Type", ContentType.APPLICATION_JSON.toString()); + authToken.put("Authorization", "Basic "+base64Creds); + return authToken; + } + + /** + * Gets the intersect list. + * + * @param List1 the List1 + * @param List2 the list2 + * @return the intersect list + */ + public static List compareLst(List list1, List list2) { + + return list1.stream() + .filter(list2::contains) + .collect(Collectors.toList()); + + } + /** + * Gets the String. + * + * @param List the List + * @return the String with the list of elements appended with Quote. + */ + public static String appendQuotesForList (List list) { + return list.stream() + .map(s -> "\"" + s + "\"") + .collect(Collectors.joining(", ")); + } + /** + * Alter the Key namae in the Map. + * @param inputMap the InputMap. + * @param oldkey the oldkey + * @param newkey the newkey + * @param keyVal the key value. + * @return the Map with the altered keys. + */ + public static Map alterKey(Map inputMap, String oldKey, String newKey, String keyVal){ + try { + inputMap.put(newKey, keyVal); + inputMap.remove(oldKey); + } catch (Exception e) { + e.printStackTrace(); + } + return inputMap; + + } + + /** + * Gets the String. + * + * @param OrgStr the original String. + * @param repStr the replace String. + * @return the replaced String. + */ + public static String strReplace(String orgStr, String repStr) { + return orgStr.replaceAll(repStr, ""); + } + + /** + * Gets the String. + * @param orgStr the originalString + * @param index the index + * @return the Sub String by index. + */ + public static String strSub(String orgStr, int index) { + return orgStr.substring(index); + } + + public static List split(String str, String repStr){ + return Stream.of(str.split(repStr)) + .map (elem -> new String(elem)) + .collect(Collectors.toList()); + } + + /** + * Concatenate. + * + * @param map + * the map + * @param keys + * the keys + * @param delimiter + * the delimiter + * @return the string + */ + public static String concatenate(Map map, String[] keys, String delimiter) { + List values = new ArrayList<>(); + for (String key : keys) { + values.add(map.get(key)); + } + return values.stream().collect(Collectors.joining(delimiter)); + } + + /** + * Gets the unique ID. + * + * @param idstring + * the idstring + * @return the unique ID + */ + public static String getUniqueID(String idstring) { + try { + MessageDigest md5 = MessageDigest.getInstance("MD5"); + return (new HexBinaryAdapter()).marshal(md5.digest(idstring.getBytes())); + } catch (NoSuchAlgorithmException e) { + LOGGER.error("Error in getUniqueID",e); + } + return ""; + } +} diff --git a/jobs/recommendation-enricher/pom.xml b/jobs/recommendation-enricher/pom.xml index f9e7c5013..bf19c0d41 100644 --- a/jobs/recommendation-enricher/pom.xml +++ b/jobs/recommendation-enricher/pom.xml @@ -205,6 +205,24 @@ + + org.apache.maven.plugins + maven-antrun-plugin + 1.8 + + + install + + + + + + + run + + + + \ No newline at end of file From 68d5b610710cf4364add9800c7533cd9d19136a4 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Fri, 2 Aug 2019 12:40:42 +0530 Subject: [PATCH 20/86] Db details for health notification is added --- installer/resources/pacbot_app/files/DB.sql | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/installer/resources/pacbot_app/files/DB.sql b/installer/resources/pacbot_app/files/DB.sql index b3efccc1e..b3936747d 100644 --- a/installer/resources/pacbot_app/files/DB.sql +++ b/installer/resources/pacbot_app/files/DB.sql @@ -886,6 +886,16 @@ CREATE TABLE IF NOT EXISTS `Recommendation_Mappings` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +CREATE TABLE IF NOT EXISTS `CloudNotification_mapping` ( + `NotificationId` varchar(10) COLLATE utf8_bin NOT NULL, + `eventType` varchar(45) COLLATE utf8_bin DEFAULT NULL, + `resourceIdKey` varchar(45) COLLATE utf8_bin DEFAULT NULL, + `resourceIdVal` varchar(45) COLLATE utf8_bin DEFAULT NULL, + `esIndex` varchar(45) COLLATE utf8_bin DEFAULT NULL, + `phdEntityKey` varchar(45) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`NotificationId`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin + /*Insert task to necessary tables*/ INSERT IGNORE INTO `task`(`id`,`index`,`mappings`,`data`) values (1,'exceptions','{\"mappings\":{\"sticky_exceptions\":{\"properties\":{\"assetGroup\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"dataSource\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"exceptionName\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"exceptionReason\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"expiryDate\":{\"type\":\"date\"},\"targetTypes\":{\"properties\":{\"name\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"rules\":{\"properties\":{\"ruleId\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"ruleName\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}}}}}}}}}}',NULL),(2,'faqs','{\"mappings\":{\"widgetinfo\":{\"properties\":{\"widgetid\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"widgetname\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}}}},\"faqinfo\":{\"properties\":{\"answer\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"faqid\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"faqname\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"tag\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"widgetid\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}}}}}}','{\"index\": {\"_index\": \"faqs\", \"_type\": \"widgetinfo\", \"_id\": \"w1\"}}\r{\"widgetid\":\"w1\",\"widgetname\":\"compliance overview\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"widgetinfo\", \"_id\": \"w2\"}}\r{\"widgetid\":\"w2\",\"widgetname\":\"patching\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"widgetinfo\", \"_id\": \"w3\"}}\r{\"widgetid\":\"w3\",\"widgetname\":\"tagging\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"widgetinfo\", \"_id\": \"w4\"}}\r{\"widgetid\":\"w4\",\"widgetname\":\"vulnerabilities\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"widgetinfo\", \"_id\": \"w5\"}}\r{\"widgetid\":\"w5\",\"widgetname\":\"certificates\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w2q7\"}}\r{\"faqid\":\"q7\",\"faqname\":\"How is unpatched count calculated ?\",\"answer\":\"Total assets which does not have updated kernel version.\",\"widgetid\":\"w2\",\"tag\":\"patching\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w3q4\"}}\r{\"faqid\":\"q4\",\"faqname\":\"How is tagging compliance % calculated ?\",\"answer\":\"Tagging compliance is calculated by dividing total taggable assets by total tagged assets.\",\"widgetid\":\"w3\",\"tag\":\"tagging\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w1q1\"}}\r{\"faqid\":\"q1\",\"faqname\":\"What is shown in this graph?\",\"answer\":\"This multi ring donut represents the overall compliance percentage. Policies are grouped into categories like security, governance, cost optimization and tagging. Rings in the donut represents compliance percentage for each of those categories. The rolled up percentage value for a given category is calculated by doing a weighted average of compliance percentage values of individual policies in that category. Weights are assigned based on the importance of the policy. Overall rolled up number in the middle of the donut represents uber compliance percentage for the selected asset group. This value is calculated by doing a simple average of compliance percentage values of the four categories.\",\"widgetid\":\"w1\",\"tag\":\"over-all\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w4q5\"}}\r{\"faqid\":\"q5\",\"faqname\":\"How is vulnerabilities compliance % calculated ?\",\"answer\":\"Vulnerabilities compliance is calculated by dividing total vulnerable assets by total servers, if an asset is not scanned by qualys , then the asset is considered as vulnerable.\",\"widgetid\":\"w4\",\"tag\":\"vulnerabilities\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w5q3\"}}\r{\"faqid\":\"q3\",\"faqname\":\"How is certificates compliance % calculated ?\",\"answer\":\"Total non-expired certificates divided by total certificates\",\"widgetid\":\"w5\",\"tag\":\"certificates\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w3q8\"}}\r{\"faqid\":\"q8\",\"faqname\":\"How is untagged count calculated ?\",\"answer\":\"Total assets which is missing either application/environment tags or both tags.\",\"widgetid\":\"w3\",\"tag\":\"tagging\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w2q2\"}}\r{\"faqid\":\"q2\",\"faqname\":\"How is patching compliance % calculated ?\",\"answer\":\"Total patched resources divided by total running resources\",\"widgetid\":\"w2\",\"tag\":\"patching\"}'); @@ -1955,6 +1965,10 @@ INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `pr INSERT IGNORE INTO `Recommendation_Mappings`(`checkId`,`type`,`resourceInfo`,`_resourceId`,`monthlySavingsField`) values ('H7IgTzjTYb','volume','Volume ID','volumeid',NULL),('DAvU99Dc4C','volume','Volume ID','volumeid','Monthly Storage Cost'),('Qch7DwouX1','ec2','Instance ID','instanceid','Estimated Monthly Savings'),('1iG5NDGVre','sg','Security Group ID','groupid',NULL),('HCP4007jGY','sg','Security Group ID','groupid',NULL),('BueAdJ7NrP','s3','Bucket Name','name',NULL),('iqdCTZKCUp','classicelb','Load Balancer Name','loadbalancername',NULL),('R365s2Qddf','s3','Bucket Name','name',NULL),('Pfx0RwqBli','s3','Bucket Name','name',NULL),('a2sEc6ILx','classicelb','Load Balancer Name','loadbalancername',NULL),('xdeXZKIUy','classicelb','Load Balancer Name','loadbalancername',NULL),('CLOG40CDO8','asg','Auto Scaling Group Name','autoscalinggroupname',NULL),('7qGXsKIUw','classicelb','Load Balancer Name','loadbalancername',NULL),('hjLMh88uM8','classicelb','Load Balancer Name','loadbalancername','Estimated Monthly Savings'),('DqdJqYeRm5','iamuser','IAM User','username',NULL),('j3DFqYTe29','ec2','Instance ID','instanceid',NULL),('f2iK5R6Dep','rdsdb','DB Instance','dbinstanceidentifier',NULL),('1MoPEMsKx6','reservedinstance','Instance Type','instancetype','Estimated Monthly Savings'),('Ti39halfu8','rdsdb','DB Instance Name','dbinstanceidentifier','Estimated Monthly Savings (On Demand)'),('Wnwm9Il5bG','ec2','Instance ID','instanceid',NULL),('V77iOLlBqz','ec2','Instance ID','instanceid',NULL),('Z4AUBRNSmz','elasticip','IP Address','publicip',NULL),('8CNsSllI5v','asg','Auto Scaling Group Name','autoscalinggroupname',NULL),('N420c450f2','cloudfront','Distribution ID','id',NULL),('TyfdMXG69d','ec2','Instance ID','instanceid',NULL),('tfg86AVHAZ','sg','Group ID','groupid',NULL),('yHAGQJV9K5','ec2','Instance ID','instanceid',NULL),('S45wrEXrLz','vpnconnection','VPN ID','vpnconnectionid',NULL),('PPkZrjsH2q','volume','Volume ID','volumeid',NULL),('opQPADkZvH','rdsdb','DB Instance','dbinstanceidentifier',NULL),('796d6f3D83','s3','Bucket Name','name',NULL),('G31sQ1E9U','redshift','Cluster','clusteridentifier','Estimated Monthly Savings'),('xSqX82fQu','classicelb','Load Balancer Name','loadbalancername',NULL),('ZRxQlPsb6c','ec2','Instance ID','instanceid',NULL),('N430c450f2','cloudfront','Distribution ID','id',NULL),('4g3Nt5M1Th','virtualinterface','Gateway ID','virtualgatewayid',NULL),('0t121N1Ty3','directconnect','Connection ID','connectionid',NULL),('N425c450f2','cloudfront','Distribution ID','id',NULL),('xuy7H1avtl','rdscluster','Cluster','dbclusteridentifier',NULL),('1e93e4c0b5','reservedinstance','Reserved Instance ID','instanceid','Estimated Monthly Savings'),('51fC20e7I2','route53','Hosted Zone ID','hostedZoneId',NULL),('cF171Db240','route53','Hosted Zone ID','hostedZoneId',NULL),('Cb877eB72b','route53','Hosted Zone ID','hostedZoneId',NULL),('b73EEdD790','route53','Hosted Zone ID','hostedZoneId',NULL),('C056F80cR3','route53','Hosted Zone ID','hostedZoneId',NULL),('B913Ef6fb4','route53','Hosted Zone ID','hostedZoneId',NULL); +INSERT IGNORE INTO `CloudNotification_mapping`(`NotificationId`,`eventType`,`resourceIdKey`,`resourceIdVal`,`esIndex`,`phdEntityKey`) values ('02BUF','CLOUDTRAIL','_resourceid.keyword','_resourceid','cloudtrl','entityvalue'),('4GIGN','S3','_resourceid.keyword','_resourceid','s3','entityvalue'),('5U846','ELASTICSEARCH','arn.keyword','arn','elasticsearch','entityvalue'),('DI3Q3','SQS','_resourceid.keyword','_resourceid','sqs','entityvalue'),('FZC49','VPN','vpnconnectionid.keyword','vpnconnectionid','vpnconnection','entityvalue'),('G30R7','KMS','_resourceid.keyword','_resourceid','kms','entityvalue'),('G4AIH','RDS','dbinstanceidentifier.keyword','dbinstanceidentifier','rdsdb','entityvalue'),('HL28B','EC2','_resourceid.keyword','_resourceid','ec2','entityvalue'),('KBDY2','DIRECTCONNECT','_resourceid.keyword','_resourceid','directconnect','entityvalue'),('LPB7Z','LAMBDA','_resourceid.keyword','_resourceid','lambda','entityvalue'),('PKI3S','CONFIG','_resourceid.keyword','_resourceid','config','entityvalue'),('S2QIA','REDSHIFT','clusteridentifier.keyword','clusteridentifier','redshift','entityvalue'),('W45AP','IAM','arn.keyword','arn','iamuser','entityvalue'),('X9GYT','VPC','_resourceid.keyword','_resourceid','vpc','entityvalue'),('YCFSX','CLOUDFRONT','_resourceid.keyword','_resourceid','cloudfront','entityvalue'),('YGS02','DYNAMODB','tablearn.keyword','tablearn','dynamodb','entityvalue'),('YGS03','MQ','_resourceid.keyword','_resourceid','mq','entityvalue'),('YGS05','APIGATEWAY','_resourceid.keyword','_resourceid','apigtw','entityvalue'); + + + UPDATE `cf_RuleInstance` SET assetGroup = 'aws' WHERE ruleId='PacMan_AmazonRDSIdleDBInstancesRule_version-1_AmazonRDSIdleDBInstancesRule_rdsdb'; From 1e6cc90e5cf66a743a0fe7da3a2f38f5db827818 Mon Sep 17 00:00:00 2001 From: Ritesh Date: Fri, 2 Aug 2019 12:48:32 +0530 Subject: [PATCH 21/86] Resolve Dependency Vulnerability Issues --- webapp/package.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index 39361ca7f..d6dab99bc 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -39,7 +39,7 @@ "d3": "^4.11.0", "font-awesome": "^4.7.0", "html2canvas": "^1.0.0-alpha.12", - "lodash": "^4.17.4", + "lodash": "^4.17.13", "moment": "^2.21.0", "ng2-datepicker": "~2.1.7", "ng2-select": "^1.2.0", @@ -69,15 +69,15 @@ "crypto-js": "^3.1.9-1", "http-status-codes": "^1.3.0", "jasmine-console-reporter": "^3.0.2", - "jasmine-core": "~2.6.2", + "jasmine-core": "^2.6.4", "jasmine-spec-reporter": "^4.2.1", - "karma": "~1.7.0", - "karma-chrome-launcher": "~2.1.1", + "karma": "^4.2.0", + "karma-chrome-launcher": "^2.1.1", "karma-cli": "~1.0.1", - "karma-coverage-istanbul-reporter": "^1.2.1", - "karma-jasmine": "~1.1.0", + "karma-coverage-istanbul-reporter": "^1.4.3", + "karma-jasmine": "^1.1.2", "karma-jasmine-html-reporter": "^0.2.2", - "protractor": "~5.1.2", + "protractor": "^6.0.0", "protractor-jasmine2-html-reporter": "0.0.7", "replace-in-file": "^3.4.2", "source-map-explorer": "^1.6.0", From 3727c6cfe907370bbdf8c41f17d9a9398d5c835a Mon Sep 17 00:00:00 2001 From: Sajeer N Date: Fri, 2 Aug 2019 15:17:01 +0530 Subject: [PATCH 22/86] Added CW rule, permission and target for creating cloud notification job --- installer/resources/lambda_submit/function.py | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/installer/resources/lambda_submit/function.py b/installer/resources/lambda_submit/function.py index 1342b5b47..66964a0a9 100644 --- a/installer/resources/lambda_submit/function.py +++ b/installer/resources/lambda_submit/function.py @@ -1,6 +1,7 @@ from core.terraform.resources.aws.aws_lambda import LambdaFunctionResource, LambdaPermission from core.terraform.resources.aws.cloudwatch import CloudWatchEventRuleResource, CloudWatchEventTargetResource from resources.datastore.es import ESDomainPolicy +from resources.datastore.es import ESDomain from resources.datastore.db import MySQLDatabase from resources.iam.lambda_role import LambdaRole from resources.iam.base_role import BaseRole @@ -137,9 +138,60 @@ class RecommendationsCollectorCloudWatchEventTarget(CloudWatchEventTargetResourc 'jobType': "jar", 'jobDesc': "Index trusted advisor checks as recommendations", 'environmentVariables': [ + {'name': "CONFIG_URL", 'value': ApplicationLoadBalancer.get_api_base_url() + "/config/batch,recommendation-enricher/prd/latest"}, + {'name': "PACMAN_API_URI", 'value': ApplicationLoadBalancer.get_api_base_url()}, + {'name': "LOGGING_ES_HOST_NAME", 'value': ESDomain.get_http_url_with_port()}, + {'name': "ES_URI", 'value': ESDomain.get_http_url_with_port()}, + {'name': "ENVIRONMENT", 'value': "prd"}, + {'name': "APP_NAME", 'value': "aws-recommendations-collector"}, + {'name': "APP_TYPE", 'value': "etl"}, + {'name': "HEIMDALL_URI", 'value': ESDomain.get_http_url_with_port()}, + {'name': "BASE_AWS_ACCOUNT", 'value': AwsAccount.get_output_attr('account_id')}, ], 'params': [ {'encrypt': False, 'key': "package_hint", 'value': "com.tmobile.cso.pacbot"}, {'encrypt': False, 'key': "config_creds", 'value': "dXNlcjpwYWNtYW4="}, ] }) + + +class CloudNotificationCollectorEventRule(CloudWatchEventRuleResource): + name = "AWS-CloudNotification-Collector" + schedule_expression = "cron(0 * * * ? *)" + + DEPENDS_ON = [SubmitJobLambdaFunction] + + +class CloudNotificationCollectorEventRuleLambdaPermission(LambdaPermission): + statement_id = "AllowExecutionFromCloudNotificationCollectorEvent" + action = "lambda:InvokeFunction" + function_name = SubmitJobLambdaFunction.get_output_attr('function_name') + principal = "events.amazonaws.com" + source_arn = CloudNotificationCollectorEventRule.get_output_attr('arn') + + +class CloudNotificationCollectorCloudWatchEventTarget(CloudWatchEventTargetResource): + rule = CloudNotificationCollectorEventRule.get_output_attr('name') + arn = SubmitJobLambdaFunction.get_output_attr('arn') + target_id = 'CloudNotificationCollectorTarget' # Unique identifier + target_input = json.dumps({ + 'jobName': "aws-cloud-notification-collector", + 'jobUuid': "aws-cloud-notification", + 'jobType': "jar", + 'jobDesc': "Health Notification Collector", + 'environmentVariables': [ + {'name': "CONFIG_URL", 'value': ApplicationLoadBalancer.get_api_base_url() + "/config/api/prd/latest"}, + {'name': "PACMAN_API_URI", 'value': ApplicationLoadBalancer.get_api_base_url()}, + {'name': "LOGGING_ES_HOST_NAME", 'value': ESDomain.get_http_url_with_port()}, + {'name': "ES_URI", 'value': ESDomain.get_http_url_with_port()}, + {'name': "ENVIRONMENT", 'value': "prd"}, + {'name': "APP_NAME", 'value': "aws-cloud-notification-collector"}, + {'name': "APP_TYPE", 'value': "etl"}, + {'name': "BASE_AWS_ACCOUNT", 'value': AwsAccount.get_output_attr('account_id')}, + ], + 'params': [ + {'encrypt': False, 'key': "package_hint", 'value': "com.tmobile"}, + {'encrypt': False, 'key': "config_creds", 'value': "dXNlcjpwYWNtYW4="}, + {'encrypt': False, 'key': "conf_src", 'value': "api-prd,application-prd"}, + ] + }) From aff92c65e7b1ac6a0a8945ac137917ac77d05b5d Mon Sep 17 00:00:00 2001 From: Kanchana Date: Fri, 2 Aug 2019 15:42:13 +0530 Subject: [PATCH 23/86] added semicolon --- installer/resources/pacbot_app/files/DB.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installer/resources/pacbot_app/files/DB.sql b/installer/resources/pacbot_app/files/DB.sql index b3936747d..5c9d103b4 100644 --- a/installer/resources/pacbot_app/files/DB.sql +++ b/installer/resources/pacbot_app/files/DB.sql @@ -894,7 +894,7 @@ CREATE TABLE IF NOT EXISTS `CloudNotification_mapping` ( `esIndex` varchar(45) COLLATE utf8_bin DEFAULT NULL, `phdEntityKey` varchar(45) COLLATE utf8_bin DEFAULT NULL, PRIMARY KEY (`NotificationId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; /*Insert task to necessary tables*/ INSERT IGNORE INTO `task`(`id`,`index`,`mappings`,`data`) values (1,'exceptions','{\"mappings\":{\"sticky_exceptions\":{\"properties\":{\"assetGroup\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"dataSource\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"exceptionName\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"exceptionReason\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"expiryDate\":{\"type\":\"date\"},\"targetTypes\":{\"properties\":{\"name\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"rules\":{\"properties\":{\"ruleId\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"ruleName\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}}}}}}}}}}',NULL),(2,'faqs','{\"mappings\":{\"widgetinfo\":{\"properties\":{\"widgetid\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"widgetname\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}}}},\"faqinfo\":{\"properties\":{\"answer\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"faqid\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"faqname\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"tag\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}},\"widgetid\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\",\"ignore_above\":256}}}}}}}','{\"index\": {\"_index\": \"faqs\", \"_type\": \"widgetinfo\", \"_id\": \"w1\"}}\r{\"widgetid\":\"w1\",\"widgetname\":\"compliance overview\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"widgetinfo\", \"_id\": \"w2\"}}\r{\"widgetid\":\"w2\",\"widgetname\":\"patching\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"widgetinfo\", \"_id\": \"w3\"}}\r{\"widgetid\":\"w3\",\"widgetname\":\"tagging\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"widgetinfo\", \"_id\": \"w4\"}}\r{\"widgetid\":\"w4\",\"widgetname\":\"vulnerabilities\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"widgetinfo\", \"_id\": \"w5\"}}\r{\"widgetid\":\"w5\",\"widgetname\":\"certificates\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w2q7\"}}\r{\"faqid\":\"q7\",\"faqname\":\"How is unpatched count calculated ?\",\"answer\":\"Total assets which does not have updated kernel version.\",\"widgetid\":\"w2\",\"tag\":\"patching\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w3q4\"}}\r{\"faqid\":\"q4\",\"faqname\":\"How is tagging compliance % calculated ?\",\"answer\":\"Tagging compliance is calculated by dividing total taggable assets by total tagged assets.\",\"widgetid\":\"w3\",\"tag\":\"tagging\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w1q1\"}}\r{\"faqid\":\"q1\",\"faqname\":\"What is shown in this graph?\",\"answer\":\"This multi ring donut represents the overall compliance percentage. Policies are grouped into categories like security, governance, cost optimization and tagging. Rings in the donut represents compliance percentage for each of those categories. The rolled up percentage value for a given category is calculated by doing a weighted average of compliance percentage values of individual policies in that category. Weights are assigned based on the importance of the policy. Overall rolled up number in the middle of the donut represents uber compliance percentage for the selected asset group. This value is calculated by doing a simple average of compliance percentage values of the four categories.\",\"widgetid\":\"w1\",\"tag\":\"over-all\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w4q5\"}}\r{\"faqid\":\"q5\",\"faqname\":\"How is vulnerabilities compliance % calculated ?\",\"answer\":\"Vulnerabilities compliance is calculated by dividing total vulnerable assets by total servers, if an asset is not scanned by qualys , then the asset is considered as vulnerable.\",\"widgetid\":\"w4\",\"tag\":\"vulnerabilities\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w5q3\"}}\r{\"faqid\":\"q3\",\"faqname\":\"How is certificates compliance % calculated ?\",\"answer\":\"Total non-expired certificates divided by total certificates\",\"widgetid\":\"w5\",\"tag\":\"certificates\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w3q8\"}}\r{\"faqid\":\"q8\",\"faqname\":\"How is untagged count calculated ?\",\"answer\":\"Total assets which is missing either application/environment tags or both tags.\",\"widgetid\":\"w3\",\"tag\":\"tagging\"}\r{\"index\": {\"_index\": \"faqs\", \"_type\": \"faqinfo\", \"_id\": \"w2q2\"}}\r{\"faqid\":\"q2\",\"faqname\":\"How is patching compliance % calculated ?\",\"answer\":\"Total patched resources divided by total running resources\",\"widgetid\":\"w2\",\"tag\":\"patching\"}'); From c5834b27d3c5a35b0a2df9e725c56e958f7b9d33 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Fri, 2 Aug 2019 16:10:24 +0530 Subject: [PATCH 24/86] Names of jar changed --- jobs/pacman-cloud-notifications/pom.xml | 2 +- jobs/recommendation-enricher/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jobs/pacman-cloud-notifications/pom.xml b/jobs/pacman-cloud-notifications/pom.xml index 9f2a17883..f47345abd 100644 --- a/jobs/pacman-cloud-notifications/pom.xml +++ b/jobs/pacman-cloud-notifications/pom.xml @@ -267,7 +267,7 @@ install - + diff --git a/jobs/recommendation-enricher/pom.xml b/jobs/recommendation-enricher/pom.xml index bf19c0d41..78447d2db 100644 --- a/jobs/recommendation-enricher/pom.xml +++ b/jobs/recommendation-enricher/pom.xml @@ -214,7 +214,7 @@ install - + From 8dd28208686efc94b35c800552eaa13b09bc1429 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Fri, 2 Aug 2019 16:29:20 +0530 Subject: [PATCH 25/86] interchanged the plugins --- jobs/pacman-cloud-notifications/pom.xml | 38 ++++++++++++------------- jobs/recommendation-enricher/pom.xml | 38 ++++++++++++------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/jobs/pacman-cloud-notifications/pom.xml b/jobs/pacman-cloud-notifications/pom.xml index f47345abd..0e358f73c 100644 --- a/jobs/pacman-cloud-notifications/pom.xml +++ b/jobs/pacman-cloud-notifications/pom.xml @@ -239,25 +239,6 @@ - - org.jacoco - jacoco-maven-plugin - 0.7.6.201602180812 - - - - prepare-agent - - - - report - test - - report - - - - org.apache.maven.plugins maven-antrun-plugin @@ -276,6 +257,25 @@ + + org.jacoco + jacoco-maven-plugin + 0.7.6.201602180812 + + + + prepare-agent + + + + report + test + + report + + + + \ No newline at end of file diff --git a/jobs/recommendation-enricher/pom.xml b/jobs/recommendation-enricher/pom.xml index 78447d2db..693bd28ff 100644 --- a/jobs/recommendation-enricher/pom.xml +++ b/jobs/recommendation-enricher/pom.xml @@ -186,25 +186,6 @@ - - org.jacoco - jacoco-maven-plugin - 0.7.6.201602180812 - - - - prepare-agent - - - - report - test - - report - - - - org.apache.maven.plugins maven-antrun-plugin @@ -223,6 +204,25 @@ + + org.jacoco + jacoco-maven-plugin + 0.7.6.201602180812 + + + + prepare-agent + + + + report + test + + report + + + + \ No newline at end of file From dd2d5fbd4da355a07d93b1d1663cd4b4f86f8747 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Fri, 2 Aug 2019 16:52:47 +0530 Subject: [PATCH 26/86] Added the module for job pom --- jobs/pom.xml | 106 ++++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 52 deletions(-) diff --git a/jobs/pom.xml b/jobs/pom.xml index 2ea49ff31..6ef454280 100644 --- a/jobs/pom.xml +++ b/jobs/pom.xml @@ -1,52 +1,54 @@ - - - 4.0.0 - - com.tmobile.cloud - jobs - 1.0.0-SNAPSHOT - pom - - PacMan Jobs Projects - Build for T-Mobile PacMan Jobs Projects - https://github.com/tmobile/pacman/jobs - - - - Apache - https://github.com/tmobile/pacman/blob/master/LICENSE - repo - - - - - - PacMan Team - PacMan Team - pacbot@t-mobile.com - - - - - T-Mobile - https://www.t-mobile.com - - - - scm:git:git://github.com/tmobile/pacman.git - scm:git:ssh://github.com/tmobile/pacman.git - https://github.com/tmobile/pacman/tree/master - - - - pacman-cloud-discovery - pacman-data-shipper - pacman-awsrules - pacman-rule-engine-2.0 - - - - - + + + 4.0.0 + + com.tmobile.cloud + jobs + 1.0.0-SNAPSHOT + pom + + PacMan Jobs Projects + Build for T-Mobile PacMan Jobs Projects + https://github.com/tmobile/pacman/jobs + + + + Apache + https://github.com/tmobile/pacman/blob/master/LICENSE + repo + + + + + + PacMan Team + PacMan Team + pacbot@t-mobile.com + + + + + T-Mobile + https://www.t-mobile.com + + + + scm:git:git://github.com/tmobile/pacman.git + scm:git:ssh://github.com/tmobile/pacman.git + https://github.com/tmobile/pacman/tree/master + + + + pacman-cloud-discovery + pacman-data-shipper + pacman-awsrules + pacman-rule-engine-2.0 + pacman-cloud-notifications + recommendation-enricher + + + + + From d1be2c26a288d35256fa0490ccb01ea5bcb88ff0 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Fri, 2 Aug 2019 17:51:03 +0530 Subject: [PATCH 27/86] artifact changed --- jobs/pacman-cloud-notifications/pom.xml | 2 +- jobs/recommendation-enricher/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jobs/pacman-cloud-notifications/pom.xml b/jobs/pacman-cloud-notifications/pom.xml index 0e358f73c..b71ecd348 100644 --- a/jobs/pacman-cloud-notifications/pom.xml +++ b/jobs/pacman-cloud-notifications/pom.xml @@ -97,7 +97,7 @@ 3.1 - com.tmobile.pacman + com.tmobile.cloud batch-commons 1.0.0-SNAPSHOT provided diff --git a/jobs/recommendation-enricher/pom.xml b/jobs/recommendation-enricher/pom.xml index 693bd28ff..d742c71d5 100644 --- a/jobs/recommendation-enricher/pom.xml +++ b/jobs/recommendation-enricher/pom.xml @@ -40,7 +40,7 @@ - com.tmobile.pacman + com.tmobile.cloud batch-commons 1.0.0-SNAPSHOT provided From d8869fca8d7e529603394b796650239f998fa719 Mon Sep 17 00:00:00 2001 From: Sajeer N Date: Fri, 2 Aug 2019 23:15:42 +0530 Subject: [PATCH 28/86] JobUuid changed as per jar file name created in dist/jobs directory --- installer/resources/lambda_submit/function.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/installer/resources/lambda_submit/function.py b/installer/resources/lambda_submit/function.py index 66964a0a9..02d5c0428 100644 --- a/installer/resources/lambda_submit/function.py +++ b/installer/resources/lambda_submit/function.py @@ -134,7 +134,7 @@ class RecommendationsCollectorCloudWatchEventTarget(CloudWatchEventTargetResourc target_id = 'RecommendationsCollectorTarget' # Unique identifier target_input = json.dumps({ 'jobName': "aws-recommendations-collector", - 'jobUuid': "aws-recommendations-collector", + 'jobUuid': "recommendation-enricher-jar-with-dependencies", 'jobType': "jar", 'jobDesc': "Index trusted advisor checks as recommendations", 'environmentVariables': [ @@ -176,7 +176,7 @@ class CloudNotificationCollectorCloudWatchEventTarget(CloudWatchEventTargetResou target_id = 'CloudNotificationCollectorTarget' # Unique identifier target_input = json.dumps({ 'jobName': "aws-cloud-notification-collector", - 'jobUuid': "aws-cloud-notification", + 'jobUuid': "pacman-cloud-notifications-jar-with-dependencies", 'jobType': "jar", 'jobDesc': "Health Notification Collector", 'environmentVariables': [ From d5bea6b27b4c0e058e59b77561a5dfba82b7f3a1 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Sat, 3 Aug 2019 14:49:31 +0530 Subject: [PATCH 29/86] Added route53 target --- installer/resources/pacbot_app/files/DB.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/installer/resources/pacbot_app/files/DB.sql b/installer/resources/pacbot_app/files/DB.sql index 5c9d103b4..9a6f1a89f 100644 --- a/installer/resources/pacbot_app/files/DB.sql +++ b/installer/resources/pacbot_app/files/DB.sql @@ -1012,6 +1012,7 @@ INSERT IGNORE INTO cf_Target (targetName,targetDesc,category,dataSourceName,targ INSERT IGNORE INTO cf_Target (targetName,targetDesc,category,dataSourceName,targetConfig,status,userId,endpoint,createdDate,modifiedDate,domain) VALUES ('deliverystream','Kinesis Fireshose','Analytics','aws','{"key":"deliverystreamarn","id":"deliverystreamarn"}','enabled','123',concat(@eshost,':',@esport,'/aws_deliverystream/deliverystream'),{d '2018-10-30'},{d '2018-10-30'},'Infra & Platforms'); INSERT IGNORE INTO cf_Target (targetName,targetDesc,category,dataSourceName,targetConfig,status,userId,endpoint,createdDate,modifiedDate,domain) VALUES ('videostream','Kinesis Videostream','Analytics','aws','{"key":"streamarn","id":"streamarn"}','enabled','123',concat(@eshost,':',@esport,'/aws_videostream/videostream'),{d '2018-10-30'},{d '2018-10-30'},'Infra & Platforms'); INSERT IGNORE INTO cf_Target (targetName,targetDesc,category,dataSourceName,targetConfig,status,userId,endpoint,createdDate,modifiedDate,domain) VALUES ('reservedinstance','Reserved Instances','Compute','aws','{"key":"instanceid","id":"instanceid"}','','123',concat(@eshost,':',@esport,'/aws_reservedinstance/reservedinstance'),{d '2018-11-01'},{d '2018-11-01'},'Infra & Platforms'); +INSERT IGNORE INTO cf_Target (targetName,targetDesc,category,dataSourceName,targetConfig,status,userId,endpoint,createdDate,modifiedDate,domain) VALUES ('route53','Route 53','Networking & Content Delivery','aws','{"key":"hostedZoneId","id":"hostedZoneId"}','','123',concat(@eshost,':',@esport,'/aws_route53/route53'),{d '2019-08-03'},{d '2019-08-03'},'Infra & Platforms'); INSERT IGNORE INTO cf_Target (targetName,targetDesc,category,dataSourceName,targetConfig,status,userId,endpoint,createdDate,modifiedDate,domain) VALUES ('acmcertificate','acmcertificate','Identity & Compliance','aws','{\"key\":\"accountid,domainname\",\"id\":\"domainname\"}','enabled','admin@pacbot.org',concat(@eshost,':',@esport,'/aws_acmcertificate/acmcertificate'),'2019-02-15','2019-02-18','Infra & Platforms'); INSERT IGNORE INTO cf_Target (targetName,targetDesc,category,dataSourceName,targetConfig,status,userId,endpoint,createdDate,modifiedDate,domain) VALUES ('iamcertificate','iamcertificate','Identity & Compliance','aws','{\"key\":\"accountid,servercertificatename\",\"id\":\"servercertificatename\"}','enabled','admin@pacbot.org',concat(@eshost,':',@esport,'/aws_iamcertificate/iamcertificate'),'2019-02-15','2019-02-18','Infra & Platforms'); From 2d7d1e9a427232d024a63c83f6b8c320ddca2e89 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Sat, 3 Aug 2019 15:45:21 +0530 Subject: [PATCH 30/86] jar changed as like job uuid --- jobs/pacman-cloud-notifications/pom.xml | 2 +- jobs/recommendation-enricher/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jobs/pacman-cloud-notifications/pom.xml b/jobs/pacman-cloud-notifications/pom.xml index b71ecd348..3198f10b3 100644 --- a/jobs/pacman-cloud-notifications/pom.xml +++ b/jobs/pacman-cloud-notifications/pom.xml @@ -248,7 +248,7 @@ install - + diff --git a/jobs/recommendation-enricher/pom.xml b/jobs/recommendation-enricher/pom.xml index d742c71d5..755e76e52 100644 --- a/jobs/recommendation-enricher/pom.xml +++ b/jobs/recommendation-enricher/pom.xml @@ -195,7 +195,7 @@ install - + From 4f6cca1dc4315b95707588a42cd3ca8b806f16cf Mon Sep 17 00:00:00 2001 From: Kanchana Date: Mon, 5 Aug 2019 09:49:26 +0530 Subject: [PATCH 31/86] jar names are reverted --- jobs/pacman-cloud-notifications/pom.xml | 2 +- jobs/recommendation-enricher/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jobs/pacman-cloud-notifications/pom.xml b/jobs/pacman-cloud-notifications/pom.xml index 3198f10b3..b71ecd348 100644 --- a/jobs/pacman-cloud-notifications/pom.xml +++ b/jobs/pacman-cloud-notifications/pom.xml @@ -248,7 +248,7 @@ install - + diff --git a/jobs/recommendation-enricher/pom.xml b/jobs/recommendation-enricher/pom.xml index 755e76e52..d742c71d5 100644 --- a/jobs/recommendation-enricher/pom.xml +++ b/jobs/recommendation-enricher/pom.xml @@ -195,7 +195,7 @@ install - + From 0c8c0dd2b7403081d3dedf01eb81e9d817440b61 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Mon, 5 Aug 2019 09:52:44 +0530 Subject: [PATCH 32/86] Added primary key --- installer/resources/pacbot_app/files/DB.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/installer/resources/pacbot_app/files/DB.sql b/installer/resources/pacbot_app/files/DB.sql index 9a6f1a89f..3de6a78d4 100644 --- a/installer/resources/pacbot_app/files/DB.sql +++ b/installer/resources/pacbot_app/files/DB.sql @@ -882,7 +882,8 @@ CREATE TABLE IF NOT EXISTS `Recommendation_Mappings` ( `type` varchar(50) COLLATE utf8_bin DEFAULT NULL, `resourceInfo` varchar(200) COLLATE utf8_bin DEFAULT NULL, `_resourceId` varchar(200) COLLATE utf8_bin DEFAULT NULL, - `monthlySavingsField` varchar(200) COLLATE utf8_bin DEFAULT NULL + `monthlySavingsField` varchar(200) COLLATE utf8_bin DEFAULT NULL, + PRIMARY KEY (`checkId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; From e82305b9eb5005f92fdb42508dba6cfb17a15673 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Mon, 5 Aug 2019 14:45:59 +0530 Subject: [PATCH 33/86] Added new rules & test cases --- .../files/rule_engine_cloudwatch_rules.json | 66 +++++ installer/resources/pacbot_app/files/DB.sql | 12 +- ...eckCloudWatchEventsForAllAccountsRule.java | 231 ++++++++---------- .../cloud/awsrules/s3/S3AccessLogsRule.java | 158 ++++++++++++ .../cloud/awsrules/utils/PacmanUtils.java | 77 ++++++ .../cloud/constants/PacmanRuleConstants.java | 9 + .../awsrules/s3/S3AccessLogsRuleTest.java | 69 ++++++ .../cloud/awsrules/utils/CommonTestUtils.java | 164 +++++++++++++ .../cloud/awsrules/utils/PacmanUtilsTest.java | 13 + 9 files changed, 668 insertions(+), 131 deletions(-) create mode 100644 jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/s3/S3AccessLogsRule.java create mode 100644 jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/s3/S3AccessLogsRuleTest.java diff --git a/installer/resources/lambda_rule_engine/files/rule_engine_cloudwatch_rules.json b/installer/resources/lambda_rule_engine/files/rule_engine_cloudwatch_rules.json index 55042cbf5..40d3c6ba1 100644 --- a/installer/resources/lambda_rule_engine/files/rule_engine_cloudwatch_rules.json +++ b/installer/resources/lambda_rule_engine/files/rule_engine_cloudwatch_rules.json @@ -2264,5 +2264,71 @@ "modifiedDate": "2019-06-10", "severity": "high", "category": "governance" + }, + { + "ruleId": "PacMan_S3AccessLogsRule_version-1_S3AccessLogsRule_s3", + "ruleUUID": "aws_s3_accesslogs", + "policyId": "PacMan_S3AccessLogsRule_version-1", + "ruleName": "S3AccessLogsRule", + "targetType": "s3", + "assetGroup": "aws", + "alexaKeyword": "S3AccessLogsRule", + "ruleParams": "{\"params\":[{\"key\":\"ruleKey\",\"value\":\"check-for-s3-access-logs\",\"encrypt\":false},{\"key\":\"esS3PubAccessIssueUrl\",\"value\":\"\/aws_s3\/issue_s3\/_search\",\"encrypt\":false},{\"key\":\"s3PublicAccessRuleId\",\"value\":\"PacMan_S3GlobalAccess_version-1_S3BucketShouldnotpubliclyaccessble_s3\",\"encrypt\":false},{\"key\":\"splitterChar\",\"value\":\",\",\"isValueNew\":true,\"encrypt\":false},{\"key\":\"fixKey\",\"value\":\"private-s3-server-access-logs-fix\",\"isValueNew\":true,\"encrypt\":false},{\"key\":\"accessLogsEnabledRegions\",\"value\":\"\",\"isValueNew\":true,\"encrypt\":false},{\"key\":\"destinationBucketForAutofix\",\"value\":\"tmo-s3-accesslog-ACCOUNT_ID-REGION-dev\",\"isValueNew\":true,\"encrypt\":false},{\"encrypt\":false,\"value\":\"high\",\"key\":\"severity\"},{\"encrypt\":false,\"value\":\"governance\",\"key\":\"ruleCategory\"}],\"environmentVariables\":[],\"ruleId\":\"PacMan_S3AccessLogsRule_version-1_S3AccessLogsRule_s3\",\"autofix\":false,\"alexaKeyword\":\"S3AccessLogsRule\",\"ruleRestUrl\":\"\",\"targetType\":\"s3\",\"pac_ds\":\"aws\",\"policyId\":\"PacMan_S3AccessLogsRule_version-1\",\"assetGroup\":\"aws\",\"ruleUUID\":\"aws_s3_accesslogs\",\"ruleType\":\"ManageRule\"}", + "ruleFrequency": "0 * * * ? *", + "ruleExecutable": "", + "ruleRestUrl": "", + "ruleType": "ManageRule", + "ruleArn": "arn:aws:events:us-east-1:***REMOVED***:rule/aws_s3_accesslogs", + "status": "ENABLED", + "userId": "asgc", + "displayName": "Private s3 buckets should be enabled with access logs", + "createdDate": "2019-08-05", + "modifiedDate": "2019-08-05", + "severity": "high", + "category": "governance" + }, + { + "ruleId": "PacMan_CloudWatchEventsForAllAccounts_version-1_CloudWatchEventsForAllAccounts_account", + "ruleUUID": "aws_account_cloud_watch_events", + "policyId": "PacMan_CloudWatchEventsForAllAccounts_version-1", + "ruleName": "CloudWatchEventsForAllAccounts", + "targetType": "account", + "assetGroup": "aws", + "alexaKeyword": "CloudWatchEventsForAllAccounts", + "ruleParams": "{\"params\":[{\"encrypt\":false,\"value\":\"check-cloudwatch-event-rule\",\"key\":\"ruleKey\"},{\"encrypt\":false,\"value\":\"role\/pac_ro\",\"key\":\"roleIdentifyingString\"},{\"encrypt\":false,\"value\":\"DO-NOT-DELETE-pacman-all-events-to-eventbus-in-ACCOUNTID\",\"key\":\"ruleName\"},{\"encrypt\":false,\"value\":\"high\",\"key\":\"severity\"},{\"encrypt\":false,\"value\":\"governance\",\"key\":\"ruleCategory\"}],\"environmentVariables\":[],\"ruleId\":\"PacMan_CloudWatchEventsForAllAccounts_version-1_CloudWatchEventsForAllAccounts_account\",\"autofix\":false,\"alexaKeyword\":\"CloudWatchEventsForAllAccounts\",\"ruleRestUrl\":\"\",\"targetType\":\"account\",\"pac_ds\":\"aws\",\"policyId\":\"PacMan_CloudWatchEventsForAllAccounts_version-1\",\"assetGroup\":\"aws\",\"ruleUUID\":\"aws_account_cloud_watch_events\",\"ruleType\":\"ManageRule\"}", + "ruleFrequency": "0 * * * ? *", + "ruleExecutable": "", + "ruleRestUrl": "", + "ruleType": "ManageRule", + "ruleArn": "arn:aws:events:us-east-1:***REMOVED***:rule/aws_account_cloud_watch_events", + "status": "ENABLED", + "userId": "asgc", + "displayName": "All Cloud watch events from all accounts should be sent to DEDICATED ACCOUNTID default event bus", + "createdDate": "2019-08-05", + "modifiedDate": "2019-08-05", + "severity": "high", + "category": "governance" + }, + { + "ruleId": "PacMan_LowUtilizationAmazonEC2InstancesRule_version-1_LowUtilizationAmazonEC2InstancesRule_ec2", + "ruleUUID": "aws_ec2_low_utilization", + "policyId": "PacMan_LowUtilizationAmazonEC2InstancesRule_version-1", + "ruleName": "LowUtilizationAmazonEC2InstancesRule", + "targetType": "ec2", + "assetGroup": "aws", + "alexaKeyword": "LowUtilizationAmazonEC2InstancesRule", + "ruleParams": "{\"params\":[{\"encrypt\":false,\"value\":\"check-for-low-utilization-amazon-ec2-instance\",\"key\":\"ruleKey\"},{\"encrypt\":false,\"value\":\"\",\"key\":\"checkId\"},{\"encrypt\":false,\"value\":\"low\",\"key\":\"severity\"},{\"isValueNew\":true,\"encrypt\":false,\"value\":\"costOptimization\",\"key\":\"ruleCategory\"},{\"key\":\"esServiceURL\",\"value\":\"\/aws_checks\/checks_resources\/_search\",\"isValueNew\":true,\"encrypt\":false}],\"environmentVariables\":[],\"ruleId\":\"PacMan_LowUtilizationAmazonEC2InstancesRule_version-1_LowUtilizationAmazonEC2InstancesRule_ec2\",\"autofix\":false,\"alexaKeyword\":\"LowUtilizationAmazonEC2InstancesRule\",\"ruleRestUrl\":\"\",\"targetType\":\"ec2\",\"pac_ds\":\"aws\",\"policyId\":\"PacMan_LowUtilizationAmazonEC2InstancesRule_version-1\",\"assetGroup\":\"aws\",\"ruleUUID\":\"aws_ec2_low_utilization\",\"ruleType\":\"ManageRule\"}", + "ruleFrequency": "0 * * * ? *", + "ruleExecutable": "", + "ruleRestUrl": "", + "ruleType": "ManageRule", + "ruleArn": "arn:aws:events:us-east-1:***REMOVED***:rule/aws_ec2_low_utilization", + "status": "ENABLED", + "userId": "asgc", + "displayName": "Amazon EC2 instances should not have low utilization", + "createdDate": "2019-08-05", + "modifiedDate": "2019-08-05", + "severity": "high", + "category": "governance" } ] diff --git a/installer/resources/pacbot_app/files/DB.sql b/installer/resources/pacbot_app/files/DB.sql index 3de6a78d4..5caa451e5 100644 --- a/installer/resources/pacbot_app/files/DB.sql +++ b/installer/resources/pacbot_app/files/DB.sql @@ -1192,6 +1192,9 @@ INSERT IGNORE INTO `cf_Policy` (`policyId`,`policyName`,`policyDesc`,`resolution INSERT IGNORE INTO `cf_Policy` (`policyId`,`policyName`,`policyDesc`,`resolution`,`policyUrl`,`policyVersion`,`status`,`userId`,`createdDate`,`modifiedDate`) VALUES ('PacMan_IAMCertificate_Expiry_For_X_Days_version-1','IAMCertificate_Expiry_For_X_Days','Check IAM certificate expiry date on following conditions:-\n\n1. If expiry date is under 90 days from current date then it is non-compliance otherwise compliance.',"Rotate the keys before the expiry",NULL,'version-1','fed',NULL,'2019-02-18','2019-03-18'); INSERT IGNORE INTO `cf_Policy` (`policyId`,`policyName`,`policyDesc`,`resolution`,`policyUrl`,`policyVersion`,`status`,`userId`,`createdDate`,`modifiedDate`) VALUES ('PacMan_ELB_Access_Logs_version-1','ELB_Access_Logs','Check access log enabled in S3 bucket for ELB with \'logging\' tag name as \'true\' or without logging tags should be passed.',"Access log should be enabled to ELB and attached to mentioned bucket",NULL,'version-1','fed',NULL,'2019-02-24','2019-03-14'); INSERT IGNORE INTO `cf_Policy` (`policyId`,`policyName`,`policyDesc`,`resolution`,`policyUrl`,`policyVersion`,`status`,`userId`,`createdDate`,`modifiedDate`) VALUES ('PacMan_CloudFront_AccessLogs_version-1','CloudFront_AccessLogs','Check access log enabled in S3 bucket for CloudFront with \'logging\' tag name as \'true\' or without logging tags should be passed.',"Access log should be enabled to cloudfront and attached to mentioned bucket",NULL,'version-1','fed',NULL,'2019-02-18','2019-03-14'); +INSERT IGNORE INTO `cf_Policy` (`policyId`,`policyName`,`policyDesc`,`resolution`,`policyUrl`,`policyVersion`,`status`,`userId`,`createdDate`,`modifiedDate`) VALUES ('PacMan_S3AccessLogsRule_version-1','S3AccessLogsRule','Protected S3 buckets should be server access logs enabled',"Protected S3 buckets should be server access logs enabled",NULL,'version-1','fed',NULL,'2019-08-05','2019-08-05'); +INSERT IGNORE INTO `cf_Policy` (`policyId`,`policyName`,`policyDesc`,`resolution`,`policyUrl`,`policyVersion`,`status`,`userId`,`createdDate`,`modifiedDate`) VALUES ('PacMan_CloudWatchEventsForAllAccounts_version-1','CloudWatchEventsForAllAccounts','Events from all AWS account should be routed to a central event bus so that the events and be processed and analyzed centrally.',"Events from all AWS account should be routed to a central event.",NULL,'version-1','fed',NULL,'2019-08-05','2019-08-05'); +INSERT IGNORE INTO `cf_Policy` (`policyId`,`policyName`,`policyDesc`,`resolution`,`policyUrl`,`policyVersion`,`status`,`userId`,`createdDate`,`modifiedDate`) VALUES ('PacMan_LowUtilizationAmazonEC2InstancesRule_version-1','LowUtilizationAmazonEC2InstancesRule','Checks the Amazon Elastic Compute Cloud (Amazon EC2) instances that were running at any time during the last 14 days and alerts you if the daily CPU utilization was 10% or less and network I/O was 5 MB or less on 4 or more days. Running instances generate hourly usage charges. Although some scenarios can result in low utilization by design, you can often lower your costs by managing the number and size of your instances. n instance had 10% or less daily average CPU utilization and 5 MB or less network I/O on at least 4 of the previous 14 days',"Consider stopping or terminating instances that have low utilization, or scale the number of instances by using Auto Scaling.",NULL,'version-1','fed',NULL,'2019-08-05','2019-08-05'); /* Rule Initialisation */ @@ -1300,6 +1303,9 @@ INSERT IGNORE INTO cf_RuleInstance (`ruleId`,`ruleUUID`,`policyId`,`ruleName`,`t INSERT IGNORE INTO cf_RuleInstance (`ruleId`,`ruleUUID`,`policyId`,`ruleName`,`targetType`,`assetGroup`,`alexaKeyword`,`ruleParams`,`ruleFrequency`,`ruleExecutable`,`ruleRestUrl`,`ruleType`,`ruleArn`,`status`,`userId`,`displayName`,`createdDate`,`modifiedDate`,`severity`,`category`) VALUES ('PacMan_ELB_Access_Logs_version-1_AppLB_Access_Logs_appelb','aws_appelb_access_logs','PacMan_ELB_Access_Logs_version-1','AppLB_Access_Logs','appelb','aws','AppLB_Access_Logs','{"params":[{"key":"ruleKey","value":"check-for-access-log-for-elb","encrypt":false},{"key":"accessLogBucketName","value":"","encrypt":false},{"encrypt":false,"value":"high","key":"severity"},{"encrypt":false,"value":"governance","key":"ruleCategory"}],"environmentVariables":[],"ruleId":"PacMan_ELB_Access_Logs_version-1_AppLB_Access_Logs_appelb","autofix":false,"alexaKeyword":"AppLBAccessLogs","ruleRestUrl":"","targetType":"appelb","pac_ds":"aws","policyId":"PacMan_ELB_Access_Logs_version-1","assetGroup":"aws","ruleUUID":"aws_appelb_access_logs","ruleType":"ManageRule"}','0 0 ? * MON *','','','Manage Rule',concat('arn:aws:events:',@region,':',@account,':rule/aws_appelb_access_logs'),'ENABLED','ASGC','Access log should be enabled to App ELB and attached to mentioned bucket','2019-02-24','2019-03-14','high','governance'); INSERT IGNORE INTO cf_RuleInstance (`ruleId`,`ruleUUID`,`policyId`,`ruleName`,`targetType`,`assetGroup`,`alexaKeyword`,`ruleParams`,`ruleFrequency`,`ruleExecutable`,`ruleRestUrl`,`ruleType`,`ruleArn`,`status`,`userId`,`displayName`,`createdDate`,`modifiedDate`,`severity`,`category`) VALUES ('PacMan_ELB_Access_Logs_version-1_ClassicLB_Access_Logs_classicelb','aws_classicelb_access_logs','PacMan_ELB_Access_Logs_version-1','ClassicLB_Access_Logs','classicelb','aws','ClassicLB_Access_Logs','{"params":[{"key":"ruleKey","value":"check-for-access-log-for-elb","encrypt":false},{"key":"accessLogBucketName","value":"","encrypt":false},{"encrypt":false,"value":"high","key":"severity"},{"encrypt":false,"value":"governance","key":"ruleCategory"}],"environmentVariables":[],"ruleId":"PacMan_ELB_Access_Logs_version-1_ClassicLB_Access_Logs_classicelb","autofix":false,"alexaKeyword":"ClassicLBAccessLogs","ruleRestUrl":"","targetType":"classicelb","pac_ds":"aws","policyId":"PacMan_ELB_Access_Logs_version-1","assetGroup":"aws","ruleUUID":"aws_classicelb_access_logs","ruleType":"ManageRule"}','0 0 ? * MON *','','','Manage Rule',concat('arn:aws:events:',@region,':',@account,':rule/aws_classicelb_access_logs'),'ENABLED','ASGC','Access log should be enabled to Classic ELB and attached to mentioned bucket','2019-02-24','2019-02-27','high','governance'); INSERT IGNORE INTO cf_RuleInstance (`ruleId`,`ruleUUID`,`policyId`,`ruleName`,`targetType`,`assetGroup`,`alexaKeyword`,`ruleParams`,`ruleFrequency`,`ruleExecutable`,`ruleRestUrl`,`ruleType`,`ruleArn`,`status`,`userId`,`displayName`,`createdDate`,`modifiedDate`,`severity`,`category`) VALUES ('PacMan_CloudFront_AccessLogs_version-1_CloudFront_AccessLogs_cloudfront','aws_cloudfront_accesslogs','PacMan_CloudFront_AccessLogs_version-1','CloudFront_AccessLogs','cloudfront','aws','CloudFront_AccessLogs','{"params":[{"key":"ruleKey","value":"check-access-log-for-cloudfront","encrypt":false},{"key":"accessLogBucketName","value":"","isValueNew":true,"encrypt":false},{"encrypt":false,"value":"high","key":"severity"},{"encrypt":false,"value":"governance","key":"ruleCategory"}],"environmentVariables":[],"ruleId":"PacMan_CloudFront_AccessLogs_version-1_CloudFront_AccessLogs_cloudfront","autofix":false,"alexaKeyword":"CloudFront_AccessLogs","ruleRestUrl":"","targetType":"cloudfront","pac_ds":"aws","policyId":"PacMan_CloudFront_AccessLogs_version-1","assetGroup":"aws","ruleUUID":"aws_cloudfront_accesslogs","ruleType":"ManageRule"}','0 0 ? * MON *','','','Manage Rule',concat('arn:aws:events:',@region,':',@account,':rule/aws_cloudfront_accesslogs'),'ENABLED','ASGC','Access log should be enabled to cloudfront and attached to mentioned bucket','2019-02-18','2019-02-28','high','governance'); +INSERT IGNORE INTO cf_RuleInstance (`ruleId`,`ruleUUID`,`policyId`,`ruleName`,`targetType`,`assetGroup`,`alexaKeyword`,`ruleParams`,`ruleFrequency`,`ruleExecutable`,`ruleRestUrl`,`ruleType`,`ruleArn`,`status`,`userId`,`displayName`,`createdDate`,`modifiedDate`,`severity`,`category`) VALUES ('PacMan_S3AccessLogsRule_version-1_S3AccessLogsRule_s3','aws_s3_accesslogs','PacMan_S3AccessLogsRule_version-1','S3AccessLogsRule','s3','aws','S3AccessLogsRule','{"params":[{"key":"ruleKey","value":"check-for-s3-access-logs","encrypt":false},{"key":"esS3PubAccessIssueUrl","value":"/aws_s3/issue_s3/_search","encrypt":false},{"key":"s3PublicAccessRuleId","value":"PacMan_S3GlobalAccess_version-1_S3BucketShouldnotpubliclyaccessble_s3","encrypt":false},{"key":"splitterChar","value":",","isValueNew":true,"encrypt":false},{"key":"fixKey","value":"private-s3-server-access-logs-fix","isValueNew":true,"encrypt":false},{"key":"accessLogsEnabledRegions","value":"","isValueNew":true,"encrypt":false},{"key":"destinationBucketForAutofix","value":"tmo-s3-accesslog-ACCOUNT_ID-REGION-dev","isValueNew":true,"encrypt":false},{"encrypt":false,"value":"high","key":"severity"},{"encrypt":false,"value":"governance","key":"ruleCategory"}],"environmentVariables":[],"ruleId":"PacMan_S3AccessLogsRule_version-1_S3AccessLogsRule_s3","autofix":false,"alexaKeyword":"S3AccessLogsRule","ruleRestUrl":"","targetType":"s3","pac_ds":"aws","policyId":"PacMan_S3AccessLogsRule_version-1","assetGroup":"aws","ruleUUID":"aws_s3_accesslogs","ruleType":"ManageRule"}','0 0 ? * MON *','','','Manage Rule',concat('arn:aws:events:',@region,':',@account,':rule/aws_s3_accesslogs'),'ENABLED','ASGC','Private s3 buckets should be enabled with access logs','2019-08-05','2019-08-05','high','governance'); +INSERT IGNORE INTO cf_RuleInstance (`ruleId`,`ruleUUID`,`policyId`,`ruleName`,`targetType`,`assetGroup`,`alexaKeyword`,`ruleParams`,`ruleFrequency`,`ruleExecutable`,`ruleRestUrl`,`ruleType`,`ruleArn`,`status`,`userId`,`displayName`,`createdDate`,`modifiedDate`,`severity`,`category`) VALUES ('PacMan_CloudWatchEventsForAllAccounts_version-1_CloudWatchEventsForAllAccounts_account','aws_account_cloud_watch_events','PacMan_CloudWatchEventsForAllAccounts_version-1','CloudWatchEventsForAllAccounts','account','aws','CloudWatchEventsForAllAccounts','{"params":[{"encrypt":false,"value":"check-cloudwatch-event-rule","key":"ruleKey"},{"encrypt":false,"value":"role/pac_ro","key":"roleIdentifyingString"},{"encrypt":false,"value":"DO-NOT-DELETE-pacman-all-events-to-eventbus-in-ACCOUNTID","key":"ruleName"},{"encrypt":false,"value":"high","key":"severity"},{"encrypt":false,"value":"governance","key":"ruleCategory"}],"environmentVariables":[],"ruleId":"PacMan_CloudWatchEventsForAllAccounts_version-1_CloudWatchEventsForAllAccounts_account","autofix":false,"alexaKeyword":"CloudWatchEventsForAllAccounts","ruleRestUrl":"","targetType":"account","pac_ds":"aws","policyId":"PacMan_CloudWatchEventsForAllAccounts_version-1","assetGroup":"aws","ruleUUID":"aws_account_cloud_watch_events","ruleType":"ManageRule"}','0 0 ? * MON *','','','Manage Rule',concat('arn:aws:events:',@region,':',@account,':rule/aws_account_cloud_watch_events'),'ENABLED','ASGC','All Cloud watch events from all accounts should be sent to DEDICATED ACCOUNTID default event bus','2019-08-05','2019-08-05','high','governance'); +INSERT IGNORE INTO cf_RuleInstance (`ruleId`,`ruleUUID`,`policyId`,`ruleName`,`targetType`,`assetGroup`,`alexaKeyword`,`ruleParams`,`ruleFrequency`,`ruleExecutable`,`ruleRestUrl`,`ruleType`,`ruleArn`,`status`,`userId`,`displayName`,`createdDate`,`modifiedDate`,`severity`,`category`) VALUES ('PacMan_LowUtilizationAmazonEC2InstancesRule_version-1_LowUtilizationAmazonEC2InstancesRule_ec2','aws_ec2_low_utilization','PacMan_LowUtilizationAmazonEC2InstancesRule_version-1','LowUtilizationAmazonEC2InstancesRule','ec2','aws','LowUtilizationAmazonEC2InstancesRule','{"params":[{"encrypt":false,"value":"check-for-low-utilization-amazon-ec2-instance","key":"ruleKey"},{"encrypt":false,"value":"","key":"checkId"},{"encrypt":false,"value":"low","key":"severity"},{"isValueNew":true,"encrypt":false,"value":"costOptimization","key":"ruleCategory"},{"key":"esServiceURL","value":"/aws_checks/checks_resources/_search","isValueNew":true,"encrypt":false}],"environmentVariables":[],"ruleId":"PacMan_LowUtilizationAmazonEC2InstancesRule_version-1_LowUtilizationAmazonEC2InstancesRule_ec2","autofix":false,"alexaKeyword":"LowUtilizationAmazonEC2InstancesRule","ruleRestUrl":"","targetType":"ec2","pac_ds":"aws","policyId":"PacMan_LowUtilizationAmazonEC2InstancesRule_version-1","assetGroup":"aws","ruleUUID":"aws_ec2_low_utilization","ruleType":"ManageRule"}','0 0 ? * MON *','','','Manage Rule',concat('arn:aws:events:',@region,':',@account,':rule/aws_ec2_low_utilization'),'ENABLED','ASGC','Amazon EC2 instances should not have low utilization','2019-08-05','2019-08-05','high','governance'); @@ -1417,7 +1423,11 @@ INSERT IGNORE INTO pac_v2_ui_download_filters (serviceId,serviceName,serviceEndp (11,'VulnerableAssets','/api/asset/v1/list/assets/vulnerable'), (12,'PullRequestAssetsByState','/api/devstandards/v1/pullrequests/asset/bystates'), (13,'PullRequestAsstesByAge','/api/devstandards/v1/pullrequests/assets/openstate'), - (14,'ApplicationOrRepositoryDistribution','/api/devstandards/v1/repositories/assets/repositoryorapplicationdistribution'); + (14,'ApplicationOrRepositoryDistribution','/api/devstandards/v1/repositories/assets/repositoryorapplicationdistribution'), + (15,'RecommendationDetails','/api/asset/v1/recommendations/detail'), + (16,'Recommendation','/api/asset/v1/recommendations'), + (17,'CloudNotificationsWithOutGlobal','/api/asset/v1/cloud/notifications?global=false'), + (18,'CloudNotificationsWithGlobal','/api/asset/v1/cloud/notifications?global=true'); INSERT IGNORE INTO pac_config_relation (`application`,`parent`) VALUES ('application','root'); diff --git a/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/cloudwatchevent/CheckCloudWatchEventsForAllAccountsRule.java b/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/cloudwatchevent/CheckCloudWatchEventsForAllAccountsRule.java index ceba76263..45655b30f 100644 --- a/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/cloudwatchevent/CheckCloudWatchEventsForAllAccountsRule.java +++ b/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/cloudwatchevent/CheckCloudWatchEventsForAllAccountsRule.java @@ -48,134 +48,105 @@ @PacmanRule(key = "check-cloudwatch-event-rule", desc = "All Cloud watch events from all accounts should be sent to designated event bus", severity = PacmanSdkConstants.SEV_HIGH, category = PacmanSdkConstants.GOVERNANCE) public class CheckCloudWatchEventsForAllAccountsRule extends BaseRule { - private static final Logger logger = LoggerFactory - .getLogger(CheckCloudWatchEventsForAllAccountsRule.class); - - /** - * The method will get triggered from Rule Engine with following parameters - * - * @param ruleParam - * - * ************* Following are the Rule Parameters*********
- *
- * - * ruleKey : check-cloudwatch-event-rule
- *
- * - * severity : Enter the value of severity
- *
- * - * ruleCategory : Enter the value of category
- *
- * - * roleIdentifyingString : Configure it as role/pacbot_ro
- *
- * - * @param resourceAttributes - * this is a resource in context which needs to be scanned this - * is provided y execution engine - * - */ - @Override - public RuleResult execute(Map ruleParam, - Map resourceAttributes) { - logger.debug("========CheckCloudWatchEventsForAllAccountsRule started========="); - Map temp = new HashMap<>(); - temp.putAll(ruleParam); - temp.put("region", "us-west-2"); - - Map map = null; - Annotation annotation = null; - AmazonCloudWatchEventsClient cloudWatchEventsClient = null; - String roleIdentifyingString = ruleParam - .get(PacmanSdkConstants.Role_IDENTIFYING_STRING); - String accountName = resourceAttributes.get("accountname"); - String ruleName = ruleParam.get(PacmanRuleConstants.RULE_NAME); - logger.info(resourceAttributes.get("accountid")); - logger.info(resourceAttributes.get("accountname")); - - String severity = ruleParam.get(PacmanRuleConstants.SEVERITY); - String category = ruleParam.get(PacmanRuleConstants.CATEGORY); - - MDC.put("executionId", ruleParam.get("executionId")); - MDC.put("ruleId", ruleParam.get(PacmanSdkConstants.RULE_ID)); - - Gson gson = new Gson(); - List> issueList = new ArrayList<>(); - LinkedHashMap issue = new LinkedHashMap<>(); - Map failedType = new HashMap<>(); - - if (!PacmanUtils.doesAllHaveValue(severity, category,ruleName)) { - logger.info(PacmanRuleConstants.MISSING_CONFIGURATION); - throw new InvalidInputException(PacmanRuleConstants.MISSING_CONFIGURATION); - } - - try { - map = getClientFor(AWSService.CLOUDWATCH_EVENTS, - roleIdentifyingString, temp); - cloudWatchEventsClient = (AmazonCloudWatchEventsClient) map - .get(PacmanSdkConstants.CLIENT); - - ListRulesRequest listRulesRequest = new ListRulesRequest(); - listRulesRequest.setNamePrefix(ruleName); - ListRulesResult listRulesResult = cloudWatchEventsClient - .listRules(listRulesRequest); - String state = null; - boolean isRuleEmpty = false; - boolean isDisabled = false; - if (listRulesResult.getRules().isEmpty()) { - isRuleEmpty = true; - failedType.put("ruleList", "Empty"); - } - - if (!listRulesResult.getRules().isEmpty()) { - for (Rule result : listRulesResult.getRules()) { - state = result.getState(); - logger.info(state); - if (!"ENABLED".equals(state)) { - isDisabled = true; - failedType.put("ruleState", "Disabled"); - } - } - } - if (isRuleEmpty || isDisabled) { - annotation = Annotation.buildAnnotation(ruleParam, - Annotation.Type.ISSUE); - annotation - .put(PacmanSdkConstants.DESCRIPTION, - "Cloud watch events from " - + accountName - + " is not been sent to designated default event bus"); - annotation.put(PacmanRuleConstants.SEVERITY, severity); - annotation.put(PacmanRuleConstants.CATEGORY, category); - - issue.put( - PacmanRuleConstants.VIOLATION_REASON, - "Cloud watch events from " - + accountName - + " is not been sent to designated default event bus!!"); - issue.put("failed_reason", gson.toJson(failedType)); - issueList.add(issue); - annotation.put("issueDetails", issueList.toString()); - logger.debug( - "========CheckCloudWatchEventsForAllAccountsRule ended with annotation : {}=========", - annotation); - return new RuleResult(PacmanSdkConstants.STATUS_FAILURE, - PacmanRuleConstants.FAILURE_MESSAGE, annotation); - } - } catch (UnableToCreateClientException e) { - logger.error("unable to get client for following input", e); - throw new InvalidInputException(e.toString()); - } - - - logger.debug("========CheckCloudWatchEventsForAllAccountsRule ended========="); - return new RuleResult(PacmanSdkConstants.STATUS_SUCCESS, - PacmanRuleConstants.SUCCESS_MESSAGE); - } - - @Override - public String getHelpText() { - return "All Cloud watch events from all accounts should be sent to designated event bus"; - } + private static final Logger logger = LoggerFactory.getLogger(CheckCloudWatchEventsForAllAccountsRule.class); + + /** + * The method will get triggered from Rule Engine with following parameters + * + * @param ruleParam ************* Following are the Rule Parameters*********

+ * + * ruleKey : check-cloudwatch-event-rule

+ * + * severity : Enter the value of severity

+ * + * ruleCategory : Enter the value of category

+ * + * roleIdentifyingString : Configure it as role/pacbot_ro

+ * + * @param resourceAttributes this is a resource in context which needs to be scanned this is provided y execution engine + * + */ + @Override + public RuleResult execute(Map ruleParam,Map resourceAttributes) { + logger.debug("========CheckCloudWatchEventsForAllAccountsRule started========="); + Map temp = new HashMap<>(); + temp.putAll(ruleParam); + temp.put("region", "us-west-2"); + + Map map = null; + Annotation annotation = null; + AmazonCloudWatchEventsClient cloudWatchEventsClient = null; + String roleIdentifyingString = ruleParam.get(PacmanSdkConstants.Role_IDENTIFYING_STRING); + String accountName = resourceAttributes.get("accountname"); + String ruleName = ruleParam.get(PacmanRuleConstants.RULE_NAME); + logger.info(resourceAttributes.get("accountid")); + logger.info(resourceAttributes.get("accountname")); + + String severity = ruleParam.get(PacmanRuleConstants.SEVERITY); + String category = ruleParam.get(PacmanRuleConstants.CATEGORY); + + MDC.put("executionId", ruleParam.get("executionId")); + MDC.put("ruleId", ruleParam.get(PacmanSdkConstants.RULE_ID)); + + Gson gson = new Gson(); + List> issueList = new ArrayList<>(); + LinkedHashMap issue = new LinkedHashMap<>(); + Map failedType = new HashMap<>(); + + if (!PacmanUtils.doesAllHaveValue(severity, category, ruleName)) { + logger.info(PacmanRuleConstants.MISSING_CONFIGURATION); + throw new InvalidInputException(PacmanRuleConstants.MISSING_CONFIGURATION); + } + + try { + map = getClientFor(AWSService.CLOUDWATCH_EVENTS,roleIdentifyingString, temp); + cloudWatchEventsClient = (AmazonCloudWatchEventsClient) map.get(PacmanSdkConstants.CLIENT); + + ListRulesRequest listRulesRequest = new ListRulesRequest(); + listRulesRequest.setNamePrefix(ruleName); + ListRulesResult listRulesResult = cloudWatchEventsClient.listRules(listRulesRequest); + String state = null; + boolean isRuleEmpty = false; + boolean isDisabled = false; + if (listRulesResult.getRules().isEmpty()) { + isRuleEmpty = true; + failedType.put("ruleList", "Empty"); + } + + if (!listRulesResult.getRules().isEmpty()) { + for (Rule result : listRulesResult.getRules()) { + state = result.getState(); + logger.info(state); + if (!"ENABLED".equals(state)) { + isDisabled = true; + failedType.put("ruleState", "Disabled"); + } + } + } + if (isRuleEmpty || isDisabled) { + annotation = Annotation.buildAnnotation(ruleParam,Annotation.Type.ISSUE); + annotation.put(PacmanSdkConstants.DESCRIPTION,"Cloud watch events from "+ accountName+ " is not been sent to designated default event bus"); + annotation.put(PacmanRuleConstants.SEVERITY, severity); + annotation.put(PacmanRuleConstants.CATEGORY, category); + + issue.put(PacmanRuleConstants.VIOLATION_REASON,"Cloud watch events from "+ accountName+ " is not been sent to designated default event bus!!"); + issue.put("failed_reason", gson.toJson(failedType)); + issueList.add(issue); + annotation.put("issueDetails", issueList.toString()); + logger.debug("========CheckCloudWatchEventsForAllAccountsRule ended with annotation : {}=========",annotation); + return new RuleResult(PacmanSdkConstants.STATUS_FAILURE,PacmanRuleConstants.FAILURE_MESSAGE, annotation); + } + } catch (UnableToCreateClientException e) { + logger.error("unable to get client for following input", e); + throw new InvalidInputException(e.toString()); + } + + logger.debug("========CheckCloudWatchEventsForAllAccountsRule ended========="); + return new RuleResult(PacmanSdkConstants.STATUS_SUCCESS,PacmanRuleConstants.SUCCESS_MESSAGE); + } + + @Override + public String getHelpText() { + return "All Cloud watch events from all accounts should be sent to designated event bus"; + } } diff --git a/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/s3/S3AccessLogsRule.java b/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/s3/S3AccessLogsRule.java new file mode 100644 index 000000000..a99a701a8 --- /dev/null +++ b/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/s3/S3AccessLogsRule.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +/** + Copyright (C) 2017 T Mobile Inc - All Rights Reserve + Purpose: This rule check for the elastic search exposed to public + Author : Kkambal1 + Modified Date: Jun 6, 2019 + + **/ +package com.tmobile.cloud.awsrules.s3; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.text.StrSubstitutor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; + +import com.amazonaws.util.StringUtils; +import com.google.common.collect.HashMultimap; +import com.tmobile.cloud.awsrules.utils.PacmanUtils; +import com.tmobile.cloud.constants.PacmanRuleConstants; +import com.tmobile.pacman.commons.PacmanSdkConstants; +import com.tmobile.pacman.commons.exception.InvalidInputException; +import com.tmobile.pacman.commons.exception.RuleExecutionFailedExeption; +import com.tmobile.pacman.commons.rule.Annotation; +import com.tmobile.pacman.commons.rule.BaseRule; +import com.tmobile.pacman.commons.rule.PacmanRule; +import com.tmobile.pacman.commons.rule.RuleResult; + +@PacmanRule(key = "check-for-s3-access-logs", desc = "This rule checks for private s3 has server access logs enabled or not", severity = PacmanSdkConstants.SEV_HIGH, category = PacmanSdkConstants.SECURITY) +public class S3AccessLogsRule extends BaseRule { + private static final Logger logger = LoggerFactory.getLogger(S3AccessLogsRule.class); + + /** + * The method will get triggered from Rule Engine with following parameters + * + * @param ruleParam + * + ************** Following are the Rule Parameters*********

+ * + *ruleKey : check-for-s3-access-logs

+ * + *esS3PubAccessIssueUrl : Enter the S3 Public Access ES issue URL

+ * + *s3PublicAccessRuleId : Enter the ruleId which is s3 with public access with read\write

+ * + * @param resourceAttributes this is a resource in context which needs to be scanned this is provided by execution engine + * + */ + + public RuleResult execute(final Map ruleParam,Map resourceAttributes) { + logger.debug("========S3AccessLogsRule started========="); + Annotation annotation = null; + String esS3PubAccessIssueUrl = null; + List> issueList = new ArrayList<>(); + LinkedHashMap issue = new LinkedHashMap<>(); + String s3Bucket = ruleParam.get(PacmanRuleConstants.RESOURCE_ID); + String destinationBucketForAutoFix = ruleParam.get(PacmanRuleConstants.DESTINATION_BUCKET_AUTOFIX); + String accessLogsEnabledRegions = ruleParam.get(PacmanRuleConstants.ACCESSLOGS_ENABLED_REGIONS); + String splitter = ruleParam.get(PacmanSdkConstants.SPLITTER_CHAR); + String region = resourceAttributes.get(PacmanRuleConstants.REGION_ATTR); + String accountId = resourceAttributes.get(PacmanRuleConstants.ACCOUNTID); + String targetType = resourceAttributes.get(PacmanRuleConstants.ENTITY_TYPE); + String isLoggingEnabled = resourceAttributes.get(PacmanRuleConstants.IS_S3_ACCESS_LOGS_ENABLED); + + String description = targetType+ " has not enabled the server access logs for " + s3Bucket; + String s3PublicAccessRuleId = ruleParam.get(PacmanRuleConstants.S3_PUBLIC_ACCESS_RULE_ID); + Map data = new HashMap<>(); + data.put("ACCOUNT_ID", accountId); + data.put("REGION", region); + destinationBucketForAutoFix = StrSubstitutor.replace(destinationBucketForAutoFix, data); + + String pacmanHost = PacmanUtils.getPacmanHost(PacmanRuleConstants.ES_URI); + logger.debug("========pacmanHost {} =========", pacmanHost); + + if (!StringUtils.isNullOrEmpty(pacmanHost)) { + esS3PubAccessIssueUrl = ruleParam.get(PacmanRuleConstants.ES_S3_PUBLIC_ACCESS_ISSUE_URL); + esS3PubAccessIssueUrl = pacmanHost + esS3PubAccessIssueUrl; + } + + MDC.put("executionId", ruleParam.get("executionId")); + MDC.put("ruleId", ruleParam.get(PacmanSdkConstants.RULE_ID)); + + if (!PacmanUtils.doesAllHaveValue(esS3PubAccessIssueUrl,s3PublicAccessRuleId,destinationBucketForAutoFix,accessLogsEnabledRegions,splitter)) { + logger.info(PacmanRuleConstants.MISSING_CONFIGURATION); + throw new InvalidInputException(PacmanRuleConstants.MISSING_CONFIGURATION); + } + try { + + Map mustFilter = new HashMap<>(); + mustFilter.put(PacmanRuleConstants.RESOURCE_ID, s3Bucket); + mustFilter.put(PacmanRuleConstants.RULE_ID, s3PublicAccessRuleId); + mustFilter.put(PacmanRuleConstants.ACCOUNTID, accountId); + mustFilter.put(PacmanRuleConstants.REGION_ATTR, region); + HashMultimap shouldFilter = HashMultimap.create(); + Map mustTermsFilter = new HashMap<>(); + shouldFilter.put(PacmanSdkConstants.ISSUE_STATUS_KEY,PacmanSdkConstants.STATUS_OPEN); + shouldFilter.put(PacmanSdkConstants.ISSUE_STATUS_KEY,PacmanRuleConstants.STATUS_EXEMPTED); + + Set resourceSet = PacmanUtils.getValueFromElasticSearchAsSet(esS3PubAccessIssueUrl,mustFilter, shouldFilter, mustTermsFilter,"_resourceid", null); + logger.debug("======issueDetails : {}", resourceSet); + + logger.debug("======isLoggingEnabled : {}", Boolean.parseBoolean(isLoggingEnabled)); + + if (resourceSet.isEmpty() && !Boolean.parseBoolean(isLoggingEnabled)) { + String destinationBucketName = resourceAttributes.get(PacmanRuleConstants.DESTINATION_BUCKET_NAME); + String logFilePrefix = resourceAttributes.get(PacmanRuleConstants.LOG_FILE_PREFIX); + annotation = Annotation.buildAnnotation(ruleParam,Annotation.Type.ISSUE); + annotation.put(PacmanSdkConstants.DESCRIPTION, description); + annotation.put(PacmanRuleConstants.SEVERITY,ruleParam.get(PacmanRuleConstants.SEVERITY)); + annotation.put(PacmanRuleConstants.CATEGORY,ruleParam.get(PacmanRuleConstants.CATEGORY)); + destinationBucketForAutoFix = destinationBucketForAutoFix.replace("ACCOUNT_ID", accountId); + destinationBucketForAutoFix = destinationBucketForAutoFix.replace("REGION", region); + annotation.put(PacmanRuleConstants.DESTINATION_BUCKET_AUTOFIX,destinationBucketForAutoFix); + annotation.put(PacmanRuleConstants.ACCESSLOGS_ENABLED_REGIONS,accessLogsEnabledRegions); + annotation.put(PacmanSdkConstants.SPLITTER_CHAR,splitter); + issue.put(PacmanRuleConstants.VIOLATION_REASON, description); + issue.put(PacmanRuleConstants.IS_S3_ACCESS_LOGS_ENABLED, isLoggingEnabled); + issue.put(PacmanRuleConstants.DESTINATION_BUCKET_NAME, destinationBucketName); + issue.put(PacmanRuleConstants.LOG_FILE_PREFIX, logFilePrefix); + issueList.add(issue); + annotation.put("issueDetails", issueList.toString()); + logger.debug("========S3AccessLogsRule ended with an annotation {} : =========",annotation); + return new RuleResult(PacmanSdkConstants.STATUS_FAILURE,PacmanRuleConstants.FAILURE_MESSAGE, annotation); + } + } catch (Exception e) { + logger.error(e.getMessage()); + throw new RuleExecutionFailedExeption(e.getMessage()); + } + logger.debug("========S3AccessLogsRule ended========="); + return new RuleResult(PacmanSdkConstants.STATUS_SUCCESS,PacmanRuleConstants.SUCCESS_MESSAGE); + } + + @Override + public String getHelpText() { + return "This rule checks for private s3 has server access logs enabled or not"; + } + +} diff --git a/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/utils/PacmanUtils.java b/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/utils/PacmanUtils.java index 33a761441..07e095266 100644 --- a/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/utils/PacmanUtils.java +++ b/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/utils/PacmanUtils.java @@ -2653,5 +2653,82 @@ public static JsonObject getConfigurationsFromConfigApi(String url,Map getValueFromElasticSearchAsSet(String esUrl, Map mustFilterMap,HashMultimap shouldFilterMap,Map mustTermsFilterMap,String fieldKey,Map> matchPhrase) + throws Exception { + JsonParser jsonParser = new JsonParser(); + + Map mustFilter = new HashMap<>(); + HashMultimap shouldFilter = HashMultimap.create(); + Map mustNotFilter = new HashMap<>(); + Map mustTermsFilter = new HashMap<>(); + + if (!mustFilterMap.isEmpty()) { + for(Map.Entry mustFilMap: mustFilterMap.entrySet()){ + mustFilter.put(convertAttributetoKeyword(mustFilMap.getKey()), mustFilMap.getValue()); + } + } + + if (!shouldFilterMap.isEmpty()) { + for(Map.Entry shouldFilMap: shouldFilterMap.entries()){ + shouldFilter.put(convertAttributetoKeyword(shouldFilMap.getKey()), shouldFilMap.getValue()); + } + } + + if (!mustTermsFilterMap.isEmpty()) { + for(Map.Entry mustTermsFilMap: mustTermsFilterMap.entrySet()){ + mustTermsFilter.put(convertAttributetoKeyword(mustTermsFilMap.getKey()), mustTermsFilMap.getValue()); + } + } + + JsonObject resultJson = RulesElasticSearchRepositoryUtil.getQueryDetailsFromES(esUrl+"?size=10000", mustFilter, + mustNotFilter, shouldFilter, null, 0, mustTermsFilter, null,matchPhrase); + if (resultJson != null && resultJson.has(PacmanRuleConstants.HITS)) { + String hitsJsonString = resultJson.get(PacmanRuleConstants.HITS).toString(); + JsonObject hitsJson = (JsonObject) jsonParser.parse(hitsJsonString); + JsonArray jsonArray = hitsJson.getAsJsonObject().get(PacmanRuleConstants.HITS).getAsJsonArray(); + return returnFieldValueAsSet(jsonArray,fieldKey); + + } + return null; + } + + /** + * Checks if is field exists. + * + * @param jsonArray the json array + * @param fieldKey the field key + * @return String, if is instance exists + */ + private static Set returnFieldValueAsSet(JsonArray jsonArray,String fieldKey) { + Set fieldValueList = new HashSet<>(); + if (jsonArray.size() > 0) { + for (int i = 0; i < jsonArray.size(); i++) { + JsonObject firstObject = (JsonObject) jsonArray.get(i); + JsonObject sourceJson = (JsonObject) firstObject.get(PacmanRuleConstants.SOURCE); + if (sourceJson != null + && (sourceJson.get(fieldKey) != null && !sourceJson.get(fieldKey).isJsonNull())) { + String fieldValue = sourceJson.get(fieldKey).getAsString(); + if (!org.apache.commons.lang.StringUtils.isEmpty(fieldValue)) { + fieldValueList.add(fieldValue); + + } + } + } + } + return fieldValueList; + } } diff --git a/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/constants/PacmanRuleConstants.java b/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/constants/PacmanRuleConstants.java index 178c1b8d5..30b292013 100644 --- a/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/constants/PacmanRuleConstants.java +++ b/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/constants/PacmanRuleConstants.java @@ -344,4 +344,13 @@ private PacmanRuleConstants() { public static final String ASSOCIATION_ID = "associationid"; public static final String SECURITY_GROUPS = "securitygroups"; public static final String ES_RDSDB_SG_URL = "esRdsDbSgUrl"; + public static final String S3_PUBLIC_ACCESS_RULE_ID = "s3PublicAccessRuleId"; + public static final String ES_S3_PUBLIC_ACCESS_ISSUE_URL = "esS3PubAccessIssueUrl"; + public static final String IS_S3_ACCESS_LOGS_ENABLED = "isLoggingEnabled"; + public static final String DESTINATION_BUCKET_NAME = "destinationBucketName"; + public static final String LOG_FILE_PREFIX = "logFilePrefix"; + public static final String DESTINATION_BUCKET_AUTOFIX = "destinationBucketForAutofix"; + public static final String ACCESSLOGS_ENABLED_REGIONS = "accessLogsEnabledRegions"; + public static final String RULE_ID = "ruleId"; + public static final String STATUS_EXEMPTED = "exempted"; } diff --git a/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/s3/S3AccessLogsRuleTest.java b/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/s3/S3AccessLogsRuleTest.java new file mode 100644 index 000000000..61329e1b9 --- /dev/null +++ b/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/s3/S3AccessLogsRuleTest.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +package com.tmobile.cloud.awsrules.s3; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.tmobile.cloud.awsrules.utils.CommonTestUtils; +import com.tmobile.cloud.awsrules.utils.PacmanEc2Utils; +import com.tmobile.cloud.awsrules.utils.PacmanUtils; +import com.tmobile.pacman.commons.exception.InvalidInputException; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ PacmanUtils.class,PacmanEc2Utils.class}) +public class S3AccessLogsRuleTest { + + @InjectMocks + S3AccessLogsRule s3AccessLogsRule; + + + + @Test + public void executeNLBTest() throws Exception { + mockStatic(PacmanUtils.class); + when(PacmanUtils.doesAllHaveValue(anyString(),anyString(),anyString(),anyString(),anyString())).thenReturn(true); + + when(PacmanUtils.getPacmanHost(anyString())).thenReturn("host"); + when(PacmanUtils.getValueFromElasticSearchAsSet(anyString(),anyObject(),anyObject(),anyObject(),anyString(),anyObject())).thenReturn(CommonTestUtils.getEmptySetString()); + assertThat(s3AccessLogsRule.execute(CommonTestUtils.getMapStringNLB("r_123 "),CommonTestUtils.getMapStringNLB("r_123 ")), is(notNullValue())); + + when(PacmanUtils.getValueFromElasticSearchAsSet(anyString(),anyObject(),anyObject(),anyObject(),anyString(),anyObject())).thenReturn(CommonTestUtils.getSetString("123")); + assertThat(s3AccessLogsRule.execute(CommonTestUtils.getMapStringNLB("r_123 "),CommonTestUtils.getMapStringNLB("r_123 ")), is(notNullValue())); + + + when(PacmanUtils.doesAllHaveValue(anyString(),anyString(),anyString(),anyString(),anyString())).thenReturn(false); + assertThatThrownBy( + () -> s3AccessLogsRule.execute(CommonTestUtils.getMapStringNLB("r_123 "),CommonTestUtils.getMapStringNLB("r_123 "))).isInstanceOf(InvalidInputException.class); + } + + @Test + public void getHelpTextTest(){ + assertThat(s3AccessLogsRule.getHelpText(), is(notNullValue())); + } +} diff --git a/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/CommonTestUtils.java b/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/CommonTestUtils.java index 60d1fb7e3..aebb224ff 100644 --- a/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/CommonTestUtils.java +++ b/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/CommonTestUtils.java @@ -26,6 +26,7 @@ import org.json.JSONObject; import com.amazonaws.services.ec2.model.GroupIdentifier; +import com.google.common.collect.HashMultimap; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; @@ -641,6 +642,16 @@ public static Map getMapObject(String passRuleResourceId) { commonMap.put("created_event_found", true); return commonMap; } + + public static HashMultimap getMulHashMapObject(String passRuleResourceId) { + HashMultimap commonMap = HashMultimap.create(); + commonMap.put("region", "region"); + commonMap.put("_resourceid", passRuleResourceId); + commonMap.put("issueCount", "issueCount"); + commonMap.put("OU", "OU"); + commonMap.put("created_event_found", true); + return commonMap; + } public static Map getEmptyMapObject() { return new HashMap<>(); @@ -963,4 +974,157 @@ public static Map> getMapStringList( commonMap.put("description", list); return commonMap; } + + public static Map getMapStringNLB(String passRuleResourceId) { + Map commonMap = new HashMap<>(); + commonMap.put("iamPriviliges","iamPriviliges"); + commonMap.put(",lambda:*,*",",lambda:*,*"); + commonMap.put(",ec2:*,*",",ec2:*,*"); + commonMap.put("lambda","lambda"); + commonMap.put(",ec2:*,*,s3:*,s3:put*",",ec2:*,*,s3:*,s3:put*"); + commonMap.put("type","network"); + + commonMap.put("cidripv6", "cidripv6"); + commonMap.put("username", "svc_123"); + commonMap.put("associationid", "associationid"); + commonMap.put("domainname", "domainname"); + commonMap.put("accesspolicies", "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"*\"},\"Action\":\"es:*\",\"Resource\":\"123/*\"}]}"); + commonMap.put("scheme", "internet-facing"); + commonMap.put("subnets", "subnets"); + commonMap.put("esElbWithSGUrl", "esElbWithSGUrl"); + commonMap.put("esEc2SgURL", "esEc2SgURL"); + commonMap.put("endpoint", "endpoint"); + commonMap.put("esRoutetableAssociationsURL", "esRoutetableAssociationsURL"); + commonMap.put("esRoutetableRoutesURL", "esRoutetableRoutesURL"); + commonMap.put("esRoutetableURL", "esRoutetableURL"); + commonMap.put("esSgRulesUrl", "esSgRulesUrl"); + commonMap.put("esSubnetURL", "esSubnetURL"); + commonMap.put("identifiableKey", "identifiableKey"); + commonMap.put("subnetEsURL", "subnetEsURL"); + commonMap.put("esSubnetURL", "esSubnetURL"); + commonMap.put("awsSearch", "awsSearch"); + commonMap.put("kernelInfoApi", "kernelInfoApi"); + commonMap.put("esNonAdminAccntsWithIAMFullAccessUrl", "esNonAdminAccntsWithIAMFullAccessUrl"); + commonMap.put("esLdapUrl", "esLdapUrl"); + commonMap.put("esQualysUrl", "esQualysUrl"); + commonMap.put("esSatAndSpacewalkUrl", "esSatAndSpacewalkUrl"); + commonMap.put("esServiceURL", "esServiceURL"); + commonMap.put("esAdGroupURL", "esAdGroupURL"); + commonMap.put("esEbsWithInstanceUrl", "esEbsWithInstanceUrl"); + commonMap.put("esAppTagURL", "esAppTagURL"); + commonMap.put("esEc2SgURL", "esEc2SgURL"); + commonMap.put("esEc2WithVulnInfoForS5Url", "esEc2WithVulnInfoForS5Url"); + commonMap.put("esEc2PubAccessPortUrl", "esEc2PubAccessPortUrl"); + commonMap.put("esSsmWithInstanceUrl", "esSsmWithInstanceUrl"); + commonMap.put("esElasticIpUrl", "esElasticIpUrl"); + commonMap.put("esAppElbWithInstanceUrl", "esAppElbWithInstanceUrl"); + commonMap.put("esClassicElbWithInstanceUrl", "esClassicElbWithInstanceUrl"); + commonMap.put("esGuardDutyUrl", "esGuardDutyUrl"); + commonMap.put("esNonAdminAccntsWithIAMFullAccessUrl", "esNonAdminAccntsWithIAMFullAccessUrl"); + commonMap.put("esSgRulesUrl", "esSgRulesUrl"); + commonMap.put("esServiceWithSgUrl", "esServiceWithSgUrl"); + commonMap.put("ES_URI", "ES_URI"); + commonMap.put("executionId", "1234"); + commonMap.put("_resourceid", passRuleResourceId); + commonMap.put("severity", "low"); + commonMap.put("ruleCategory", "security"); + commonMap.put("accountid", "12345"); + commonMap.put("checkId", "1234567"); + commonMap.put("serviceEsURL", "url"); + commonMap.put("serviceAccountEsURL", "serviceAccountEsURL"); + commonMap.put("description", "R FND"); + commonMap.put("elasticIpEsUrl", "elasticIpEsUrl"); + commonMap.put("region", "us-east-1"); + commonMap.put("authType", "authType"); + commonMap.put("splitterChar", ","); + commonMap.put("roleIdentifyingString", "roleIdentifyingString"); + commonMap.put("ldapApi", "ldapApi"); + commonMap.put("satAndSpacewalkApi", "satAndSpacewalkApi"); + commonMap.put("qualysApi", "qualysApi"); + commonMap.put("kernelVersionByInstanceIdUrl", + "kernelVersionByInstanceIdUrl"); + commonMap.put("defaultKernelCriteriaUrl", "defaultKernelCriteriaUrl"); + commonMap.put("accountNames", "accountNames"); + commonMap.put("sourceType", "sourceType"); + commonMap.put("statename", "running"); + commonMap.put("ebsWithInstanceUrl", "ebsWithInstanceUrl"); + commonMap.put("volumeid", "volumeid"); + commonMap.put("loadbalancername", "loadbalancername"); + commonMap.put("targetExpireDuration", "150"); + commonMap.put("validto", "12/10/2018 23:33"); + commonMap.put("appElbWithInstanceUrl", "appElbWithInstanceUrl"); + commonMap.put("loadbalancerarn", "loadbalancerarn"); + commonMap.put("classicElbWithInstanceUrl", "classicElbWithInstanceUrl"); + commonMap.put("guardDutyEsUrl", "guardDutyEsUrl"); + commonMap.put("dbinstanceidentifier", "dbinstanceidentifier"); + commonMap.put("dbsnapshotarn", "dbsnapshotarn"); + commonMap.put("publiclyaccessible", "true"); + commonMap.put("apiGWURL", "apiGWURL"); + commonMap.put("portToCheck", "22"); + commonMap.put("sgRulesUrl", "sgRulesUrl"); + commonMap.put("cidrIp", "cidrIp"); + commonMap.put("serviceWithSgUrl", "serviceWithSgUrl"); + commonMap.put("esUrl", "esUrl"); + commonMap.put("groupid", "groupid"); + commonMap.put("adGroupEsURL", "adGroupEsURL"); + commonMap.put("target", "30"); + commonMap.put("inScope", "true"); + commonMap.put("role", "role"); + commonMap.put("passwordlastused", "2018-07-16 12:16:38+00"); + commonMap.put("pwdInactiveDuration", "1"); + commonMap.put("status_RED", "status_RED"); + commonMap.put("tags.Application", "identifiableKey"); + commonMap.put("_entitytype", "elasticache"); + commonMap.put("appTagEsURL", "appTagEsURL"); + commonMap.put("heimdallESURL", "heimdallESURL"); + commonMap.put("deprecatedInstanceType", "deprecatedInstanceType"); + commonMap.put("instancetype", "xyz"); + commonMap.put("running", "running"); + commonMap.put("instanceid", "instanceid"); + commonMap.put("ec2PubAccessPortUrl", "ec2PubAccessPortUrl"); + commonMap.put("ec2WithVulnInfoForS5Url", "ec2WithVulnInfoForS5Url"); + commonMap.put("ec2PortRuleId", "ec2PortRuleId"); + commonMap.put("severityVulnValue", "severityVulnValue"); + commonMap.put("publicipaddress", "publicipaddress"); + commonMap.put("Stopped", "Stopped"); + commonMap.put("statetransitionreason", + "User initiated (2017-10-20 11:36:20 GMT)"); + commonMap.put("targetstoppedDuration", "30"); + commonMap.put("privateipaddress", "privateipaddress"); + commonMap.put("port", "22"); + commonMap.put("ssmWithInstanceUrl", "ssmWithInstanceUrl"); + commonMap.put("mandatoryTags", "mandatoryTags"); + commonMap.put("targetType", "targetType"); + commonMap.put("internetGateWay", "internetGateWay"); + commonMap.put("ec2SgEsURL", "ec2SgEsURL"); + commonMap.put("routetableAssociationsEsURL", + "routetableAssociationsEsURL"); + commonMap.put("routetableRoutesEsURL", "routetableRoutesEsURL"); + commonMap.put("routetableEsURL", "routetableEsURL"); + commonMap.put("target", "30"); + commonMap.put("sgRulesUrl", "sgRulesUrl"); + commonMap.put("cidrIp", "cidrIp"); + commonMap.put("subnetid", "subnetid"); + commonMap.put("vpcid", "vpcid"); + commonMap.put("accountname", "accountname"); + commonMap.put("client", "client"); + commonMap.put("platform", "platform"); + commonMap.put("ruleName", "ruleName"); + commonMap.put("functionname", "functionname"); + commonMap.put("timePeriodInHours", "30"); + commonMap.put("threshold", "30"); + commonMap.put("rolename", "rolename"); + commonMap.put("adminRolesToCompare", "adminRolesToCompare"); + commonMap.put("kernelversionForComparision.x86_64", + "kernelversionForComparision.x86_64"); + commonMap.put("reponse", "success"); + commonMap.put("lucene_version", "success"); + commonMap.put("final_u_last_patched", "2018-08-01 00:00:00.000000"); + commonMap.put("final_kernel_release", "123"); + commonMap.put("firstdiscoveredon", "2018-08-03 10:00:00+00"); + commonMap.put("discoveredDaysRange", "7"); + commonMap.put("vpc", "vpc"); + commonMap.put("securitygroups", "securitygroups"); + return commonMap; + } } diff --git a/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/PacmanUtilsTest.java b/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/PacmanUtilsTest.java index dd079eb0f..19814df1c 100644 --- a/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/PacmanUtilsTest.java +++ b/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/PacmanUtilsTest.java @@ -26,10 +26,12 @@ import static org.mockito.Matchers.anyString; import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; +import io.vavr.collection.HashMultimap; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.net.URL; +import java.util.Map; import javax.net.ssl.SSLContext; @@ -429,5 +431,16 @@ public void getResponseTest() throws Exception { when(closeableHttpClient.execute((HttpGet) any())).thenReturn(httpResponse); assertThat(pacmanUtils.getResponse(CommonTestUtils.getMapString("123"),"123"),is(notNullValue())); } + + @SuppressWarnings("static-access") + @Test + public void getValueFromElasticSearchSetTest() throws Exception { + mockStatic(RulesElasticSearchRepositoryUtil.class); + when(RulesElasticSearchRepositoryUtil.getQueryDetailsFromES(anyString(),anyObject(),anyObject(),anyObject(),anyString(),anyInt(),anyObject(),anyObject(),anyObject())).thenReturn(CommonTestUtils.getJsonObject()); + assertThat(pacmanUtils.getValueFromElasticSearchAsSet("test",CommonTestUtils.getMapObject("123"),CommonTestUtils.getMulHashMapObject("123"),CommonTestUtils.getMapObject("123"),"test",CommonTestUtils.getMapStringList("123")),is(notNullValue())); + + when(RulesElasticSearchRepositoryUtil.getQueryDetailsFromES(anyString(),anyObject(),anyObject(),anyObject(),anyString(),anyInt(),anyObject(),anyObject(),anyObject())).thenReturn(CommonTestUtils.getEmptyJsonObject()); + assertThat(pacmanUtils.getValueFromElasticSearchAsSet("test",CommonTestUtils.getMapObject("123"),CommonTestUtils.getMulHashMapObject("123"),CommonTestUtils.getMapObject("123"),"test",CommonTestUtils.getMapStringList("123")),is(nullValue())); + } } From 6005b29168a09d3836b1956c50128ee46653a705 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Mon, 5 Aug 2019 14:57:15 +0530 Subject: [PATCH 34/86] removed unused import --- .../java/com/tmobile/cloud/awsrules/utils/PacmanUtilsTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/PacmanUtilsTest.java b/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/PacmanUtilsTest.java index 19814df1c..3f85302b7 100644 --- a/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/PacmanUtilsTest.java +++ b/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/PacmanUtilsTest.java @@ -26,7 +26,6 @@ import static org.mockito.Matchers.anyString; import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; -import io.vavr.collection.HashMultimap; import java.io.ByteArrayInputStream; import java.io.InputStream; From 12b9b07a5924f50c35893392adacb201b057e963 Mon Sep 17 00:00:00 2001 From: Kanchana Date: Mon, 5 Aug 2019 16:18:40 +0530 Subject: [PATCH 35/86] RDS db & unused sg autofix --- installer/resources/pacbot_app/files/DB.sql | 42 +++ .../SecurityGroupNotUsedRule.java | 25 +- .../cloud/awsrules/utils/PacmanUtils.java | 123 ++++++++ .../SecurityGroupNotUsedRuleTest.java | 4 +- .../publicaccess/PublicAccessAutoFix.java | 57 ++++ .../autofix/rds/RdsDbPublicAccessAutoFix.java | 271 ++++++++++++++++++ .../pacman/autofix/sg/UnusedSgAutoFix.java | 129 +++++++++ .../pacman/common/PacmanSdkConstants.java | 3 + .../autofix/manager/AutoFixManager.java | 57 ++-- .../manager/ResourceTaggingManager.java | 4 + 10 files changed, 675 insertions(+), 40 deletions(-) create mode 100644 jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/autofix/rds/RdsDbPublicAccessAutoFix.java create mode 100644 jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/autofix/sg/UnusedSgAutoFix.java diff --git a/installer/resources/pacbot_app/files/DB.sql b/installer/resources/pacbot_app/files/DB.sql index 5caa451e5..d1fca1e10 100644 --- a/installer/resources/pacbot_app/files/DB.sql +++ b/installer/resources/pacbot_app/files/DB.sql @@ -1732,6 +1732,27 @@ INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pa INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.auto.fix.mail.template.columns.PacMan_RedShiftPublicAccess_version-1_RedShiftPublicAccess_redshift','Description PlaceHolder'); INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.auto.fix.common.email.notifications.PacMan_RedShiftPublicAccess_version-1_RedShiftPublicAccess_redshift','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('autofix.whitelist.accounts.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.auto.fix.mail.subject.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.auto.warning.mail.subject.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.autofix.rule.violation.message.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.autofix.rule.warning.message.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.autofix.rule.post.fix.message.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.autofix.waittime.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.auto.fix.max.email.notifications.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.auto.fix.mail.template.columns.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.auto.fix.common.email.notifications.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','Description PlaceHolder'); + +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('autofix.whitelist.accounts.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.autofix.contact.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.autofix.fix.type.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.auto.fix.mail.subject.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.autofix.rule.post.fix.message.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.autofix.fix.notify.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.auto.fix.mail.template.columns.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','Description PlaceHolder'); +INSERT IGNORE INTO `pac_config_key_metadata` (`cfkey`, `description`) values('pacman.auto.fix.common.email.notifications.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','Description PlaceHolder'); + + INSERT IGNORE INTO pac_config_properties (`cfkey`,`value`,`application`,`profile`,`label`,`createdBy`,`createdDate`,`modifiedBy`,`modifiedDate`) VALUES ('logging.config','classpath:spring-logback.xml','application','prd','latest',NULL,NULL,NULL,NULL); @@ -1975,6 +1996,27 @@ INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `pr INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.auto.fix.mail.template.columns.PacMan_RedShiftPublicAccess_version-1_RedShiftPublicAccess_redshift','Resource Id,Account Id,Region,Attached Sg,Detached Sg','rule','prd','latest',NULL,NULL,NULL,NULL); INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.auto.fix.common.email.notifications.PacMan_RedShiftPublicAccess_version-1_RedShiftPublicAccess_redshift','commonTemplate','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('autofix.whitelist.accounts.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.auto.fix.mail.subject.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','PacBot autofix action - Rds DB with public access restored back','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.auto.warning.mail.subject.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','PacBot autofix - Rds DB detected with public access','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.autofix.rule.violation.message.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','Rds DB (${RESOURCE_ID}) from account (${ACCOUNT_ID}) of region (${REGION}) created by you is open to internet','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.autofix.rule.warning.message.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','The access to this Rds DB will be automatically fixed by PacBot after {days} days if no exception is granted.','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.autofix.rule.post.fix.message.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','PacBot has now automatically revoked the public access of this Rds DB created by you as it was a violation of','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.autofix.waittime.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','48','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.auto.fix.max.email.notifications.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','4','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.auto.fix.mail.template.columns.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','Resource Id,Account Id,Region,Attached Sg,Detached Sg','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.auto.fix.common.email.notifications.PacMan_rdsdb_version-1_RdsDbPublicAccess_rdsdb','commonTemplate','rule','prd','latest',NULL,NULL,NULL,NULL); + +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('autofix.whitelist.accounts.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.autofix.contact.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.autofix.fix.type.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','silent','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.auto.fix.mail.subject.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','PacBot - Unused AWS Security Group Auto Deleted Report which are created by PacBot','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.autofix.fix.notify.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.autofix.rule.post.fix.message.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','PacBot has now automatically deleted the following list of unused security group resources which are created by PacBot','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.auto.fix.mail.template.columns.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','Resource Id,Account Id,Region,Group Name','rule','prd','latest',NULL,NULL,NULL,NULL); +INSERT IGNORE INTO `pac_config_properties` (`cfkey`, `value`, `application`, `profile`, `label`, `createdBy`, `createdDate`, `modifiedBy`, `modifiedDate`) values('pacman.auto.fix.common.email.notifications.PacMan_Unused-Security-group_version-1_UnusedSecurityGroup_sg','commonTemplate','rule','prd','latest',NULL,NULL,NULL,NULL); + + INSERT IGNORE INTO `Recommendation_Mappings`(`checkId`,`type`,`resourceInfo`,`_resourceId`,`monthlySavingsField`) values ('H7IgTzjTYb','volume','Volume ID','volumeid',NULL),('DAvU99Dc4C','volume','Volume ID','volumeid','Monthly Storage Cost'),('Qch7DwouX1','ec2','Instance ID','instanceid','Estimated Monthly Savings'),('1iG5NDGVre','sg','Security Group ID','groupid',NULL),('HCP4007jGY','sg','Security Group ID','groupid',NULL),('BueAdJ7NrP','s3','Bucket Name','name',NULL),('iqdCTZKCUp','classicelb','Load Balancer Name','loadbalancername',NULL),('R365s2Qddf','s3','Bucket Name','name',NULL),('Pfx0RwqBli','s3','Bucket Name','name',NULL),('a2sEc6ILx','classicelb','Load Balancer Name','loadbalancername',NULL),('xdeXZKIUy','classicelb','Load Balancer Name','loadbalancername',NULL),('CLOG40CDO8','asg','Auto Scaling Group Name','autoscalinggroupname',NULL),('7qGXsKIUw','classicelb','Load Balancer Name','loadbalancername',NULL),('hjLMh88uM8','classicelb','Load Balancer Name','loadbalancername','Estimated Monthly Savings'),('DqdJqYeRm5','iamuser','IAM User','username',NULL),('j3DFqYTe29','ec2','Instance ID','instanceid',NULL),('f2iK5R6Dep','rdsdb','DB Instance','dbinstanceidentifier',NULL),('1MoPEMsKx6','reservedinstance','Instance Type','instancetype','Estimated Monthly Savings'),('Ti39halfu8','rdsdb','DB Instance Name','dbinstanceidentifier','Estimated Monthly Savings (On Demand)'),('Wnwm9Il5bG','ec2','Instance ID','instanceid',NULL),('V77iOLlBqz','ec2','Instance ID','instanceid',NULL),('Z4AUBRNSmz','elasticip','IP Address','publicip',NULL),('8CNsSllI5v','asg','Auto Scaling Group Name','autoscalinggroupname',NULL),('N420c450f2','cloudfront','Distribution ID','id',NULL),('TyfdMXG69d','ec2','Instance ID','instanceid',NULL),('tfg86AVHAZ','sg','Group ID','groupid',NULL),('yHAGQJV9K5','ec2','Instance ID','instanceid',NULL),('S45wrEXrLz','vpnconnection','VPN ID','vpnconnectionid',NULL),('PPkZrjsH2q','volume','Volume ID','volumeid',NULL),('opQPADkZvH','rdsdb','DB Instance','dbinstanceidentifier',NULL),('796d6f3D83','s3','Bucket Name','name',NULL),('G31sQ1E9U','redshift','Cluster','clusteridentifier','Estimated Monthly Savings'),('xSqX82fQu','classicelb','Load Balancer Name','loadbalancername',NULL),('ZRxQlPsb6c','ec2','Instance ID','instanceid',NULL),('N430c450f2','cloudfront','Distribution ID','id',NULL),('4g3Nt5M1Th','virtualinterface','Gateway ID','virtualgatewayid',NULL),('0t121N1Ty3','directconnect','Connection ID','connectionid',NULL),('N425c450f2','cloudfront','Distribution ID','id',NULL),('xuy7H1avtl','rdscluster','Cluster','dbclusteridentifier',NULL),('1e93e4c0b5','reservedinstance','Reserved Instance ID','instanceid','Estimated Monthly Savings'),('51fC20e7I2','route53','Hosted Zone ID','hostedZoneId',NULL),('cF171Db240','route53','Hosted Zone ID','hostedZoneId',NULL),('Cb877eB72b','route53','Hosted Zone ID','hostedZoneId',NULL),('b73EEdD790','route53','Hosted Zone ID','hostedZoneId',NULL),('C056F80cR3','route53','Hosted Zone ID','hostedZoneId',NULL),('B913Ef6fb4','route53','Hosted Zone ID','hostedZoneId',NULL); INSERT IGNORE INTO `CloudNotification_mapping`(`NotificationId`,`eventType`,`resourceIdKey`,`resourceIdVal`,`esIndex`,`phdEntityKey`) values ('02BUF','CLOUDTRAIL','_resourceid.keyword','_resourceid','cloudtrl','entityvalue'),('4GIGN','S3','_resourceid.keyword','_resourceid','s3','entityvalue'),('5U846','ELASTICSEARCH','arn.keyword','arn','elasticsearch','entityvalue'),('DI3Q3','SQS','_resourceid.keyword','_resourceid','sqs','entityvalue'),('FZC49','VPN','vpnconnectionid.keyword','vpnconnectionid','vpnconnection','entityvalue'),('G30R7','KMS','_resourceid.keyword','_resourceid','kms','entityvalue'),('G4AIH','RDS','dbinstanceidentifier.keyword','dbinstanceidentifier','rdsdb','entityvalue'),('HL28B','EC2','_resourceid.keyword','_resourceid','ec2','entityvalue'),('KBDY2','DIRECTCONNECT','_resourceid.keyword','_resourceid','directconnect','entityvalue'),('LPB7Z','LAMBDA','_resourceid.keyword','_resourceid','lambda','entityvalue'),('PKI3S','CONFIG','_resourceid.keyword','_resourceid','config','entityvalue'),('S2QIA','REDSHIFT','clusteridentifier.keyword','clusteridentifier','redshift','entityvalue'),('W45AP','IAM','arn.keyword','arn','iamuser','entityvalue'),('X9GYT','VPC','_resourceid.keyword','_resourceid','vpc','entityvalue'),('YCFSX','CLOUDFRONT','_resourceid.keyword','_resourceid','cloudfront','entityvalue'),('YGS02','DYNAMODB','tablearn.keyword','tablearn','dynamodb','entityvalue'),('YGS03','MQ','_resourceid.keyword','_resourceid','mq','entityvalue'),('YGS05','APIGATEWAY','_resourceid.keyword','_resourceid','apigtw','entityvalue'); diff --git a/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/securitygroup/SecurityGroupNotUsedRule.java b/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/securitygroup/SecurityGroupNotUsedRule.java index 8bf5cca57..5602aa388 100644 --- a/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/securitygroup/SecurityGroupNotUsedRule.java +++ b/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/securitygroup/SecurityGroupNotUsedRule.java @@ -36,6 +36,7 @@ import com.tmobile.cloud.constants.PacmanRuleConstants; import com.tmobile.pacman.commons.PacmanSdkConstants; import com.tmobile.pacman.commons.exception.InvalidInputException; +import com.tmobile.pacman.commons.exception.RuleExecutionFailedExeption; import com.tmobile.pacman.commons.rule.Annotation; import com.tmobile.pacman.commons.rule.BaseRule; import com.tmobile.pacman.commons.rule.PacmanRule; @@ -49,9 +50,7 @@ public class SecurityGroupNotUsedRule extends BaseRule { /** * The method will get triggered from Rule Engine with following parameters * - * @param ruleParam - * - * ************* Following are the Rule Parameters*********

+ * @param ruleParam ************* Following are the Rule Parameters*********

* * severity : Enter the value of severity

* @@ -67,8 +66,7 @@ public class SecurityGroupNotUsedRule extends BaseRule { * * threadsafe : if true , rule will be executed on multiple threads

* - * @param resourceAttributes this is a resource in context which needs to be scanned this - * is provided by execution engine + * @param resourceAttributes this is a resource in context which needs to be scanned this is provided by execution engine * */ @@ -81,6 +79,7 @@ public RuleResult execute(final Map ruleParam,Map ruleParam,Map serviceWithSgUrlsList = PacmanUtils.splitStringToAList(serviceWithSgUrls, tagsSplitter); - if (resourceAttributes != null) { + if (!resourceAttributes.isEmpty()) { groupId = StringUtils.trim(resourceAttributes.get(PacmanRuleConstants.GROUP_ID)); - Map map = PacmanUtils.getQueryFromElasticSearch(groupId,serviceWithSgUrlsList,esUrl); + String resource; + try { + resource = PacmanUtils.getQueryFromElasticSearch(groupId,serviceWithSgUrlsList,esUrl,ruleParam); + - if(map.isEmpty()){ + if(StringUtils.isNullOrEmpty(resource)){ annotation = Annotation.buildAnnotation(ruleParam,Annotation.Type.ISSUE); annotation.put(PacmanSdkConstants.DESCRIPTION,"Unused security group found!!"); annotation.put(PacmanRuleConstants.SEVERITY, severity); annotation.put(PacmanRuleConstants.SUBTYPE, Annotation.Type.RECOMMENDATION.toString()); annotation.put(PacmanRuleConstants.CATEGORY, category); + annotation.put(PacmanRuleConstants.GROUP_NAME, groupName); - issue.put(PacmanRuleConstants.VIOLATION_REASON, "Security group not associated to any of EC2/ApplicationElb/ClassicElb/RDS "); + issue.put(PacmanRuleConstants.VIOLATION_REASON, "Security group not associated to any of EC2/ApplicationElb/ClassicElb/RDSDB/RDSCluster/RedShift/Lambda/Elasticsearch"); issueList.add(issue); annotation.put("issueDetails",issueList.toString()); logger.debug("========SecurityGroupNotUsedRule ended with an annotation : {}=========",annotation); return new RuleResult(PacmanSdkConstants.STATUS_FAILURE,PacmanRuleConstants.FAILURE_MESSAGE,annotation); } + } catch (Exception e) { + logger.error("unable to determine",e); + throw new RuleExecutionFailedExeption("unable to determine"+e); + } } logger.debug("========SecurityGroupNotUsedRule ended========="); diff --git a/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/utils/PacmanUtils.java b/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/utils/PacmanUtils.java index 07e095266..2d137fa22 100644 --- a/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/utils/PacmanUtils.java +++ b/jobs/pacman-awsrules/src/main/java/com/tmobile/cloud/awsrules/utils/PacmanUtils.java @@ -2730,5 +2730,128 @@ private static Set returnFieldValueAsSet(JsonArray jsonArray,String fiel } return fieldValueList; } + + /** + * Gets the query from elastic search. + * + * @param securityGroupId the security group id + * @param serviceWithSgEsUrl the service with sg es url + * @param esUrlParam the es url param + * @param ruleParams the rule params + * @return the query from elastic search + * @throws Exception the exception + */ + public static String getQueryFromElasticSearch(String securityGroupId, + List serviceWithSgEsUrl, String esUrlParam,Map ruleParams) throws Exception { + String securityGroupAttribute = null; + String servicesWithSgurl = null; + String returnedValue = null; + String latest = ""; + for (String esUrl : serviceWithSgEsUrl) { + servicesWithSgurl = esUrlParam + esUrl; + if (esUrl.contains("ec2") || esUrl.contains("lambda") || esUrl.contains("appelb") + || esUrl.contains("classicelb") || esUrl.contains("elasticsearch")) { + securityGroupAttribute = PacmanRuleConstants.EC2_WITH_SECURITYGROUP_ID; + if(esUrl.contains("elasticsearch")){ + latest = "true"; + } + } else { + securityGroupAttribute = PacmanRuleConstants.SECURITYGROUP_ID_ATTRIBUTE; + } + Map> matchPhrase = new HashMap<>(); + + List ids = new ArrayList<>(); + ids.add(securityGroupId); + matchPhrase.put(securityGroupAttribute, ids); + returnedValue = getValueFromElasticSearch(ruleParams.get("accountid"),"", servicesWithSgurl, securityGroupAttribute, ruleParams.get("region"), securityGroupAttribute, latest,matchPhrase); + if (!StringUtils.isEmpty(returnedValue)) { + List listSecurityGroupID = new ArrayList<>(); + getSecurityGrouplist(returnedValue, ":;", listSecurityGroupID); + for(GroupIdentifier sgId:listSecurityGroupID){ + if(sgId.getGroupId().equals(securityGroupId)){ + return securityGroupId; + } + } + + } + + } + return returnedValue; + } + + /** + * get value from elastic search. + * + * @param accountId the account id + * @param id the id + * @param esUrl the es url + * @param attributeName the attribute name + * @param region the region + * @param fieldKey the field key + * @param latest the latest + * @param matchPhrase the match phrase + * @return String, if successful + * @throws Exception the exception + */ + public static String getValueFromElasticSearch(String accountId,String id, String esUrl, String attributeName, String region,String fieldKey,String latest,Map> matchPhrase) + throws Exception { + JsonParser jsonParser = new JsonParser(); + + Map mustFilter = new HashMap<>(); + Map mustNotFilter = new HashMap<>(); + HashMultimap shouldFilter = HashMultimap.create(); + Map mustTermsFilter = new HashMap<>(); + + if (!StringUtils.isEmpty(id)) { + mustFilter.put(convertAttributetoKeyword(attributeName), id); + } + + if(!StringUtils.isEmpty(region)){ + mustFilter.put(convertAttributetoKeyword(PacmanRuleConstants.REGION), region); + } + + if(!StringUtils.isEmpty(latest)){ + mustFilter.put(PacmanRuleConstants.LATEST, "true"); + } + + if(!StringUtils.isEmpty(accountId)){ + mustFilter.put(convertAttributetoKeyword(PacmanRuleConstants.ACCOUNTID), accountId); + } + + JsonObject resultJson = RulesElasticSearchRepositoryUtil.getQueryDetailsFromES(esUrl, mustFilter, + mustNotFilter, shouldFilter, null, 0, mustTermsFilter, null,matchPhrase); + if (resultJson != null && resultJson.has(PacmanRuleConstants.HITS)) { + String hitsJsonString = resultJson.get(PacmanRuleConstants.HITS).toString(); + JsonObject hitsJson = (JsonObject) jsonParser.parse(hitsJsonString); + JsonArray jsonArray = hitsJson.getAsJsonObject().get(PacmanRuleConstants.HITS).getAsJsonArray(); + return returnFieldValue(jsonArray,fieldKey); + + } + return null; + } + + /** + * Checks if is field exists. + * + * @param jsonArray the json array + * @param fieldKey the field key + * @return String, if is instance exists + */ + private static String returnFieldValue(JsonArray jsonArray,String fieldKey) { + if (jsonArray.size() > 0) { + for (int i = 0; i < jsonArray.size(); i++) { + JsonObject firstObject = (JsonObject) jsonArray.get(i); + JsonObject sourceJson = (JsonObject) firstObject.get(PacmanRuleConstants.SOURCE); + if (sourceJson != null + && (sourceJson.get(fieldKey) != null && !sourceJson.get(fieldKey).isJsonNull())) { + String fieldValue = sourceJson.get(fieldKey).getAsString(); + if (!org.apache.commons.lang.StringUtils.isEmpty(fieldValue)) { + return fieldValue; + } + } + } + } + return null; + } } diff --git a/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/securitygroup/SecurityGroupNotUsedRuleTest.java b/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/securitygroup/SecurityGroupNotUsedRuleTest.java index 45fd0436c..ae09709bd 100644 --- a/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/securitygroup/SecurityGroupNotUsedRuleTest.java +++ b/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/securitygroup/SecurityGroupNotUsedRuleTest.java @@ -48,9 +48,9 @@ public void executeTest() throws Exception { true); when(PacmanUtils.splitStringToAList(anyString(),anyString())).thenReturn(CommonTestUtils.getListString()); when(PacmanUtils.getPacmanHost(anyString())).thenReturn("host"); - when(PacmanUtils.getQueryFromElasticSearch(anyString(),anyObject(),anyString())).thenReturn(CommonTestUtils.getEmptyMapBoolean("r_123 ")); + when(PacmanUtils.getQueryFromElasticSearch(anyString(),anyObject(),anyString(),anyObject())).thenReturn(""); assertThat(securityGroupNotUsedRule.execute(CommonTestUtils.getMapString("r_123 "),CommonTestUtils.getMapString("r_123 ")), is(notNullValue())); - when(PacmanUtils.getQueryFromElasticSearch(anyString(),anyObject(),anyString())).thenReturn(CommonTestUtils.getMapBoolean("r_123 ")); + when(PacmanUtils.getQueryFromElasticSearch(anyString(),anyObject(),anyString(),anyObject())).thenReturn("123"); assertThat(securityGroupNotUsedRule.execute(CommonTestUtils.getMapString("r_123 "),CommonTestUtils.getMapString("r_123 ")), is(notNullValue())); diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/autofix/publicaccess/PublicAccessAutoFix.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/autofix/publicaccess/PublicAccessAutoFix.java index e439ff95a..02081e168 100644 --- a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/autofix/publicaccess/PublicAccessAutoFix.java +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/autofix/publicaccess/PublicAccessAutoFix.java @@ -516,4 +516,61 @@ public static boolean applySecurityGroupsToRedshift(AmazonRedshift amazonRedshif } return applysgFlg; } + + /** + * Gets the DB instance for rds db resource. + * + * @param clientMap the client map + * @param resourceId the resource id + * @return the DB instance for rds db resource + * @throws Exception the exception + */ + public static List getDBInstanceForRdsDbResource(Map clientMap,String resourceId) throws Exception { + AmazonRDS amazonRDS = (AmazonRDS) clientMap.get("client"); + DescribeDBInstancesRequest instancesRequest = new DescribeDBInstancesRequest(); + instancesRequest.setDBInstanceIdentifier(resourceId); + DescribeDBInstancesResult dbInstancesResult = amazonRDS.describeDBInstances(instancesRequest); + + return dbInstancesResult.getDBInstances(); + + } + + /** + * Apply security groups to rds db. + * + * @param amazonRDS the amazon RDS + * @param sgIdToBeAttached the sg id to be attached + * @param resourceId the resource id + * @return true, if successful + * @throws Exception the exception + */ + public static boolean applySecurityGroupsToRdsDb(AmazonRDS amazonRDS, Set sgIdToBeAttached, String resourceId) throws Exception { + boolean applysgFlg = false; + try { + ModifyDBInstanceRequest instanceRequest = new ModifyDBInstanceRequest(); + instanceRequest.setDBInstanceIdentifier(resourceId); + instanceRequest.setVpcSecurityGroupIds(sgIdToBeAttached); + amazonRDS.modifyDBInstance(instanceRequest); + applysgFlg = true; + } catch (Exception e) { + logger.error("Apply Security Group operation failed for rdsdb {}" , resourceId ); + throw new Exception(e); + } + return applysgFlg; + } + + /** + * Delete security group. + * + * @param resourceId the resource id + * @param ec2Client the ec 2 client + * @return the boolean + * @throws Exception the exception + */ + public static Boolean deleteSecurityGroup(String resourceId,AmazonEC2 ec2Client) throws Exception { + DeleteSecurityGroupRequest deleteSecurityGroupRequest = new DeleteSecurityGroupRequest(); + deleteSecurityGroupRequest.setGroupId(resourceId); + ec2Client.deleteSecurityGroup(deleteSecurityGroupRequest); + return true; + } } diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/autofix/rds/RdsDbPublicAccessAutoFix.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/autofix/rds/RdsDbPublicAccessAutoFix.java new file mode 100644 index 000000000..11db48dac --- /dev/null +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/autofix/rds/RdsDbPublicAccessAutoFix.java @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +/** + Copyright (C) 2018 T Mobile Inc - All Rights Reserve + Purpose: Application ELB's publicly accessible AWS resources + Author :Santhoshi,Kanchana + Modified Date: Nov 06, 2018 + **/ +package com.tmobile.pacman.autofix.rds; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.amazonaws.services.ec2.AmazonEC2; +import com.amazonaws.services.ec2.model.IpPermission; +import com.amazonaws.services.ec2.model.SecurityGroup; +import com.amazonaws.services.rds.AmazonRDS; +import com.amazonaws.services.rds.model.DBInstance; +import com.amazonaws.services.rds.model.VpcSecurityGroupMembership; +import com.tmobile.pacman.autofix.publicaccess.PublicAccessAutoFix; +import com.tmobile.pacman.common.PacmanSdkConstants; +import com.tmobile.pacman.common.exception.AutoFixException; +import com.tmobile.pacman.commons.autofix.BaseFix; +import com.tmobile.pacman.commons.autofix.FixResult; +import com.tmobile.pacman.commons.autofix.PacmanFix; +import com.tmobile.pacman.dto.AutoFixTransaction; +import com.tmobile.pacman.util.CommonUtils; + +@PacmanFix(key = "publicly-accessible-rdsdb", desc = "Rdsdb's applies security group without public access") +public class RdsDbPublicAccessAutoFix extends BaseFix { + /** The Constant LOGGER. */ + private static final Logger LOGGER = LoggerFactory.getLogger(RdsDbPublicAccessAutoFix.class); + + private static final String EXISTING_GROUPS = "existingRdsDbGroups"; + private static String ATTACHED_SG = null; + private static String DETACHED_SG = null; + + @Override + public FixResult executeFix(Map issue, Map clientMap, Map ruleParams) { + String resourceId = issue.get("resourceDisplayId"); + String defaultCidrIp = ruleParams.get("defaultCidrIp"); + Map ec2ClinetMap = null; + List securityGroupsDetails = null; + AmazonEC2 ec2Client = null; + Collection ipPermissionsToBeAdded; + Set securityGroupsSet = new HashSet<>(); + Set alreadyCheckedSgSet = new HashSet<>(); + try { + ec2ClinetMap = PublicAccessAutoFix.getAWSClient("ec2", issue, CommonUtils.getPropValue(PacmanSdkConstants.AUTO_FIX_ROLE_NAME)); + + Set securityGroupsTobeApplied = new HashSet<>(); + AmazonRDS amazonRDS = (AmazonRDS) clientMap.get("client"); + + List instances = PublicAccessAutoFix.getDBInstanceForRdsDbResource(clientMap, resourceId); + if(instances.get(0).getPubliclyAccessible()){ + Integer port = instances.get(0).getEndpoint().getPort(); + List originalSgMembers = instances.get(0).getVpcSecurityGroups(); + + for(VpcSecurityGroupMembership sgm : originalSgMembers){ + if("active".equals(sgm.getStatus())){ + securityGroupsSet.add(sgm.getVpcSecurityGroupId()); + } + } + + if (ec2ClinetMap != null) { + ec2Client = (AmazonEC2) ec2ClinetMap.get("client"); + securityGroupsDetails = PublicAccessAutoFix.getExistingSecurityGroupDetails(securityGroupsSet,ec2Client); + } + + String vpcid; + String securityGroupId = null; + Set publiclyAccessible = new HashSet<>(); + boolean isSgApplied = false; + + for (SecurityGroup securityGroup : securityGroupsDetails) { + ipPermissionsToBeAdded = new ArrayList<>(); + publiclyAccessible = new HashSet<>(); + vpcid = securityGroup.getVpcId(); + securityGroupId = securityGroup.getGroupId(); + PublicAccessAutoFix.nestedSecurityGroupDetails(securityGroupId, ipPermissionsToBeAdded, ec2Client, publiclyAccessible,alreadyCheckedSgSet,port); + + if (!publiclyAccessible.isEmpty()) { + // copy the security group and remove in bound rules + String createdSgId = PublicAccessAutoFix.createSecurityGroup(securityGroupId, vpcid,ec2Client, ipPermissionsToBeAdded,resourceId,defaultCidrIp,securityGroup.getIpPermissions()); + if(!StringUtils.isEmpty(createdSgId)){ + securityGroupsTobeApplied.add(createdSgId); + } + } else { + securityGroupsTobeApplied.add(securityGroupId); + } + } + if (!securityGroupsTobeApplied.isEmpty()) { + + isSgApplied = PublicAccessAutoFix.applySecurityGroupsToRdsDb(amazonRDS,securityGroupsTobeApplied, resourceId); + ATTACHED_SG = securityGroupsTobeApplied.toString(); + } + + if (isSgApplied) { + LOGGER.info("{} sg's successfully applied for the resource {}",securityGroupsTobeApplied, resourceId); + } + } + } + + catch (Exception e) { + LOGGER.error("error in rds db autofix {}",e); + throw new RuntimeException("Auto fix failed"); + } + return new FixResult(PacmanSdkConstants.STATUS_SUCCESS_CODE, "the rds db "+resourceId+" is now fixed"); + } + + /* + * (non-Javadoc) + * + * @see + * com.tmobile.pacman.commons.autofix.BaseFix#backupExistingConfigForResource + * (java.lang.String, java.lang.String, java.util.Map, java.util.Map, + * java.util.Map) + */ + @Override + public boolean backupExistingConfigForResource(final String resourceId, final String resourceType, Map clientMap, Map ruleParams, Map issue) throws AutoFixException { + StringBuilder oldConfig = new StringBuilder(); + List instance; + try { + instance = PublicAccessAutoFix.getDBInstanceForRdsDbResource(clientMap,resourceId); + + List originalSgMembers = instance.get(0).getVpcSecurityGroups(); + + for(VpcSecurityGroupMembership sgm : originalSgMembers){ + if("active".equals(sgm.getStatus())){ + + if (oldConfig.length() > 0) { + oldConfig.append(",").append(sgm.getVpcSecurityGroupId()); + } else { + oldConfig.append(sgm.getVpcSecurityGroupId()); + } + + } + } + } catch (Exception e) { + LOGGER.error("back up failed {}", e); + throw new AutoFixException("backup failed"); + } + DETACHED_SG = oldConfig.toString(); + backupOldConfig(resourceId, EXISTING_GROUPS, oldConfig.toString()); + LOGGER.debug("backup complete for {}" , resourceId); + return true; + } + + /* + * (non-Javadoc) + * + * @see + * com.tmobile.pacman.commons.autofix.BaseFix#isFixCandidate(java.lang.String + * , java.lang.String, java.util.Map, java.util.Map, java.util.Map) + */ + @Override + public boolean isFixCandidate(String resourceId, String resourceType, Map clientMap, Map ruleParams, Map issue) throws AutoFixException { + + Map ec2ClinetMap = null; + List securityGroupsDetails = null; + AmazonEC2 ec2Client = null; + Collection ipPermissionsToBeAdded; + Set securityGroupsSet = new HashSet<>(); + Set alreadyCheckedSgSet = new HashSet<>(); + Boolean hasPublicAccess= false; + try { + ec2ClinetMap = PublicAccessAutoFix.getAWSClient("ec2", issue, CommonUtils.getPropValue(PacmanSdkConstants.AUTO_FIX_ROLE_NAME)); + + List instances = PublicAccessAutoFix.getDBInstanceForRdsDbResource(clientMap, resourceId); + if(instances.get(0).getPubliclyAccessible()){ + Integer port = instances.get(0).getEndpoint().getPort(); + List originalSgMembers = instances.get(0).getVpcSecurityGroups(); + + for(VpcSecurityGroupMembership sgm : originalSgMembers){ + if("active".equals(sgm.getStatus())){ + securityGroupsSet.add(sgm.getVpcSecurityGroupId()); + } + } + + if (ec2ClinetMap != null) { + ec2Client = (AmazonEC2) ec2ClinetMap.get("client"); + securityGroupsDetails = PublicAccessAutoFix.getExistingSecurityGroupDetails(securityGroupsSet,ec2Client); + } + + String securityGroupId = null; + Set publiclyAccessible = new HashSet<>(); + + for (SecurityGroup securityGroup : securityGroupsDetails) { + ipPermissionsToBeAdded = new ArrayList<>(); + publiclyAccessible = new HashSet<>(); + securityGroupId = securityGroup.getGroupId(); + PublicAccessAutoFix.nestedSecurityGroupDetails(securityGroupId, ipPermissionsToBeAdded, ec2Client, publiclyAccessible,alreadyCheckedSgSet,port); + + if (!publiclyAccessible.isEmpty()) { + hasPublicAccess = true; + } + } + + } + } + + catch (Exception e) { + LOGGER.error("error in autofix {}",e); + throw new RuntimeException("Auto fix failed"); + } + return hasPublicAccess; + + } + + /* + * (non-Javadoc) + * + * @see + * com.tmobile.pacman.commons.autofix.BaseFix#addDetailsToTransactionLog() + */ + @Override + public AutoFixTransaction addDetailsToTransactionLog(Map annotation) { + LinkedHashMap transactionParams = new LinkedHashMap(); + if (!StringUtils.isEmpty(annotation.get("_resourceid"))) { + transactionParams.put("resourceId", annotation.get("_resourceid")); + } else { + transactionParams.put("resourceId", "No Data"); + } + if (!StringUtils.isEmpty(annotation.get("accountid"))) { + transactionParams.put("accountId", annotation.get("accountid")); + } else { + transactionParams.put("accountId", "No Data"); + } + if (!StringUtils.isEmpty(annotation.get("region"))) { + transactionParams.put("region", annotation.get("region")); + } else { + transactionParams.put("region", "No Data"); + } + if (!StringUtils.isEmpty(ATTACHED_SG)) { + transactionParams.put("attachedSg", ATTACHED_SG); + }else{ + transactionParams.put("attachedSg", "No Data"); + } + if (!StringUtils.isEmpty(DETACHED_SG)) { + transactionParams.put("detachedSg", DETACHED_SG); + } else { + transactionParams.put("detachedSg", "No Data"); + } + ATTACHED_SG = null; + DETACHED_SG = null; + return new AutoFixTransaction(null,transactionParams); + } + +} \ No newline at end of file diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/autofix/sg/UnusedSgAutoFix.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/autofix/sg/UnusedSgAutoFix.java new file mode 100644 index 000000000..c2b6f3676 --- /dev/null +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/autofix/sg/UnusedSgAutoFix.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright 2018 T Mobile, 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. + ******************************************************************************/ +/** + Copyright (C) 2018 T Mobile Inc - All Rights Reserve + Purpose: Application ELB's publicly accessible AWS resources + Author :Santhoshi,Kanchana + Modified Date: Oct 22, 2018 + **/ +package com.tmobile.pacman.autofix.sg; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.amazonaws.services.ec2.AmazonEC2; +import com.amazonaws.util.StringUtils; +import com.tmobile.pacman.autofix.publicaccess.PublicAccessAutoFix; +import com.tmobile.pacman.common.PacmanSdkConstants; +import com.tmobile.pacman.common.exception.AutoFixException; +import com.tmobile.pacman.commons.autofix.BaseFix; +import com.tmobile.pacman.commons.autofix.FixResult; +import com.tmobile.pacman.commons.autofix.PacmanFix; +import com.tmobile.pacman.dto.AutoFixTransaction; +import com.tmobile.pacman.util.CommonUtils; + +@PacmanFix(key = "unused-sg-auto-fix", desc = "Unused Security Group will be removed") +public class UnusedSgAutoFix extends BaseFix { + /** The Constant LOGGER. */ + private static final Logger LOGGER = LoggerFactory.getLogger(UnusedSgAutoFix.class); + + + @Override + public FixResult executeFix(Map issue, Map clientMap, Map ruleParams) { + String resourceId = issue.get("_resourceid"); + Map ec2ClinetMap = null; + + AmazonEC2 ec2Client = null; + try { + + ec2ClinetMap = PublicAccessAutoFix.getAWSClient("ec2",issue,CommonUtils.getPropValue(PacmanSdkConstants.AUTO_FIX_ROLE_NAME)); + if (ec2ClinetMap != null) { + ec2Client = (AmazonEC2) ec2ClinetMap.get("client"); + if(PublicAccessAutoFix.deleteSecurityGroup(resourceId, ec2Client)){ + LOGGER.info("{} unused sg successfully deleted", resourceId); + } + } + } + + catch (Exception e) { + LOGGER.error("error in unused ag autofix {}",e); + throw new RuntimeException(e.getMessage()); + } + return new FixResult(PacmanSdkConstants.STATUS_SUCCESS_CODE, "the unused sg "+resourceId+" is now deleted"); + + } + + + /* * (non-Javadoc) + * + * @see + * com.tmobile.pacman.commons.autofix.BaseFix#backupExistingConfigForResource + * (java.lang.String, java.lang.String, java.util.Map, java.util.Map, + * java.util.Map)*/ + + @Override + public boolean backupExistingConfigForResource(final String resourceId, final String resourceType, Map clientMap, Map ruleParams, Map issue)throws AutoFixException { + return true; + } + + + /* * (non-Javadoc) + * + * @see + * com.tmobile.pacman.commons.autofix.BaseFix#isFixCandidate(java.lang.String + * , java.lang.String, java.util.Map, java.util.Map, java.util.Map)*/ + + @Override + public boolean isFixCandidate(String resourceId, String resourceType, Map clientMap, Map ruleParams, Map issue) throws AutoFixException { + String groupName = issue.get("groupname"); + return !StringUtils.isNullOrEmpty(groupName) && groupName.startsWith(PacmanSdkConstants.PACBOT_CREATED_SG_DESC); + } + + + /** (non-Javadoc) + * + * @see + * com.tmobile.pacman.commons.autofix.BaseFix#addDetailsToTransactionLog()*/ + + @Override + public AutoFixTransaction addDetailsToTransactionLog(Map annotation) { + LinkedHashMap transactionParams = new LinkedHashMap(); + if (!StringUtils.isNullOrEmpty(annotation.get("_resourceid"))) { + transactionParams.put("resourceId", annotation.get("_resourceid")); + } else { + transactionParams.put("resourceId", "No Data"); + } + if (!StringUtils.isNullOrEmpty(annotation.get("accountid"))) { + transactionParams.put("accountId", annotation.get("accountid")); + } else { + transactionParams.put("accountId", "No Data"); + } + if (!StringUtils.isNullOrEmpty(annotation.get("region"))) { + transactionParams.put("region", annotation.get("region")); + } else { + transactionParams.put("region", "No Data"); + } + if (!StringUtils.isNullOrEmpty(annotation.get("groupname"))) { + transactionParams.put("groupName", annotation.get("groupname")); + }else{ + transactionParams.put("groupName", "No Data"); + } + return new AutoFixTransaction(null,transactionParams); + } +} diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/common/PacmanSdkConstants.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/common/PacmanSdkConstants.java index 5c4f9ddce..8d2248733 100644 --- a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/common/PacmanSdkConstants.java +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/common/PacmanSdkConstants.java @@ -605,5 +605,8 @@ public interface PacmanSdkConstants extends com.tmobile.pacman.commons.PacmanSdk /** The pac monitor slack user. */ String PAC_MONITOR_SLACK_USER = "pacman.monitoring.slack.user"; + + /** *. */ + String PACBOT_CREATED_SG_DESC = "PacBot created SG During Autofix"; } diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/AutoFixManager.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/AutoFixManager.java index 0b44b76b7..3a97f461a 100644 --- a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/AutoFixManager.java +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/AutoFixManager.java @@ -184,7 +184,7 @@ public Map performAutoFixs(Map ruleParam, try { existingIssues = getOpenAndExcepmtedAnnotationForRule(ruleParam); } catch (Exception e) { - logger.error("unable to get open issue for rule" + ruleId); + logger.error("unable to get open issue for rule {} {}",ruleId,e); autoFixStats.put("auto-fix-error", "unable to get open issue for rule" + ruleId + "-- >" + e.getMessage()); return autoFixStats; } @@ -222,19 +222,19 @@ public Map performAutoFixs(Map ruleParam, logger.info("Account id is blacklisted {}" , annotation.get(PacmanSdkConstants.ACCOUNT_ID)); continue; } - logger.debug(String.format("processing for %s " , resourceId)); + logger.debug("processing for{} " , resourceId); if ((!isResourceTypeExemptedFromCutOfDateCriteria(targetType) && resourceCreatedBeforeCutoffData(resourceId, targetType)) || !isresourceIdMatchesCriteria(resourceId) ||!isAFixCandidate(isFixCandidateMethod,fixObject, resourceId, targetType, clientMap, ruleParam,annotation)) { - logger.debug(String.format("exempted by various conditions --> %s " , resourceId)); + logger.debug("exempted by various conditions -->{} " , resourceId); continue; } - logger.debug(String.format("not exempted by conditions --> %s " , resourceId)); + logger.debug("not exempted by conditions --> {} " , resourceId); try{ autoFixPlan = autoFixPlanManager.getAutoFixPalnForResource(resourceId, ruleParam); // find plan associates with resource and issue }catch (Exception e) { - logger.debug("no plan found for resource {}",resourceId); + logger.error("no plan found for resource {} {}",e,resourceId); } if(null!=autoFixPlan){ logger.debug("got autofix plan with id" + autoFixPlan.getPlanId()); @@ -266,7 +266,7 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) try{ if(autoFixPlan!=null && !Status.SUSPENDED.equals(autoFixPlan.getPlanStatus())) // suspend if not already suspended autoFixPlanManager.suspendPlan(autoFixPlan,ruleParam); - logger.debug(String.format("auto fix plan suspended for plan # --> %s",autoFixPlan.getPlanId())); + logger.debug("auto fix plan suspended for plan # --> {}",autoFixPlan.getPlanId()); autoFixTrans.add(new AutoFixTransaction(AutoFixAction.SUSPEND_AUTO_FIX_PLAN, resourceId,ruleId, executionId, transactionId, "auto fix plan suspended with id" + autoFixPlan.getPlanId(),type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION),parentDocId)); }catch(Exception e) { @@ -282,7 +282,7 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) // the violation emails and exempted afterwards if (!nextStepManager.isSilentFixEnabledForRule(ruleId) && !MailUtils.sendAutoFixNotification(ruleParam, resourceOwner, targetType, resourceId, exceptionExpiryDate, AutoFixAction.AUTOFIX_ACTION_EXEMPTED,addDetailsToLogTrans,annotation)) { - logger.error(String.format("unable to send email to %s" ,resourceOwner.toString())); + logger.error("unable to send email to {}" ,resourceOwner); } } // should be removed for deployment @@ -311,7 +311,7 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) logger.error(String.format("unable to create autofix plan for %s,%s,%s,%s,%s",ruleId, annotation.get(PacmanSdkConstants.ANNOTATION_PK), resourceId, annotation.get(PacmanSdkConstants.DOC_ID), targetType),e); } - logger.debug(String.format("found the resource Owner %s" , resourceOwner.toString())); + logger.debug("found the resource Owner {}" , resourceOwner); if (Strings.isNullOrEmpty(resourceOwner.getEmailId()) && !Strings.isNullOrEmpty(resourceOwner.getName()) && resourceOwner.getName().contains("@")) { // case @@ -335,7 +335,7 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) .setEmailId(CommonUtils.getPropValue(PacmanSdkConstants.ORPHAN_RESOURCE_OWNER_EMAIL)); } } catch (Exception e) { - logger.error(String.format("unable to find the resource owner for %s " , resourceId)); + logger.error("unable to find the resource owner for {} and {} " , resourceId,e); resourceOwner = new ResourceOwner("CSO", CommonUtils.getPropValue(PacmanSdkConstants.ORPHAN_RESOURCE_OWNER_EMAIL)); resourceOwnerNotFoundCounter++; @@ -364,7 +364,7 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) continue; // notification was not sent, skip further // execution } - logger.debug(String.format("email sent to %s" , resourceOwner.toString())); + logger.debug("email sent to {}" , resourceOwner); autoFixTrans.add(new AutoFixTransaction(AutoFixAction.AUTOFIX_ACTION_EMAIL, resourceId,ruleId, executionId, transactionId, "email sent to " + resourceOwner.getEmailId(),type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION),parentDocId)); notificationSentCounter++; @@ -377,10 +377,10 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) transactionId, "auto fix plan synchronized with id" + autoFixPlan.getPlanId(),type,annotation.get("targetType"),annotationId,annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION),parentDocId)); } }catch(Exception e){ - logger.error(String.format("unable to syn plan for %s" , resourceId),e); + logger.error("unable to syn plan for {} and {}" , resourceId,e); } } catch (Exception e) { - logger.error(String.format("unable to post email action for %s ", resourceId)); + logger.error("unable to post email action for {} and {}", resourceId,e); } fixResults.add(new FixResult(PacmanSdkConstants.STATUS_SUCCESS_CODE, String.format("email sent to owner of resource %s" , resourceId))); @@ -391,8 +391,7 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) try { backupMethod.invoke(fixObject, resourceId, targetType, clientMap, ruleParam,annotation); } catch (Exception e) { - logger.error(String.format( - "unable to backup the configuration for %s and %s" , targetType ,resourceId)); + logger.error("unable to backup the configuration for {} and {} and {}" , targetType ,resourceId,e); continue; } autoFixTrans.add(new AutoFixTransaction(AutoFixAction.AUTOFIX_ACTION_BACKUP, resourceId,ruleId, @@ -420,14 +419,14 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) }catch(Exception e){ logger.error(String.format("unable to syn plan for %s" , resourceId),e); } - logger.debug(String.format("autofixed the resource %s and email sent to %s and plan synchronized", - resourceId, resourceOwner.toString())); + logger.debug("autofixed the resource {} and email sent to {} and plan synchronized", + resourceId, resourceOwner); } // if(annotation.get("policyId").equalsIgnoreCase("PacMan_ApplicationTagsShouldBeValid_version-1")){ // silentautoFixTrans.add(new AutoFixTransaction(resourceId, ruleId,annotation.get("accountid") , annotation.get("region"),annotation.get("correct_application_tag"))); // } else{ - logger.error(String.format("unable to send email to %s " , resourceOwner.toString())); + logger.error("unable to send email to {}" , resourceOwner); } if(nextStepManager.isSilentFixEnabledForRule(ruleId) && null!=addDetailsToTransactionLogMethod){ @@ -445,7 +444,7 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) if (!MailUtils.sendAutoFixNotification(ruleParam, resourceOwner, targetType, resourceId, "", AutoFixAction.AUTOFIX_ACTION_EMAIL_REMIND_EXCEPTION_EXPIRY,addDetailsToLogTrans,annotation)) { - logger.error(String.format("unable to send email to %s" , resourceOwner.toString())); + logger.error("unable to send email to {}" , resourceOwner); } } } @@ -461,7 +460,7 @@ && resourceCreatedBeforeCutoffData(resourceId, targetType)) } // publish the transactions here // if any transaction exists post it - if (autoFixTrans != null && autoFixTrans.size() > 0) { + if (autoFixTrans != null && !autoFixTrans.isEmpty()) { ElasticSearchDataPublisher dataPublisher = new ElasticSearchDataPublisher(); dataPublisher.publishAutoFixTransactions(autoFixTrans,ruleParam); dataPublisher.close(); @@ -542,7 +541,7 @@ private boolean isAFixCandidate(Method isFixCandidateMethod, Object fixObject, S Map clientMap, Map ruleParam, Map annotation) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { try{ Boolean isFixCandidate = null==isFixCandidateMethod?true:(Boolean)isFixCandidateMethod.invoke(fixObject, resourceId, targetType, clientMap, ruleParam,annotation); - logger.debug("is fix candidate ==> " + isFixCandidate); + logger.debug("is fix candidate ==> {} ",isFixCandidate); return isFixCandidate; }catch(Exception e){ @@ -565,6 +564,7 @@ private boolean isResourceTypeExemptedFromCutOfDateCriteria(String targetType) { .asList(CommonUtils.getPropValue(PacmanSdkConstants.AUTOFIX_EXEMPTED_TYPES_KEY).split("\\s*,\\s*")); return exemptedtypes.contains(targetType); } catch (Exception e) { + logger.error("error in isResourceTypeExemptedFromCutOfDateCriteria {}",e); return false; } } @@ -615,7 +615,7 @@ private boolean isresourceIdMatchesCriteria(String resourceId) { try { p = Pattern.compile(CommonUtils.getPropValue(PacmanSdkConstants.FIX_ONLY_MATCHING_RESOURCE_PATTERN)); } catch (Exception e) { - logger.info("no resource filter pattern defined"); + logger.info("no resource filter pattern defined {}",e); return true; } Matcher m = p.matcher(resourceId.toLowerCase()); @@ -648,9 +648,8 @@ private Map getAWSClient(String targetType, Map : annotation.get(PacmanSdkConstants.REGION)), ruleIdentifyingString); } catch (UnableToCreateClientException e1) { - String msg = String.format("unable to create client for account %s and region %s" , annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION)); - logger.error(msg); - throw new Exception(msg); + logger.error("unable to create client for account {} and region {} and {}" , annotation.get(PacmanSdkConstants.ACCOUNT_ID),annotation.get(PacmanSdkConstants.REGION),e1); + throw new Exception("unable to create client for account and region"); } return clientMap; } @@ -674,6 +673,7 @@ private boolean resourceCreatedBeforeCutoffData(final String resourceid, String // get the creation date // for now returning true to indicate resource was created befroe // cutoff + logger.error("error {}" , e); return true; } } @@ -705,7 +705,7 @@ private Date getResourceCreatedDate(final String resourceId, String resourceType } throw new Exception("unable to find resource creation date"); } catch (Exception exception) { - logger.error(String.format("Cannot find resource creation data " + " response from service--> %s" , response), exception); + logger.error("Cannot find resource creation data {} response from service--> {}" , response, exception); throw exception; } } @@ -744,7 +744,7 @@ private boolean isAccountBlackListedForAutoFix(String account, String ruleId) { List blacklist = Arrays.asList(blacklistStr.split("\\s*,\\s*")); return blacklist.contains(account); } catch (Exception e) { - logger.error(String.format("%s account is assumed blacklisted for autofix for ruleId %s" ,account, ruleId)); + logger.error("account is assumed blacklisted for autofix for ruleId {} and {} and {}" ,account, ruleId,e); return Boolean.TRUE; // be defensive , if not able to figure out , assume blacklist } } @@ -774,13 +774,12 @@ private List> getOpenAndExcepmtedAnnotationForRule(Map fields = new ArrayList(); + List fields = new ArrayList<>(); Long totalDocs = ESUtils.getTotalDocumentCountForIndexAndType(esUrl, indexName, null, mustFilter, null, shouldFilter); // get all the issues for this ruleId - List> existingIssues = ESUtils.getDataFromES(esUrl, indexName.toLowerCase(), null, + return ESUtils.getDataFromES(esUrl, indexName.toLowerCase(), null, mustFilter, null, shouldFilter, fields, 0, totalDocs); - return existingIssues; } /** diff --git a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/ResourceTaggingManager.java b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/ResourceTaggingManager.java index 4bf888387..edad5aae4 100644 --- a/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/ResourceTaggingManager.java +++ b/jobs/pacman-rule-engine-2.0/src/main/java/com/tmobile/pacman/commons/autofix/manager/ResourceTaggingManager.java @@ -342,6 +342,10 @@ public String getPacmanTagValue(String resourceId, Map clientMap case REDSHIFT: { return ""; } + + case RDS: { + return ""; + } default: throw new OperationNotPermittedException("this resource tagging is not imlemented yet"); From b1e9f0e62d9a70b16bf6ec2781cfedd47f5f144e Mon Sep 17 00:00:00 2001 From: Kanchana Date: Mon, 5 Aug 2019 16:40:50 +0530 Subject: [PATCH 36/86] added test case var --- .../java/com/tmobile/cloud/awsrules/utils/CommonTestUtils.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/CommonTestUtils.java b/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/CommonTestUtils.java index aebb224ff..7f36c1cc3 100644 --- a/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/CommonTestUtils.java +++ b/jobs/pacman-awsrules/src/test/java/com/tmobile/cloud/awsrules/utils/CommonTestUtils.java @@ -983,6 +983,7 @@ public static Map getMapStringNLB(String passRuleResourceId) { commonMap.put("lambda","lambda"); commonMap.put(",ec2:*,*,s3:*,s3:put*",",ec2:*,*,s3:*,s3:put*"); commonMap.put("type","network"); + commonMap.put("destinationBucketForAutofix","destinationBucketForAutofix"); commonMap.put("cidripv6", "cidripv6"); commonMap.put("username", "svc_123"); From f53e17a6b0108af9a94ce76e0918706ea5d330a5 Mon Sep 17 00:00:00 2001 From: Aditya Agarwal Date: Mon, 5 Aug 2019 17:16:43 +0530 Subject: [PATCH 37/86] made offline and health flow --- .../src/app/core/services/workflow.service.ts | 2 +- .../asset-groups/asset-groups.component.ts | 10 +- .../asset-groups/domains/domains.component.ts | 2 +- .../admin/policies/policies.component.ts | 2 +- .../modules/admin/rules/rules.component.ts | 2 +- .../assets/asset-list/asset-list.component.ts | 4 +- .../aws-notifications.component.html | 4 +- .../cloud-notifications.component.css | 166 ++++++ .../cloud-notifications.component.html | 78 +++ .../cloud-notifications.component.spec.ts | 37 ++ .../cloud-notifications.component.ts | 478 ++++++++++++++++++ .../compliance-dashboard.component.css | 1 + .../modules/compliance/compliance.module.ts | 6 + .../digital-dev-dashboard.component.css | 1 + .../event-details/event-details.component.css | 136 +++++ .../event-details.component.html | 143 ++++++ .../event-details.component.spec.ts | 25 + .../event-details/event-details.component.ts | 364 +++++++++++++ .../patching-compliance.component.css | 1 + .../autofix-schedule.component.css | 95 ++++ .../autofix-schedule.component.html | 34 ++ .../autofix-schedule.component.spec.ts | 39 ++ .../autofix-schedule.component.ts | 53 ++ .../tagging-instances-table.component.ts | 6 +- .../post-login-header.component.css | 6 +- .../post-login-header.component.html | 2 +- .../post-login-header.component.ts | 4 +- .../common/user-info/user-info.component.css | 9 +- .../post-login-app.component.css | 12 +- .../post-login-app.component.html | 26 +- .../post-login-app.component.ts | 21 +- .../post-login-app/post-login-app.module.ts | 3 +- .../back-navigation.component.css | 58 +++ .../back-navigation.component.html | 17 + .../back-navigation.component.spec.ts | 39 ++ .../back-navigation.component.ts | 54 ++ .../constants/field-display-name-mapping.ts | 79 ++- webapp/src/app/shared/constants/routes.ts | 18 + .../copy-element/copy-element.component.css | 4 + .../copy-element/copy-element.component.html | 2 + .../copy-element.component.spec.ts | 25 + .../copy-element/copy-element.component.ts | 62 +++ .../data-table/data-table.component.css | 9 +- .../data-table/data-table.component.html | 2 +- .../shared/data-table/data-table.component.ts | 2 +- .../error-message/error-message.component.ts | 2 +- .../shared/help-text/help-text.component.css | 18 +- .../shared/models/exception-input.model.ts | 14 + .../src/app/shared/models/exception.model.ts | 10 + .../shared/services/copy-element.service.ts | 49 ++ .../services/exception-management.service.ts | 57 +++ .../shared/services/router-utility.service.ts | 22 + .../services/toast-observable.service.ts | 45 ++ .../src/app/shared/services/utils.service.ts | 34 +- webapp/src/app/shared/shared.module.ts | 13 +- webapp/src/assets/icons/alarm.svg | 3 + webapp/src/assets/icons/auto-fix-enabled.svg | 23 + webapp/src/assets/icons/question.svg | 13 + webapp/src/assets/icons/scheduled.svg | 3 + webapp/src/config/configurations.ts | 2 +- webapp/src/config/domain-mapping.ts | 8 +- webapp/src/environments/environment.prod.ts | 20 + webapp/src/environments/environment.stg.ts | 20 + webapp/src/environments/environment.ts | 20 + webapp/src/styles.css | 1 + 65 files changed, 2434 insertions(+), 86 deletions(-) create mode 100644 webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.css create mode 100644 webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.html create mode 100644 webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.spec.ts create mode 100644 webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.ts create mode 100644 webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.css create mode 100644 webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.html create mode 100644 webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.spec.ts create mode 100644 webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.ts create mode 100644 webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.css create mode 100644 webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.html create mode 100644 webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.spec.ts create mode 100644 webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.ts create mode 100644 webapp/src/app/shared/back-navigation/back-navigation.component.css create mode 100644 webapp/src/app/shared/back-navigation/back-navigation.component.html create mode 100644 webapp/src/app/shared/back-navigation/back-navigation.component.spec.ts create mode 100644 webapp/src/app/shared/back-navigation/back-navigation.component.ts create mode 100644 webapp/src/app/shared/copy-element/copy-element.component.css create mode 100644 webapp/src/app/shared/copy-element/copy-element.component.html create mode 100644 webapp/src/app/shared/copy-element/copy-element.component.spec.ts create mode 100644 webapp/src/app/shared/copy-element/copy-element.component.ts create mode 100644 webapp/src/app/shared/models/exception-input.model.ts create mode 100644 webapp/src/app/shared/models/exception.model.ts create mode 100644 webapp/src/app/shared/services/copy-element.service.ts create mode 100644 webapp/src/app/shared/services/exception-management.service.ts create mode 100644 webapp/src/app/shared/services/toast-observable.service.ts create mode 100644 webapp/src/assets/icons/alarm.svg create mode 100644 webapp/src/assets/icons/auto-fix-enabled.svg create mode 100644 webapp/src/assets/icons/question.svg create mode 100644 webapp/src/assets/icons/scheduled.svg diff --git a/webapp/src/app/core/services/workflow.service.ts b/webapp/src/app/core/services/workflow.service.ts index bbec608ee..4edfdbed8 100644 --- a/webapp/src/app/core/services/workflow.service.ts +++ b/webapp/src/app/core/services/workflow.service.ts @@ -79,7 +79,7 @@ export class WorkflowService { this.router.navigate([destinationUrlAndParams['url']], {queryParams: destinationUrlAndParams['queryParams']}); } - checkIfFlowExistsCurrently(currentLevel) { + checkIfFlowExistsCurrently(currentLevel?) { let flowExiststatus = false; // getLevel(); this.level = this.getDetailsFromStorage(); diff --git a/webapp/src/app/pacman-features/modules/admin/asset-groups/asset-groups.component.ts b/webapp/src/app/pacman-features/modules/admin/asset-groups/asset-groups.component.ts index 0d146aae2..3c616389c 100644 --- a/webapp/src/app/pacman-features/modules/admin/asset-groups/asset-groups.component.ts +++ b/webapp/src/app/pacman-features/modules/admin/asset-groups/asset-groups.component.ts @@ -332,8 +332,8 @@ export class AssetGroupsComponent implements OnInit { "color": "#ed0295" } }; - } else if (getCols[col].toLowerCase() == "no of target types") { - let targetTypeName = getData[row]['Target Types'].map(target => target.targetType); + } else if (getCols[col].toLowerCase() === "no of target types") { + let targetTypeName = getData[row]['Asset Types'].map(target => target.targetType); targetTypeName = _.uniq(targetTypeName); cellObj = { link: "", @@ -346,8 +346,8 @@ export class AssetGroupsComponent implements OnInit { text: targetTypeName.length, valText: targetTypeName.length, }; - } else if (getCols[col].toLowerCase() == "target types") { - let targetTypeName = getData[row][getCols[col]].map(target => target.targetType); + } else if (getCols[col].toLowerCase() == "asset types") { + let targetTypeName = getData[row][getCols[col]].map(target => target.targetType); targetTypeName = _.uniq(targetTypeName); cellObj = { link: "", @@ -383,7 +383,7 @@ export class AssetGroupsComponent implements OnInit { this.outerArr = this.outerArr.splice(halfLength); } this.allColumns = Object.keys(totalVariablesObj); - this.allColumns = ["Group Name", "No of Target Types", "Target Types", "Actions"]; + this.allColumns = ["Group Name", "No of Target Types", "Asset Types", "Actions"]; } catch (error) { this.errorMessage = this.errorHandling.handleJavascriptError(error); this.logger.log("error", error); diff --git a/webapp/src/app/pacman-features/modules/admin/asset-groups/domains/domains.component.ts b/webapp/src/app/pacman-features/modules/admin/asset-groups/domains/domains.component.ts index 169abad07..f99f2869d 100644 --- a/webapp/src/app/pacman-features/modules/admin/asset-groups/domains/domains.component.ts +++ b/webapp/src/app/pacman-features/modules/admin/asset-groups/domains/domains.component.ts @@ -379,7 +379,7 @@ export class DomainsComponent implements OnInit, OnDestroy { this.outerArr = this.outerArr.splice(halfLength); } this.allColumns = Object.keys(totalVariablesObj); - this.allColumns = ['Domain Name', 'Domain Desc', 'Target Types Count', 'Config', 'Actions']; + this.allColumns = ['Domain Name', 'Domain Desc', 'Asset Types Count', 'Config', 'Actions']; } catch (error) { this.errorMessage = this.errorHandling.handleJavascriptError(error); this.logger.log('error', error); diff --git a/webapp/src/app/pacman-features/modules/admin/policies/policies.component.ts b/webapp/src/app/pacman-features/modules/admin/policies/policies.component.ts index 407922a1a..5c05a1e89 100644 --- a/webapp/src/app/pacman-features/modules/admin/policies/policies.component.ts +++ b/webapp/src/app/pacman-features/modules/admin/policies/policies.component.ts @@ -364,7 +364,7 @@ export class PoliciesComponent implements OnInit, OnDestroy { this.outerArr = this.outerArr.splice(halfLength); } this.allColumns = Object.keys(totalVariablesObj); - this.allColumns = ['Policy Id','Policy Name', 'Policy Description', 'Policy Version','No of Rules', 'Actions']; + this.allColumns = ['Policy Id','Policy Name', 'Policy Description', 'Policy Version', 'No of Rules', 'Actions']; } catch (error) { this.errorMessage = this.errorHandling.handleJavascriptError(error); this.logger.log('error', error); diff --git a/webapp/src/app/pacman-features/modules/admin/rules/rules.component.ts b/webapp/src/app/pacman-features/modules/admin/rules/rules.component.ts index c0b96e07e..be5103cce 100644 --- a/webapp/src/app/pacman-features/modules/admin/rules/rules.component.ts +++ b/webapp/src/app/pacman-features/modules/admin/rules/rules.component.ts @@ -374,7 +374,7 @@ export class RulesComponent implements OnInit, OnDestroy { this.outerArr = this.outerArr.splice(halfLength); } this.allColumns = Object.keys(totalVariablesObj); - this.allColumns = ['Rule Name', 'Target Type', 'Asset Group', 'Rule Frequency', 'Rule Type', 'Status', 'Actions']; + this.allColumns = ['Rule Name', 'Asset Type', 'Asset Group', 'Rule Frequency', 'Rule Type', 'Status', 'Actions']; } catch (error) { this.errorMessage = this.errorHandling.handleJavascriptError(error); this.logger.log('error', error); diff --git a/webapp/src/app/pacman-features/modules/assets/asset-list/asset-list.component.ts b/webapp/src/app/pacman-features/modules/assets/asset-list/asset-list.component.ts index be5fd2772..d95ed497b 100644 --- a/webapp/src/app/pacman-features/modules/assets/asset-list/asset-list.component.ts +++ b/webapp/src/app/pacman-features/modules/assets/asset-list/asset-list.component.ts @@ -624,8 +624,8 @@ export class AssetListComponent implements OnInit, OnDestroy { try { this.workflowService.addRouterSnapshotToLevel(this.router.routerState.snapshot.root); let resourceType; - if (row.row['Target Type']) { - resourceType = row.row['Target Type'].text; + if (row.row['Asset Type']) { + resourceType = row.row['Asset Type'].text; } if ( this.urlID && (this.urlID.toLowerCase() === 'pull-request-trend' || this.urlID.toLowerCase() === 'pull-request-age' || this.urlID.toLowerCase() === 'branching-strategy') ) { diff --git a/webapp/src/app/pacman-features/modules/assets/aws-notifications/aws-notifications.component.html b/webapp/src/app/pacman-features/modules/assets/aws-notifications/aws-notifications.component.html index a9a8e2a55..618558ecc 100644 --- a/webapp/src/app/pacman-features/modules/assets/aws-notifications/aws-notifications.component.html +++ b/webapp/src/app/pacman-features/modules/assets/aws-notifications/aws-notifications.component.html @@ -26,8 +26,8 @@

{{pageTitle}}

    -
  • -
    +
  • +
    diff --git a/webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.css b/webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.css new file mode 100644 index 000000000..edffc2f0b --- /dev/null +++ b/webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.css @@ -0,0 +1,166 @@ +.policy-knowledgebase-wrapper { + height: 100%; + justify-content: flex-start; + padding-bottom: 2px; +} + +.each-tile { + padding: 2vh 1.66em 2vh 2em; + background: #fff; + border-radius: 5px; + box-shadow: 0 1px 4px 0 #d9dbe2; + height: 100%; + border-bottom: 5px solid #ed027400; + cursor: pointer; + transition: 0.3s ease; + position: relative; + user-select: none; +} + +.each-tile:hover { + transform: translateY(-2px); +} + +.each-tile.active { + border-bottom: 5px solid #ed0274; +} + +.tile-wrap { + width: 25%; + padding: 2px 1em 2em; + min-width: 15em; + flex-grow: 1; + max-width: 27em; +} + +.each-tile:hover .tile-number { + color: #ed0274; +} + +.tile-number { + font-size: 1.5em; + font-weight: bold; + padding-bottom: 3px; + text-decoration: underline; +} + +.tile-txt { + font-family: ex2-light; + line-height: 1.2; + opacity: 0.8; +} + +.tile-img { + width: 2em; + margin-left: 2em; + height: 2em; + object-fit: contain; + object-position: right; +} + +.tile-parent { + padding: 0 1em; + flex-shrink: 0; + flex-flow: wrap; + align-items: stretch; + position: relative; + min-height: 9em; +} + +.tile-hover { + border-radius: 3px; + background-color: #000000; + z-index: 1; + opacity: 0; + pointer-events: none; + transition: 0.3s ease; + top: 0; + left: 0; + border-radius: 5px; + right: 0; + color: #fff; + bottom: -5px; +} + +.each-tile:hover .tile-hover { + opacity: 0.6; + pointer-events: auto; +} + +.data-table-container { + padding: 0 2em 2em; + min-height: 18em; +} + +.cloud-notifications-wrap { + overflow: auto; +} + +.error-message { + top: 50%; + left: 50%; + transform: translate(-50%, calc(-50% - 2em)); + font-family: ex2-light; + opacity: 0.8; +} + +.loader-summary { + transform: translateY(calc(-1em - 300%)); +} + +.toggle-parent { + width: 2.6em; + height: 1em; + background: #d0d0d0; + margin-right: 0.5em; + border-radius: 0.5em; + border: 1px solid #c1c1c1; + cursor: pointer; +} + +.toggle-slider { + height: 1.4em; + width: 1.4em; + background: #ed0274; + top: 50%; + transition: 0.3s ease; + transform: translateY(-50%); + border: 5px solid #ed0274; + border-radius: 0.8em; + box-shadow: 0 0 4px 0px rgba(0,0,0,0.1); + left: -3px; +} + +.toggle-slider.right { + left: calc(1.1em + 3px); +} + +.each-tab { + color: #777; + padding: 2px 2px 4px; + margin-right: 0.5em; + cursor: pointer; + transition: 0.4s ease; + user-select: none; +} + +.each-tab.active { + color: #ed0274; +} + +.toggle-wrap { + padding: 0 2em 1em; +} + +.help-icon { + padding-bottom: 2px; + transition: 0.3s ease; +} + +.help-icon:hover { + transform: scale(1.2); +} + +.breadcrumb-top { + padding-top: 0.5em; +} \ No newline at end of file diff --git a/webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.html b/webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.html new file mode 100644 index 000000000..54045e40a --- /dev/null +++ b/webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.html @@ -0,0 +1,78 @@ + + +
    +
    + +
    +
    + +
    +
    +
    +
    Asset-Specific
    +
    +
    +
    +
    General
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    {{tile.value}}
    +
    {{tile.title}}
    +
    +
    + +
    +
    + Click to {{tile.active ? 'remove' : 'add'}} filter +
    +
    +
    +
    +
    Unable to fetch notifications summary!
    +
    +
    + + +
    +
    +
    +
    diff --git a/webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.spec.ts b/webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.spec.ts new file mode 100644 index 000000000..71d597506 --- /dev/null +++ b/webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.spec.ts @@ -0,0 +1,37 @@ +// *Copyright 2018 T Mobile, 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. A copy of the License is located at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * or in the "license" file accompanying this file. This file is distributed on +// * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or +// * implied. See the License for the specific language governing permissions and +// * limitations under the License. + + import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CloudNotificationsComponent } from './cloud-notifications.component'; + +describe('CloudNotificationsComponent', () => { + let component: CloudNotificationsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CloudNotificationsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CloudNotificationsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.ts b/webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.ts new file mode 100644 index 000000000..a68228164 --- /dev/null +++ b/webapp/src/app/pacman-features/modules/compliance/cloud-notifications/cloud-notifications.component.ts @@ -0,0 +1,478 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { environment } from './../../../../../environments/environment'; +import { AssetGroupObservableService } from '../../../../core/services/asset-group-observable.service'; +import { Router, ActivatedRoute } from '@angular/router'; +import { Subscription } from 'rxjs/Subscription'; +import { UtilsService } from '../../../../shared/services/utils.service'; +import { LoggerService } from '../../../../shared/services/logger.service'; +import { CommonResponseService } from './../../../../shared/services/common-response.service'; +import { DownloadService } from '../../../../shared/services/download.service'; +import { WorkflowService } from '../../../../core/services/workflow.service'; +import { RouterUtilityService } from '../../../../shared/services/router-utility.service'; +import { FilterManagementService } from '../../../../shared/services/filter-management.service'; + +@Component({ + selector: 'app-cloud-notifications', + templateUrl: './cloud-notifications.component.html', + styleUrls: ['./cloud-notifications.component.css'], + providers: [ + LoggerService + ] +}) + +export class CloudNotificationsComponent implements OnInit, OnDestroy { + + constructor( + private assetGroupObservableService: AssetGroupObservableService, + private router: Router, + private utils: UtilsService, + private logger: LoggerService, + private workflowService: WorkflowService, + private commonResponseService: CommonResponseService, + private downloadService: DownloadService, + private routerUtilityService: RouterUtilityService, + private activatedRoute: ActivatedRoute, + private filterManagementService: FilterManagementService + ) { + this.currentPageLevel = this.routerUtilityService.getpageLevel(this.router.routerState.snapshot.root); + } + + popRows = ['Download Data']; + tabSelected = 'asset'; + assetGroupSubscription: Subscription; + dataSubscription: Subscription; + summarySubscription: Subscription; + selectedAssetGroup; + currentPageLevel = 0; + filtersObj = {}; + tilesObj = [ + // { + // title: 'Autofixes', + // icon: '../assets/icons/auto-fix-enabled.svg', + // value: -1, + // active: false, + // key: 'Autofix' + // }, + { + title: 'Scheduled', + icon: '../assets/icons/scheduled.svg', + value: -1, + active: false, + key: 'scheduledChange' + }, + { + title: 'Notifications', + icon: '../assets/icons/alarm.svg', + value: -1, + active: false, + key: 'accountNotification' + }, + { + title: 'Issues', + icon: '../assets/icons/critical.svg', + value: -1, + active: false, + key: 'issue' + } + ]; + paginatorSize = 25; + totalRows = 0; + bucketNumber = 0; + currentBucket: any = []; + firstPaginator = 1; + lastPaginator: number; + currentPointer = 0; + prevFilter = {}; + outerArr = []; + allColumns = []; + errorValue = 0; + summaryValue = 0; + errorMsg = 'apiResponseError'; + searchTxt = ''; + filter = { + 'eventtypecategory': '' + }; + filterArray = []; + + ngOnInit() { + this.activatedRoute.queryParams.subscribe(params => { + this.routerParam(); + }); + this.assetGroupSubscription = this.assetGroupObservableService + .getAssetGroup() + .subscribe(assetGroupName => { + this.selectedAssetGroup = assetGroupName; + this.calibrateFilter(); + this.getSummary(); + this.updateComponent(); + }); + } + + routerParam() { + try { + const currentQueryParams = this.routerUtilityService.getQueryParametersFromSnapshot(this.router.routerState.snapshot.root); + if (currentQueryParams) { + + this.filtersObj = this.utils.processFilterObj( + currentQueryParams + ); + delete this.filter['eventstatus']; + delete this.filter['_resourceid']; + Object.assign(this.filter, this.utils.processFilterObj( + currentQueryParams + )); + + this.filterArray = this.filterManagementService.getFilterArray(this.utils.processFilterObj( + currentQueryParams + )); + + if (JSON.stringify(this.prevFilter) !== JSON.stringify(this.filtersObj)) { + this.prevFilter = JSON.parse(JSON.stringify(this.filtersObj)); + this.getSummary(); + this.updateComponent(); + } + } + } catch (error) { + this.logger.log('error', error); + } + } + + deleteFilters(event?) { + try { + if (!event) { + this.filterArray = []; + } else { + if (event.clearAll) { + this.filterArray = []; + event.array.forEach(element => { + delete this.filter[element.filterkey]; + delete this.filtersObj[element.filterkey]; + }); + } else { + this.filterArray.splice(event.index, 1); + delete this.filter[event.array.filterkey]; + delete this.filtersObj[event.array.filterkey]; + } + this.router.navigate([], { + relativeTo: this.activatedRoute, + queryParams: this.filterArray.length ? this.utils.makeFilterObj(this.filtersObj) : {filter: ''}, + queryParamsHandling: 'merge' + }); + } + } catch (error) { + this.logger.log('error', error); + } +} + + calibrateFilter () { + const arr = []; + for (let i = 0 ; i < this.tilesObj.length; i++) { + if (this.tilesObj[i].active) { + arr.push(this.tilesObj[i].key); + } + } + this.filter['eventtypecategory'] = this.utils.arrayToCommaSeparatedString(arr); + } + + handleTileClick(val, i) { + val.active = !val.active; + this.calibrateFilter(); + this.updateComponent(); + } + + contextChange(val) { + if (this.tabSelected !== val) { + this.tabSelected = val; + for (let j = 0; j < this.tilesObj.length; j++) { + this.tilesObj[j].active = false; + } + this.calibrateFilter(); + this.getSummary(); + this.updateComponent(); + } + } + + toggleSlider() { + if (this.tabSelected === 'general') { + return 'asset'; + } else { + return 'general'; + } + } + + updateComponent() { + this.outerArr = []; + this.searchTxt = ''; + this.currentBucket = []; + this.bucketNumber = 0; + this.firstPaginator = 1; + this.currentPointer = 0; + this.errorMsg = 'apiResponseError'; + this.allColumns = []; + this.getData(); + } + + getSummary() { + if (this.summarySubscription) { + this.summarySubscription.unsubscribe(); + } + this.summaryValue = 0; + const queryParam = { + 'ag': this.selectedAssetGroup, + 'global': this.tabSelected === 'general', + 'resourceId': this.filter['_resourceid'], + 'eventStatus': this.filter['eventstatus'] + }; + const url = environment.cloudNotifSummary.url; + const method = environment.cloudNotifSummary.method; + const payload = {}; + this.summarySubscription = this.commonResponseService.getData( url, method, payload, queryParam).subscribe( + response => { + try { + this.summaryValue = 1; + // this.tilesObj[0].value = response[0].autofixCount; + this.tilesObj[0].value = response[0].eventscheduledCount; + this.tilesObj[1].value = response[0].eventNotificationCount; + this.tilesObj[2].value = response[0].evnetIssuesCount; + } catch (e) { + this.summaryValue = -1; + this.logger.log('error', e); + } + }, + error => { + this.summaryValue = -1; + this.logger.log('error', error); + }); + } + + getData() { + if (this.dataSubscription) { + this.dataSubscription.unsubscribe(); + } + this.errorValue = 0; + const payload = { + 'ag': this.selectedAssetGroup, + 'filter': this.filter, + 'from': (this.bucketNumber) * this.paginatorSize, + 'searchtext': this.searchTxt, + 'size': this.paginatorSize + }; + const TableUrl = environment.cloudNotifications.url; + const TableMethod = environment.cloudNotifications.method; + const queryParam = { + global: this.tabSelected === 'general' + }; + this.dataSubscription = this.commonResponseService.getData( TableUrl, TableMethod, payload, queryParam).subscribe( + response => { + try { + this.errorValue = 1; + if (response.data.response.length === 0) { + this.errorValue = -1; + this.errorMsg = 'noDataAvailable'; + } + this.totalRows = response.data.total; + if (response.data.response.length > 0) { + this.firstPaginator = (this.bucketNumber * this.paginatorSize) + 1; + this.lastPaginator = (this.bucketNumber * this.paginatorSize) + this.paginatorSize; + this.currentPointer = this.bucketNumber; + if (this.lastPaginator > this.totalRows) { + this.lastPaginator = this.totalRows; + } + const updatedResponse = this.utils.massageTableData(response.data.response); + this.currentBucket[this.bucketNumber] = updatedResponse; + this.processData(updatedResponse); + } + } catch (e) { + this.errorValue = -1; + this.logger.log('error', e); + this.errorMsg = 'jsError'; + } + }, + error => { + this.errorValue = -1; + this.logger.log('error', error); + this.errorMsg = 'apiResponseError'; + }); + } + + processData(data) { + let innerArr = {}; + const totalVariablesObj = {}; + let cellObj = {}; + this.outerArr = []; + const datainString = JSON.stringify(data); + const getData = JSON.parse(datainString); + const getCols = Object.keys(getData[0]); + + for (let row = 0 ; row < getData.length ; row++) { + innerArr = {}; + for (let col = 0; col < getCols.length; col++) { + if (getCols[col].toLowerCase() === 'affected resources' || getCols[col].toLowerCase() === 'event') { + cellObj = { + 'link': 'Event Details', + 'properties': + { + 'color': '' + }, + 'colName': getCols[col], + 'hasPreImg': false, + 'imgLink': '', + 'text': getData[row][getCols[col]], + 'valText': getData[row][getCols[col]] + }; + } else if (getCols[col].toLowerCase() === 'start time' || getCols[col].toLowerCase() === 'end time') { + cellObj = { + 'link': '', + 'properties': + { + 'color': '' + }, + 'colName': getCols[col], + 'hasPreImg': false, + 'imgLink': '', + 'text': getData[row][getCols[col]] ? new Date(getData[row][getCols[col]]).toLocaleString() : '', + 'valText': getData[row][getCols[col]] ? new Date(getData[row][getCols[col]]).getTime() : '' + }; + } else { + cellObj = { + 'link': '', + 'properties': + { + 'color': '' + }, + 'colName': getCols[col], + 'hasPreImg': false, + 'imgLink': '', + 'text': getData[row][getCols[col]], + 'valText': getData[row][getCols[col]] + }; + } + innerArr[getCols[col]] = cellObj; + totalVariablesObj[getCols[col]] = ''; + } + this.outerArr.push(innerArr); + } + if (this.outerArr.length > getData.length) { + const halfLength = this.outerArr.length / 2; + this.outerArr = this.outerArr.splice(halfLength); + } + this.allColumns = Object.keys(totalVariablesObj); + } + + goToDetails(row) { + try { + if (row.col.toLowerCase() === 'affected resources' || row.col.toLowerCase() === 'event') { + const arnId = encodeURIComponent(row.row['eventarn'].text); + this.workflowService.addRouterSnapshotToLevel(this.router.routerState.snapshot.root); + this.router.navigate( + ['pl/compliance/event-details', arnId], + { queryParams: {'global': this.tabSelected === 'general', autofix: row.row['Event Category'].text.toLowerCase() === 'autofix'}, queryParamsHandling: 'merge' } + ).then(response => { + this.logger.log('info', 'Successfully navigated to details page: ' + response); + }) + .catch(error => { + this.logger.log('error', 'Error in navigation - ' + error); + }); + } + } catch (error) { + this.logger.log('error', error); + } + } + + callHelp() { + const newParams = { widgetId: 'w8' }; + this.router.navigate( + ['/pl', { outlets: { helpTextModal: ['help-text'] } }], + { queryParams: newParams, queryParamsHandling: 'merge' } + ); + } + + prevPg() { + this.currentPointer--; + this.processData(this.currentBucket[this.currentPointer]); + this.firstPaginator = (this.currentPointer * this.paginatorSize) + 1; + this.lastPaginator = (this.currentPointer * this.paginatorSize) + this.paginatorSize; + } + + nextPg() { + if (this.currentPointer < this.bucketNumber) { + this.currentPointer++; + this.processData(this.currentBucket[this.currentPointer]); + this.firstPaginator = (this.currentPointer * this.paginatorSize) + 1; + this.lastPaginator = (this.currentPointer * this.paginatorSize) + this.paginatorSize; + if (this.lastPaginator > this.totalRows) { + this.lastPaginator = this.totalRows; + } + } else { + this.bucketNumber++; + this.getData(); + } + } + + handlePopClick(rowText) { + const fileType = 'csv'; + try { + let queryParams; + queryParams = { + 'fileFormat': 'csv', + 'serviceId': this.tabSelected === 'general' ? 23 : 22, + 'fileType': fileType + }; + const downloadRequest = { + 'ag': this.selectedAssetGroup, + 'filter': this.filter, + 'from': 0, + 'searchtext': this.searchTxt, + 'size': this.totalRows + }; + const downloadUrl = environment.download.url; + const downloadMethod = environment.download.method; + const downloadName = 'Event Logs'; + this.downloadService.requestForDownload( + queryParams, + downloadUrl, + downloadMethod, + downloadRequest, + downloadName, + this.totalRows); + } catch (error) { + this.logger.log('error', error); + } + } + + searchCalled(search) { + this.searchTxt = search; + } + + callNewSearch() { + this.bucketNumber = 0; + this.currentBucket = []; + this.getData(); + } + + ngOnDestroy() { + if (this.assetGroupSubscription) { + this.assetGroupSubscription.unsubscribe(); + } + if (this.dataSubscription) { + this.dataSubscription.unsubscribe(); + } + if (this.summarySubscription) { + this.summarySubscription.unsubscribe(); + } + } +} diff --git a/webapp/src/app/pacman-features/modules/compliance/compliance-dashboard/compliance-dashboard.component.css b/webapp/src/app/pacman-features/modules/compliance/compliance-dashboard/compliance-dashboard.component.css index c356001ca..9b4ddce05 100644 --- a/webapp/src/app/pacman-features/modules/compliance/compliance-dashboard/compliance-dashboard.component.css +++ b/webapp/src/app/pacman-features/modules/compliance/compliance-dashboard/compliance-dashboard.component.css @@ -15,6 +15,7 @@ .floating-widgets-header { height: 6em; padding: 1.9em 1.8em; + align-items: center; } .data-table-wrap { diff --git a/webapp/src/app/pacman-features/modules/compliance/compliance.module.ts b/webapp/src/app/pacman-features/modules/compliance/compliance.module.ts index 281e9a118..170e1510b 100644 --- a/webapp/src/app/pacman-features/modules/compliance/compliance.module.ts +++ b/webapp/src/app/pacman-features/modules/compliance/compliance.module.ts @@ -20,6 +20,7 @@ import { ComplianceRoutingModule } from './compliance-routing.module'; import { ComplianceComponent } from './compliance.component'; import { ComplianceIssuesComponent } from './../../secondary-components/compliance-issues/compliance-issues.component'; import { PacmanIssuesComponent } from './../../secondary-components/pacman-issues/pacman-issues.component'; +import { AutofixScheduleComponent } from './../../secondary-components/autofix-schedule/autofix-schedule.component'; import { MultilineBrushZoomComponent } from './../../secondary-components/multiline-brush-zoom/multiline-brush-zoom.component'; import { MultiBandDonutComponent } from './../../secondary-components/multi-band-donut/multi-band-donut.component'; import { IssuesCategoryComponent } from './../../secondary-components/issues-category/issues-category.component'; @@ -42,6 +43,8 @@ import { AllVulnerabilityTableComponent } from './../../secondary-components/all import { VulnerabilityTrendComponent } from './../../secondary-components/vulnerability-trend/vulnerability-trend.component'; import { PatchingComplianceComponent } from './patching-compliance/patching-compliance.component'; import { TaggingComplianceComponent } from './tagging-compliance/tagging-compliance.component'; +import { CloudNotificationsComponent } from './cloud-notifications/cloud-notifications.component'; +import { EventDetailsComponent } from './event-details/event-details.component'; import { CertificateComplianceComponent } from './certificate-compliance/certificate-compliance.component'; import { WindowRefService } from './../../services/window.service'; import { AllPatchingTableComponent } from './../../secondary-components/all-patching-table/all-patching-table.component'; @@ -138,6 +141,7 @@ import { IssueListingService } from '../../services/issue-listing.service'; IssueListingComponent, IssueDetailsComponent, VulnerabilitiesComplianceComponent, + AutofixScheduleComponent, IssueBlocksComponent, DetailsInfoComponent, VulnerabilityIssueComponent, @@ -149,7 +153,9 @@ import { IssueListingService } from '../../services/issue-listing.service'; VulnerabilityTrendComponent, PatchingComplianceComponent, TaggingComplianceComponent, + CloudNotificationsComponent, CertificateComplianceComponent, + EventDetailsComponent, AllPatchingTableComponent, PatchingIssueComponent, PatchingCurrentStateComponent, diff --git a/webapp/src/app/pacman-features/modules/compliance/digital-dev-dashboard/digital-dev-dashboard.component.css b/webapp/src/app/pacman-features/modules/compliance/digital-dev-dashboard/digital-dev-dashboard.component.css index 86034e8ee..d6f54cb6c 100644 --- a/webapp/src/app/pacman-features/modules/compliance/digital-dev-dashboard/digital-dev-dashboard.component.css +++ b/webapp/src/app/pacman-features/modules/compliance/digital-dev-dashboard/digital-dev-dashboard.component.css @@ -24,6 +24,7 @@ .floating-widgets-header { padding: 0em 1.4em; + align-items: center; } .section { diff --git a/webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.css b/webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.css new file mode 100644 index 000000000..2e99abf79 --- /dev/null +++ b/webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.css @@ -0,0 +1,136 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + + .floating-widgets-section { + height: 100%; + width: 100%; +} + +.floating-widgets-container { + overflow: hidden; +} + +.floating-widgets-container:hover { + overflow: auto; overflow: overlay; +} + +.widget-wrapper { + min-height: 17em; + padding: 1.5em .5em; +} + +/* css for edge browser */ +@supports (-ms-ime-align: auto) { + .floating-widgets-container { + overflow: auto; + } +} + +.container{ + padding: 1.3em 1.5em; + background-color: #fff; + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.15); + border: solid 1px #d6e2f1; + border-radius: 4px; + height: 100%; + overflow: auto; +} +.main-container{ + padding: 1em 1.5em 1.5em; +} +.description-wrapper{ + padding: 0.5em; + flex-flow: wrap; +} +.text-header{ + font-size: 1.3em; + font-weight: 600; + line-height: 1.3; + padding: .3em 0; +} +.text-description{ + line-height: 1.5; + font-size: 1.2em; + color: #333; + font-family: ex2-light; + letter-spacing: 0.2px; + white-space: pre-line; + word-break: break-word; +} + +.table-head-wrapper /deep/ .head-cell-wrapper{ + text-align: left; +} + +.desc-wrap { + min-height: 14em; +} + +.desc-wrapper { + width: 25%; + padding-right: 2em; + flex-shrink: 0; + padding-bottom: 0.5em; + flex-grow: 1; +} + +.caps { + text-transform: capitalize; +} + +.err-msg { + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + font-size: 1.1em; +} + +.pad-bot { + padding-bottom: 0.5em; +} + +.link { + color: #ed0274; + cursor: pointer; + word-break: break-all; +} + +.link:hover { + text-decoration: underline; +} + +.model-title { + color: #ed0295; + font-size: 1.2em; + cursor: pointer; + padding-right: 1em; +} + +.arrow-modal { + margin-right: -1em; + margin-left: 7px; + transition: 0.4s ease; + cursor: pointer; +} + +.copy-object { + pointer-events: none; + transition: 0.2s ease; + opacity: 0; +} + +.each-cell-list-row:hover .copy-object { + opacity: 1; + pointer-events: auto; +} diff --git a/webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.html b/webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.html new file mode 100644 index 000000000..2c9876e34 --- /dev/null +++ b/webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.html @@ -0,0 +1,143 @@ + + +
    +
    + +
    +
    +
    + + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    Description
    + +
    + +
    +
    +
    Category
    +
    + + +
    +
    +
    +
    Status
    +
    + + +
    +
    +
    +
    Start Time
    +
    + + +
    +
    +
    +
    End Time
    +
    + + +
    +
    +
    +
    Start Time
    +
    + + +
    +
    +
    +
    End Time
    +
    + + +
    +
    +
    +
    Policy Name
    +
    + + +
    +
    +
    +
    Policy ID
    +
    + + +
    +
    +
    +
    Issue ID
    +
    + + +
    +
    +
    +
    Resource ID
    +
    + + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    diff --git a/webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.spec.ts b/webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.spec.ts new file mode 100644 index 000000000..aec5750e6 --- /dev/null +++ b/webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EventDetailsComponent } from './event-details.component'; + +describe('EventDetailsComponent', () => { + let component: EventDetailsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ EventDetailsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(EventDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.ts b/webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.ts new file mode 100644 index 000000000..af9ddc44a --- /dev/null +++ b/webapp/src/app/pacman-features/modules/compliance/event-details/event-details.component.ts @@ -0,0 +1,364 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { AssetGroupObservableService } from '../../../../core/services/asset-group-observable.service'; +import { Subscription } from 'rxjs/Subscription'; +import { environment } from './../../../../../environments/environment'; +import { ActivatedRoute, Router } from '@angular/router'; +import { CommonResponseService } from '../../../../shared/services/common-response.service'; +import { LoggerService } from '../../../../shared/services/logger.service'; +import { UtilsService } from '../../../../shared/services/utils.service'; +import { WorkflowService } from '../../../../core/services/workflow.service'; +import { ExceptionManagementService } from '../../../../shared/services/exception-management.service'; +import { Exception } from '../../../../shared/models/exception.model'; +import { ExceptionInput } from '../../../../shared/models/exception-input.model'; + +@Component({ + selector: 'app-event-details', + templateUrl: './event-details.component.html', + styleUrls: ['./event-details.component.css'] +}) +export class EventDetailsComponent implements OnInit, OnDestroy { + + constructor( + private activatedRoute: ActivatedRoute, + private assetGroupObservableService: AssetGroupObservableService, + private logger: LoggerService, + private commonResponseService: CommonResponseService, + private exceptionMangamentService: ExceptionManagementService, + private router: Router, + private utils: UtilsService, + private workflowService: WorkflowService + ) { + this.assetGroupSubscription = this.assetGroupObservableService.getAssetGroup().subscribe(assetGroupName => { + this.backButtonRequired = this.workflowService.checkIfFlowExistsCurrently( + this.pageLevel + ); + this.selectedAssetGroup = assetGroupName; + }); + } + + routeSubscription: Subscription; + assetGroupSubscription: Subscription; + getDescriptionSubscription: Subscription; + getAutofixSubscription: Subscription; + getDetailsSubscription: Subscription; + selectedAssetGroup; + breadcrumbArray: any = ['Health Notifications']; + breadcrumbLinks: any = ['health-notifications']; + breadcrumbPresent = 'Event Details'; + backButtonRequired; + responseStatusInfo = { + loadState: 0, + errorMessage: 'apiResponseError' + }; + responseStatusDetails = { + loadState: 0, + errorMessage: 'apiResponseError' + }; + arnId; + descData; + pageLevel = 0; + global; + titleVal = 'Request Exception'; + description = 'Choose policies below to be exempted against selected assets'; + showExceptionalModal = false; + cbprocessData: Exception; + inputToException: any = {}; + paginatorSize = 25; + totalRows = 0; + firstPaginator = 1; + lastPaginator: number; + outerArr = []; + allColumns = []; + searchTxt = ''; + searchPassed = ''; + autofix = false; + autofixData; + + ngOnInit() { + this.routeSubscription = this.activatedRoute.params.subscribe(params => { + const urlParams = params; + this.arnId = decodeURIComponent(urlParams.arn); + }); + this.activatedRoute.queryParams.subscribe(params => { + this.autofix = params.autofix === 'true' || params.autofix === true; + this.global = params.global === true || params.global === 'true'; + }); + this.updateComponent(); + } + + updateComponent() { + this.outerArr = []; + this.firstPaginator = 1; + this.allColumns = []; + if (!this.autofix) { + this.getDescription(); + if (!this.global || this.global === 'false') { + this.getDetails(); + } + } else { + this.getAutofixDetails(); + } + } + + requestNewException() { + this.inputToException['disablePolicy'] = true; + const data = { + ruleId: this.autofixData.ruleId, + ruleName: this.autofixData.ruleName, + expiringIn: 0, + exceptionReason: '', + exceptionEndDate: null, + allPolicyIds: [], + common: this.inputToException + }; + + const exceptionRawInput: ExceptionInput = data; + this.cbprocessData = this.exceptionMangamentService.createDataToAddOrModifyException(exceptionRawInput); + + } + + getDescription() { + this.responseStatusInfo.loadState = 0; + if (this.getDescriptionSubscription) { + this.getDescriptionSubscription.unsubscribe(); + } + + const Url = environment.getEventDescription.url; + const Method = environment.getEventDescription.method; + const queryParams = { + 'ag': this.selectedAssetGroup, + 'eventArn': this.arnId, + 'global': this.global + }; + + try { + this.getDescriptionSubscription = this.commonResponseService.getData(Url, Method, {}, queryParams).subscribe( + response => { + try { + this.descData = response; + this.responseStatusInfo.loadState = 1; + } catch (e) { + this.responseStatusInfo.errorMessage = 'jsError'; + this.responseStatusInfo.loadState = -1; + this.logger.log('error', e); + } + }, + error => { + this.responseStatusInfo.errorMessage = 'apiResponseError'; + this.responseStatusInfo.loadState = -1; + this.logger.log('error', error); + }); + } catch (error) { + this.responseStatusInfo.errorMessage = 'jsError'; + this.responseStatusInfo.loadState = -1; + this.logger.log('error', error); + } + } + + getAutofixDetails() { + this.responseStatusInfo.loadState = 0; + if (this.getAutofixSubscription) { + this.getAutofixSubscription.unsubscribe(); + } + + const Url = environment.getAutofixDetails.url; + const Method = environment.getAutofixDetails.method; + const queryParams = { + }; + + const payload = { + ag: this.selectedAssetGroup, + filter: { + resourceId: this.arnId + }, + from: 0, + size: 0 + }; + + try { + this.getAutofixSubscription = this.commonResponseService.getData(Url, Method, payload, queryParams).subscribe( + response => { + try { + this.autofixData = response.data; + this.inputToException['allResourceIds'] = [this.autofixData.resourceId]; + this.inputToException['resourceType'] = this.autofixData.resourceType; + this.inputToException['allTargetTypes'] = [this.autofixData.resourceType]; + this.inputToException['disablePolicy'] = true; + this.responseStatusInfo.loadState = 1; + } catch (e) { + this.responseStatusInfo.errorMessage = 'jsError'; + this.responseStatusInfo.loadState = -1; + this.logger.log('error', e); + } + }, + error => { + this.responseStatusInfo.errorMessage = 'apiResponseError'; + this.responseStatusInfo.loadState = -1; + this.logger.log('error', error); + }); + } catch (error) { + this.responseStatusInfo.errorMessage = 'jsError'; + this.responseStatusInfo.loadState = -1; + this.logger.log('error', error); + } + } + + getDetails() { + this.responseStatusDetails.loadState = 0; + if (this.getDetailsSubscription) { + this.getDetailsSubscription.unsubscribe(); + } + + const Url = environment.getEventDetails.url; + const Method = environment.getEventDetails.method; + const queryParams = { + 'ag': this.selectedAssetGroup, + 'eventArn': this.arnId, + 'global': this.global + }; + + try { + this.getDetailsSubscription = this.commonResponseService.getData(Url, Method, {}, queryParams).subscribe( + response => { + this.responseStatusDetails.loadState = 1; + if (response.length === 0) { + this.responseStatusDetails.loadState = -1; + this.responseStatusDetails.errorMessage = 'noDataAvailable'; + } + this.totalRows = response.length; + if (this.totalRows > 0) { + this.lastPaginator = this.totalRows; + const updatedResponse = this.utils.massageTableData(response); + this.processData(updatedResponse); + } + }, + error => { + this.responseStatusDetails.errorMessage = 'apiResponseError'; + this.responseStatusDetails.loadState = -1; + this.logger.log('error', error); + }); + } catch (error) { + this.responseStatusDetails.errorMessage = 'jsError'; + this.responseStatusDetails.loadState = -1; + this.logger.log('error', error); + } + } + + navigateBack() { + try { + this.workflowService.goBackToLastOpenedPageAndUpdateLevel(this.router.routerState.snapshot.root); + } catch (error) { + this.logger.log('error', error); + } + } + + processData(data) { + let innerArr = {}; + const totalVariablesObj = {}; + let cellObj = {}; + this.outerArr = []; + const datainString = JSON.stringify(data); + const getData = JSON.parse(datainString); + const getCols = Object.keys(getData[0]); + + for (let row = 0 ; row < getData.length ; row++) { + innerArr = {}; + for (let col = 0; col < getCols.length; col++) { + if (getCols[col].toLowerCase() === 'resource id') { + cellObj = { + 'link': 'View Asset Details', + 'properties': + { + 'color': '' + }, + 'colName': getCols[col], + 'hasPreImg': false, + 'imgLink': '', + 'text': getData[row][getCols[col]], + 'valText': getData[row][getCols[col]] + }; + } else { + cellObj = { + 'link': '', + 'properties': + { + 'color': '' + }, + 'colName': getCols[col], + 'hasPreImg': false, + 'imgLink': '', + 'text': getData[row][getCols[col]], + 'valText': getData[row][getCols[col]] + }; + } + innerArr[getCols[col]] = cellObj; + totalVariablesObj[getCols[col]] = ''; + } + this.outerArr.push(innerArr); + } + if (this.outerArr.length > getData.length) { + const halfLength = this.outerArr.length / 2; + this.outerArr = this.outerArr.splice(halfLength); + } + this.allColumns = Object.keys(totalVariablesObj); + } + + goToDetails(row) { + try { + if (row.col.toLowerCase() === 'resource id') { + this.workflowService.addRouterSnapshotToLevel(this.router.routerState.snapshot.root); + const targetType = row.row['Asset Type'].text; + const resourceId = encodeURI(row.row['Resource ID'].text); + this.router.navigate( + ['../../../', 'assets', 'assets-details', targetType, resourceId], + { + relativeTo: this.activatedRoute, + queryParamsHandling: 'merge' + } + ).catch(error => { + this.logger.log('error', 'Error in navigation - ' + error); + }); + } + } catch (error) { + this.logger.log('error', error); + } + } + + goToLinkDetails(page, p1?, p2?) { + const arr = [page]; + if (p1) { + arr.push(p1); + } + if (p2) { + arr.push(encodeURIComponent(p2)); + } + this.workflowService.addRouterSnapshotToLevel(this.router.routerState.snapshot.root); + this.router.navigate( + ['pl', { outlets: { details: arr } }], + { queryParamsHandling: 'merge' } + ); + } + + searchCalled(search) { + this.searchTxt = search; + if (this.searchTxt === '') { + this.searchPassed = this.searchTxt; + } + } + + callNewSearch() { + this.searchPassed = this.searchTxt; + } + + ngOnDestroy() { + this.routeSubscription.unsubscribe(); + this.assetGroupSubscription.unsubscribe(); + if (this.getDescriptionSubscription) { + this.getDescriptionSubscription.unsubscribe(); + } + if (this.getDetailsSubscription) { + this.getDetailsSubscription.unsubscribe(); + } + } + +} diff --git a/webapp/src/app/pacman-features/modules/compliance/patching-compliance/patching-compliance.component.css b/webapp/src/app/pacman-features/modules/compliance/patching-compliance/patching-compliance.component.css index cb91271ff..6df9f2a6e 100644 --- a/webapp/src/app/pacman-features/modules/compliance/patching-compliance/patching-compliance.component.css +++ b/webapp/src/app/pacman-features/modules/compliance/patching-compliance/patching-compliance.component.css @@ -37,6 +37,7 @@ height: 4em; /*padding: 1.9em 1.8em;*/ padding: 0em 1.8em; + align-items: center; } .floating-widgets-header h1 { diff --git a/webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.css b/webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.css new file mode 100644 index 000000000..ef1c7a475 --- /dev/null +++ b/webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.css @@ -0,0 +1,95 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. +*/ + +.status-wrap { + padding: 0.5em; +} + +.plan-circle { + background: #ccc; + height: 14px; + width: 14px; + border-radius: 7px; + flex-shrink: 0; + opacity: 0.88; + z-index: 2; +} + +.plan-circle.completed { + background: #57C17C; +} + +.plan-separator { + background: #cecece; + height: 2px; + width: 130px; + margin: 0 3px; + flex-grow: 1; +} + +.plan-wrap { + padding: 1em 0; + max-width: 90%; +} + +.plan-txt { + color: #888; + padding-top: 0.6em; + text-align: center; + white-space: nowrap; + transform: translateX(calc(-50% + 7px)); +} + +.last-element { + width: 14px; + max-width: 1.2em; +} + +.tick { + display: none; + width: 0.8em; + height: 0.8em; + object-fit: contain; + object-position: center; +} + +.completed .tick { + display: block; +} + +.today-marker { + z-index: 1; + height: 20px; + width: 20px; + object-fit: contain; + object-position: center; + top: 0px; + transition: 4s ease; + left: -3px; +} + +.text-header { + font-size: 1.3em; + font-weight: 600; + line-height: 1.3; + padding: .3em 0; +} + +.green-track { + top: 0; + left: 0; + bottom: 0; + width: 0%; + background: #57c17c; +} \ No newline at end of file diff --git a/webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.html b/webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.html new file mode 100644 index 000000000..aa60efd58 --- /dev/null +++ b/webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.html @@ -0,0 +1,34 @@ + + +
    +
    Autofix Plan
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    {{plan.action == 'AUTOFIX_ACTION_EMAIL' ? 'Email Notification ' + (i + 1) : 'Fixed'}}
    +
    {{plan.plannedActionTime | date: 'd MMM y, h:mm a'}}
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.spec.ts b/webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.spec.ts new file mode 100644 index 000000000..70cfeddb9 --- /dev/null +++ b/webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.spec.ts @@ -0,0 +1,39 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + + import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AutofixScheduleComponent } from './autofix-schedule.component'; + +describe('AutofixScheduleComponent', () => { + let component: AutofixScheduleComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ AutofixScheduleComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AutofixScheduleComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.ts b/webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.ts new file mode 100644 index 000000000..5a7778ca5 --- /dev/null +++ b/webapp/src/app/pacman-features/secondary-components/autofix-schedule/autofix-schedule.component.ts @@ -0,0 +1,53 @@ +/* + *Copyright 2018 T Mobile, 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. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or + * implied. See the License for the specific language governing permissions and + * limitations under the License. +*/ + +import { Component, OnInit, Input } from '@angular/core'; + +@Component({ + selector: 'app-autofix-schedule', + templateUrl: './autofix-schedule.component.html', + styleUrls: ['./autofix-schedule.component.css'] +}) + +export class AutofixScheduleComponent implements OnInit { + + constructor() { } + + @Input() autofixData; + transformVal = -1; + + ngOnInit() { + if (this.autofixData && this.autofixData.planItems && this.autofixData.planItems.length > 1 + && new Date().getTime() + >= new Date( this.autofixData.planItems[0].plannedActionTime ).getTime() + && new Date().getTime() + <= new Date( this.autofixData.planItems[this.autofixData.planItems.length - 1].plannedActionTime ).getTime() + ) { + this.transformVal = 0; + setTimeout(() => { + this.transformVal = ( + ( new Date().getTime() + - new Date(this.autofixData.planItems[0].plannedActionTime).getTime() + ) + * (this.autofixData.planItems.length - 1) + * 150 + ) + / ( + new Date( this.autofixData.planItems[this.autofixData.planItems.length - 1].plannedActionTime ).getTime() + - new Date( this.autofixData.planItems[0].plannedActionTime ).getTime() + ); + }, 100); + } + } +} diff --git a/webapp/src/app/pacman-features/secondary-components/tagging-instances-table/tagging-instances-table.component.ts b/webapp/src/app/pacman-features/secondary-components/tagging-instances-table/tagging-instances-table.component.ts index aa1d96ed5..7c35ca03f 100644 --- a/webapp/src/app/pacman-features/secondary-components/tagging-instances-table/tagging-instances-table.component.ts +++ b/webapp/src/app/pacman-features/secondary-components/tagging-instances-table/tagging-instances-table.component.ts @@ -337,21 +337,21 @@ export class TaggingInstancesTableComponent implements OnInit, OnDestroy { this.workflowService.addRouterSnapshotToLevel(this.router.routerState.snapshot.root); if (row.col.toLowerCase() === 'environment untagged' && row.row['environment Untagged'].text > 0) { const eachParams = {'tagName': 'Environment', 'tagged' : false}; - eachParams['application'] = row.row.application.valText; + eachParams['application'] = row.row.Application.valText; let newParams = this.utils.makeFilterObj(eachParams); newParams = Object.assign(newParams, apiTarget); newParams['mandatory'] = 'tagged'; this.router.navigate(['../../', 'assets' , 'asset-list'], {relativeTo: this.activatedRoute, queryParams: newParams, queryParamsHandling : 'merge'}); } else if (row.col.toLowerCase() === 'role untagged' && row.row['role Untagged'].text > 0) { const eachParams = {'tagName': 'Role', 'tagged' : false}; - eachParams['application'] = row.row.application.valText; + eachParams['application'] = row.row.Application.valText; let newParams = this.utils.makeFilterObj(eachParams); newParams = Object.assign(newParams, apiTarget); newParams['mandatory'] = 'tagged'; this.router.navigate(['../../', 'assets' , 'asset-list'], {relativeTo: this.activatedRoute, queryParams: newParams, queryParamsHandling : 'merge'}); } else if (row.col.toLowerCase() === 'stack untagged' && row.row['stack Untagged'].text > 0) { const eachParams = {'tagName': 'Stack', 'tagged' : false}; - eachParams['application'] = row.row.application.valText; + eachParams['application'] = row.row.Application.valText; let newParams = this.utils.makeFilterObj(eachParams); newParams = Object.assign(newParams, apiTarget); newParams['mandatory'] = 'tagged'; diff --git a/webapp/src/app/post-login-app/common/post-login-header/post-login-header.component.css b/webapp/src/app/post-login-app/common/post-login-header/post-login-header.component.css index 20c230f40..4dae9fed8 100644 --- a/webapp/src/app/post-login-app/common/post-login-header/post-login-header.component.css +++ b/webapp/src/app/post-login-app/common/post-login-header/post-login-header.component.css @@ -88,11 +88,13 @@ nav .nav-icon:last-child { .user-options { position: absolute; - right: 100%; top: 150%; - transform: translateX(29%); + transform: translateX(10px); + -webkit-transition: all 0.5s; transition: all 0.5s; opacity: 1; + white-space: nowrap; + right: 0; } .user-option.visible { diff --git a/webapp/src/app/post-login-app/common/post-login-header/post-login-header.component.html b/webapp/src/app/post-login-app/common/post-login-header/post-login-header.component.html index 1ec0130ac..5fe5b7137 100644 --- a/webapp/src/app/post-login-app/common/post-login-header/post-login-header.component.html +++ b/webapp/src/app/post-login-app/common/post-login-header/post-login-header.component.html @@ -21,7 +21,7 @@
    - Hi, {{FirstName}} + Hi, {{FirstName}}