Fix: Run both sonar and clm scans in parallel
[ccsdk/cds.git] / ms / py-executor / blueprints_grpc / executor_utils.py
1 #!/usr/bin/python
2 #
3 #  Copyright © 2018-2019 AT&T Intellectual Property.
4 #
5 #  Licensed under the Apache License, Version 2.0 (the "License");
6 #  you may not use this file except in compliance with the License.
7 #  You may obtain a copy of the License at
8 #
9 #      http://www.apache.org/licenses/LICENSE-2.0
10 #
11 #  Unless required by applicable law or agreed to in writing, software
12 #  distributed under the License is distributed on an "AS IS" BASIS,
13 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 #  See the License for the specific language governing permissions and
15 #  limitations under the License.
16
17 import datetime
18 import importlib
19 import importlib.util
20 import json
21 import logging
22 import sys
23 import time
24
25 from google.protobuf import json_format, struct_pb2
26 from google.protobuf.timestamp_pb2 import Timestamp
27 from proto.BluePrintCommon_pb2 import (
28     EVENT_COMPONENT_EXECUTED,
29     EVENT_COMPONENT_NOTIFICATION,
30     EVENT_COMPONENT_PROCESSING,
31     EVENT_COMPONENT_TRACE,
32     Status
33 )
34 from proto.BluePrintProcessing_pb2 import (
35     ExecutionServiceInput,
36     ExecutionServiceOutput,
37 )
38
39 from .script_executor_configuration import ScriptExecutorConfiguration
40
41 logger = logging.getLogger("Utils")
42
43
44 def current_time():
45     ts = time.time()
46     return datetime.datetime.fromtimestamp(ts).strftime("%Y-%m-%dT%H:%M:%S.%fZ")
47
48
49 def blueprint_id(input: ExecutionServiceInput):
50     blueprint_name = input.actionIdentifiers.blueprintName
51     blueprint_version = input.actionIdentifiers.blueprintVersion
52     return blueprint_name + '/' + blueprint_version
53
54
55 def blueprint_location(config: ScriptExecutorConfiguration, input: ExecutionServiceInput):
56     blueprint_name = input.actionIdentifiers.blueprintName
57     blueprint_version = input.actionIdentifiers.blueprintVersion
58     return config.blueprints_processor('blueprintDeployPath') + '/' + blueprint_name + '/' + blueprint_version
59
60
61 def instance_for_input(config: ScriptExecutorConfiguration, input: ExecutionServiceInput):
62     blueprint_name = input.actionIdentifiers.blueprintName
63     blueprint_version = input.actionIdentifiers.blueprintVersion
64     action_name = input.actionIdentifiers.actionName
65     # Get Blueprint python script location
66     script_location = blueprint_location(config, input) + '/' + 'Scripts/python/__init__.py'
67     logger.info(script_location)
68
69     # Create Dynamic Module Name
70     module_name = blueprint_name + '-' + blueprint_version
71     spec = importlib.util.spec_from_file_location(module_name, script_location)
72     logger.info(spec)
73     dynamic_module = importlib.util.module_from_spec(spec)
74     # Add blueprint modules
75     sys.modules[spec.name] = dynamic_module
76     spec.loader.exec_module(dynamic_module)
77     script_clazz = getattr(dynamic_module, action_name)
78     return script_clazz()
79
80
81 def log_response(input: ExecutionServiceInput, message: str):
82     payload = struct_pb2.Struct()
83     payload['message'] = message
84     status = Status()
85     status.timestamp = current_time()
86     status.eventType = EVENT_COMPONENT_TRACE
87     return ExecutionServiceOutput(commonHeader=input.commonHeader,
88                                   actionIdentifiers=input.actionIdentifiers,
89                                   payload=payload, status=status)
90
91
92 def send_notification(input: ExecutionServiceInput, message: str):
93     payload = struct_pb2.Struct()
94     payload['message'] = message
95     status = Status()
96     status.timestamp = current_time()
97     status.eventType = EVENT_COMPONENT_NOTIFICATION
98     return ExecutionServiceOutput(commonHeader=input.commonHeader,
99                                   actionIdentifiers=input.actionIdentifiers,
100                                   payload=payload, status=status)
101
102
103 def ack_response(input: ExecutionServiceInput):
104     timestamp = Timestamp()
105     timestamp.GetCurrentTime()
106     response_common_header = input.commonHeader
107     status = Status()
108     status.timestamp = current_time()
109     status.eventType = EVENT_COMPONENT_PROCESSING
110     return ExecutionServiceOutput(commonHeader=response_common_header,
111                                   actionIdentifiers=input.actionIdentifiers,
112                                   status=status)
113
114
115 def success_response(input: ExecutionServiceInput, property_json: json, code: int):
116     timestamp = Timestamp()
117     timestamp.GetCurrentTime()
118     status = Status()
119     status.timestamp = current_time()
120     status.eventType = EVENT_COMPONENT_EXECUTED
121     status.code = code
122     status.message = 'success'
123     payload_struct = create_response_payload_from_json(input.actionIdentifiers.actionName, property_json)
124     return ExecutionServiceOutput(commonHeader=input.commonHeader,
125                                   actionIdentifiers=input.actionIdentifiers, status=status, payload=payload_struct)
126
127
128 def failure_response(input: ExecutionServiceInput, property_json: json, error_code: int,
129                      error_message: str):
130     timestamp = Timestamp()
131     timestamp.GetCurrentTime()
132     status = Status()
133     status.timestamp = current_time()
134     status.eventType = EVENT_COMPONENT_EXECUTED
135     status.code = error_code
136     status.message = 'failure'
137     payload_struct = create_response_payload_from_json(input.actionIdentifiers.actionName, property_json)
138     status.errorMessage = error_message
139     return ExecutionServiceOutput(commonHeader=input.commonHeader,
140                                   actionIdentifiers=input.actionIdentifiers, status=status, payload=payload_struct)
141
142
143 def create_response_payload_from_json(action_name, property_json: json):
144     # Create response Pay load json from property Json
145     payload_key = action_name + '-response'
146     response_payload = {}
147     response_payload[payload_key] = property_json
148     response_payload_json = json.dumps(response_payload)
149     # Create Struct from Json
150     payload_struct = struct_pb2.Struct()
151     json_format.Parse(str(response_payload_json), payload_struct, ignore_unknown_fields=True)
152     return payload_struct