def get_asset(id): """ Get asset by id. Object response for the GET(id) request. This response is NOT cached. """ try: uframe_url, timeout, timeout_read = get_uframe_assets_info() if id == 0: error = 'Zero (0) is an invalid asset id value.' current_app.logger.info(error) return make_response(error, 400) url = '/'.join([uframe_url, 'assets', str(id)]) payload = requests.get(url, timeout=(timeout, timeout_read)) if payload.status_code != 200: error = 'Unable to locate an asset with an id of %d.' % id current_app.logger.info(error) return make_response(error, 400) data = payload.json() data_list = [data] result, _ = _compile_assets(data_list) return jsonify(**result[0]) except ConnectionError: error = 'Error: ConnectionError during GET request for asset with id %d.' % id current_app.logger.info(error) return bad_request(error) except Timeout: error = 'Error: Timeout during GET request for asset with id %d.' % id current_app.logger.info(error) return bad_request(error) except Exception as err: error = 'Error processing GET request for asset with id %d. %s' % (id, str(err)) current_app.logger.info(error) return bad_request(error)
def delete_asset(id): """ Delete an asset by id. """ this_asset = "" try: url = current_app.config['UFRAME_ASSETS_URL'] + '/assets/%s' % str(id) response = requests.delete(url, headers=_uframe_headers()) asset_cache = cache.get('asset_list') if asset_cache: cache.delete('asset_list') for row in asset_cache: if row['id'] == id: this_asset = row break if this_asset: cache.delete('asset_list') asset_cache.remove(this_asset) cache.set('asset_list', asset_cache, timeout=CACHE_TIMEOUT) return response.text, response.status_code except ConnectionError: message = 'ConnectionError during delete asset.' current_app.logger.info(message) return bad_request(message) except Timeout: message = 'Timeout during during delete asset.' current_app.logger.info(message) return bad_request(message) except Exception as err: message = str(err) current_app.logger.info(message) return bad_request(message)
def get_asset_events(id): """ Get events for asset id. """ try: if id == 0: error = 'Zero (0) is an invalid asset id value, unable to GET asset events without valid asset id.' current_app.logger.info(error) return bad_request(error) uframe_url, timeout, timeout_read = get_uframe_assets_info() url = "/".join([uframe_url, 'assets', str(id), 'events']) payload = requests.get(url, timeout=(timeout, timeout_read), headers=_uframe_headers()) if payload.status_code != 200: error = '(%d) GET request failed for asset (id %d) events.' % (payload.status_code, id) current_app.logger.info(error) return bad_request(error) data = payload.json() for each in data: each['eventClass'] = each.pop('@class') return jsonify({'events': data}) except ConnectionError: error = 'Error: ConnectionError during GET request for asset (id %d) events.' % id current_app.logger.info(error) return bad_request(error) except Timeout: error = 'Error: Timeout during GET request for asset (id %d) events.' % id current_app.logger.info(error) return bad_request(error) except Exception as err: error = 'Error processing GET request for asset (id %d) events. %s' % (id, str(err)) current_app.logger.info(error) return bad_request(error)
def create_asset(): """ Create a new asset, the return will be uframe asset format (not ooi-ui-services format). Cache ('asset_list') is updated with new asset Either a success or an error message. Login required. """ debug = False try: data = json.loads(request.data) if valid_create_asset_request_data(data): if debug: print '\n debug validated required fields...' url = current_app.config['UFRAME_ASSETS_URL'] + '/%s' % 'assets' if 'lastModifiedTimestamp' in data: del data['lastModifiedTimestamp'] if 'asset_class' in data: data['@class'] = data.pop('asset_class') # Create asset in uframe response = requests.post(url, data=json.dumps(data), headers=_uframe_headers()) if response.status_code == 201: json_response = json.loads(response.text) data['assetId'] = json_response['id'] data['tense'] = 'NEW' data_list = [data] try: compiled_data, _ = _compile_assets(data_list) except Exception: raise if not compiled_data or compiled_data is None: raise Exception('_compile_assets returned empty or None result.') # Update asset cache ('asset_list') asset_cache = cache.get('asset_list') if asset_cache: cache.delete('asset_list') asset_cache.append(compiled_data[0]) cache.set('asset_list', asset_cache, timeout=CACHE_TIMEOUT) else: return bad_request('Failed to create asset!') return response.text, response.status_code except ConnectionError: message = 'ConnectionError during create asset.' current_app.logger.info(message) return bad_request(message) except Timeout: message = 'Timeout during during create asset.' current_app.logger.info(message) return bad_request(message) except Exception as err: message = str(err) current_app.logger.info(message) return bad_request(message)
def update_asset(id): """ Update asset by id. Last writer wins; new format of request.data to be handled (post 5/31): {"assetInfo.array":"EnduranceAss","assetInfo.assembly":"testass","oper":"edit","id":"227"} """ try: data = json.loads(request.data) if 'asset_class' in data: data['@class'] = data.pop('asset_class') url = current_app.config['UFRAME_ASSETS_URL'] + '/%s/%s' % ('assets', id) response = requests.put(url, data=json.dumps(data), headers=_uframe_headers()) if response.status_code != 200: message = '(%d) Failed to update asset %d.' % (response.status_code, id) return bad_request(message) if response.status_code == 200: data_list = [data] try: compiled_data, _ = _compile_assets(data_list) except Exception: raise if not compiled_data or compiled_data is None: raise Exception('_compile_assets returned empty or None result.') asset_cache = cache.get('asset_list') if "error" in asset_cache: message = 'Error returned in \'asset_list\' cache; unable to update cache.' return bad_request(message) if asset_cache: cache.delete('asset_list') for row in asset_cache: if row['id'] == id: row.update(compiled_data[0]) break cache.set('asset_list', asset_cache, timeout=CACHE_TIMEOUT) return response.text, response.status_code except ConnectionError: message = 'Error: ConnectionError during update asset request (id: %d)' % id current_app.logger.info(message) return bad_request(message) except Timeout: message = 'Error: Timeout during during update asset request (id: %d)' % id current_app.logger.info(message) return bad_request(message) except Exception as err: message = str(err) current_app.logger.info(message) return bad_request(message)
def update_user_event_notification(id): """ Update user_event_notification associated with SystemEventDefinition. """ log = False try: data = json.loads(request.data) # Get existing notification notification_id = data['id'] if notification_id != id: message = "Inconsistent ID, user_event_notification id provided in data does not match id provided." return bad_request(message) notification = UserEventNotification.query.filter_by( id=notification_id).first() #print '\n test notification...' if notification is None: message = "Invalid ID, user_event_notification record not found." #print '\n message: ', message return bad_request(message) # Validate user to be notified exists user = User.query.filter_by(id=notification.user_id).first() # Validate user_id matches id value user_id = data['user_id'] if user_id != notification.user_id: message = "Inconsistent User ID, user_id provided in data does not match id." return bad_request(message) notification.system_event_definition_id = data[ 'system_event_definition_id'] notification.user_id = data['user_id'] notification.use_email = data['use_email'] notification.use_redmine = data['use_redmine'] notification.use_phone = data['use_phone'] notification.use_log = data['use_log'] notification.use_sms = data['use_sms'] try: db.session.add(notification) db.session.commit() except Exception as err: db.session.rollback() return bad_request( 'IntegrityError creating user_event_notification.') #print '\n notification.to_json(): ', notification.to_json() return jsonify(notification.to_json()), 201 except Exception as err: #if log: print '\n (log) update_user_event_notification - exception: ', err.message return conflict('Insufficient data, or bad data format.')
def create_user_event_notification(): """ Create user_event_notification associated with SystemEventDefinition. Usage: Whenever a SystemEvent occurs, for the system_event_definition_id, this notification indicates who and how to contact them with the SystemEvent information. """ log = False try: data = json.loads(request.data) create_has_required_fields(data) system_event_definition_id = data['system_event_definition_id'] definition = SystemEventDefinition.query.get( system_event_definition_id) if definition is None: message = "Invalid SystemEventDefinition ID, SystemEventDefinition record not found." #if log: print '\n message: ', message return bad_request(message) #return jsonify(error=message), 404 # Validate user to be notified exists user_id = data['user_id'] user = User.query.filter_by(id=user_id).first() if not user: message = "Invalid User ID, User record not found." #if log: print '\n message: ', message return bad_request(message) # Create UserEventNotification notification = UserEventNotification() notification.system_event_definition_id = data[ 'system_event_definition_id'] notification.user_id = data['user_id'] notification.use_email = data['use_email'] notification.use_redmine = data['use_redmine'] notification.use_phone = data['use_phone'] notification.use_log = data['use_log'] notification.use_sms = data['use_sms'] try: db.session.add(notification) db.session.commit() except Exception as err: #if log: print '\n (log) create_user_event_notification - message: ', err.message db.session.rollback() return bad_request('IntegrityError creating notification') return jsonify(notification.to_json()), 201 except Exception as err: #if log: print '\n (log) create_user_event_notification - exception: ', err.message return conflict('Insufficient data, or bad data format.')
def create_user_event_notification(): """ Create user_event_notification associated with SystemEventDefinition. Usage: Whenever a SystemEvent occurs, for the system_event_definition_id, this notification indicates who and how to contact them with the SystemEvent information. """ log = False try: data = json.loads(request.data) create_has_required_fields(data) system_event_definition_id = data['system_event_definition_id'] definition = SystemEventDefinition.query.get(system_event_definition_id) if definition is None: message = "Invalid SystemEventDefinition ID, SystemEventDefinition record not found." #if log: print '\n message: ', message return bad_request(message) #return jsonify(error=message), 404 # Validate user to be notified exists user_id = data['user_id'] user = User.query.filter_by(id=user_id).first() if not user: message = "Invalid User ID, User record not found." #if log: print '\n message: ', message return bad_request(message) # Create UserEventNotification notification = UserEventNotification() notification.system_event_definition_id = data['system_event_definition_id'] notification.user_id = data['user_id'] notification.use_email = data['use_email'] notification.use_redmine = data['use_redmine'] notification.use_phone = data['use_phone'] notification.use_log = data['use_log'] notification.use_sms = data['use_sms'] try: db.session.add(notification) db.session.commit() except Exception as err: #if log: print '\n (log) create_user_event_notification - message: ', err.message db.session.rollback() return bad_request('IntegrityError creating notification') return jsonify(notification.to_json()), 201 except Exception as err: #if log: print '\n (log) create_user_event_notification - exception: ', err.message return conflict('Insufficient data, or bad data format.')
def update_user_event_notification(id): """ Update user_event_notification associated with SystemEventDefinition. """ log = False try: data = json.loads(request.data) # Get existing notification notification_id = data['id'] if notification_id != id: message = "Inconsistent ID, user_event_notification id provided in data does not match id provided." return bad_request(message) notification = UserEventNotification.query.filter_by(id=notification_id).first() #print '\n test notification...' if notification is None: message = "Invalid ID, user_event_notification record not found." #print '\n message: ', message return bad_request(message) # Validate user to be notified exists user = User.query.filter_by(id=notification.user_id).first() # Validate user_id matches id value user_id = data['user_id'] if user_id != notification.user_id: message = "Inconsistent User ID, user_id provided in data does not match id." return bad_request(message) notification.system_event_definition_id = data['system_event_definition_id'] notification.user_id = data['user_id'] notification.use_email = data['use_email'] notification.use_redmine = data['use_redmine'] notification.use_phone = data['use_phone'] notification.use_log = data['use_log'] notification.use_sms = data['use_sms'] try: db.session.add(notification) db.session.commit() except Exception as err: db.session.rollback() return bad_request('IntegrityError creating user_event_notification.') #print '\n notification.to_json(): ', notification.to_json() return jsonify(notification.to_json()), 201 except Exception as err: #if log: print '\n (log) update_user_event_notification - exception: ', err.message return conflict('Insufficient data, or bad data format.')
def c2_get_array_mission_display(array_code): #Get C2 array mission (display), return mission_display (contents of platform Mission tab) array = Array.query.filter_by(array_code=array_code).first() if not array: return bad_request('unknown array (array_code: \'%s\')' % array_code) mission_display = {} return jsonify(mission_display=mission_display)
def c2_get_array_mission_display(array_code): #Get C2 array mission (display), return mission_display (contents of platform Mission tab) array = Array.query.filter_by(array_code=array_code).first() if not array: return bad_request('unknown array (array_code: \'%s\')' % array_code) mission_display = {} return jsonify(mission_display=mission_display)
def c2_get_missions(): """ Get list of missions. """ valid_states = ['active', 'inactive'] missions = [] try: state = None if request.args: if 'state' in request.args: state = (request.args['state']).lower() if state not in valid_states: state = None result = uframe_get_missions(state) ids = [] if result is not None: for item in result: ids.append(item['mission_id']) tmp = make_mission_response(ids) if tmp is not None: missions = tmp return jsonify(missions=missions) except Exception as err: message = str(err.message) current_app.logger.info(message) return bad_request(message)
def c2_direct_access_start(reference_designator): """ Start direct access. (when button 'Start Direct' is selected.) (Transition from 'DRIVER_STATE_COMMAND' to 'DRIVER_STATE_DIRECT_ACCESS'.) POST Sample: http://uft21.ooi.rutgers.edu:12572/instrument/api/RS10ENGC-XX00X-00-FLORDD001/start Command: "DRIVER_EVENT_START_DIRECT" """ rd = reference_designator NOT_NONE = 'NOT_NONE' state_DRIVER_STATE_COMMAND = 'DRIVER_STATE_COMMAND' capability_DRIVER_EVENT_START_DIRECT = 'DRIVER_EVENT_START_DIRECT' target_state = 'DRIVER_STATE_DIRECT_ACCESS' try: # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Prepare to execute - direct access start command # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Validate reference_designator _state, _capabilities, result = direct_access_get_state_and_capabilities(rd) if _state == target_state: return jsonify(result) # Verify _state and _capabilities match expected state and capabilities verify_state_and_capabilities(rd, _state, _capabilities, expected_state=state_DRIVER_STATE_COMMAND, expected_capability=capability_DRIVER_EVENT_START_DIRECT) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Execute driver command 'DRIVER_EVENT_START_DIRECT' on upstream server # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Execute driver command suffix = 'command=%22DRIVER_EVENT_START_DIRECT%22&timeout=60000' response = uframe_post_instrument_driver_command(reference_designator, 'execute', suffix) if response.status_code != 200: message = '(%s) execute %s failed.' % (str(response.status_code), capability_DRIVER_EVENT_START_DIRECT) if response.content: message = '(%s) %s' % (str(response.status_code), str(response.content)) raise Exception(message) # Validate reference_designator _state, _capabilities, result = direct_access_get_state_and_capabilities(rd) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Final - direct access response final checks for success or failure # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Verify _state and _capabilities match expected state and capabilities verify_state_and_capabilities(rd, _state, _capabilities, expected_state=target_state, expected_capability=NOT_NONE) return jsonify(result) except Exception as err: message = '(%s) exception: %s' % (rd, err.message) current_app.logger.info(message) return bad_request(err.message)
def c2_get_instrument_mission_selection(reference_designator, mission_plan_store): # C2 get [instrument] selected mission_plan content from store (file, uframe), return mission_plan if not mission_plan_store: return bad_request('mission_plan_store parameter is empty') mission_plan = {} instrument = _get_instrument(reference_designator) if instrument: mission_plan = _get_mission_selection(mission_plan_store) return jsonify(mission_plan=mission_plan)
def c2_get_platform_mission_selection(reference_designator, mission_plan_store): # C2 get [platform] selected mission_plan content, return mission_plan if not mission_plan_store: return bad_request('mission_plan_store parameter is empty') mission_plan = {} platform = _get_platform(reference_designator) if platform: mission_plan = _get_mission_selection(mission_plan_store) return jsonify(mission_plan=mission_plan)
def _get_mission_selection(mission_plan_store): mission_plan = [] response_text = json_get_uframe_mission_selection(mission_plan_store) if response_text: try: mission_plan.append(response_text) except: return bad_request('Malformed mission_plan data; not in valid json format.') return mission_plan
def c2_direct_access_exit(reference_designator): """ Exit direct access. (when button 'Exit Direct' is selected.) Transition from 'DRIVER_STATE_DIRECT_ACCESS' to 'DRIVER_STATE_COMMAND' (execute 'DRIVER_EVENT_STOP_DIRECT') """ rd = reference_designator NOT_NONE = 'NOT_NONE' state_DRIVER_STATE_DIRECT_ACCESS = 'DRIVER_STATE_DIRECT_ACCESS' capability_DRIVER_EVENT_STOP_DIRECT = 'DRIVER_EVENT_STOP_DIRECT' target_state = 'DRIVER_STATE_COMMAND' try: # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Prepare to execute - direct access start command # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Validate reference_designator _state, _capabilities, result = direct_access_get_state_and_capabilities(rd) # If current state is the same as target state, return status result if _state == target_state: return jsonify(result) # Verify current _state and _capabilities match expected state and capabilities verify_state_and_capabilities(rd, _state, _capabilities, expected_state=state_DRIVER_STATE_DIRECT_ACCESS, expected_capability=capability_DRIVER_EVENT_STOP_DIRECT) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Execute driver command 'DRIVER_EVENT_STOP_DIRECT' on upstream server # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - suffix = 'command=%22DRIVER_EVENT_STOP_DIRECT%22&timeout=60000' # Execute driver command response = uframe_post_instrument_driver_command(reference_designator, 'execute', suffix) if response.status_code != 200: message = '(%s) execute %s failed.' % (str(response.status_code), capability_DRIVER_EVENT_STOP_DIRECT) if response.content: message = '(%s) %s' % (str(response.status_code), str(response.content)) raise Exception(message) # Validate reference_designator _state, _capabilities, result = direct_access_get_state_and_capabilities(rd) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Final - direct access response final checks for success or failure # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Verify _state and _capabilities match expected state and capabilities verify_state_and_capabilities(rd, _state, _capabilities, expected_state=target_state, expected_capability=NOT_NONE) return jsonify(result) except Exception as err: message = '(%s) exception: %s' % (rd, err.message) current_app.logger.info(message) return bad_request(err.message)
def get_all_assets(): """ Get bad assets. """ try: results = _get_all_assets() return jsonify({"assets": results}) except ConnectionError: message = 'ConnectionError during get bad assets.' current_app.logger.info(message) return bad_request(message) except Timeout: message = 'Timeout during during get bad asset.' current_app.logger.info(message) return bad_request(message) except Exception as err: message = str(err) current_app.logger.info(message) return bad_request(message)
def update_user_event_notification(id): """ Update user_event_notification associated with SystemEventDefinition. """ try: data = json.loads(request.data) # Get existing notification notification_id = data["id"] if notification_id != id: message = "Inconsistent ID, user_event_notification id provided in data does not match id provided." return bad_request(message) notification = UserEventNotification.query.filter_by(id=notification_id).first() if notification is None: message = "Invalid ID, user_event_notification record not found." return bad_request(message) # Validate user to be notified exists user = User.query.filter_by(id=notification.user_id).first() # Validate user_id matches id value user_id = data["user_id"] if user_id != notification.user_id: message = "Inconsistent User ID, user_id provided in data does not match id." return bad_request(message) notification.system_event_definition_id = data["system_event_definition_id"] notification.user_id = data["user_id"] notification.use_email = data["use_email"] notification.use_redmine = data["use_redmine"] notification.use_phone = data["use_phone"] notification.use_log = data["use_log"] notification.use_sms = data["use_sms"] try: db.session.add(notification) db.session.commit() except: db.session.rollback() return bad_request("IntegrityError creating user_event_notification.") return jsonify(notification.to_json()), 201 except: return conflict("Insufficient data, or bad data format.")
def _get_mission_selection(mission_plan_store): mission_plan = [] response_text = json_get_uframe_mission_selection(mission_plan_store) if response_text: try: mission_plan.append(response_text) except: return bad_request( 'Malformed mission_plan data; not in valid json format.') return mission_plan
def c2_mission_run(mission_id, run_id): """ Get mission run. """ try: result = uframe_mission_run(mission_id, run_id) return jsonify(result), 200 except Exception as err: message = err.message current_app.logger.info(message) return bad_request(message)
def c2_get_instrument_mission_selection(reference_designator, mission_plan_store): # C2 get [instrument] selected mission_plan content from store (file, uframe), return mission_plan if not mission_plan_store: return bad_request('mission_plan_store parameter is empty') mission_plan = {} instrument = _get_instrument(reference_designator) if instrument: mission_plan = _get_mission_selection(mission_plan_store) return jsonify(mission_plan=mission_plan)
def _get_mission_selections(reference_designator): mission_selections = [] response_text = json_get_uframe_mission_selections(reference_designator) if response_text: try: mission_selections = json.loads(response_text) except: return bad_request('Malformed mission_selections; not in valid json format. (reference designator \'%s\')' % reference_designator) return mission_selections
def c2_get_platform_mission_selection(reference_designator, mission_plan_store): # C2 get [platform] selected mission_plan content, return mission_plan if not mission_plan_store: return bad_request('mission_plan_store parameter is empty') mission_plan = {} platform = _get_platform(reference_designator) if platform: mission_plan = _get_mission_selection(mission_plan_store) return jsonify(mission_plan=mission_plan)
def c2_deactivate_mission(mission_id): """ Deactivate a mission. """ try: result = uframe_deactivate_mission(mission_id) mission = get_mission_info(mission_id, result) return jsonify(mission=mission), 200 except Exception as err: message = err.message current_app.logger.info(message) return bad_request(message)
def get_vocabulary(): """ Get dict of all vocabulary entries. Key is reference designator, value is display name. """ try: vocab_dict = get_vocab() return jsonify({'vocab': vocab_dict}) except Exception as err: message = 'Error getting uframe vocabulary; %s' % str(err) current_app.logger.info(message) return bad_request(message)
def _get_mission_selections(reference_designator): mission_selections = [] response_text = json_get_uframe_mission_selections(reference_designator) if response_text: try: mission_selections = json.loads(response_text) except: return bad_request( 'Malformed mission_selections; not in valid json format. (reference designator \'%s\')' % reference_designator) return mission_selections
def c2_delete_mission(mission_id): """ Delete a mission. """ try: mission = {} result = uframe_delete_mission(mission_id) if result is not None: mission = result return jsonify(mission) except Exception as err: message = err.message current_app.logger.info(message) return bad_request(message)
def c2_mission_set_version(mission_id, version_id): """ Set mission version. """ try: if request.data is None: message = 'Provide request data to set script version.' raise Exception(message) result = uframe_mission_set_version(mission_id, version_id) return jsonify(result), 200 except Exception as err: message = err.message current_app.logger.info(message) return bad_request(message)
def c2_instrument_lock(reference_designator): """ Lock instrument. """ debug = True rd = reference_designator #status = {} current_user_data = {"locked-by": "*****@*****.**", "key": "*****@*****.**"} try: if debug: print '\n debug -- c2_instrument_lock entered...' try: result = get_lock_status(rd) if debug: print '\n result: ', result except: raise payload = json.dumps(current_user_data) print '\n payload: ', payload response = uframe_post_instrument_lock(rd,'lock', payload) if response.status_code != 201: if debug: print '\n (%d) failed to post lock...' % response.status_code message = 'Failed to lock instrument, status code: %d' % response.status_code raise Exception(message) # Determine result of POST answer = None if response.content: try: answer = json.loads(response.content) except: message = 'Failed to parse malformed json.' if debug: print '\n exception: ', message raise Exception(message) if debug: print '\n answer: ', answer # Check lock status try: status = get_lock_status(rd) if debug: print '\n status: ', status except: raise if debug: print '\n check status: ', status return jsonify(status) except Exception as err: message = '(%s) exception: %s' % (reference_designator, err.message) if debug: print '\n exception: ', message current_app.logger.info(message) return bad_request(err.message)
def c2_instrument_get_lock(reference_designator): """ Get instrument lock status. """ status = {} debug = False rd = reference_designator try: if debug: print '\n debug -- c2_instrument_get_lock entered...' status = get_lock_status(rd) return jsonify(status) except Exception as err: message = '(%s) exception: %s' % (reference_designator, err.message) if debug: print '\n exception: ', message current_app.logger.info(message) return bad_request(err.message)
def get_user_event_notifications(): """ List all user_event_notifications (by user_id if provided) """ result = [] try: if "user_id" in request.args: user_id = request.args.get("user_id") user = User.query.get(user_id) if user is None: message = "Invalid User ID, User record not found." return bad_request(message) notifications = UserEventNotification.query.filter_by(user_id=user_id).all() else: notifications = UserEventNotification.query.all() if notifications: result = [notify.to_json() for notify in notifications] return jsonify({"notifications": result}) except: return conflict("Insufficient data, or bad data format.")
def get_user_event_notifications(): """ List all user_event_notifications (by user_id if provided) """ result = [] try: if 'user_id' in request.args: user_id = request.args.get('user_id') user = User.query.get(user_id) if user is None: message = "Invalid User ID, User record not found." return bad_request(message) notifications = UserEventNotification.query.filter_by( user_id=user_id).all() else: notifications = UserEventNotification.query.all() if notifications: result = [notify.to_json() for notify in notifications] return jsonify({'notifications': result}) except: return conflict('Insufficient data, or bad data format.')
def c2_add_mission(): """ Add a mission. """ try: if request.data is None: message = 'Provide request data to add new mission.' raise Exception(message) result = uframe_add_mission(request.data) if result is None or len(result) == 0: message = 'Failed to add new mission.' raise Exception(message) mission_id = result['id'] result = uframe_get_mission(mission_id) mission = get_mission_info(mission_id, result) return jsonify(mission=mission), 201 except Exception as err: message = err.message current_app.logger.info(message) return bad_request(message)
def c2_instrument_unlock(reference_designator): """ Unlock instrument. """ debug = False rd = reference_designator status = {} current_user_data = {"locked-by": None} try: if debug: print '\n debug -- c2_instrument_lock entered...' try: result = get_lock_status(rd) print '\n result: ', result except: raise payload = json.dumps(current_user_data) print '\n payload: ', payload response = uframe_post_instrument_lock(rd,'unlock', payload) if response.status_code != 201: print '\n (%d) failed to post lock...' % response.status_code status = None if response.content: try: status = json.loads(response.content) except: message = 'Failed to parse malformed json.' print '\n exception: ', message print '\n answer: ', status return jsonify(status) except Exception as err: message = '(%s) exception: %s' % (reference_designator, err.message) if debug: print '\n exception: ', message current_app.logger.info(message) return bad_request(err.message)
def update_notification_ticket(id): """ Update redmine ticket as a part of notification process (for alerts only) """ debug = False #log = False result = None try: # Get alert, definition and notification to update redmine ticket alert, definition, notification = get_redmine_info_from_alert(id) if alert is None or definition is None or notification is None: message = 'Failed to retrieve alert, definition or notification for update_notification_ticket. (id: %d)' % id raise Exception(message) # Populate required fields to create a redmine ticket project = current_app.config['REDMINE_PROJECT_ID'] # Use user_event_notification for determining assigned user's redmine id redmine_id = 1 name = None assigned_user = User.query.get(notification.user_id) if assigned_user is not None: name = assigned_user.first_name + ' ' + assigned_user.last_name tmp_id = get_user_redmine_id(project, name) if tmp_id is not None: redmine_id = tmp_id else: # todo issue - assigned_user is None message = "Invalid User ID, User record not found." #if log: print '\n message: ', message return bad_request(message) # Get alert ticket id ticket_id = alert.ticket_id #if debug: print '\n (debug) update_notification_ticket id: ', ticket_id ts_updated = dt.datetime.strftime(dt.datetime.now(), "%Y-%m-%dT%H:%M:%S") update_info = '\nUpdated: %s ' % ts_updated # Get current redmine ticket redmine_ticket = get_redmine_ticket_for_notification(ticket_id) # Set fields for update project = redmine_ticket['project'] subject = redmine_ticket['subject'] description = redmine_ticket['description'] priority = redmine_ticket['priority'] if 'assigned_to' in redmine_ticket: assigned_id = redmine_ticket['assigned_to'] else: # Use user_event_notification for determining assigned user's redmine id redmine_id = 1 name = None assigned_user = User.query.get(notification.user_id) if assigned_user is not None: name = assigned_user.first_name + ' ' + assigned_user.last_name tmp_id = get_user_redmine_id(project, name) if tmp_id is not None: redmine_id = tmp_id else: # todo issue - assigned_user is None message = "Invalid User ID, User record not found." #if log: print '\n message: ', message return bad_request(message) assigned_id = redmine_id # Update subject for recent receipt of alert (not past escalate boundary yet) description += update_info result = update_redmine_ticket_for_notification( ticket_id, project, subject, description, priority, assigned_id) if result is None: message = 'Failed to update redmine ticket (ticket_id: %d' % ticket_id raise Exception(message) if debug: print '\n \tupdate_notification_ticket - ticket_id: ', ticket_id return ticket_id except Exception as err: message = err.message current_app.logger.exception('[update_notification_ticket] %s ' % message) return result
def reissue_notification_ticket(id): """ Create another (re-issue) redmine ticket as a part of notification process (for alerts only) """ debug = False # development debug #log = False # used in except blocks result = None try: if debug: print '\n \t(debug) entered reissue_notification_ticket, id: ', id # Get alert, definition and notification to update redmine ticket alert, definition, notification = get_redmine_info_from_alert(id) if alert is None or definition is None or notification is None: message = 'Failed to retrieve alert, definition or notification for update_notification_ticket. (id: %d)' % id current_app.logger.exception('[update_notification_ticket] %s ' % message) raise Exception(message) # Populate required fields to create a redmine ticket project = current_app.config['REDMINE_PROJECT_ID'] if debug: print '\n \t(debug) -- Reissue redmine ticket (project: %s), get ticket_id...' % project print '\n \t(debug) -- Current ticket id: ', alert.ticket_id # Get current redmine ticket redmine_ticket = get_redmine_ticket_for_notification(alert.ticket_id) if debug: print '\n \t(debug) -- Current redmine ticket: ', redmine_ticket # Set assigned id to reflect update to user currently assigned to alert.ticket_id #assigned_id = redmine_ticket['assigned_to'] if 'assigned_to' in redmine_ticket: assigned_id = redmine_ticket['assigned_to'] else: # Use user_event_notification for determining assigned user's redmine id redmine_id = 1 name = None assigned_user = User.query.get(notification.user_id) if assigned_user is not None: name = assigned_user.first_name + ' ' + assigned_user.last_name tmp_id = get_user_redmine_id(project, name) if tmp_id is not None: redmine_id = tmp_id else: # todo issue - assigned_user is None message = "Invalid User ID, User record not found." #if log: print '\n message: ', message return bad_request(message) assigned_id = redmine_id # Update description to indicate previously issued ticket id for this alert. update_info = '\n* Associated with previously issued ticket: %d' % alert.ticket_id if debug: print '\n \t(debug) -- New reissued ticket update_info: ', update_info # Create new redmine ticket prefix = (alert.event_type).upper() + '*: ' subject = prefix + alert.event_response description = alert.event_response + update_info priority = definition.severity if debug: print '\n \t(debug) New ticket subject: ', subject if debug: print '\n \t(debug) New ticket description: ', description ticket_id = create_redmine_ticket_for_notification( project, subject, description, priority, assigned_id) if ticket_id is None: message = 'Failed to reissue (create another new)_redmine_ticket.' current_app.logger.exception('[reissue_notification_ticket] %s ' % message) return result # update escalate fields if successful creating the redmine ticket escalated = True ts_escalated = dt.datetime.strftime( dt.datetime.now(), "%Y-%m-%dT%H:%M:%S") # should this be event_time? SystemEvent.update_alert_alarm_escalation(id=alert.id, ticket_id=ticket_id, escalated=escalated, ts_escalated=ts_escalated) if debug: print '\n \t(debug) reissue_notification_ticket -- updated alert_alarm: ', alert.to_json( ) ticket_link_id = TicketSystemEventLink.insert_ticket_link( system_event_id=alert.id, ticket_id=ticket_id) if debug: print '\n \t(debug) -- (notifications) ticket_link_id: ', ticket_link_id ''' # debug - view contents of alert_alarm escalation fields; verify changes have been persisted escalated_alert_alarm = SystemEvent.query.get(alert_alarm.id) print '\n (debug) *** escalated alert_alarm.to_json(): ', escalated_alert_alarm.to_json() ''' result = ticket_id if debug: print '\n \treissue_notification_ticket - ticket_id: ', ticket_id except Exception as err: message = err.message current_app.logger.exception('[reissue_notification_ticket] %s ' % message) finally: return result
def c2_direct_access_exit(reference_designator): """ Exit direct access, transition to instrument driver state. If error, raise exception. Exit 'DRIVER_STATE_DIRECT_ACCESS', execute command 'DRIVER_EVENT_STOP_DIRECT'. """ debug = False rd = reference_designator state_DRIVER_STATE_DIRECT_ACCESS = 'DRIVER_STATE_DIRECT_ACCESS' capability_DRIVER_EVENT_STOP_DIRECT = 'DRIVER_EVENT_STOP_DIRECT' try: # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Prepare to execute - direct access start command # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Validate reference_designator, get status and capabilities _state, _capabilities, result = direct_access_get_state_and_capabilities(rd) # If current state is not in the state_DRIVER_STATE_DIRECT_ACCESS, then return status result # Log request to exit direct access state when not in direct access. if _state != state_DRIVER_STATE_DIRECT_ACCESS: message = 'Request to exit direct access for instrument %s, when in driver state %s' % (rd, _state) current_app.logger.info(message) return jsonify(result) # Verify current _state and _capabilities match expected state and capabilities verify_state_and_capabilities(rd, _state, _capabilities, expected_state=state_DRIVER_STATE_DIRECT_ACCESS, expected_capability=capability_DRIVER_EVENT_STOP_DIRECT) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Execute driver command 'DRIVER_EVENT_STOP_DIRECT' on upstream server # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - suffix = 'command=%22DRIVER_EVENT_STOP_DIRECT%22&timeout=60000' response = uframe_post_instrument_driver_command(reference_designator, 'execute', suffix) if response.status_code != 200: message = '(%s) execute %s failed.' % (str(response.status_code), capability_DRIVER_EVENT_STOP_DIRECT) raise Exception(message) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Verify command execution status by reviewing error information returned from instrument driver # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if response.content: try: response_data = json.loads(response.content) except Exception: raise Exception('Direct access exit command - malformed response data; invalid json format.') # Evaluate response content for error (review 'value' list info in response_data ) if response_data: status_code, status_type, status_message = _eval_POST_response_data(response_data, "") #- - - - - - - - - - - - - - - - - - - - - - - - - - if debug: print '\n direct_access EXIT - response_data: ', json.dumps(response_data, indent=4, sort_keys=True) print '\n direct_access EXIT - status_code: ', status_code if status_code != 200: print '\n direct_access EXIT - status_message: ', status_message #- - - - - - - - - - - - - - - - - - - - - - - - - - if status_code != 200: raise Exception(status_message) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Final - Verify _state has changed from state_DRIVER_STATE_DIRECT_ACCESS, if not error # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Get state, capabilities and response result for reference_designator _state, _capabilities, result = direct_access_get_state_and_capabilities(rd) if _state == state_DRIVER_STATE_DIRECT_ACCESS: message = 'The current state is \'DRIVER_STATE_DIRECT_ACCESS\'; failed to exit direct access.' raise Exception(message) return jsonify(result) except Exception as err: message = '(%s) direct access exit exception: %s' % (rd, err.message) current_app.logger.info(message) return bad_request(err.message)
def c2_direct_access_sniffer(reference_designator): """ Sniff port/ip/title for data, return data Sample request: http://localhost:4000/c2/instrument/RS10ENGC-XX00X-00-FLORDD001/direct_access/sniffer (using hardcoded message: message = '{"ip": "128.6.240.37", "port": 54366}' ) Sample response: { "msg": "3671820966.2507 : PA_HEARTBEAT : CRC OK : 'HB'\n" } curl -H "Content-Type: application/json" -X POST --upload-file post_sniff_flord.txt http://localhost:4000/c2/instrument/RS10ENGC-XX00X-00-FLORDD001/direct_access/sniffer curl -H "Content-Type: application/json" -X POST --upload-file post_sniff_vadcp_1.txt http://localhost:4000/c2/instrument/RS10ENGC-XX00X-00-VADCPA011/direct_access/sniffer """ # VADCP #message = '{"ip": "128.6.240.37", "port": 34868, "title": "Beams 1-4"}' #message = '{"ip": "128.6.240.37", "port": 48989, "title": "5th Beam"}' # FLORD #message = '{"ip": "128.6.240.37", "port": 54366, "title": "FLOR"}' #message = '{"ip": "128.6.240.37", "port": 54366}' # {"ip": "128.6.240.37", "port": 54366} _data = None rd = reference_designator required_variables = ['ip', 'port', 'title'] try: # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Get request data, process required items. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if not request.data: message = 'Direct access sniffer requires request.data for POST.' raise Exception(message) # Get request data and process request_data = json.loads(request.data) if request_data is None: message = 'Direct access sniffer request data is None. (%s).' % rd raise Exception(message) # Verify required items are provided in request.data and not empty for item in required_variables: if item not in request_data: message = 'Malformed direct access sniffer request, missing %s (%s).' % (item, rd) raise Exception(message) else: if not request_data[item] or request_data[item] is None: message = 'Malformed direct access sniffer request, %s is empty (%s).' % (item, rd) raise Exception(message) # Get ip, port and title ip = request_data['ip'] port = request_data['port'] title = request_data['title'] # Issue request to sniffer process s = None try: s = sock.socket(sock.AF_INET, sock.SOCK_STREAM) s.connect((ip, port)) _data = None try: _data = s.recv(4096) except Exception: pass if s is not None: s.close() #if _data: # if debug: print 'Received: ', repr(_data) except Exception: if s is not None: s.close() pass return jsonify(msg=_data) except Exception as err: message = '(%s) exception: %s' % (reference_designator, err.message) current_app.logger.info(message) return bad_request(err.message)
def c2_direct_access_execute(reference_designator): """ Execute direct access command. While in 'DRIVER_STATE_DIRECT_ACCESS', execute commands sent from direct access terminal window. Process direct access terminal commands: Receive content, send to instrument driver. [Upon receipt of response from instrument, forward response to UI.] Use sniffer. Note valid commands in direct_access_buttons list: "direct_access_buttons": [ "Interrupt", "Print Menu", "Print Metadata", "Read Data", "Restore Factory Defaults", "Restore Settings", "Run Settings", "Run Wiper", "Save Settings", "Set Clock>", "Set Date>", "Set>" ], "input_dict": { "Interrupt": "!!!!!", "Print Menu": "$mnu\r\n", "Print Metadata": "$met\r\n", "Read Data": "$get\r\n", "Restore Factory Defaults": "$rfd\r\n", "Restore Settings": "$rls\r\n", "Run Settings": "$run\r\n", "Run Wiper": "$mvs\r\n", "Save Settings": "$sto\r\n", "Set Clock>": "$clk ", "Set Date>": "$date \r\n", "Set>": "set " }, POST request.data shall provide attribute 'command' or 'command_text': { "command": "Print Metadata" "title": "FLOR" } where valid command value is one of items in direct_access_buttons dictionary (key for input_config). OR { "command_text": "$mnu\r\n" "title": "FLOR" } """ rd = reference_designator TRIPS = '"""' NOT_NONE = 'NOT_NONE' state_DRIVER_STATE_DIRECT_ACCESS = 'DRIVER_STATE_DIRECT_ACCESS' target_state = state_DRIVER_STATE_DIRECT_ACCESS try: command_request = None command_text = None command_request_value = None using_command_request = True # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Get request data, process required items. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if not request.data: message = 'Direct access execute command requires request.data for POST.' raise Exception(message) # Get request data and process request_data = json.loads(request.data) if request_data is None: message = 'Direct access execute command did not receive request data (%s).' % rd raise Exception(message) if 'title' not in request_data: message = 'Malformed direct access execute command, missing title (%s).' % rd raise Exception(message) if ('command' not in request_data) and ('command_text' not in request_data): message = 'Malformed direct access execute command, missing command or command text (%s).' % rd raise Exception(message) # Get title, and command_request or command_text. title = request_data['title'] if 'command' in request_data: command_request = request_data['command'] command_text = None elif 'command_text' in request_data: command_text = request_data['command_text'] command_request = None using_command_request = False # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Verify required fields are not None. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if title is None: message = 'No direct access title data provided for instrument %s.' % rd raise Exception(message) if using_command_request: if command_request is None: message = 'No direct access command data provided for instrument %s.' % rd raise Exception(message) else: if command_text is None: message = 'No direct access command_text data provided for instrument %s.' % rd raise Exception(message) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Prepare to execute - get state, capabilities and status. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _state, _capabilities, result = direct_access_get_state_and_capabilities(rd) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Verify current _state and _capabilities match expected state and capabilities # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - verify_state_and_capabilities(rd, _state, _capabilities, expected_state=state_DRIVER_STATE_DIRECT_ACCESS, expected_capability=NOT_NONE) if using_command_request: #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Get valid direct access commands from direct_access_buttons #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - valid_commands = [] if result: if 'direct_access_buttons' in result: valid_commands = result['direct_access_buttons'] else: message = 'Instrument %s missing direct_access_buttons dictionary.' % rd raise Exception(message) #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Verify there are valid commands; otherwise error. #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if not valid_commands: message = 'Instrument %s direct_access_buttons list is empty.' % rd raise Exception(message) #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Verify command_request from request data is a valid command; otherwise error. #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if command_request not in valid_commands: message = 'Instrument %s command received \'%s\' not in list of available commands.' % \ (rd, command_request) raise Exception(message) #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Verify direct_config available; otherwise error. #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if 'direct_config' not in result['value']: message = 'Instrument %s has missing direct access direct_config list.' % rd raise Exception(message) #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Verify direct_config is not empty; otherwise error. #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if not result['value']['direct_config']: message = 'Instrument %s has empty direct access direct_config list.' % rd raise Exception(message) #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # If direct_config has contents, process list of dictionaries #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ip = None data = None eol = None located_requested_item = False for direct_config in result['value']['direct_config']: # Get and check title; if title in dictionary does not match requested title; go to next item. _title = None if 'title' in direct_config: _title = direct_config['title'] if _title != title: continue # Identified item in direct_config; process item located_requested_item = True # Get and check ip from direct_config dictionary ip = None if 'ip' in direct_config: ip = direct_config['ip'] if ip is None or not ip: message = 'Instrument %s has invalid ip: \'%r\'.' % (rd, ip) raise Exception(message) # Get and check data from direct_config dictionary data = None if 'data' in direct_config: data = direct_config['data'] if data is None or not data: message = 'Instrument %s has invalid data: \'%r\'.' % (rd, data) raise Exception(message) # Get and check eol from direct_config dictionary eol = None if 'eol' in direct_config: eol = direct_config['eol'] if eol is None or not eol: message = 'Instrument %s has invalid or empty eol: \'%r\'.' % (rd, eol) raise Exception(message) #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # If processing a command_request, get remaining items for processing #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if using_command_request: # Verify input_dict is in direct_config if 'input_dict' not in direct_config: message = 'Instrument %s has missing direct access input_dict dictionary.' % rd raise Exception(message) # Get command_request_values; verify command_request in list and therefore valid. command_request_values = direct_config['input_dict'] if command_request not in command_request_values: message = 'Instrument %s direct access command %s not found in direct_config.' % rd raise Exception(message) # Get command_request_value from input_dict provided. command_request_value = command_request_values[command_request] # Was the requested title located in the direct_config? If not, error. if not located_requested_item: message = 'Instrument %s did not have a matching title \'%s\' in direct access direct_config.' % (rd, title) raise Exception(message) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Prepare command value to send to instrument. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if using_command_request: # Using command button value command_value = command_request_value else: # Using command_text, prepare command_value try: command_value = ast.literal_eval(TRIPS + command_text + TRIPS) if eol: command_value += eol except Exception as err: message = 'Exception processing command value (literal_eval): %s' % str(err) raise Exception(message) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Execute - direct access command. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - try: send_command(rd, command_value, ip, data) except Exception as err: message = 'Exception processing command: %s' % str(err) raise Exception(message) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Final - Verify _state and _capabilities match expected state and capabilities. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - verify_state_and_capabilities(rd, _state, _capabilities, expected_state=target_state, expected_capability=NOT_NONE) return jsonify(result) except Exception as err: message = '(%s) exception: %s' % (rd, err.message) current_app.logger.info(message) return bad_request(err.message)