223 lines
7.6 KiB
Plaintext
223 lines
7.6 KiB
Plaintext
from urllib2_aws4auth import aws_urlopen, Request
|
|
from urllib2 import HTTPError
|
|
from urllib import urlencode
|
|
import json
|
|
import system
|
|
import boto3
|
|
from pprint import pformat
|
|
|
|
STAGE = 'prod'
|
|
STAGE_CONFIG = {
|
|
'alpha':{
|
|
'region':'us-east-1',
|
|
'endpoint': 'https://0wuzuy9rx3.execute-api.us-east-1.amazonaws.com/prod/user-activity-logger'
|
|
},
|
|
'beta': {
|
|
'region':'us-east-1',
|
|
'endpoint': 'https://33ymuc1b2a.execute-api.us-east-1.amazonaws.com/prod/user-activity-logger'
|
|
},
|
|
'prod': {
|
|
'region':'us-east-1',
|
|
'endpoint': 'https://ahikprejp4.execute-api.us-east-1.amazonaws.com/prod/user-activity-logger'
|
|
}
|
|
}
|
|
REGION = STAGE_CONFIG.get(STAGE, 'alpha').get('region', 'us-east-1')
|
|
SERVICE = 'execute-api'
|
|
ENDPOINT = STAGE_CONFIG.get(STAGE, 'alpha').get('endpoint', 'https://0wuzuy9rx3.execute-api.us-east-1.amazonaws.com/prod/user-activity-logger')
|
|
LOGGER = system.util.getLogger('productMetrics')
|
|
|
|
def openSession():
|
|
CREDS = boto3.Session().get_credentials()
|
|
AWS_ACCESS_KEY_ID = CREDS.access_key
|
|
AWS_SECRET_ACCESS_KEY = CREDS.secret_key
|
|
TOKEN = CREDS.token
|
|
|
|
OPENER = aws_urlopen(
|
|
AWS_ACCESS_KEY_ID,
|
|
AWS_SECRET_ACCESS_KEY,
|
|
REGION,
|
|
SERVICE,
|
|
session_token=TOKEN,
|
|
verify=False)
|
|
return OPENER
|
|
|
|
def formatPayload(payload):
|
|
"""Formats the payload based on what API expects to receive in the payload
|
|
Also adds in some defaults (nulls) for the optional fields in case they are skipped from the payload
|
|
Since defaults are not defined to required fields, will throw an error if they are not provided in the payload
|
|
Args:
|
|
payload (dict):all the fields that need to be sent to the API
|
|
|
|
Returns:
|
|
dict: dict formatted correctly for the API call
|
|
"""
|
|
data = {
|
|
"project_id": "scada-activity-logger", #key used to log hashed user product metrics in backend, not the name of ignition project.
|
|
"stage": payload.get("stage"),
|
|
"plugin": "scada_activity_logger",
|
|
"payload": {
|
|
"username": payload.get("username"),
|
|
"session_id": payload.get("session_id"),
|
|
"site": payload.get("site"),
|
|
"start_time": payload.get("start_time"),
|
|
"end_time": payload.get("end_time", None),
|
|
"user_UTCoffset": payload.get("user_UTCoffset", None),
|
|
"resource_type": payload.get("resource_type"),
|
|
"resource": payload.get("resource"),
|
|
"current_page": payload.get("current_page"),
|
|
"concurrent_users": payload.get("concurrent_users", getConcurrentUsers())
|
|
}
|
|
}
|
|
return data
|
|
|
|
def getConcurrentUsers():
|
|
"""Get the number of concurrent user session for the current project
|
|
|
|
Returns:
|
|
int: number of concurrent users
|
|
"""
|
|
project_name = system.project.getProjectName()
|
|
concurrent_users = len(system.perspective.getSessionInfo())
|
|
return concurrent_users
|
|
|
|
def createActivityPayload(viewObj, resource_type, resource = None, current_page= None):
|
|
"""Creates the activity payload for hashed user product metrics
|
|
Typically called from view shutdown event script
|
|
Uses the info from the view's custom param named activity_logger and session params to build the payload
|
|
|
|
Args:
|
|
viewObj: reference to the view (since custom param activity_logger is created on the view). If calling this function from a component pass self.view, if calling from view event scripts, pass self
|
|
resource_type (string): page/session/click
|
|
resource (string, optional): The resource that user interacted with. page name if interaction was with a page, feature/button name if it was a user click type interaction. Defaults to None.
|
|
current_page (string, optional): Page name that the user is on when the interaction takes place. Defaults to None.
|
|
|
|
Returns:
|
|
dict: payload that needs to be formatted before sending to the API
|
|
"""
|
|
if viewObj.session.custom.product_metrics.enable and viewObj.session.props.device.type != 'designer':
|
|
# since viewObj is a reference to the view, viewObj.session is reference to session
|
|
session = viewObj.session
|
|
stage = session.props.gateway.address
|
|
user = session.props.auth.user.userName
|
|
session_id = session.props.id
|
|
site = session.custom.fc
|
|
start_time = system.date.format(viewObj.custom.activityLogger.start_time, 'yyyy-MM-dd HH:mm:ss')
|
|
end_time = None
|
|
user_UTCoffset = session.props.device.timezone.utcOffset
|
|
concurrent_users = getConcurrentUsers()
|
|
if resource_type == 'page':
|
|
end_time = system.date.format(system.date.now(), 'yyyy-MM-dd HH:mm:ss')
|
|
try:
|
|
pageid = viewObj.custom.activityLogger.pageid
|
|
resource = pageid if resource == None else resource
|
|
current_page = pageid if current_page == None else current_page
|
|
except:
|
|
pass
|
|
if resource_type == 'click':
|
|
start_time = system.date.format(system.date.now(), 'yyyy-MM-dd HH:mm:ss')
|
|
end_time = None
|
|
try:
|
|
pageid = viewObj.custom.activityLogger.pageid
|
|
# resource = pageid if resource == None else resource
|
|
current_page = pageid if current_page == None else current_page
|
|
except:
|
|
pass
|
|
|
|
payload = {
|
|
"stage": stage,
|
|
"username": user,
|
|
"session_id": session_id,
|
|
"site": site,
|
|
"start_time": start_time,
|
|
"end_time": end_time,
|
|
"resource_type": resource_type,
|
|
"resource": resource,
|
|
"current_page": current_page,
|
|
"user_UTCoffset": user_UTCoffset,
|
|
"concurrent_users": concurrent_users
|
|
}
|
|
activityPayload = formatPayload(payload)
|
|
return activityPayload
|
|
else:
|
|
return None
|
|
|
|
def callActivityLoggerAPI(activityPayload):
|
|
"""Makes a post api call with the provided payload to log hashed user product metrics
|
|
Handles converting the payload from dict to json
|
|
|
|
Args:
|
|
activityPayload (dict): Final payload that needs to be sent to the API
|
|
Function will convert the payload to json
|
|
"""
|
|
if activityPayload:
|
|
opener = openSession()
|
|
params = activityPayload
|
|
payload = json.dumps(params)
|
|
method = 'POST'
|
|
# in the headers the Ignition session username (session.props.auth.user.userName) must be supplied as 'X-Ignition-User'
|
|
headers = {
|
|
'Content-type': 'application/json',
|
|
}
|
|
req = Request(url=ENDPOINT, method=method, data=payload, headers=headers)
|
|
# open the request and process the read
|
|
try:
|
|
resp = opener(req)
|
|
response = json.loads(resp.read())
|
|
error = None
|
|
except HTTPError, e:
|
|
error = str(e)
|
|
response = None
|
|
system.perspective.print(error)
|
|
LOGGER.info(error)
|
|
return {'error': error, 'response':response }
|
|
|
|
def callLogger(viewObj, resource_type, resource = None, current_page= None):
|
|
"""Combines the createActivityPayload and callActivityLoggerAPI to log hashed user product metrics
|
|
Typically called from view shutdown event script
|
|
Uses the info from the view's custom param named activity_logger and session params to build the payload
|
|
"""
|
|
activityPayload = createActivityPayload(viewObj, resource_type, resource, current_page)
|
|
if activityPayload:
|
|
callActivityLoggerAPI(activityPayload)
|
|
|
|
|
|
|
|
def testapi():
|
|
print STAGE
|
|
user = 'ankikarw'
|
|
opener = openSession()
|
|
params = {
|
|
"project_id": "scada-activity-logger",
|
|
"stage": "api test alpha",
|
|
"plugin": "scada_activity_logger",
|
|
"payload": {
|
|
"username": "user",
|
|
"session_id": "1234567989",
|
|
"site": "EWR4",
|
|
"start_time": "2023-11-06 10:45:25",
|
|
"end_time": "2023-11-06 10:57:18",
|
|
"user_UTCoffset": "-8",
|
|
"resource_type": "page",
|
|
"resource": "home",
|
|
"current_page": "home",
|
|
"concurrent_users": "5"
|
|
}
|
|
}
|
|
payload = json.dumps(params)
|
|
method = 'POST'
|
|
headers = {
|
|
'Content-type': 'application/json',
|
|
}
|
|
req = Request(url=ENDPOINT, method=method, data=payload, headers=headers)
|
|
# open the request and process the read
|
|
try:
|
|
resp = opener(req)
|
|
response = json.loads(resp.read())
|
|
error = None
|
|
print response
|
|
except HTTPError, e:
|
|
error = str(e)
|
|
response = None
|
|
print error
|
|
LOGGER.info(error)
|
|
return {'error': error, 'response':response } |