def add_subscription_from_file():
    """Add the Redfish Subscription From File.

        EventTypes:
            - ResourceUpdated
            - ResourceAdded
            - ResourceRemoved
            - Alert

        Returns:
            True: If the read from file is successful

    """
    data = get_file_content()
    if data is None:
        return False

    subscription_data = data["members"]
    if not subscription_data:
        return False
    for single_subscription in subscription_data:
        subscription_id = single_subscription["Id"]
        destination = single_subscription["Destination"]
        event_types = single_subscription["EventTypes"]
        context = single_subscription["Context"]

        sc = Subscription(subscription_id, destination, event_types, context)

        for event_type in sc.get_event_types():
            util.get_subscriptions_by_type()[event_type][subscription_id] = sc

        util.get_all_subscriptions()[subscription_id] = sc

    return True
    def test_dispatch_event_request_fail(self, exception_mock, request_mock,
                                         sleep_mock):
        """Tests dispatch event with request fail"""

        with open('oneview_redfish_toolkit/mockups/oneview/Alert.json') as f:
            event_mockup = json.loads(f.read())

            event = Event(event_mockup)

        with open(
                'oneview_redfish_toolkit/mockups/redfish/EventDestination.json'
        ) as f:
            subscription_mockup = json.loads(f.read())

            subscription = Subscription(subscription_mockup['Id'],
                                        subscription_mockup['Destination'],
                                        subscription_mockup['EventTypes'],
                                        subscription_mockup['Context'])

        dispatcher = EventDispatcher(event, subscription, 1, 1)

        request_mock.side_effect = Exception()

        dispatcher.run()

        sleep_mock.assert_called_with(1)
        self.assertTrue(exception_mock.called)
    def test_serialize(self):
        # Tests the serialize function result against known result

        try:
            subscription = Subscription("e7f93fa2-0cb4-11e8-9060-e839359bc36a",
                                        "http://www.dnsname.com/Destination1",
                                        ["Alert", "StatusChange"], None)
        except Exception as e:
            self.fail("Failed to instantiate Subscription class."
                      " Error: {}".format(e))

        try:
            result = json.loads(subscription.serialize())
        except Exception as e:
            self.fail("Failed to serialize. Error: ".format(e))

        self.assertEqual(self.subscription_mockup, result)
    def test_submit_event_with_subscriber(self, start_mock, subscription_mock,
                                          check_ov_availability):
        """Tests SubmitTestEvent action with two subscribers"""

        config.load_config(self.config_file)

        with open('oneview_redfish_toolkit/mockups/oneview/Alert.json') as f:
            event_mockup = Event(json.loads(f.read()))

        subscription_mock['Alert'].values.return_value = [
            Subscription('1', 'destination1', [], 'context1'),
            Subscription('2', 'destination2', [], 'context2')
        ]

        util.dispatch_event(event_mockup)

        self.assertTrue(start_mock.call_count == 2)
    def test_class_instantiation(self):
        # Tests if class is correctly instantiated and validated

        try:
            subscription = Subscription("", "", [], None)
        except Exception as e:
            self.fail("Failed to instantiate Subscription class."
                      " Error: {}".format(e))
        self.assertIsInstance(subscription, Subscription)
def add_subscription():
    """Add the Redfish Subscription.

        Add a new subscription when this POST operation is requested.
        The body of the request must have the Destination,
        an array of EventTypes. Context is optional.

        EventTypes:
            - ResourceUpdated
            - ResourceAdded
            - ResourceRemoved
            - Alert

        Returns:
            JSON: JSON with Subscription information.

        Exception:
            KeyError: When occur a key mapping error.
            return abort(400)

    """

    # get Destination, EventTypes and Context from post
    # generate subscription uuid
    # add subscription in subscriptions_by_type
    # add subscription in all_subscriptions

    try:
        body = request.get_json()
        destination = body["Destination"]

        if not validators.url(destination):
            abort(status.HTTP_400_BAD_REQUEST, "Destination must be an URI.")

        # read all_subscription file and check if destination already present
        is_duplicate = _is_duplicate_subscription(destination)
        if is_duplicate:
            abort(status.HTTP_400_BAD_REQUEST, "Destination is duplicate")

        event_types = body["EventTypes"]

        if not event_types:
            abort(status.HTTP_400_BAD_REQUEST, "EventTypes cannot be empty.")

        context = body.get("Context")
    except KeyError:
        error_message = "Invalid JSON key. The JSON request body " \
                        "must have the keys Destination and EventTypes. " \
                        "The Context is optional."
        abort(status.HTTP_400_BAD_REQUEST, error_message)

    subscription_id = str(uuid.uuid1())

    try:
        # Build Subscription object and validates it
        sc = Subscription(subscription_id, destination, event_types, context)
    except ValidationError:
        error_message = "Invalid EventType. The EventTypes are " \
                        "StatusChange, ResourceUpdated, ResourceAdded, " \
                        "ResourceRemoved and Alert."
        abort(status.HTTP_400_BAD_REQUEST, error_message)

    lock = _get_file_lock()
    lock.acquire()
    try:
        # checking for duplicate subscription again to avoid concurrency issue
        is_duplicate = _is_duplicate_subscription(destination)
        if not is_duplicate:
            # write subscription to the all_subscription.json file
            _add_subscription_to_file(sc.redfish)
            for event_type in sc.get_event_types():
                util.get_subscriptions_by_type(
                )[event_type][subscription_id] = sc

            util.get_all_subscriptions()[subscription_id] = sc
    except Exception as e:
        logging.exception("Error while adding subscription: " + str(e))
        abort(status.HTTP_500_INTERNAL_SERVER_ERROR,
              "Error while adding subscription to the file")
    finally:
        lock.release()
    # Build redfish json
    json_str = sc.serialize()

    # Build response and returns
    response = Response(response=json_str,
                        status=status.HTTP_201_CREATED,
                        mimetype="application/json")
    response.headers.add(
        "Location", "/redfish/v1/EventService/EventSubscriptions/"
        "{}".format(subscription_id))
    return response
