Esempio n. 1
0
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)
Esempio n. 2
0
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)
Esempio n. 3
0
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)
Esempio n. 4
0
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)
Esempio n. 5
0
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)
Esempio n. 6
0
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.')
Esempio n. 7
0
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.')
Esempio n. 10
0
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)
Esempio n. 11
0
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)
Esempio n. 12
0
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)
Esempio n. 13
0
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)
Esempio n. 14
0
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)
Esempio n. 15
0
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)
Esempio n. 16
0
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
Esempio n. 17
0
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)
Esempio n. 18
0
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.")
Esempio n. 20
0
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
Esempio n. 21
0
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)
Esempio n. 22
0
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)
Esempio n. 23
0
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
Esempio n. 24
0
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)
Esempio n. 25
0
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)
Esempio n. 26
0
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)
Esempio n. 27
0
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
Esempio n. 28
0
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)
Esempio n. 29
0
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)
Esempio n. 30
0
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)
Esempio n. 31
0
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.")
Esempio n. 33
0
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.')
Esempio n. 34
0
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)
Esempio n. 35
0
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)
Esempio n. 36
0
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
Esempio n. 37
0
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
Esempio n. 38
0
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)
Esempio n. 39
0
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)
Esempio n. 40
0
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)