def add_subscription():
    """Add the Redfish Subscription.

        Add a new subscription when this POST operation is requested.
        The body of the request must have the Destination,
        an array of EventTypes. Context is optional.

        EventTypes:
            - StatusChange
            - ResourceUpdated
            - ResourceAdded
            - ResourceRemoved
            - Alert

        Returns:
            JSON: JSON with Subscription information.

        Exception:
            OneViewRedfishError: When occur a key mapping error.
            return abort(400)

            Exception: Unexpected error.
            return abort(500)
    """
    try:
        # get Destination, EventTypes and Context from post
        # generate subscription uuid
        # add subscription in subscriptions_by_type
        # add subscription in all_subscriptions

        try:
            body = request.get_json()
            destination = body["Destination"]

            if not validators.url(destination):
                raise OneViewRedfishError({
                    "errorCode":
                    "INVALID_INFORMATION",
                    "message":
                    "Destination must be an URI."
                })

            event_types = body["EventTypes"]

            if not event_types:
                raise OneViewRedfishError({
                    "errorCode":
                    "INVALID_INFORMATION",
                    "message":
                    "EventTypes cannot be empty."
                })

            context = body.get("Context")
        except KeyError:
            raise OneViewRedfishError({
                "errorCode":
                "INVALID_INFORMATION",
                "message":
                "Invalid JSON key. The JSON request body"
                " must have the keys Destination and EventTypes."
                " The Context is optional."
            })

        subscription_id = str(uuid.uuid1())

        try:
            # Build Subscription object and validates it
            sc = Subscription(subscription_id, destination, event_types,
                              context)
        except ValidationError:
            raise OneViewRedfishError({
                "errorCode":
                "INVALID_INFORMATION",
                "message":
                "Invalid EventType. The EventTypes are "
                "StatusChange, ResourceUpdated, ResourceAdded,"
                " ResourceRemoved and Alert."
            })

        for event_type in sc.get_event_types():
            util.subscriptions_by_type[event_type][subscription_id] = sc

        util.all_subscriptions[subscription_id] = sc

        # Build redfish json
        json_str = sc.serialize()

        # Build response and returns
        response = Response(response=json_str,
                            status=status.HTTP_201_CREATED,
                            mimetype="application/json")
        response.headers.add(
            "Location", "/redfish/v1/EventService/EventSubscriptions/"
            "{}".format(subscription_id))
        return response

    except OneViewRedfishError as e:
        logging.exception(e)
        abort(status.HTTP_400_BAD_REQUEST, e.msg['message'])
    except Exception as e:
        logging.exception(e)
        return abort(status.HTTP_500_INTERNAL_SERVER_ERROR)
def add_subscription():
    """Add the Redfish Subscription.

        Add a new subscription when this POST operation is requested.
        The body of the request must have the Destination,
        an array of EventTypes. Context is optional.

        EventTypes:
            - ResourceUpdated
            - ResourceAdded
            - ResourceRemoved
            - Alert

        Returns:
            JSON: JSON with Subscription information.

        Exception:
            KeyError: When occur a key mapping error.
            return abort(400)

    """

    # get Destination, EventTypes and Context from post
    # generate subscription uuid
    # add subscription in subscriptions_by_type
    # add subscription in all_subscriptions

    try:
        body = request.get_json()
        destination = body["Destination"]

        if not validators.url(destination):
            abort(status.HTTP_400_BAD_REQUEST,
                  "Destination must be an URI.")

        event_types = body["EventTypes"]

        if not event_types:
            abort(status.HTTP_400_BAD_REQUEST,
                  "EventTypes cannot be empty.")

        context = body.get("Context")
    except KeyError:
        error_message = "Invalid JSON key. The JSON request body " \
                        "must have the keys Destination and EventTypes. " \
                        "The Context is optional."
        abort(status.HTTP_400_BAD_REQUEST, error_message)

    subscription_id = str(uuid.uuid1())

    try:
        # Build Subscription object and validates it
        sc = Subscription(subscription_id, destination,
                          event_types, context)
    except ValidationError:
        error_message = "Invalid EventType. The EventTypes are " \
                        "StatusChange, ResourceUpdated, ResourceAdded, " \
                        "ResourceRemoved and Alert."
        abort(status.HTTP_400_BAD_REQUEST, error_message)

    for event_type in sc.get_event_types():
        util.get_subscriptions_by_type()[event_type][subscription_id] = sc

    util.get_all_subscriptions()[subscription_id] = sc

    # Build redfish json
    json_str = sc.serialize()

    # Build response and returns
    response = Response(
        response=json_str,
        status=status.HTTP_201_CREATED,
        mimetype="application/json")
    response.headers.add(
        "Location", "/redfish/v1/EventService/EventSubscriptions/"
                    "{}".format(subscription_id))
    return response