Exemplo n.º 1
0
class PluginService(HydraService):
    """
        Plugin SOAP service
    """
    @rpc(_returns=SpyneArray(Unicode))
    def get_plugins(ctx):
        """
        Get all available plugins
        
        Args:

        Returns:
            List(string): A list of all the available plugins (the contents of plugin.xml)
        """
        plug_ins = plugins.get_plugins(**ctx.in_header.__dict__)

        return plug_ins

    @rpc(Plugin, _returns=Unicode)
    def run_plugin(ctx, plugin):
        """
        Run a plugin

        Args:
            plugin (Plugin): A plugin object containing the location of the plugin and its parameters.

        Returns:
            string: The process ID of the plugin
        """

        pid = plugins.run_plugin(plugin, **ctx.in_header.__dict__)

        return pid

    @rpc(Unicode, Integer, _returns=Unicode)
    def check_plugin_status(ctx, plugin_name, pid):
        """
        Check the status of a plugin by looking into the log file for the PID

        Args:
            plugin_name (string): The name of the plugin being checked (used to identify the log file to look in)
            pid (int): The ID of the plugin to check

        Returns:
            string: The logs produced by the plugin. If the PID is not correct, return
            "No log found for PID %s in %s"

        Raises:
            IOError: If the log file does not exist for the plugin name
        """
        status = plugins.check_plugin_status(plugin_name, pid,
                                             **ctx.in_header.__dict__)
        return status
class MatrixResourceData(HydraComplexModel):
    _type_info = [
        ('resource_id', Integer32(min_occurs=1)),
        ('attributes', SpyneArray(MatrixResourceAttribute)),
    ]

    def __init__(self, resource_id=None, attributes=None):
        super(MatrixResourceData, self).__init__()
        if resource_id is None:
            return
        self.resource_id = resource_id
        self.attributes = [
            MatrixResourceAttribute(attr_id, dataset)
            for attr_id, dataset in attributes.items()
        ]
class GroupDatasetMatrix(HydraComplexModel):
    _type_info = [
        ('scenario_id', Integer32(min_occurs=1)),
        ('groups', SpyneArray(MatrixResourceData)),
    ]

    def __init__(self, scenario_id=None, groups=None):
        super(GroupDatasetMatrix, self).__init__()
        if scenario_id is None:
            return
        self.scenario_id = scenario_id
        group_data = []
        for group_id, attributes in groups.items():
            group = MatrixResourceData(group_id, attributes)
            group_data.append(group)
        self.groups = group_data
class LinkDatasetMatrix(HydraComplexModel):
    _type_info = [
        ('scenario_id', Integer32(min_occurs=1)),
        ('links', SpyneArray(MatrixResourceData)),
    ]

    def __init__(self, scenario_id=None, links=None):
        super(LinkDatasetMatrix, self).__init__()
        if scenario_id is None:
            return
        self.scenario_id = scenario_id
        link_data = []
        for link_id, attributes in links.items():
            link = MatrixResourceData(link_id, attributes)
            link_data.append(link)
        self.links = link_data
class NodeDatasetMatrix(HydraComplexModel):
    _type_info = [
        ('scenario_id', Integer32(min_occurs=1)),
        ('nodes', SpyneArray(MatrixResourceData)),
    ]

    def __init__(self, scenario_id=None, nodes=None):
        super(NodeDatasetMatrix, self).__init__()
        if scenario_id is None:
            return
        self.scenario_id = scenario_id
        node_data = []
        for node_id, attributes in nodes.items():
            node = MatrixResourceData(node_id, attributes)
            node_data.append(node)
        self.nodes = node_data
Exemplo n.º 6
0
class HydraResourceAttrCollection(HydraComplexModel):
    __namespace__ = 'soap_server.hydra_complexmodels'
    _type_info = [
        ('id',     SpyneInteger(default=None)),
        ('name',   Unicode(min_occurs=1)),
        ('layout', Unicode),
        ('resource_attr_ids',  SpyneArray(SpyneInteger)),
    ]

    def __init__(self, parent=None):
        super(HydraResourceAttrCollection, self).__init__()
        if  parent is None:
            return
        self.id = parent.collection_id
        self.name = parent.collection_name
        self.layout = parent.layout
        self.resource_attr_ids = [i.resource_attr_id for i in parent.items]

    def get_layout(self):
        if hasattr(self, 'layout') and self.layout is not None:
            return str(self.layout).replace('{%s}'%NS, '')
        else:
            return None
Exemplo n.º 7
0
class TemplateService(HydraService):
    """
        The template SOAP service
    """
    @rpc(Unicode, _returns=Template)
    def upload_template_xml(ctx, template_xml):
        """
            Add the template, type and typeattrs described
            in an XML file.

            Delete type, typeattr entries in the DB that are not in the XML file
            The assumption is that they have been deleted and are no longer required.
        """
        tmpl_i = template.upload_template_xml(template_xml,
                                              **ctx.in_header.__dict__)

        return Template(tmpl_i)

    @rpc(Unicode, Integer, _returns=SpyneArray(TypeSummary))
    def get_matching_resource_types(ctx, resource_type, resource_id):
        """
            Get the possible types of a resource by checking its attributes
            against all available types.

            @returns A list of TypeSummary objects.
        """
        types = template.get_matching_resource_types(resource_type,
                                                     resource_id,
                                                     **ctx.in_header.__dict__)
        ret_types = [TypeSummary(ts) for ts in types]
        return ret_types

    @rpc(SpyneArray(ResourceTypeDef), _returns=SpyneArray(TemplateType))
    def assign_types_to_resources(ctx, resource_types):
        """Assign new types to list of resources.
        This function checks if the necessary
        attributes are present and adds them if needed. Non existing attributes
        are also added when the type is already assigned. This means that this
        function can also be used to update resources, when a resource type has
        changed.
        """
        types = template.assign_types_to_resources(resource_types,
                                                   **ctx.in_header.__dict__)
        ret_val = [TemplateType(t) for t in types]
        return ret_val

    @rpc(Integer, Unicode, Integer, _returns=TypeSummary)
    def assign_type_to_resource(ctx, type_id, resource_type, resource_id):
        """Assign new type to a resource. This function checks if the necessary
        attributes are present and adds them if needed. Non existing attributes
        are also added when the type is already assigned. This means that this
        function can also be used to update resources, when a resource type has
        changed.
        """
        templatetype = template.assign_type_to_resource(
            type_id, resource_type, resource_id, **ctx.in_header.__dict__)
        ret_type = TypeSummary()
        ret_type.name = templatetype.type_name
        ret_type.id = templatetype.type_id
        ret_type.template_name = templatetype.template.template_name
        ret_type.template_id = templatetype.template.template_id

        return ret_type

    @rpc(Integer, Integer, _returns=Unicode)
    def apply_template_to_network(ctx, template_id, network_id):
        """
            Given a template and a network, try to match up and assign
            all the nodes & links in the network to the types in the template
        """
        template.apply_template_to_network(template_id, network_id,
                                           **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, Integer, _returns=Unicode)
    def set_network_template(ctx, template_id, network_id):
        """
            Given a template and a network, try to match up and assign
            all the nodes & links in the network to the types in the template
        """
        template.set_network_template(template_id, network_id,
                                      **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer,
         Integer,
         Unicode(pattern="[YN]", default='N'),
         _returns=Unicode)
    def remove_template_from_network(ctx, network_id, template_id,
                                     remove_attrs):
        """
            Given a template and a network, try to match up and assign
            all the nodes & links in the network to the types in the template
        """
        template.remove_template_from_network(network_id, template_id,
                                              remove_attrs,
                                              **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, Unicode, Integer, _returns=Unicode)
    def remove_type_from_resource(ctx, type_id, resource_type, resource_id):
        """

            Remove a resource type trom a resource
        """
        template.remove_type_from_resource(type_id, resource_type, resource_id,
                                           **ctx.in_header.__dict__)

        return 'OK'

    @rpc(Template, _returns=Template)
    def add_template(ctx, tmpl):
        """
            Add template and a type and typeattrs.
        """
        tmpl_i = template.add_template(tmpl, **ctx.in_header.__dict__)

        return Template(tmpl_i)

    @rpc(Template, _returns=Template)
    def update_template(ctx, tmpl):
        """
            Update template and a type and typeattrs.
        """
        tmpl_i = template.update_template(tmpl, **ctx.in_header.__dict__)
        return Template(tmpl_i)

    @rpc(Integer, _returns=Template)
    def delete_template(ctx, template_id):
        """
            Update template and a type and typeattrs.
        """
        template.delete_template(template_id, **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer(min_occurs=0, max_occurs='unbounded'),
         _returns=SpyneArray(Template))
    def get_templates(ctx, template_ids):
        """
            Get all resource template templates.
        """
        tmpls = template.get_templates(template_ids=template_ids,
                                       **ctx.in_header.__dict__)
        ret_templates = [Template(t) for t in tmpls]

        return ret_templates

    @rpc(Integer, Integer, _returns=Unicode)
    def remove_attr_from_type(ctx, type_id, attr_id):
        """

            Remove an attribute from a type
        """
        success = 'OK'
        template.remove_attr_from_type(type_id, attr_id,
                                       **ctx.in_header.__dict__)
        return success

    @rpc(Integer, _returns=Template)
    def get_template(ctx, template_id):
        """
            Get a specific resource template template, either by ID or name.
        """
        tmpl_i = template.get_template(template_id, **ctx.in_header.__dict__)
        tmpl = Template(tmpl_i)

        return tmpl

    @rpc(Unicode, _returns=Template)
    def get_template_by_name(ctx, template_name):
        """
            Get a specific resource template, either by ID or name.
        """
        tmpl_i = template.get_template_by_name(template_name,
                                               **ctx.in_header.__dict__)
        if tmpl_i is not None:
            tmpl = Template(tmpl_i)

            return tmpl
        else:
            return None

    @rpc(TemplateType, _returns=TemplateType)
    def add_templatetype(ctx, templatetype):
        """
            Add a template type with typeattrs.
        """

        tmpl_type = template.add_templatetype(templatetype,
                                              **ctx.in_header.__dict__)

        return TemplateType(tmpl_type)

    @rpc(TemplateType, _returns=TemplateType)
    def update_templatetype(ctx, templatetype):
        """
            Update a resource type and its typeattrs.
            New typeattrs will be added. typeattrs not sent will be ignored.
            To delete typeattrs, call delete_typeattr
        """
        type_i = template.update_templatetype(templatetype,
                                              **ctx.in_header.__dict__)
        return TemplateType(type_i)

    @rpc(Integer, _returns=Template)
    def delete_templatetype(ctx, type_id):
        """
            Update template and a type and typeattrs.
        """
        template.delete_templatetype(type_id, **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, _returns=TemplateType)
    def get_templatetype(ctx, type_id):
        """
            Get a specific resource type by ID.
        """
        type_i = template.get_templatetype(type_id, **ctx.in_header.__dict__)
        templatetype = TemplateType(type_i)
        return templatetype

    @rpc(Integer, Unicode, _returns=TemplateType)
    def get_templatetype_by_name(ctx, template_id, type_name):
        """
            Get a specific resource type by name.
        """

        type_i = template.get_templatetype_by_name(template_id, type_name,
                                                   **ctx.in_header.__dict__)
        tmpltype = TemplateType(type_i)

        return tmpltype

    @rpc(TypeAttr, _returns=TemplateType)
    def add_typeattr(ctx, typeattr):
        """
            Add an typeattr to an existing type.
        """
        updated_template_type = template.add_typeattr(typeattr,
                                                      **ctx.in_header.__dict__)

        ta = TemplateType(updated_template_type)
        return ta

    @rpc(TypeAttr, _returns=Unicode)
    def delete_typeattr(ctx, typeattr):
        """
            Remove an typeattr from an existing type
        """
        success = 'OK'
        template.delete_typeattr(typeattr, **ctx.in_header.__dict__)
        return success

    @rpc(Integer, _returns=Unicode)
    def get_network_as_xml_template(ctx, network_id):
        """
            Turn an existing network into an xml template
            using its attributes.
            If an optional scenario ID is passed in, default
            values will be populated from that scenario.
        """
        template_xml = template.get_network_as_xml_template(
            network_id, **ctx.in_header.__dict__)

        return template_xml

    @rpc(Integer, Integer, Integer, _returns=ValidationError)
    def validate_attr(ctx, resource_attr_id, scenario_id, template_id):
        """
            Validate that the value of a specified resource attribute is valid
            relative to the data restrictions specified on the template. If no
            template is specified, (set as null), then validation will be made
            against every template on the network.
        """
        error_dict = template.validate_attr(resource_attr_id, scenario_id,
                                            template_id)
        if error_dict is None:
            return None

        error = ValidationError(
            ref_key=error_dict.get('ref_key'),
            ref_id=error_dict.get('ref_id'),
            ref_name=error_dict.get('ref_name'),
            resource_attr_id=error_dict.get('resource_attr_id'),
            attr_id=error_dict.get('attr_id'),
            attr_name=error_dict.get('attr_name'),
            dataset_id=error_dict.get('dataset_id'),
            scenario_id=error_dict.get('scenario_id'),
            template_id=error_dict.get('template_id'),
            error_text=error_dict.get('error_text'))
        return error

    @rpc(SpyneArray(Integer32),
         Integer,
         Integer,
         _returns=SpyneArray(ValidationError))
    def validate_attrs(ctx, resource_attr_ids, scenario_id, template_id):
        errors = []
        error_dicts = template.validate_attrs(resource_attr_ids, scenario_id,
                                              template_id)
        for error_dict in error_dicts:
            error = ValidationError(
                ref_key=error_dict.get('ref_key'),
                ref_id=error_dict.get('ref_id'),
                ref_name=error_dict.get('ref_name'),
                resource_attr_id=error_dict.get('resource_attr_id'),
                attr_id=error_dict.get('attr_id'),
                attr_name=error_dict.get('attr_name'),
                dataset_id=error_dict.get('dataset_id'),
                scenario_id=error_dict.get('scenario_id'),
                template_id=error_dict.get('template_id'),
                error_text=error_dict.get('error_text'))
            errors.append(error)

        return errors

    @rpc(Integer, Integer, _returns=SpyneArray(ValidationError))
    def validate_scenario(ctx, scenario_id, template_id):
        errors = []
        error_dicts = template.validate_scenario(scenario_id, template_id)
        for error_dict in error_dicts:
            error = ValidationError(
                ref_key=error_dict.get('ref_key'),
                ref_id=error_dict.get('ref_id'),
                ref_name=error_dict.get('ref_name'),
                resource_attr_id=error_dict.get('resource_attr_id'),
                attr_id=error_dict.get('attr_id'),
                attr_name=error_dict.get('attr_name'),
                dataset_id=error_dict.get('dataset_id'),
                scenario_id=error_dict.get('scenario_id'),
                template_id=error_dict.get('template_id'),
                error_text=error_dict.get('error_text'))
            errors.append(error)

        return errors

    @rpc(Integer,
         Integer,
         Integer(min_occurs=0, max_occurs=1),
         _returns=SpyneArray(Unicode))
    def validate_network(ctx, network_id, template_id, scenario_id):
        errors = template.validate_network(network_id, template_id,
                                           scenario_id)
        return errors

    @rpc(Integer, Integer, _returns=SpyneArray(Unicode))
    def check_type_compatibility(ctx, type_1_id, type_2_id):
        errors = template.check_type_compatibility(type_1_id, type_2_id)
        return errors
Exemplo n.º 8
0
class NetworkService(HydraService):
    """
        The network SOAP service.
    """
    @rpc(Network, Unicode(pattern="[YN]", default='Y'), _returns=Network)
    def add_network(ctx, net, return_summary):
        """
        Takes an entire network complex model and saves it to the DB.  This
        complex model includes links & scenarios (with resource data).  Returns
        the network's complex model.

        As links connect two nodes using the node_ids, if the nodes are new
        they will not yet have node_ids. In this case, use negative ids as
        temporary IDS until the node has been given an permanent ID.

        All inter-object referencing of new objects should be done using
        negative IDs in the client.

        The returned object will have positive IDS

        Args:
            net (hydra_complexmodels.Network): The entire network complex model structure including nodes, links, scenarios and data

        Returns:
            hydra_complexmodels.Network: The full network structure, with correct IDs for all resources

        """
        net = network.add_network(net, **ctx.in_header.__dict__)
        ret_net = Network(net, summary=return_summary == 'Y')
        return ret_net

    @rpc(Integer,
         Unicode(pattern="[YN]", default='Y'),
         Unicode(pattern="[YN]", default='N'),
         Unicode(pattern="[YN]", default='Y'),
         Integer,
         SpyneArray(Integer()),
         _returns=Network)
    def get_network(ctx, network_id, include_resources, summary, include_data,
                    template_id, scenario_ids):
        """
        Return a whole network as a complex model.

        Args:
            network_id   (int)              : The ID of the network to retrieve
            include_resources      (char) ('Y' or 'N'): Optional flag to indicate whether resources are included with the network.
            summary      (char) ('Y' or 'N'): Optional flag to indicate whether attributes are returned with the nodes & links. Setting to 'Y' has significant speed improvements at the cost of not retrieving attribute information.
            include_data (char) ('Y' or 'N'): Optional flag to indicate whether to return datasets with the network. Defaults to 'Y', but using 'N' is much faster.
            template_id  (int)              : Optional parameter which will only return attributes on the resources that are in this template.
            scenario_ids (List(int))        : Optional parameter to indicate which scenarios to return with the network. If left unspecified, all scenarios are returned

        Returns:
            hydra_complexmodels.Network: A network complex model

        Raises:
            ResourceNotFoundError: If the network is not found.
        """
        include_resources = True if include_resources == 'Y' else False
        summary = True if summary == 'Y' else False
        net = network.get_network(network_id, include_resources, summary,
                                  include_data, scenario_ids, template_id,
                                  **ctx.in_header.__dict__)
        ret_net = Network(net, summary)
        return ret_net

    @rpc(Integer, _returns=Unicode)
    def get_network_as_json(ctx, network_id):
        """
        Return a whole network as a json string. Used for testing.

        Args:
            network_id (int): The ID of the network to retrieve

        Returns:
            string: A json-encoded representation of the network

        """
        net = network.get_network(network_id, False, 'Y', [], None,
                                  **ctx.in_header.__dict__)

        return json.dumps(str(net))

    @rpc(Integer, Unicode, _returns=Network)
    def get_network_by_name(ctx, project_id, network_name):
        """
        Search for a network by its name and return it.

        Args:
            project_id (int): As network names are only unique within a project, search for the network within the specified project
            network_name (string): The name of the network

        Returns:
            hydra_complexmodels.Network: The entire network structure, no filtering is performed, so all data and attributes are returned

        Raises:
            ResourceNotFoundError: If the project or network is not found
        """

        net = network.get_network_by_name(project_id, network_name,
                                          **ctx.in_header.__dict__)

        return Network(net)

    @rpc(Integer, Unicode, _returns=Unicode)
    def network_exists(ctx, project_id, network_name):
        """
        Using a network's name, check if a network exists or not within a project.

        Args:
            project_id (int): The project in which you are searching
            network_name (string): The name of the network you are searching for

        Returns:
           Unicode: 'Y' or 'N'

        Raises:
            ResourceNotFoundError: If the project is not defined
        """

        net_exists = network.network_exists(project_id, network_name,
                                            **ctx.in_header.__dict__)

        return net_exists

    @rpc(Network,
         Unicode(pattern="['YN']", default='Y'),
         Unicode(pattern="['YN']", default='Y'),
         Unicode(pattern="['YN']", default='Y'),
         Unicode(pattern="['YN']", default='Y'),
         _returns=Network)
    def update_network(ctx, net, update_nodes, update_links, update_groups,
                       update_scenarios):
        """
        Update an entire network.
        Send a network complex model with updated nodes, links, groups or scenarios. Using
        flags, tell the function which of these to update.

        Args:
            net (hydra_complexmodels.Network): A network reflecting an already existing network (must have an ID), which is to be updated
            updated_nodes (char) (Y or N): Flag to indicated whether the incoming network's nodes should be updated
            updated_links (char) (Y or N): Flag to indicated whether the incoming network's links should be updated
            updated_groups (char) (Y or N): Flag to indicated whether the incoming network's resource groups should be updated
            updated_scenarios (char) (Y or N): Flag to indicated whether the incoming network's data should be updated

        Returns:
            hydra_complexmodels.Network: The updated network, in summarised forms (without data or attributes)

        Raises:
            ResourceNotFoundError: If the network does not exist.


        """
        upd_nodes = True if update_nodes == 'Y' else False
        upd_links = True if update_links == 'Y' else False
        upd_groups = True if update_groups == 'Y' else False
        upd_scenarios = True if update_scenarios == 'Y' else False

        net = network.update_network(net, upd_nodes, upd_links, upd_groups,
                                     upd_scenarios, **ctx.in_header.__dict__)
        return Network(net, summary=True)

    @rpc(Integer, Integer(min_occurs=0), _returns=Node)
    def get_node(ctx, node_id, scenario_id):
        """
        Get a node using the node_id.
        optionally, scenario_id can be included if data is to be included

        Args:
            node_id (int): The node to retrieve
            scenario_id (int) (optional): Include this if you want to include data with the scenario

        Returns:
            hydra_complexmodels.Node: A node complex model, with attributes and data if requested)

        Raises:
            ResourceNotFoundError: If the node or scenario is not found

        """
        node = network.get_node(node_id, **ctx.in_header.__dict__)

        if scenario_id is not None:
            ret_node = Node(node)

            res_scens = scenario.get_resource_data('NODE', node_id,
                                                   scenario_id, None)

            rs_dict = {}
            for rs in res_scens:
                rs_dict[rs.resource_attr_id] = rs

            for ra in ret_node.attributes:
                if rs_dict.get(ra.id):
                    ra.resourcescenario = ResourceScenario(rs_dict[ra.id])

            return ret_node
        else:
            ret_node = Node(node)
            return ret_node

    @rpc(Integer, Integer, _returns=Link)
    def get_link(ctx, link_id, scenario_id):
        """
        Get a link using the link_id.
        optionally, scenario_id can be included if data is to be included

        Args:
            link_id (int): The link to retrieve
            scenario_id (int) (optional): Include this if you want to include data with the scenario

        Returns:
            hydra_complexmodels.Link: A link complex model, with attributes and data if requested)

        Raises:
            ResourceNotFoundError: If the link or scenario is not found

        """
        link = network.get_link(link_id, **ctx.in_header.__dict__)

        if scenario_id is not None:
            ret_link = Link(link)
            res_scens = scenario.get_resource_data('LINK', link_id,
                                                   scenario_id, None)
            rs_dict = {}
            for rs in res_scens:
                rs_dict[rs.resource_attr_id] = rs

            for ra in ret_link.attributes:
                if rs_dict.get(ra.id):
                    ra.resourcescenario = ResourceScenario(rs_dict[ra.id])

            return ret_link
        else:
            ret_link = Link(link)
            return ret_link

    @rpc(Integer(min_occurs=1, max_occurs="unbounded"),
         Integer(min_occurs=0),
         _returns=SpyneArray(Node))
    def get_nodes(ctx, node_ids, scenario_id):
        """
        Get nodes using the node_ids.
        optionally, scenario_id can be included if data is to be included

        Args:
            node_id (int): The node to retrieve
            scenario_id (int) (optional): Include this if you want to include data with the scenario

        Returns:
            hydra_complexmodels.Node: A node complex model, with attributes and data if requested)

        Raises:
            ResourceNotFoundError: If the node or scenario is not found

        """
        nodes = network.get_nodes(node_ids, **ctx.in_header.__dict__)
        ret_nodes = []
        if scenario_id is not None:
            for node in nodes:
                ret_node = Node(node)

                res_scens = scenario.get_resource_data('NODE', node.node_id,
                                                       scenario_id, None)

                rs_dict = {}
                for rs in res_scens:
                    rs_dict[rs.resource_attr_id] = rs

                for ra in ret_node.attributes:
                    if rs_dict.get(ra.id):
                        ra.resourcescenario = ResourceScenario(rs_dict[ra.id])
                ret_nodes.append(ret_node)

        else:
            ret_nodes = [Node(node) for node in nodes]

        return ret_nodes

    @rpc(Integer(min_occurs=1, max_occurs="unbounded"),
         Integer(min_occurs=0),
         _returns=SpyneArray(Link))
    def get_links(ctx, link_ids, scenario_id):
        """
        Get links using the link_ids.
        optionally, scenario_id can be included if data is to be included

        Args:
            link_id (int): The link to retrieve
            scenario_id (int) (optional): Include this if you want to include data with the scenario

        Returns:
            hydra_complexmodels.Link: A link complex model, with attributes and data if requested)

        Raises:
            ResourceNotFoundError: If the link or scenario is not found

        """
        links = network.get_links(link_ids, **ctx.in_header.__dict__)
        ret_links = []
        if scenario_id is not None:
            for link in links:
                ret_link = Link(link)

                res_scens = scenario.get_resource_data('LINK', link.link_id,
                                                       scenario_id, None)

                rs_dict = {}
                for rs in res_scens:
                    rs_dict[rs.resource_attr_id] = rs

                for ra in ret_link.attributes:
                    if rs_dict.get(ra.id):
                        ra.resourcescenario = ResourceScenario(rs_dict[ra.id])
                ret_links.append(ret_link)

        else:
            ret_links = [Link(link) for link in links]

        return ret_links

    @rpc(Integer, Integer, _returns=ResourceGroup)
    def get_resourcegroup(ctx, group_id, scenario_id):
        """
        Get a resourcegroup using the group_id.
        optionally, scenario_id can be included if data is to be included

        Args:
            group_id (int): The resource group to retrieve
            scenario_id (int) (optional): Include this if you want to include data with the scenario

        Returns:
            hydra_complexmodels.ResourceGroup: A resource group complex model, with attributes and data if requested)

        Raises:
            ResourceNotFoundError: If the group or scenario is not found

        """
        group = network.get_resourcegroup(group_id, **ctx.in_header.__dict__)

        if scenario_id is not None:
            ret_group = ResourceGroup(group)
            res_scens = scenario.get_resource_data('GROUP', group_id,
                                                   scenario_id, None)
            rs_dict = {}
            for rs in res_scens:
                rs_dict[rs.resource_attr_id] = rs

            for ra in ret_group.attributes:
                if rs_dict.get(ra.id):
                    ra.resourcescenario = ResourceScenario(rs_dict[ra.id])

            return ret_group
        else:
            ret_group = ResourceGroup(group)
            return ret_group

    @rpc(Integer, _returns=Unicode)
    def delete_network(ctx, network_id):
        """
        Set status of network to 'X' so it will no longer appear when you retrieve its project.
        This will not delete the network from the DB. For that use purge_network

        Args:
            network_id (int): The network to delete

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the network is not found
        """
        #check_perm('delete_network')
        network.set_network_status(network_id, 'X', **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, Unicode(pattern="[YN]", default='Y'), _returns=Unicode)
    def purge_network(ctx, network_id, purge_data):
        """
        Remove a network from hydra platform completely.

        Args:
            network_id (int): The network to remove completely
            purge_data (string) ('Y' or 'N'): Any data left unconnected can be left in the DB or deleted with this flag.

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the network is not found
        """
        #check_perm('delete_network')
        network.purge_network(network_id, purge_data, **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, _returns=Unicode)
    def activate_network(ctx, network_id):
        """
        Un-Deletes a network. (Set the status to 'Y' meaning it'll be included
        when you request a project's networks.

        Args:
            network_id (int): The network to reactivate

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the network is not found.
        """
        #check_perm('delete_network')
        network.set_network_status(network_id, 'A', **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, _returns=NetworkExtents)
    def get_network_extents(ctx, network_id):
        """
        Given a network, return its maximum extents.
        This would be the minimum x value of all nodes,
        the minimum y value of all nodes,
        the maximum x value of all nodes and
        maximum y value of all nodes.

        Args:
            network_id (int): The network to get the extents for

        Returns:
            NetworkExtents: the min x, max x, min y, max y of all nodes in the network

        Raises:
            ResourceNotFoundError: If the network is not found.

        """
        extents = network.get_network_extents(network_id,
                                              **ctx.in_header.__dict__)

        ne = NetworkExtents()
        ne.network_id = extents['network_id']
        ne.min_x = extents['min_x']
        ne.max_x = extents['max_x']
        ne.min_y = extents['min_y']
        ne.max_y = extents['max_y']

        return ne

    @rpc(Integer, Node, _returns=Node)
    def add_node(ctx, network_id, node):
        """
        Add a node to a network:

        .. code-block:: python

            (Node){
               id = 1027
               name = "Node 1"
               description = "Node Description"
               x = 0.0
               y = 0.0
               attributes =
                  (ResourceAttrArray){
                     ResourceAttr[] =
                        (ResourceAttr){
                           attr_id = 1234
                        },
                        (ResourceAttr){
                           attr_id = 4321
                        },
                  }
             }

        Args:
            network_id (int):  The id of the network to receive the new node
            node       (hydra_complexmodels.Node): The node to be added (see above for the format)

        Returns:
            hydra_complexmodels.Node: The newly added node, complete with an ID

        Raises:
            ResourceNotFoundError: If the network is not found
        """

        node_dict = network.add_node(network_id, node,
                                     **ctx.in_header.__dict__)

        new_node = Node(node_dict)

        return new_node

    @rpc(Integer, SpyneArray(Node), _returns=SpyneArray(Node))
    def add_nodes(ctx, network_id, nodes):
        """
        Add a lost of nodes to a network

        Args:
            network_id (int):  The id of the network to receive the new node
            node       (List(hydra_complexmodels.Node)): A list of the nodes to be added

        Returns:
            List(hydra_complexmodels.Node): The newly added nodes, each complete with an ID

        Raises:
            ResourceNotFoundError: If the network is not found
        """

        node_s = network.add_nodes(network_id, nodes, **ctx.in_header.__dict__)
        new_nodes = []
        for node in nodes:
            for node_ in node_s:
                if (node.name == node_.node_name):
                    new_nodes.append(Node(node_, summary=True))
                    break

        return new_nodes

    @rpc(Integer, SpyneArray(Link), _returns=SpyneArray(Link))
    def add_links(ctx, network_id, links):
        """
        Add a lost of links to a network

        Args:
            network_id (int):  The id of the network to receive the new link
            link       (List(hydra_complexmodels.Link)): A list of the links to be added

        Returns:
            List(hydra_complexmodels.Link): The newly added links, each complete with an ID

        Raises:
            ResourceNotFoundError: If the network is not found

        """
        link_s = network.add_links(network_id, links, **ctx.in_header.__dict__)

        new_links = []
        for link in links:
            for link_ in link_s:
                if (link.name == link_.link_name):
                    new_links.append(Link(link_, summary=True))
                    break

        return new_links

    @rpc(Node, _returns=Node)
    def update_node(ctx, node):
        """
        Update a node.
        If new attributes are present, they will be added to the node.
        The non-presence of attributes does not remove them.

        .. code-block:: python

            (Node){
               id = 1039
               name = "Node 1"
               description = "Node Description"
               x = 0.0
               y = 0.0
               status = "A"
               attributes =
                  (ResourceAttrArray){
                     ResourceAttr[] =
                        (ResourceAttr){
                           id = 850
                           attr_id = 1038
                           ref_id = 1039
                           ref_key = "NODE"
                           attr_is_var = True
                        },
                        (ResourceAttr){
                           id = 852
                           attr_id = 1040
                           ref_id = 1039
                           ref_key = "NODE"
                           attr_is_var = True
                        },
                  }
             }

        Args:
            node (hydra_complexmodels.Node): The node to be updated

        Returns:
            hydra_complexmodels.Node: The updated node.

        Raises:
            ResourceNotFoundError: If the node is not found
        """

        node_dict = network.update_node(node, **ctx.in_header.__dict__)
        updated_node = Node(node_dict)

        return updated_node

    @rpc(Integer, _returns=Unicode)
    def delete_node(ctx, node_id):
        """
        Set status of node to 'X' so it will no longer appear when you retrieve its network.
        This will not delete the node from the DB. For that use purge_node

        Args:
            node_id (int): The node to delete

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the node is not found
        """
        #check_perm('edit_topology')
        network.set_node_status(node_id, 'X', **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, _returns=Unicode)
    def activate_node(ctx, node_id):
        """
        Set the status of a node to 'A'

        Un-Deletes a node. (Set the status to 'Y' meaning it'll be included
        when you request a network.

        Args:
            node_id (int): The node to reactivate

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the node is not found.
        """
        #check_perm('edit_topology')
        network.set_node_status(node_id, 'A', **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, Unicode(pattern="[YN]", default='Y'), _returns=Unicode)
    def purge_node(ctx, node_id, purge_data):
        """
            Remove node from DB completely
            If there are attributes on the node, use purge_data to try to
            delete the data. If no other resources link to this data, it
            will be deleted.

        Args:
            node_id (int): The node to remove completely
            purge_data (string) ('Y' or 'N'): Any data left unconnected can be left in the DB or deleted with this flag.

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the node is not found
        """
        network.delete_node(node_id, purge_data, **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, Link, _returns=Link)
    def add_link(ctx, network_id, link):
        """
        Add a link to a network

        Args:
            network_id (int):  The id of the network to receive the new link
            link       (hydra_complexmodels.Link): The link to be added (see above for the format)

        Returns:
            hydra_complexmodels.Link: The newly added link, complete with an ID

        Raises:
            ResourceNotFoundError: If the network is not found
        """

        link_dict = network.add_link(network_id, link,
                                     **ctx.in_header.__dict__)
        new_link = Link(link_dict)

        return new_link

    @rpc(Link, _returns=Link)
    def update_link(ctx, link):
        """
        Update a link.

        Args:
            link       (hydra_complexmodels.Link): The link to be updated

        Returns:
            hydra_complexmodels.Link: The updated link.

        Raises:
            ResourceNotFoundError: If the link is not found
        """
        link_dict = network.update_link(link, **ctx.in_header.__dict__)
        updated_link = Link(link_dict)

        return updated_link

    @rpc(Integer, _returns=Unicode)
    def delete_link(ctx, link_id):
        """
        Set the status of a link to 'X'

        Args:
            link_id (int): The link to delete

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the link is not found

        """
        network.set_link_status(link_id, 'X', **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, _returns=Unicode)
    def activate_link(ctx, link_id):
        """
        Set the status of a link to 'A'

        Args:
            link_id (int): The link to reactivate

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the link is not found.

        """
        network.set_link_status(link_id, 'A', **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, Unicode(pattern="[YN]", default='Y'), _returns=Unicode)
    def purge_link(ctx, link_id, purge_data):
        """
        Remove link from DB completely
        If there are attributes on the link, use purge_data to try to
        delete the data. If no other resources link to this data, it
        will be deleted.

        Args:
            link_id (int): The link to reactivate

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the link is not found.
        """
        network.delete_link(link_id, purge_data, **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, ResourceGroup, _returns=ResourceGroup)
    def add_group(ctx, network_id, group):
        """
        Add a resourcegroup to a network

        Args:
            network_id (int):  The id of the network to receive the new node
            group      (hydra_complexmodels.ResourceGroup): The group to be added

        Returns:
            hydra_complexmodels.ResourceGroup: The newly added group, complete with an ID

        Raises:
            ResourceNotFoundError: If the network is not found
        """

        group_i = network.add_group(network_id, group,
                                    **ctx.in_header.__dict__)
        new_group = ResourceGroup(group_i)

        return new_group

    @rpc(Integer, _returns=Unicode)
    def delete_group(ctx, group_id):
        """
        Set the status of a group to 'X'
        Args:
            group_id (int): The resource group to delete

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the resource group is not found

        """
        network.set_group_status(group_id, 'X', **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, Unicode(pattern="[YN]", default='Y'), _returns=Unicode)
    def purge_group(ctx, group_id, purge_data):
        """
        Remove a resource group from the DB completely. If purge data is set
        to 'Y', any data that is unconnected after the removal of the group
        will be removed also.

        Args:
            group_id (int): The resource group to remove completely
            purge_data (string) ('Y' or 'N'): Any data left unconnected can be left in the DB or deleted with this flag.

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the resource group is not found

        """
        network.delete_group(group_id, purge_data, **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, _returns=Unicode)
    def activate_group(ctx, group_id):
        """
        Set the status of a group to 'A'

        Args:
            group_id (int): The resource group to reactivate

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the resource group is not found.

        """
        network.set_group_status(group_id, 'A', **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, _returns=SpyneArray(Scenario))
    def get_scenarios(ctx, network_id):
        """
        Get all the scenarios in a given network.

        Args:
            network_id (int): The network from which to retrieve the scenarios

        Returns:
            List(hydra_complexmodels.Scenario): All the scenarios in the network

        Raises:
            ResourceNotFoundError: If the network is not found
        """
        scenarios_i = network.get_scenarios(network_id,
                                            **ctx.in_header.__dict__)

        scenarios = [Scenario(scen) for scen in scenarios_i]

        return scenarios

    @rpc(Integer, _returns=SpyneArray(Integer))
    def validate_network_topology(ctx, network_id):
        """
        Check for the presence of orphan nodes in a network.
        Args:
            network_id (int): The network to check

        Returns:
            List(int)): IDs of all the orphan nodes in the network

        Raises:
            ResourceNotFoundError: If the network is not found

        """
        return network.validate_network_topology(network_id,
                                                 **ctx.in_header.__dict__)

    @rpc(Integer,
         Integer(min_occurs=1, max_occurs="unbounded"),
         _returns=SpyneArray(ResourceSummary))
    def get_resources_of_type(ctx, network_id, type_id):
        """
        Return a list of Nodes, Links or ResourceGroups
        which have the specified type.

        Args:
            network_id (int): Types of resources in this network
            type_id    (int): Search for resources of this type.

        Returns:
            List(ResourceSummary): These objects contain the attributes common to all resources, namely: type, id, name, description, attribues and types.

        Raises:
            ResourceNotFoundError: If the network or type is not found
        """

        if type(type_id) == int:
            type_id = [type_id]

        nodes, links, networks, groups = network.get_resources_of_type(
            network_id, type_id, **ctx.in_header.__dict__)

        resources = []
        for n in nodes:
            resources.append(ResourceSummary(n))
        for l in links:
            resources.append(ResourceSummary(l))
        for n in networks:
            resources.append(ResourceSummary(n))
        for g in groups:
            resources.append(ResourceSummary(g))

        return resources

    @rpc(Integer, _returns=Unicode)
    def clean_up_network(ctx, network_id):
        """
        Purge all nodes, links, groups and scenarios from a network which
        have previously been deleted.

        Args:
            network_id (int): The network to clean up

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the network is not found

        """
        return network.clean_up_network(network_id, **ctx.in_header.__dict__)

    @rpc(Integer,
         Integer,
         Integer(max_occurs="unbounded"),
         Unicode(pattern="['YN']", default='N'),
         _returns=SpyneArray(ResourceAttr))
    def get_all_node_data(ctx, network_id, scenario_id, node_ids,
                          include_metadata):
        """
        Return all the attributes for all the nodes in a given network and a
        given scenario.


        Args:
            network_id (int): The network to search in
            scenario_id (int): The scenario to search
            node_ids (List(int)) (optional): The specific nodes to search for data in. If not specified, all the nodes in the network will be searched.
            include_metadata: (string) ('Y' or 'N'): Default 'N'. Set to 'Y' to return metadata. This may vause a performance hit as metadata is BIG!

        Returns:
            List(ResourceAttr), each with a resourcescenario attribute, containing the actual value for the scenario specified.

        Raises:
            ResourceNotFoundError: If the network or scenario are not found

        """
        start = datetime.datetime.now()

        node_resourcescenarios = network.get_attributes_for_resource(
            network_id, scenario_id, 'NODE', node_ids, include_metadata)

        log.info("Qry done in %s", (datetime.datetime.now() - start))
        start = datetime.datetime.now()

        return_ras = []
        for ns in node_resourcescenarios:
            ra = ResourceAttr(ns.resourceattr)
            x = ResourceScenario(ns, ra.attr_id)
            ra.resourcescenario = x
            return_ras.append(ra)

        log.info("Return vals built in %s", (datetime.datetime.now() - start))

        return return_ras

    @rpc(Integer,
         Unicode(pattern="['YN']", default='N'),
         Unicode(pattern="['YN']", default='N'),
         Integer(min_occurs=0, max_occurs=1),
         Integer(min_occurs=0, max_occurs=1),
         _returns=SpyneArray(ResourceData))
    def get_all_resource_data(ctx, scenario_id, include_values,
                              include_metadata, page_start, page_end):
        """
        Return all the attributes for all the nodes in a given network and a
        given scenario.

        In this function array data and timeseries data are returned as JSON strings.

        If your data structure looks like:

        +----+----+-----+
        | H1 | H2 | H3  |
        +====+====+=====+
        | 1  | 10 | 100 |
        +----+----+-----+
        | 2  | 20 | 200 |
        +----+----+-----+
        | 3  | 30 | 300 |
        +----+----+-----+
        | 4  | 40 | 400 |
        +----+----+-----+

        Then hydra will provide the data in the following format:

        '{
            "H1" : {"0":1, "1":2, "3":3, "4":4},\n
            "H2"  : {"0":10, "1":20, "3":30, "4":40},\n
            "H3"  : {"0":100, "1":200, "3":300, "4":400}\n
        }'

        For a timeseries:

        +-------------------------+----+----+-----+
        | Time                    | H1 | H2 | H3  |
        +=========================+====+====+=====+
        | 2014/09/04 16:46:12:00  | 1  | 10 | 100 |
        +-------------------------+----+----+-----+
        | 2014/09/05 16:46:12:00  | 2  | 20 | 200 |
        +-------------------------+----+----+-----+
        | 2014/09/06 16:46:12:00  | 3  | 30 | 300 |
        +-------------------------+----+----+-----+
        | 2014/09/07 16:46:12:00  | 4  | 40 | 400 |
        +-------------------------+----+----+-----+

        Then hydra will provide the data in the following format:

        '{
            "H1" : {\n
                    "2014/09/04 16:46:12:00":1,\n
                    "2014/09/05 16:46:12:00":2,\n
                    "2014/09/06 16:46:12:00":3,\n
                    "2014/09/07 16:46:12:00":4},\n

            "H2" : {\n
                    "2014/09/04 16:46:12:00":10,\n
                    "2014/09/05 16:46:12:00":20,\n
                    "2014/09/06 16:46:12:00":30,\n
                    "2014/09/07 16:46:12:00":40},\n

            "H3" :  {\n
                     "2014/09/04 16:46:12:00":100,\n
                     "2014/09/05 16:46:12:00":200,\n
                     "2014/09/06 16:46:12:00":300,\n
                     "2014/09/07 16:46:12:00":400}\n
        }'


        Args:
            scenario_id (int): The scenario to search
            include_values (string) ('Y' or 'N'): Default 'N'. Set to 'Y' to return the values. This may vause a performance hit as values are BIG!
            include_metadata: (string) ('Y' or 'N'): Default 'N'. Set to 'Y' to return metadata. This may vause a performance hit as metadata is BIG!
            page_start (int): The start of the search results (allows you to contol the nuber of results)
            page_end (int): The end of the search results

        Returns:
            List(ResourceData): A list of objects describing datasets specifically designed for efficiency

        """
        start = datetime.datetime.now()

        log.info("Getting all resource data for scenario %s", scenario_id)
        node_resourcedata = network.get_all_resource_data(
            scenario_id,
            include_metadata=include_metadata,
            page_start=page_start,
            page_end=page_end)

        log.info("Qry done in %s", (datetime.datetime.now() - start))

        start = datetime.datetime.now()

        return_ras = []
        for nodeattr in node_resourcedata:
            ra = ResourceData(nodeattr, include_values)
            return_ras.append(ra)

        log.info("%s return data found in %s", len(return_ras),
                 (datetime.datetime.now() - start))

        return return_ras

    @rpc(Integer,
         Integer,
         Integer(max_occurs="unbounded"),
         Unicode(pattern="['YN']", default='N'),
         _returns=SpyneArray(ResourceAttr))
    def get_all_link_data(ctx, network_id, scenario_id, link_ids,
                          include_metadata):
        """
        Return all the attributes for all the links in a given network and a
        given scenario.
        Returns a list of ResourceAttr objects, each with a resourcescenario
        attribute, containing the actual value for the scenario specified.

        Args:
            network_id (int): The network to search in
            scenario_id (int): The scenario to search
            link_ids (List(int)) (optional): The specific links to search for data in. If not specified, all the links in the network will be searched.
            include_metadata: (string) ('Y' or 'N'): Default 'N'. Set to 'Y' to return metadata. This may vause a performance hit as metadata is BIG!

        Returns:
            List(ResourceAttr), each with a resourcescenario attribute, containing the actual value for the scenario specified.

        Raises:
            ResourceNotFoundError: If the network or scenario are not found


        """
        start = datetime.datetime.now()

        link_resourcescenarios = network.get_attributes_for_resource(
            network_id, scenario_id, 'LINK', link_ids, include_metadata)

        log.info("Qry done in %s", (datetime.datetime.now() - start))
        start = datetime.datetime.now()

        return_ras = []
        for linkrs in link_resourcescenarios:
            ra = ResourceAttr(linkrs.resourceattr)
            ra.resourcescenario = ResourceScenario(linkrs, ra.attr_id)
            return_ras.append(ra)

        log.info("Return vals built in %s", (datetime.datetime.now() - start))

        return return_ras

    @rpc(Integer,
         Integer,
         Integer(max_occurs="unbounded"),
         Unicode(pattern="['YN']", default='N'),
         _returns=SpyneArray(ResourceAttr))
    def get_all_group_data(ctx, network_id, scenario_id, group_ids,
                           include_metadata):
        """
        Return all the attributes for all the groups in a given network and a
        given scenario.
        Returns a list of ResourceAttr objects, each with a resourcescenario
        attribute, containing the actual value for the scenario specified.

        Args:
            network_id (int): The network to search in
            scenario_id (int): The scenario to search
            group_ids (List(int)) (optional): The specific resource groups to search for data in. If not specified, all the groups in the network will be searched.
            include_metadata: (string) ('Y' or 'N'): Default 'N'. Set to 'Y' to return metadata. This may vause a performance hit as metadata is BIG!

        Returns:
            List(ResourceAttr), each with a resourcescenario attribute, containing the actual value for the scenario specified.

        """

        group_resourcescenarios = network.get_attributes_for_resource(
            network_id, scenario_id, 'GROUP', group_ids, include_metadata)
        return_ras = []
        for grouprs in group_resourcescenarios:
            ra = ResourceAttr(grouprs.resourceattr)
            ra.resourcescenario = ResourceScenario(grouprs, ra.attr_id)
            return_ras.append(ra)

        return return_ras
Exemplo n.º 9
0
class UserService(HydraService):
    """
        The user soap service
    """
    @rpc(Integer, _returns=Unicode)
    def get_username(ctx, uid):
        """

        Get a user's username.

        Args:
            uid (int): The ID of the user

        Returns:
            string: the user's username

        Raises:
            ResourceNotFoundError: If the uid is not found
            
        """
        username = users.get_username(uid, **ctx.in_header.__dict__)
        return username

    @rpc(User, _returns=User)
    def add_user(ctx, user):
        """
        Add a new user.

        Args:
            user (hydra_complexmodels.User): The user to be added, including username, display name and password

        Returns:
            hydra_complexmodels.User: The newly added user, without password

        Raises:
            ResourceNotFoundError: If the uid is not found
        """
        user_i = users.add_user(user, **ctx.in_header.__dict__)
        #u = User()
        #u.__dict__ = user_i.__dict__
        #return u

        return User(user_i)

    @rpc(User, _returns=User)
    def update_user_display_name(ctx, user):
        """
        Update a user's display name

        Args:
            user (hydra_complexmodels.User): The user to be updated. Only the display name is updated

        Returns:
            hydra_complexmodels.User: The updated user, without password

        Raises:
            ResourceNotFoundError: If the uid is not found
        """
        user_i = users.update_user_display_name(user, **ctx.in_header.__dict__)

        return User(user_i)

    @rpc(Integer, Unicode, _returns=User)
    def update_user_password(ctx, user_id, new_password):
        """
        Update a user's password

        Args:
            user_id (int): The ID user to be updated.
            new_password (string): The new password.

        Returns:
            hydra_complexmodels.User: The updated user, without password

        Raises:
            ResourceNotFoundError: If the user_id is not found
        """
        user_i = users.update_user_password(user_id, new_password,
                                            **ctx.in_header.__dict__)

        return User(user_i)

    @rpc(Unicode, _returns=User)
    def get_user_by_name(ctx, username):
        """
        Get a user by username

        Args:
            username (string): The username being searched for

        Returns:
            hydra_complexmodels.User: The requested user, or None 

        """
        user_i = users.get_user_by_name(username, **ctx.in_header.__dict__)
        if user_i:
            return User(user_i)

        return None

    @rpc(Integer, _returns=Unicode)
    def delete_user(ctx, user_id):
        """
        Delete a user permenantly from the DB.

        Args:
            user_id (int): The ID user to be deleted.

        Returns:
            string: 'OK' 

        Raises:
            ResourceNotFoundError: If the user_id is not found
        """
        success = 'OK'
        users.delete_user(user_id, **ctx.in_header.__dict__)
        return success

    @rpc(Role, _returns=Role)
    def add_role(ctx, role):
        """
        Add a new role. A role is the highest level in the permission tree
        and is container for permissions. Users are then assigned a role, which
        gives them the specified permissions

        Args:
            role (hydra_complexmodels.Role): The role to be added 

        Returns:
            hydra_complexmodels.Role: The newly created role, complete with ID

        """
        role_i = users.add_role(role, **ctx.in_header.__dict__)
        return Role(role_i)

    @rpc(Integer, _returns=Unicode)
    def delete_role(ctx, role_id):
        """
        Permenantly delete a role (and all its sub-permissions and users)

        Args:
            role_id (int): The role to be deleted 

        Returns:
            string: 'OK' 

        Raises:
            ResourceNotFoundError: If the role_id is not found
        """
        success = 'OK'
        users.delete_role(role_id, **ctx.in_header.__dict__)
        return success

    @rpc(Perm, _returns=Perm)
    def add_perm(ctx, perm):
        """
        Add a new permission. A permission defines a particular action that
        a user can perform. A permission is independent of roles and are
        added to roles later.

        Args:
            perm (hydra_complexmodels.Perm): The new permission.

        Returns:
            hydra_complexmodels.Perm: The new permission 

        """
        perm_i = users.add_perm(perm, **ctx.in_header.__dict__)
        return Perm(perm_i)

    @rpc(Integer, _returns=Unicode)
    def delete_perm(ctx, perm_id):
        """
        Permenantly delete a permission

        Args:
            perm_id (int): The permission to be deleted 

        Returns:
            string: 'OK' 

        Raises:
            ResourceNotFoundError: If the perm_id is not found
        """
        success = 'OK'
        users.delete_perm(perm_id, **ctx.in_header.__dict__)
        return success

    @rpc(Integer, Integer, _returns=Role)
    def set_user_role(ctx, user_id, role_id):
        """
        Assign a user to a role 

        Args:
            user_id (int): The user to be given the new role
            role_id (int): The role to receive the new user

        Returns:
            hydra_complexmodels.Role: Returns the role to which the user has been added. (contains all the user roles).

        Raises:
            ResourceNotFoundError: If the user_id or role_id do not exist
        """
        role_i = users.set_user_role(user_id, role_id,
                                     **ctx.in_header.__dict__)

        return Role(role_i)

    @rpc(Integer, Integer, _returns=Unicode)
    def delete_user_role(ctx, user_id, role_id):
        """
        Remove a user from a role 

        Args:
            user_id (int): The user to be removed from the role
            role_id (int): The role to lose the user

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the role does not contain the user or if the user or role do not exist.
        """

        success = 'OK'
        users.delete_user_role(user_id, role_id, **ctx.in_header.__dict__)
        return success

    @rpc(Integer, Integer, _returns=Role)
    def set_role_perm(ctx, role_id, perm_id):
        """
        Assign a permission to a role 

        Args:
            role_id (int): The role to receive the permission
            perm_id (int): The permission being added to the role

        Returns:
            hydra_complexmodels.Role: The newly updated role, complete with new permission

        Raises:
            ResourceNotFoundError: If the role or permission do not exist 
        """
        role_i = users.set_role_perm(role_id, perm_id,
                                     **ctx.in_header.__dict__)
        return Role(role_i)

    @rpc(Integer, Integer, _returns=Unicode)
    def delete_role_perm(ctx, role_id, perm_id):
        """
        Remove a permission from a role 

        Args:
            role_id (int): The role to lose the permission 
            perm_id (int): The permission being removed from the role

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the role does not contain the permission or if the userermission or role do not exist.
        """

        success = 'OK'
        users.delete_role_perm(role_id, perm_id, **ctx.in_header.__dict__)
        return success

    @rpc(Role, _returns=Role)
    def update_role(ctx, role):
        """
        Update a role.
        Used to add multiple permissions and users to a role in one go.

        Args:
            role (hydra_complexmodels.Role): The role with new users & permissions

        Returns:
            hydra_complexmodels.Role: The newly updated role

        Raises:
            ResourceNotFoundError: If the role or any users or permissions do not exist
        """
        role_i = users.update_role(role, **ctx.in_header.__dict__)
        return Role(role_i)

    @rpc(_returns=SpyneArray(User))
    def get_all_users(ctx):
        """
        Get the username & ID of all users.

        Args:

        Returns:
            List(hydra_complexmodels.User): All the users in the system

        Raises:

        """

        all_user_dicts = users.get_all_users(**ctx.in_header.__dict__)
        all_user_cms = [User(u) for u in all_user_dicts]
        return all_user_cms

    @rpc(_returns=SpyneArray(Perm))
    def get_all_perms(ctx):
        """
        Get all permissions

        Args:

        Returns:
            List(hydra_complexmodels.Perm): All the permissions in the system

        Raises:


        """
        all_perm_dicts = users.get_all_perms(**ctx.in_header.__dict__)
        all_perm_cms = [Perm(p) for p in all_perm_dicts]
        return all_perm_cms

    @rpc(_returns=SpyneArray(Role))
    def get_all_roles(ctx):
        """
        Get all roles

        Args:

        Returns:
            List(hydra_complexmodels.Role): All the roles in the system

        Raises:


        """
        all_role_dicts = users.get_all_roles(**ctx.in_header.__dict__)
        all_role_cms = [Role(r) for r in all_role_dicts]
        return all_role_cms

    @rpc(Integer, _returns=Role)
    def get_role(ctx, role_id):
        """
        Get a role by its ID.

        Args:
            role_id (int): The ID of the role to retrieve
        Returns:
            hydra_complexmodels.Role: The role

        Raises:
            ResourceNotFoundError: If the role does not exist

        """
        role_i = users.get_role(role_id, **ctx.in_header.__dict__)
        return Role(role_i)

    @rpc(Unicode, _returns=Role)
    def get_role_by_code(ctx, role_code):
        """
        Get a role by its code instead of ID (IDS can change between databases. codes
        are more stable)

        Args:
            role_code (string): The code of the role to retrieve
        Returns:
            hydra_complexmodels.Role: The role

        Raises:
            ResourceNotFoundError: If the role does not exist


        """
        role_i = users.get_role_by_code(role_code, **ctx.in_header.__dict__)

        return Role(role_i)

    @rpc(Unicode, _returns=SpyneArray(Role))
    def get_user_roles(ctx, user_id):
        """
        Get the roles assigned to a user. (A user can have multiple roles)

        Args:
            user_id (int): The ID of the user whose roles you want 

        Returns:
            List(hydra_complexmodels.Role): The roles of the user

        Raises:
            ResourceNotFoundError: If the user does not exist

        """
        roles = users.get_user_roles(user_id, **ctx.in_header.__dict__)
        return [Role(r) for r in roles]

    @rpc(Integer, _returns=Perm)
    def get_perm(ctx, perm_id):
        """
        Get a permission, by ID

        Args:
            perm_id (int): The ID of the permission

        Returns:
            hydra_complexmodels.Perm: The permission 

        Raises:
            ResourceNotFoundError: If the permission does not exist

        """
        perm = users.get_perm(perm_id, **ctx.in_header.__dict__)
        perm_cm = Perm(perm)
        return perm_cm

    @rpc(Unicode, _returns=Perm)
    def get_perm_by_code(ctx, perm_code):
        """
        Get a permission by its code.  Permission IDS change between hydra instances. Codes are more stable.

        Args:
            perm_id (int): The code of the permission.

        Returns:
            hydra_complexmodels.Perm: The permission 

        Raises:
            ResourceNotFoundError: If the permission does not exist

        """
        perm = users.get_perm_by_code(perm_code, **ctx.in_header.__dict__)
        perm_cm = Perm(perm)
        return perm_cm

    @rpc(Unicode, _returns=SpyneArray(Perm))
    def get_user_permissions(ctx, user_id):
        """
        Get all the permissions granted to the user, based on all the roles that the user is in.
        Args:
            user_id (int): The user whose permissions you want

        Returns:
            List(hydra_complexmodels.Perm): The user's permissions 

        Raises:
            ResourceNotFoundError: If the user does not exist


        """
        perms = users.get_user_permissions(user_id, **ctx.in_header.__dict__)
        return [Perm(p) for p in perms]
Exemplo n.º 10
0
class AttributeService(HydraService):
    """
        The attribute SOAP service
    """
    @rpc(Attr, _returns=Attr)
    def add_attribute(ctx, attr):
        """
        Add a generic attribute, which can then be used in creating
        a resource attribute, and put into a type.

        .. code-block:: python

            (Attr){
                name = "Test Attr"
                dimen = "very big"
                description = "I am a very big attribute"
            }

        Args:
            attr (hydra_complexmodels.Attr): An attribute object, as described above.

        Returns:
            hydra_complexmodels.Attr: An attribute object, similar to the one sent in but with an ID. 
        """

        attr = attributes.add_attribute(attr, **ctx.in_header.__dict__)
        return Attr(attr)

    @rpc(Attr, _returns=Attr)
    def update_attribute(ctx, attr):
        """
        Update a generic attribute, which can then be used in creating a resource attribute, and put into a type.

        .. code-block:: python

            (Attr){
                id = 1020
                name = "Test Attr"
                dimen = "very big"
                description = "I am a very big attribute"
            }

        Args:
            attr (hydra_complexmodels.Attr): An attribute complex model, as described above.

        Returns:
            hydra_complexmodels.Attr: An attribute complex model, reflecting the one sent in. 

        """
        attr = attributes.update_attribute(attr, **ctx.in_header.__dict__)
        return Attr(attr)

    @rpc(SpyneArray(Attr), _returns=SpyneArray(Attr))
    def add_attributes(ctx, attrs):
        """
        Add multiple generic attributes

        Args:
            attrs (List[Attr]): A list of attribute complex models, 
                as described above.

        Returns:
            List[Attr]: A list of attribute complex models,
                reflecting the ones sent in. 

        """

        attrs = attributes.add_attributes(attrs, **ctx.in_header.__dict__)
        ret_attrs = [Attr(attr) for attr in attrs]
        return ret_attrs

    @rpc(_returns=SpyneArray(Attr))
    def get_all_attributes(ctx):
        """
        Get all the attributes in the system

        Args:
            None

        Returns:
            List[Attr]: A list of attribute complex models
        """

        attrs = attributes.get_attributes(**ctx.in_header.__dict__)
        ret_attrs = [Attr(attr) for attr in attrs]
        return ret_attrs

    @rpc(Integer, _returns=Attr)
    def get_attribute_by_id(ctx, ID):
        """
        Get a specific attribute by its ID.

        Args:
            ID (int): The ID of the attribute

        Returns:
            hydra_complexmodels.Attr: An attribute complex model.
                Returns None if no attribute is found.
        """
        attr = attributes.get_attribute_by_id(ID, **ctx.in_header.__dict__)

        if attr:
            return Attr(attr)

        return None

    @rpc(Unicode, Unicode, _returns=Attr)
    def get_attribute(ctx, name, dimension):
        """
        Get a specific attribute by its name and dimension (this combination
        is unique for attributes in Hydra Platform).

        Args:
            name (unicode): The name of the attribute
            dimension (unicode): The dimension of the attribute

        Returns:
            hydra_complexmodels.Attr: An attribute complex model.
                Returns None if no attribute is found.

        """
        attr = attributes.get_attribute_by_name_and_dimension(
            name, dimension, **ctx.in_header.__dict__)
        if attr:
            return Attr(attr)

        return None

    @rpc(Integer, _returns=SpyneArray(Attr))
    def get_template_attributes(ctx, template_id):
        """
            Get all the attributes in a template.
            Args

                param (int) template_id

            Returns

                List(Attr)
        """
        attrs = attributes.get_template_attributes(template_id,
                                                   **ctx.in_header.__dict__)

        return [Attr(a) for a in attrs]

    @rpc(SpyneArray(Attr), _returns=SpyneArray(Attr))
    def get_attributes(ctx, attrs):
        """
        Get a list of attribute, by their names and dimension. Takes a list
            of attribute objects, picks out their name & dimension, finds the appropriate
            attribute in the DB and updates the incoming attribute with an ID.
            The same attributes go out that came in, except this time with an ID.
            If one of the incoming attributes does not match, this attribute is not
            returned.

        Args:
            attrs (List(Attr)): A list of attribute complex models

        Returns:
            List(hydra_complexmodels.Attr): List of Attr complex models
        
        """
        ret_attrs = []
        for a in attrs:
            log.info("Getting attribute %s, %s", a.name, a.dimen)
            attr = attributes.get_attribute_by_name_and_dimension(
                a.name, a.dimen, **ctx.in_header.__dict__)
            if attr:
                a.id = attr.attr_id
                a.cr_date = str(attr.cr_date)
                a.name = attr.attr_name
                a.dimen = attr.attr_dimen
                a.description = attr.attr_description
                ret_attrs.append(a)
            else:
                ret_attrs.append(None)

        return ret_attrs

    @rpc(Integer, Unicode(pattern="['YN']"), _returns=ResourceAttr)
    def update_resource_attribute(ctx, resource_attr_id, is_var):
        """
        Update a resource attribute (which means update the is_var flag
        as this is the only thing you can update on a resource attr)

        Args:
            resource_attr_id (int): ID of the complex model to be updated
            is_var           (unicode): 'Y' or 'N'

        Returns:
            List(hydra_complexmodels.ResourceAttr): Updated ResourceAttr

        Raises:
            ResourceNotFoundError if the resource_attr_id is not in the DB
        """
        updated_ra = attributes.update_resource_attribute(
            resource_attr_id, is_var, **ctx.in_header.__dict__)
        return ResourceAttr(updated_ra)

    @rpc(Integer, _returns=Unicode)
    def delete_resourceattr(ctx, resource_attr_id):
        """
        Deletes a resource attribute and all associated data.
        ***WILL BE DEPRECATED***

        Args:
            resource_attr_id (int): ID of the complex model to be deleted 

        Returns:
            unicode: 'OK'

        Raises:
            ResourceNotFoundError if the resource_attr_id is not in the DB

        """
        attributes.delete_resource_attribute(resource_attr_id,
                                             **ctx.in_header.__dict__)

        return 'OK'

    @rpc(Integer, _returns=Unicode)
    def delete_resource_attribute(ctx, resource_attr_id):
        """
        Add a resource attribute attribute to a resource (Duplicate of delete_resourceattr)

        Args:
            resource_attr_id (int): ID of the complex model to be deleted 

        Returns:
            unicode: 'OK'

        Raises:
            ResourceNotFoundError if the resource_attr_id is not in the DB

        """
        attributes.delete_resource_attribute(resource_attr_id,
                                             **ctx.in_header.__dict__)

        return "OK"

    @rpc(Integer,
         Integer,
         Unicode(pattern="['YN']", default='N'),
         _returns=ResourceAttr)
    def add_network_attribute(ctx, network_id, attr_id, is_var):
        """
        Add a resource attribute to a network.

        Args:
            network_id (int): ID of the network 
            attr_id    (int): ID of the attribute to assign to the network
            is_var     (string) 'Y' or 'N'. Indicates whether this attribute is
                a variable or not. (a variable is typically the result of a model run,
                so therefore doesn't need data assigned to it initially)

        Returns:
            hydra_complexmodels.ResourceAttr: A complex model of the newly created resource attribute.
        Raises:
            ResourceNotFoundError: If the network or attribute are not in the DB.
            HydraError           : If the attribute is already on the network.

        """
        new_ra = attributes.add_resource_attribute('NETWORK', network_id,
                                                   attr_id, is_var,
                                                   **ctx.in_header.__dict__)

        return ResourceAttr(new_ra)

    @rpc(Integer, Integer, _returns=SpyneArray(ResourceAttr))
    def add_network_attrs_from_type(ctx, type_id, network_id):
        """
        Adds all the attributes defined by a type to a network.

        Args:
            type_id    (int): ID of the type used to get the resource attributes from
            network_id (int): ID of the network 

        Returns:
            List(hydra_complexmodels.ResourceAttr): All the newly created network attributes

        Raises:
            ResourceNotFoundError if the type_id or network_id are not in the DB
        """
        new_resource_attrs = attributes.add_resource_attrs_from_type(
            type_id, 'NETWORK', network_id, **ctx.in_header.__dict__)

        return [ResourceAttr(ra) for ra in new_resource_attrs]

    @rpc(Integer,
         Integer(min_occurs=0, max_occurs=1),
         _returns=SpyneArray(ResourceAttr))
    def get_network_attributes(ctx, network_id, type_id):
        """
        Get all a network's attributes (not the attributes of the nodes and links. just the network itself).

        Args:
            network_id (int): ID of the network 
            type_id    (int) (optional): ID of the type. If specified will only return the resource attributes relative to that type

        Returns:
            List(hydra_complexmodels.ResourceAttr): All the network attributes

        Raises:
            ResourceNotFoundError if the type_id or network_id are not in the DB

 
        """
        resource_attrs = attributes.get_resource_attributes(
            'NETWORK', network_id, type_id)

        return [ResourceAttr(ra) for ra in resource_attrs]

    @rpc(Integer,
         Integer,
         Unicode(pattern="['YN']", default='N'),
         _returns=ResourceAttr)
    def add_node_attribute(ctx, node_id, attr_id, is_var):
        """
        Add a resource attribute to a node.

        Args:
            node_id (int): The ID of the Node
            attr_id (int): THe ID if the attribute being added.
            is_var (char): Y or N. Indicates whether the attribute is a variable or not.

        Returns:
            hydra_complexmodels.ResourceAttr: The newly created node attribute

        Raises:
            ResourceNotFoundError: If the node or attribute do not exist
            HydraError: If this addition causes a duplicate attribute on the node.

        """
        new_ra = attributes.add_resource_attribute('NODE', node_id, attr_id,
                                                   is_var,
                                                   **ctx.in_header.__dict__)

        return ResourceAttr(new_ra)

    @rpc(Integer, Integer, _returns=SpyneArray(ResourceAttr))
    def add_node_attrs_from_type(ctx, type_id, node_id):
        """
        Adds all the attributes defined by a type to a node.

        Args:
            type_id (int): ID of the type used to get the resource attributes from
            node_id (int): ID of the node 

        Returns:
            List(hydra_complexmodels.ResourceAttr): All the newly created node attributes

        Raises:
            ResourceNotFoundError if the type_id or node_id are not in the DB
 
        """
        new_resource_attrs = attributes.add_resource_attrs_from_type(
            type_id, 'NODE', node_id, **ctx.in_header.__dict__)
        return [ResourceAttr(ra) for ra in new_resource_attrs]

    @rpc(Integer,
         Integer(min_occurs=0, max_occurs=1),
         _returns=SpyneArray(ResourceAttr))
    def get_node_attributes(ctx, node_id, type_id):
        """
        Get all a node's attributes.

        Args:
            node_id (int): ID of the node 
            type_id (int) (optional): ID of the type. If specified will only return the resource attributes relative to that type

        Returns:
            List(hydra_complexmodels.ResourceAttr): All the node's attributes

        Raises:
            ResourceNotFoundError if the type_id or node_id do not exist.
        """

        resource_attrs = attributes.get_resource_attributes(
            'NODE', node_id, type_id)

        return [ResourceAttr(ra) for ra in resource_attrs]

    @rpc(Integer,
         Integer(min_occurs=0, max_occurs=1),
         _returns=SpyneArray(ResourceAttr))
    def get_all_node_attributes(ctx, network_id, template_id):
        """
        Get all the resource attributes for all the nodes in the network.

        Args:
            network_id (int): The ID of the network that you want the node attributes from
            template_id (int) (optional): If this is specified, then it will only return the attributes in this template.

        Returns:
            List(hydra_complexmodels.ResourceAttr): The resource attributes of all the nodes in the network.
        """
        resource_attrs = attributes.get_all_resource_attributes(
            'NODE', network_id, template_id)

        return [ResourceAttr(ra) for ra in resource_attrs]

    @rpc(Integer,
         Integer,
         Unicode(pattern="['YN']", default='N'),
         _returns=ResourceAttr)
    def add_link_attribute(ctx, link_id, attr_id, is_var):
        """
        Add a resource attribute to a link.

        Args:
            link_id (int): The ID of the Link
            attr_id (int): THe ID if the attribute being added.
            is_var (char): Y or N. Indicates whether the attribute is a variable or not.

        Returns:
            hydra_complexmodels.ResourceAttr: The newly created link attribute

        Raises:
            ResourceNotFoundError: If the link or attribute do not exist
            HydraError: If this addition causes a duplicate attribute on the link.

        """
        new_ra = attributes.add_resource_attribute('LINK', link_id, attr_id,
                                                   is_var,
                                                   **ctx.in_header.__dict__)

        return ResourceAttr(new_ra)

    @rpc(Integer, Integer, _returns=SpyneArray(ResourceAttr))
    def add_link_attrs_from_type(ctx, type_id, link_id):
        """
        Adds all the attributes defined by a type to a link.

        Args:
            type_id (int): ID of the type used to get the resource attributes from
            link_id (int): ID of the link

        Returns:
            List(hydra_complexmodels.ResourceAttr): All the newly created link attributes

        Raises:
            ResourceNotFoundError if the type_id or link_id are not in the DB
 
        """

        new_resource_attrs = attributes.add_resource_attrs_from_type(
            type_id, 'LINK', link_id, **ctx.in_header.__dict__)
        return [ResourceAttr(ra) for ra in new_resource_attrs]

    @rpc(Integer,
         Integer(min_occurs=0, max_occurs=1),
         _returns=SpyneArray(ResourceAttr))
    def get_link_attributes(ctx, link_id, type_id):
        """
        Get all a link's attributes.

        Args:
            link_id (int): ID of the link 
            type_id (int) (optional): ID of the type. If specified will only return the resource attributes relative to that type

        Returns:
            List(hydra_complexmodels.ResourceAttr): All the link's attributes

        Raises:
            ResourceNotFoundError if the type_id or link_id do not exist.
        """

        resource_attrs = attributes.get_resource_attributes(
            'LINK', link_id, type_id)

        return [ResourceAttr(ra) for ra in resource_attrs]

    @rpc(Integer,
         Integer(min_occurs=0, max_occurs=1),
         _returns=SpyneArray(ResourceAttr))
    def get_all_link_attributes(ctx, network_id, template_id):
        """
        Get all the resource attributes for all the links in the network.

        Args:
            network_id (int): The ID of the network that you want the link attributes from
            template_id (int) (optional): If this is specified, then it will only return the attributes in this template.

        Returns:
            List(hydra_complexmodels.ResourceAttr): The resource attributes of all the links in the network.
        """

        resource_attrs = attributes.get_all_resource_attributes(
            'LINK', network_id, template_id)

        return [ResourceAttr(ra) for ra in resource_attrs]

    @rpc(Integer,
         Integer,
         Unicode(pattern="['YN']", default='N'),
         _returns=ResourceAttr)
    def add_group_attribute(ctx, group_id, attr_id, is_var):
        """
        Add a resource attribute to a group.

        Args:
            group_id (int): The ID of the Group
            attr_id (int): THe ID if the attribute being added.
            is_var (char): Y or N. Indicates whether the attribute is a variable or not.

        Returns:
            hydra_complexmodels.ResourceAttr: The newly created group attribute

        Raises:
            ResourceNotFoundError: If the group or attribute do not exist
            HydraError: If this addition causes a duplicate attribute on the group.

        """

        new_ra = attributes.add_resource_attribute('GROUP', group_id, attr_id,
                                                   is_var,
                                                   **ctx.in_header.__dict__)

        return ResourceAttr(new_ra)

    @rpc(Integer, Integer, _returns=SpyneArray(ResourceAttr))
    def add_group_attrs_from_type(ctx, type_id, group_id):
        """
        Adds all the attributes defined by a type to a group.

        Args:
            type_id (int): ID of the type used to get the resource attributes from
            group_id (int): ID of the group

        Returns:
            List(hydra_complexmodels.ResourceAttr): All the newly created group attributes

        Raises:
            ResourceNotFoundError if the type_id or group_id are not in the DB
 
        """
        new_resource_attrs = attributes.add_resource_attrs_from_type(
            type_id, 'GROUP', group_id, **ctx.in_header.__dict__)
        return [ResourceAttr(ra) for ra in new_resource_attrs]

    @rpc(Integer,
         Integer(min_occurs=0, max_occurs=1),
         _returns=SpyneArray(ResourceAttr))
    def get_group_attributes(ctx, group_id, type_id):
        """
        Get all a group's attributes.

        Args:
            group_id (int): ID of the group 
            type_id (int) (optional): ID of the type. If specified will only return the resource attributes relative to that type

        Returns:
            List(hydra_complexmodels.ResourceAttr): All the group's attributes

        Raises:
            ResourceNotFoundError if the type_id or group_id do not exist.
        """

        resource_attrs = attributes.get_resource_attributes(
            'GROUP', group_id, type_id, **ctx.in_header.__dict__)

        return [ResourceAttr(ra) for ra in resource_attrs]

    @rpc(Integer,
         Integer(min_occurs=0, max_occurs=1),
         _returns=SpyneArray(ResourceAttr))
    def get_all_group_attributes(ctx, network_id, template_id):
        """
        Get all the resource attributes for all the groups in the network.

        Args:
            network_id (int): The ID of the network that you want the group attributes from
            template_id (int) (optional): If this is specified, then it will only return the attributes in this template.

        Returns:
            List(hydra_complexmodels.ResourceAttr): The resource attributes of all the groups in the network.
        """

        resource_attrs = attributes.get_all_resource_attributes(
            'GROUP', network_id, template_id, **ctx.in_header.__dict__)

        return [ResourceAttr(ra) for ra in resource_attrs]

    @rpc(Integer, _returns=Unicode)
    def check_attr_dimension(ctx, attr_id):
        """
        Check that the dimension of the resource attribute data is consistent
        with the definition of the attribute.
        If the attribute says 'volume', make sure every dataset connected
        with this attribute via a resource attribute also has a dimension
        of 'volume'.
        
        Args:
            attr_id (int): The ID of the attribute you want to check

        Returns:
            string: 'OK' if all is well.

        Raises:
            HydraError: If a dimension mismatch is found.
        """

        attributes.check_attr_dimension(attr_id, **ctx.in_header.__dict__)

        return 'OK'

    @rpc(Integer, Integer, _returns=Unicode)
    def set_attribute_mapping(ctx, resource_attr_a, resource_attr_b):
        """
        Define one resource attribute from one network as being the same as
        that from another network.

        Args:
            resource_attr_a (int): The ID of the source resoure attribute
            resource_attr_b (int): The ID of the target resoure attribute

        Returns:
            string: 'OK' if all is well.

        Raises:
            ResourceNotFoundError: If either resource attribute is not found.
        """
        attributes.set_attribute_mapping(resource_attr_a, resource_attr_b,
                                         **ctx.in_header.__dict__)

        return 'OK'

    @rpc(Integer, Integer, _returns=Unicode)
    def delete_attribute_mapping(ctx, resource_attr_a, resource_attr_b):
        """
        Delete a mapping which said one resource attribute from one network 
        was the same as the resource attribute in another.

        Args:
            resource_attr_a (int): The ID of the source resoure attribute
            resource_attr_b (int): The ID of the target resoure attribute

        Returns:
            string: 'OK' if all is well. If the mapping isn't there, it'll still return 'OK', so make sure the IDs are correct! 

        """
        attributes.delete_attribute_mapping(resource_attr_a, resource_attr_b,
                                            **ctx.in_header.__dict__)

        return 'OK'

    @rpc(Integer,
         Integer(min_occurs=0, max_occurs=1),
         _returns=SpyneArray(ResourceAttrMap))
    def get_mappings_in_network(ctx, network_id, network_2_id):
        """
        Get all the resource attribute mappings in a network (both from and to). If another network
        is specified, only return the mappings between the two networks.

        Args:
            network_id (int): The network you want to check the mappings of (both from and to)
            network_2_id (int) (optional): The partner network

        Returns:
            List(hydra_complexmodels.ResourceAttrMap): All the mappings to and from the network(s) in question.
        """
        mapping_rs = attributes.get_mappings_in_network(
            network_id, network_2_id, **ctx.in_header.__dict__)

        mappings = [ResourceAttrMap(m) for m in mapping_rs]
        return mappings

    @rpc(Integer, Integer(min_occurs=0, max_occurs=1), _returns=Unicode)
    def delete_mappings_in_network(ctx, network_id, network_2_id):
        """
        Delete all the resource attribute mappings in a network. If another network
        is specified, only delete the mappings between the two networks.

        Args:
            network_id (int): The network you want to delete the mappings from (both from and to)
            network_2_id (int) (optional): The partner network

        Returns:
            string: 'OK'
        """
        attributes.delete_mappings_in_network(network_id, network_2_id,
                                              **ctx.in_header.__dict__)

        return 'OK'

    @rpc(Integer,
         Integer(min_occurs=0, max_occurs=1),
         _returns=SpyneArray(ResourceAttrMap))
    def get_node_mappings(ctx, node_id, node_2_id):
        """
        Get the mappings for all the attributes of a given node. If a second node
        is specified, return only the mappings between these nodes..

        Args:
            node_id (int): The node you want to delete the mappings from (both from and to)
            node_2_id (int) (optional): The partner node

        Returns:
            List(hydra_complexmodels.ResourceAttrMap): All the mappings to and from the node(s) in question.
        """
        mapping_rs = attributes.get_node_mappings(node_id, node_2_id,
                                                  **ctx.in_header.__dict__)

        mappings = [ResourceAttrMap(m) for m in mapping_rs]
        return mappings

    @rpc(Integer, Integer, _returns=Unicode)
    def check_mapping_exists(ctx, resource_attr_id_source,
                             resource_attr_id_target):
        """
        Check whether a mapping exists between two resource attributes
        This does not check whether a reverse mapping exists, so order is important here.

        Args:
            resource_attr_id_source (int): The source resource attribute 
            resource_attr_id_target (int) (optional): The target resource attribute

        Returns:
            string: 'Y' if a mapping between the source and target exists. 'N' in every other case.

        """
        is_mapped = attributes.check_attribute_mapping_exists(
            resource_attr_id_source, resource_attr_id_target,
            **ctx.in_header.__dict__)

        return is_mapped
Exemplo n.º 11
0
class ProjectService(HydraService):
    """
        The project SOAP service
    """

    @rpc(Project, _returns=Project)
    def add_project(ctx, project):
        """
            Add a new project

            Args:
                project (hydra_complexmodels.Project): The new project to be added. The project does not include networks.

            Returns:
                hydra_complexmodels.Project: The project received, but with an ID this time.


            Raises:

        """

        new_proj = project_lib.add_project(project, **ctx.in_header.__dict__) 
        ret_proj = Project(new_proj)
        return ret_proj

    @rpc(Project, _returns=Project)
    def update_project(ctx, project):
        """
            Update a project

            Args:
                project (hydra_complexmodels.Project): The project to be updated. All the attributes of this project will be used to update the existing project

            Returns:
                hydra_complexmodels.Project: The updated project 

            Raises:
                ResourceNotFoundError: If the project is not found.

        """
        proj_i = project_lib.update_project(project,  **ctx.in_header.__dict__) 

        return Project(proj_i)


    @rpc(Integer, _returns=Project)
    def get_project(ctx, project_id):
        """
        Get an existing Project

        Args:
            project_id (int): The ID of the project to retrieve 

        Returns:
            hydra_complexmodels.Project: The requested project 

        Raises:
            ResourceNotFoundError: If the project is not found.
        """
        proj_dict = project_lib.get_project(project_id,  **ctx.in_header.__dict__) 

        return Project(proj_dict)
 
    @rpc(Unicode, _returns=Project)
    def get_project_by_name(ctx, project_name):
        """
        If you don't know the ID of the project in question, but do know
        the name, use this function to retrieve it.
    
        Args:
            project_name (string): The name of the project to retrieve 

        Returns:
            hydra_complexmodels.Project: The requested project 

        Raises:
            ResourceNotFoundError: If the project is not found.

        """
        proj_dict = project_lib.get_project_by_name(project_name,  **ctx.in_header.__dict__) 

        return Project(proj_dict)

    @rpc(Integer, _returns=SpyneArray(ProjectSummary))
    def get_projects(ctx, user_id):
        """
        Get all the projects belonging to a user. 

        Args:
            user_id (int): The user ID whose projects you want 

        Returns:
            List(hydra_complexmodels.Project): The requested projects

        Raises:
            ResourceNotFoundError: If the User is not found.

        """
        if user_id is None:
            user_id = ctx.in_header.user_id
        project_dicts = project_lib.get_projects(user_id,  **ctx.in_header.__dict__)
        projects = [Project(p) for p in project_dicts]
        return projects


    @rpc(Integer, _returns=Unicode)
    def delete_project(ctx, project_id):
        """
        Set the status of a project to 'X'. This does NOT delete the project from
        the database (which also entails deleting all sub-networks, data etc). For
        that, use purge_project.
        
        Args:
            project_id (int): The ID of the project to delete. 

        Returns:
            string: 'OK' 

        Raises:
            ResourceNotFoundError: If the Project is not found.

        """
        project_lib.set_project_status(project_id, 'X',  **ctx.in_header.__dict__)
        return 'OK' 

    @rpc(Integer, _returns=Unicode)
    def purge_project(ctx, project_id):
        """
        Delete a project from the DB completely. WARNING: THIS WILL DELETE ALL
        THE PROJECT'S NETWORKS AND CANNOT BE REVERSED!

        Args:
            project_id (int): The ID of the project to purge. 

        Returns:
            string: 'OK' 

        Raises:
            ResourceNotFoundError: If the Project is not found.
        """
        project_lib.delete_project(project_id,  **ctx.in_header.__dict__)
        return 'OK' 

    @rpc(Integer, Unicode(pattern="[YN]", default='Y'), _returns=SpyneArray(Network))
    def get_networks(ctx, project_id, include_data):
        """
        Get all networks in a project
        
        Args:
            project_id (int): The ID of the project whose networks you want.
            include_data (string) ('Y' or 'N'): Include data with the networks? Defaults as 'Y' but using 'N' gives a significant performance boost.

        Returns:
            List(hydra_complexmodels.Network): All the project's Networks.

        Raises:
            ResourceNotFoundError: If the Project is not found.

        """
        net_dicts = project_lib.get_networks(project_id, include_data=include_data, **ctx.in_header.__dict__)
        networks = [Network(n, summary=True) for n in net_dicts]
        return networks

    @rpc(Integer, _returns=Project)
    def get_network_project(ctx, network_id):
        """
        Get the project of a specified network

        Args:
            network_id (int): The ID of the network whose project details you want 

        Returns:
            hydra_complexmodels.Project: The parent project of the specified Network

        Raises:
            ResourceNotFoundError: If the Network is not found.


        """
        proj = project_lib.get_network_project(network_id, **ctx.in_header.__dict__)

        return Project(proj)
Exemplo n.º 12
0
class ScenarioService(HydraService):
    """
        The scenario SOAP service
        as all resources already exist, there is no need to worry
        about negative IDS
    """
    @rpc(Integer, Unicode(pattern="['YN']", default='N'), _returns=Scenario)
    def get_scenario(ctx, scenario_id, return_summary):
        """
            Get the specified scenario
        """
        scen = scenario.get_scenario(scenario_id, **ctx.in_header.__dict__)

        if return_summary == 'Y':
            return Scenario(scen, summary=True)
        else:
            return Scenario(scen, summary=False)

    @rpc(Integer,
         Scenario,
         Unicode(pattern="['YN']", default='N'),
         _returns=Scenario)
    def add_scenario(ctx, network_id, scen, return_summary):
        """
            Add a scenario to a specified network.
        """
        new_scen = scenario.add_scenario(network_id, scen,
                                         **ctx.in_header.__dict__)
        if return_summary == 'Y':
            return Scenario(new_scen, summary=True)
        else:
            return Scenario(new_scen, summary=False)

    @rpc(Scenario,
         Unicode(pattern="['YN']", default='Y'),
         Unicode(pattern="['YN']", default='Y'),
         Unicode(pattern="['YN']", default='N'),
         _returns=Scenario)
    def update_scenario(ctx, scen, update_data, update_groups, return_summary):
        """
            Update a single scenario
            as all resources already exist, there is no need to worry
            about negative IDS
        """
        upd_data = True if update_data == 'Y' else False
        upd_grp = True if update_groups == 'Y' else False

        updated_scen = scenario.update_scenario(scen,
                                                update_data=upd_data,
                                                update_groups=upd_grp,
                                                **ctx.in_header.__dict__)

        if return_summary == 'Y':
            return Scenario(updated_scen, summary=True)
        else:
            return Scenario(updated_scen, summary=False)

    @rpc(Integer, _returns=Unicode)
    def purge_scenario(ctx, scenario_id):
        """
            Set the status of a scenario to 'X'.
        """

        return scenario.purge_scenario(scenario_id, **ctx.in_header.__dict__)

    @rpc(Integer, _returns=Unicode)
    def delete_scenario(ctx, scenario_id):
        """
            Set the status of a scenario to 'X'.
        """

        return scenario.set_scenario_status(scenario_id, 'X',
                                            **ctx.in_header.__dict__)

    @rpc(Integer, _returns=Unicode)
    def activate_scenario(ctx, scenario_id):
        """
            Set the status of a scenario to 'X'.
        """

        return scenario.set_scenario_status(scenario_id, 'A',
                                            **ctx.in_header.__dict__)

    @rpc(Integer, _returns=Scenario)
    def clone_scenario(ctx, scenario_id):

        cloned_scen = scenario.clone_scenario(scenario_id,
                                              **ctx.in_header.__dict__)

        return Scenario(cloned_scen, summary=True)

    @rpc(Integer, Integer, _returns=ScenarioDiff)
    def compare_scenarios(ctx, scenario_id_1, scenario_id_2):
        scenariodiff = scenario.compare_scenarios(scenario_id_1, scenario_id_2,
                                                  **ctx.in_header.__dict__)

        return ScenarioDiff(scenariodiff)

    @rpc(Integer, _returns=Unicode)
    def lock_scenario(ctx, scenario_id):
        result = scenario.lock_scenario(scenario_id, **ctx.in_header.__dict__)
        return result

    @rpc(Integer, _returns=Unicode)
    def unlock_scenario(ctx, scenario_id):
        result = scenario.unlock_scenario(scenario_id,
                                          **ctx.in_header.__dict__)
        return result

    @rpc(Integer, _returns=SpyneArray(Scenario))
    def get_dataset_scenarios(ctx, dataset_id):
        """
            Get all the scenarios attached to a dataset
            @returns a list of scenario_ids
        """

        scenarios = scenario.get_dataset_scenarios(dataset_id,
                                                   **ctx.in_header.__dict__)

        return [Scenario(s, summary=True) for s in scenarios]

    @rpc(Integer,
         SpyneArray(ResourceScenario),
         _returns=SpyneArray(ResourceScenario))
    def update_resourcedata(ctx, scenario_id, resource_scenarios):
        """
            Update the data associated with a scenario.
            Data missing from the resource scenario will not be removed
            from the scenario. Use the remove_resourcedata for this task.
        """
        res = scenario.update_resourcedata(scenario_id, resource_scenarios,
                                           **ctx.in_header.__dict__)
        ret = [ResourceScenario(r) for r in res]
        return ret

    @rpc(SpyneArray(Integer32), SpyneArray(ResourceScenario), _returns=Unicode)
    def bulk_update_resourcedata(ctx, scenario_ids, resource_scenarios):
        """
            Update the data associated with a scenario.
            Data missing from the resource scenario will not be removed
            from the scenario. Use the remove_resourcedata for this task.
        """

        scenario.bulk_update_resourcedata(scenario_ids, resource_scenarios,
                                          **ctx.in_header.__dict__)

        return 'OK'

    @rpc(Integer, ResourceScenario, _returns=Unicode)
    def delete_resourcedata(ctx, scenario_id, resource_scenario):
        """
            Remove the data associated with a resource in a scenario.
        """
        success = 'OK'
        scenario.delete_resourcedata(scenario_id, resource_scenario,
                                     **ctx.in_header.__dict__)
        return success

    @rpc(Integer, Integer, Dataset, _returns=ResourceScenario)
    def add_data_to_attribute(ctx, scenario_id, resource_attr_id, dataset):
        """
                Add data to a resource scenario outside of a network update
        """
        new_rs = scenario.add_data_to_attribute(scenario_id, resource_attr_id,
                                                dataset,
                                                **ctx.in_header.__dict__)
        x = ResourceScenario(new_rs)
        return x

    @rpc(Integer, _returns=SpyneArray(Dataset))
    def get_scenario_data(ctx, scenario_id):
        scenario_data = scenario.get_scenario_data(scenario_id,
                                                   **ctx.in_header.__dict__)
        data_cm = [Dataset(d) for d in scenario_data]
        return data_cm

    @rpc(Integer,
         Integer(min_occurs=1, max_occurs='unbounded'),
         Integer(min_occurs=0, max_occurs=1),
         _returns=SpyneArray(ResourceScenario))
    def get_node_data(ctx, node_id, scenario_id, type_id):
        """
            Get all the resource scenarios for a given node 
            in a given scenario. If type_id is specified, only
            return the resource scenarios for the attributes
            within the type.
        """
        node_data = scenario.get_resource_data('NODE', node_id, scenario_id,
                                               type_id,
                                               **ctx.in_header.__dict__)

        ret_data = [ResourceScenario(rs) for rs in node_data]
        return ret_data

    @rpc(Integer,
         Integer,
         Integer(min_occurs=0, max_occurs=1),
         _returns=SpyneArray(ResourceScenario))
    def get_link_data(ctx, link_id, scenario_id, type_id):
        """
            Get all the resource scenarios for a given link 
            in a given scenario. If type_id is specified, only
            return the resource scenarios for the attributes
            within the type.
        """
        link_data = scenario.get_resource_data('LINK', link_id, scenario_id,
                                               type_id,
                                               **ctx.in_header.__dict__)

        ret_data = [ResourceScenario(rs) for rs in link_data]
        return ret_data

    @rpc(Integer,
         Integer,
         Integer(min_occurs=0, max_occurs=1),
         _returns=SpyneArray(ResourceScenario))
    def get_network_data(ctx, network_id, scenario_id, type_id):
        """
            Get all the resource scenarios for a given network 
            in a given scenario. If type_id is specified, only
            return the resource scenarios for the attributes
            within the type.
        """
        network_data = scenario.get_resource_data('NETWORK', network_id,
                                                  scenario_id, type_id,
                                                  **ctx.in_header.__dict__)

        ret_data = [ResourceScenario(rs) for rs in network_data]
        return ret_data

    @rpc(Integer,
         Integer,
         Integer(min_occurs=0, max_occurs=1),
         _returns=SpyneArray(ResourceScenario))
    def get_resourcegroup_data(ctx, resourcegroup_id, scenario_id, type_id):
        """
            Get all the resource scenarios for a given resourcegroup 
            in a given scenario. If type_id is specified, only
            return the resource scenarios for the attributes
            within the type.
        """
        group_data = scenario.get_resource_data('GROUP', resourcegroup_id,
                                                scenario_id, type_id,
                                                **ctx.in_header.__dict__)

        ret_data = [ResourceScenario(rs) for rs in group_data]
        return ret_data

    @rpc(SpyneArray(Integer), SpyneArray(Integer), _returns=AttributeData)
    def get_node_attribute_data(ctx, node_ids, attr_ids):
        """
            Get the data for multiple attributes on multiple nodes
            across multiple scenarios.
            @returns a list of AttributeData objects, which consist of a list
            of ResourceAttribute objects and a list of corresponding
            ResourceScenario objects.
        """

        node_attrs, resource_scenarios = scenario.get_attribute_data(
            attr_ids, node_ids, **ctx.in_header.__dict__)

        node_ras = [ResourceAttr(na) for na in node_attrs]
        node_rs = [ResourceScenario(rs) for rs in resource_scenarios]

        ret_obj = AttributeData()
        ret_obj.resourceattrs = node_ras
        ret_obj.resourcescenarios = node_rs

        return ret_obj

    @rpc(Integer, Integer, _returns=SpyneArray(ResourceAttr))
    def get_attribute_datasets(ctx, attr_id, scenario_id):
        """
            Get all the datasets from resource attributes with the given attribute
            ID in the given scenario.

            Return a list of resource attributes with their associated
            resource scenarios (and values).
        """
        resource_attrs = scenario.get_attribute_datasests(
            attr_id, scenario_id, **ctx.in_header.__dict__)

        ra_cms = []
        for ra in resource_attrs:
            res_attr_cm = ResourceAttr(ra)
            for rs in ra.resourcescenarios:
                if rs.scenario_id == scenario_id:
                    res_attr_cm.resourcescenario = ResourceScenario(rs)
            ra_cms.append(res_attr_cm)

        return ra_cms

    @rpc(Integer(min_occurs=1, max_occurs='unbounded'),
         Integer(min_occurs=1, max_occurs='unbounded'),
         _returns=SpyneArray(ResourceScenario))
    def get_resourcescenarios(ctx, resource_attr_id, scenario_id):
        """
            Get all the resource scenarios from a list of scenarios and resource scenarios
            Return a list of resource scenarios.
        """

        if not isinstance(resource_attr_id, list):
            resource_attr_id = [resource_attr_id]

        if not isinstance(scenario_id, list):
            scenario_id = [scenario_id]

        resource_scenarios = scenario.get_resourcescenarios(
            resource_attr_id, scenario_id, **ctx.in_header.__dict__)

        rs_cms = []
        for rs in resource_scenarios:
            rs_cms.append(ResourceScenario(rs))

        return rs_cms

    @rpc(Integer(min_occurs=1, max_occurs='unbounded'),
         Integer,
         Integer,
         _returns=SpyneArray(ResourceScenario))
    def copy_data_from_scenario(ctx, resource_attr_ids, source_scenario_id,
                                target_scenario_id):
        """
            Copy the datasets from a source scenario into the equivalent resource scenarios
            in the target scenario. Parameters are a list of resource attribute IDS, the
            ID of the source scenario and the ID of the target scenario.
        """
        updated_resourcescenarios = scenario.copy_data_from_scenario(
            resource_attr_ids, source_scenario_id, target_scenario_id,
            **ctx.in_header.__dict__)

        ret_resourcescenarios = [
            ResourceScenario(rs) for rs in updated_resourcescenarios
        ]

        return ret_resourcescenarios

    @rpc(Integer, Integer, Integer, _returns=ResourceScenario)
    def set_resourcescenario_dataset(ctx, resource_attr_id, scenario_id,
                                     dataset_id):
        """
            A short-hand way of creating a resource scenario. This function says:
            assign this datset ID to this resource attribute in this scenario.
            All the IDs must already exist.
        """

        rs = scenario.set_rs_dataset(resource_attr_id, scenario_id, dataset_id,
                                     **ctx.in_header.__dict__)

        return ResourceScenario(rs)

    @rpc(Integer, Integer, _returns=SpyneArray(ResourceGroupItem))
    def get_resourcegroupitems(ctx, group_id, scenario_id):
        items = scenario.get_resourcegroupitems(group_id, scenario_id,
                                                **ctx.in_header.__dict__)

        return [ResourceGroupItem(rgi) for rgi in items]

    @rpc(Integer, Integer, Integer, Integer, _returns=ResourceScenario)
    def update_value_from_mapping(ctx, source_resource_attr_id,
                                  target_resource_attr_id, source_scenario_id,
                                  target_scenario_id):

        updated_rs = scenario.update_value_from_mapping(
            source_resource_attr_id, target_resource_attr_id,
            source_scenario_id, target_scenario_id, **ctx.in_header.__dict__)

        if updated_rs is not None:
            return ResourceScenario(updated_rs)
        else:
            return None
class Service(HydraService):
    __service_name__ = "AdvancedDatasetRetrievalService"

    @rpc(Integer32(min_occurs=1, max_occurs='unbounded'),
         Integer32(min_occurs=1, max_occurs='unbounded'),
         Integer32(min_occurs=1, max_occurs='unbounded'),
         _returns=SpyneArray(NodeDatasetMatrix))
    def get_node_dataset_matrix(ctx, node_ids, attribute_ids, scenario_ids):
        """
            Given a list of resources, attributes and scenarios return a matrix
            of datasets. If a resource doesn't have an attribute, return None.
            If a resource has an attribute but no dataset, return None.

        """

        if len(scenario_ids) == 0:
            raise HydraError("No scenarios specified!")
        if len(attribute_ids) == 0:
            raise HydraError("No attributes specified!")
        if len(node_ids) == 0:
            raise HydraError("No resources specified")

        nodes = _get_nodes(node_ids)

        resource_attrs = _get_resource_attributes('NODE', node_ids,
                                                  attribute_ids)

        data = _get_data('NODE', node_ids, attribute_ids, scenario_ids)

        #group the data by scenario
        node_attr_dict = get_attr_dict('NODE', scenario_ids, node_ids,
                                       attribute_ids, nodes, resource_attrs,
                                       data)

        returned_matrix = [
            NodeDatasetMatrix(scenario_id, data)
            for scenario_id, data in node_attr_dict.items()
        ]

        return returned_matrix

    @rpc(Integer32(min_occurs=1, max_occurs='unbounded'),
         Integer32(min_occurs=1, max_occurs='unbounded'),
         Integer32(min_occurs=1, max_occurs='unbounded'),
         _returns=SpyneArray(LinkDatasetMatrix))
    def get_link_dataset_matrix(ctx, link_ids, attribute_ids, scenario_ids):
        """
            Given a list of resources, attributes and scenarios return a matrix
            of datasets. If a resource doesn't have an attribute, return None.
            If a resource has an attribute but no dataset, return None.

        """

        if len(scenario_ids) == 0:
            raise HydraError("No scenarios specified!")
        if len(attribute_ids) == 0:
            raise HydraError("No attributes specified!")
        if len(link_ids) == 0:
            raise HydraError("No resources specified")

        links = _get_links(link_ids)

        resource_attrs = _get_resource_attributes('LINK', link_ids,
                                                  attribute_ids)

        data = _get_data('LINK', link_ids, attribute_ids, scenario_ids)

        link_attr_dict = get_attr_dict('LINK', scenario_ids, link_ids,
                                       attribute_ids, links, resource_attrs,
                                       data)

        returned_matrix = [
            LinkDatasetMatrix(scenario_id, data)
            for scenario_id, data in link_attr_dict.items()
        ]

        return returned_matrix

    @rpc(Integer32(min_occurs=1, max_occurs='unbounded'),
         Integer32(min_occurs=1, max_occurs='unbounded'),
         Integer32(min_occurs=1, max_occurs='unbounded'),
         _returns=SpyneArray(GroupDatasetMatrix))
    def get_group_dataset_matrix(ctx, group_ids, attribute_ids, scenario_ids):
        """
            Given a list of resources, attributes and scenarios return a matrix
            of datasets. If a resource doesn't have an attribute, return None.
            If a resource has an attribute but no dataset, return None.

        """
        if len(scenario_ids) == 0:
            raise HydraError("No scenarios specified!")
        if len(attribute_ids) == 0:
            raise HydraError("No attributes specified!")
        if len(group_ids) == 0:
            raise HydraError("No resources specified")

        groups = _get_groups(group_ids)

        resource_attrs = _get_resource_attributes('GROUP', group_ids,
                                                  attribute_ids)

        data = _get_data('GROUP', group_ids, attribute_ids, scenario_ids)

        group_attr_dict = get_attr_dict('GROUP', scenario_ids, group_ids,
                                        attribute_ids, groups, resource_attrs,
                                        data)

        returned_matrix = [
            GroupDatasetMatrix(scenario_id, data)
            for scenario_id, data in group_attr_dict.items()
        ]

        return returned_matrix
Exemplo n.º 14
0
class UnitService(HydraService):
    """
    """

    # @rpc(Unicode, _returns=Boolean)
    # def add_dimension(ctx, dimension):
    #     """Add a physical dimensions (such as ``Volume`` or ``Speed``) to the
    #     servers list of dimensions. If the dimension already exists, nothing is
    #     done.
    #     """
    #     result = units.add_dimension(dimension, **ctx.in_header.__dict__)
    #     return result
    #
    # @rpc(Unicode, _returns=Boolean)
    # def delete_dimension(ctx, dimension):
    #     """Delete a physical dimension from the list of dimensions. Please note
    #     that deleting works only for dimensions listed in the custom file.
    #     """
    #     result = units.delete_dimension(dimension, **ctx.in_header.__dict__)
    #     return result
    #
    # @rpc(Unit, _returns=Boolean)
    # def add_unit(ctx, unit):
    #     """Add a physical unit to the servers list of units. The Hydra server
    #     provides a complex model ``Unit`` which should be used to add a unit.
    #
    #     A minimal example:
    #
    #     .. code-block:: python
    #
    #         from HydraLib import PluginLib
    #
    #         cli = PluginLib.connect()
    #
    #         new_unit = cli.factory.create('hyd:Unit')
    #         new_unit.name = 'Teaspoons per second'
    #         new_unit.abbr = 'tsp s^-1'
    #         new_unit.cf = 0               # Constant conversion factor
    #         new_unit.lf = 1.47867648e-05  # Linear conversion factor
    #         new_unit.dimension = 'Volumetric flow rate'
    #         new_unit.info = 'A flow of one teaspoon per second.'
    #
    #         cli.service.add_unit(new_unit)
    #     """
    #     # Convert the complex model into a dict
    #     unitdict = get_object_as_dict(unit, Unit)
    #     units.add_unit(unitdict, **ctx.in_header.__dict__)
    #     return True

    # @rpc(Unit, _returns=Boolean)
    # def update_unit(ctx, unit):
    #     """Update an existing unit added to the custom unit collection. Please
    #     not that units built in to the library can not be updated.
    #     """
    #     unitdict = get_object_as_dict(unit, Unit)
    #     result = units.update_unit(unitdict, **ctx.in_header.__dict__)
    #     return result
    #
    # @rpc(Unit, _returns=Boolean)
    # def delete_unit(ctx, unit):
    #     """Delete a unit from the custom unit collection.
    #     """
    #     unitdict = get_object_as_dict(unit, Unit)
    #     result = units.delete_unit(unitdict, **ctx.in_header.__dict__)
    #     return result

    @rpc(Decimal(min_occurs=1, max_occurs="unbounded"),
         Unicode,
         Unicode,
         _returns=Decimal(min_occurs="1", max_occurs="unbounded"))
    def convert_units(ctx, values, unit1, unit2):
        """Convert a value from one unit to another one.

        Example::

            >>> cli = PluginLib.connect()
            >>> cli.service.convert_units(20.0, 'm', 'km')
            0.02
        """
        return units.convert_units(values, unit1, unit2,
                                   **ctx.in_header.__dict__)

    @rpc(Integer, Unicode, _returns=Integer)
    def convert_dataset(ctx, dataset_id, to_unit):
        """Convert a whole dataset (specified by 'dataset_id' to new unit
        ('to_unit').
        """
        return units.convert_dataset(dataset_id, to_unit,
                                     **ctx.in_header.__dict__)

    @rpc(Unicode, _returns=Unicode)
    def get_unit_dimension(ctx, unit1):
        """Get the corresponding physical dimension for a given unit.

        Example::

            >>> cli = PluginLib.connect()
            >>> cli.service.get_dimension('m')
            Length
        """
        dim = units.get_unit_dimension(unit1, **ctx.in_header.__dict__)

        return dim

    @rpc(_returns=SpyneArray(Unicode))
    def get_dimensions(ctx):
        """Get a list of all physical dimensions available on the server.
        """
        dim_list = units.get_dimensions(**ctx.in_header.__dict__)
        return dim_list

    @rpc(Unicode(
        pattern="[YN]",
        default='N',
    ),
         _returns=SpyneArray(Dimension))
    def get_all_dimensions(ctx, full):
        """Get a list of all physical dimensions available on the server.
        """

        include_full = full == 'Y'
        dimdict = units.get_all_dimensions(full=include_full,
                                           **ctx.in_header.__dict__)
        dimens = []
        for dim_name, unit_list in dimdict.items():
            if include_full:
                dimens.append(DimensionComplete(dim_name, unit_list))
            else:
                dimens.append(Dimension(dim_name, unit_list))
        return dimens

    @rpc(Unicode, _returns=SpyneArray(Unit))
    def get_units(ctx, dimension):
        """Get a list of all units corresponding to a physical dimension.
        """
        unit_list = units.get_units(dimension, **ctx.in_header.__dict__)
        return unit_list

    @rpc(Unicode, Unicode, _returns=Boolean)
    def check_consistency(ctx, unit, dimension):
        """Check if a given units corresponds to a physical dimension.
        """
        return units.check_consistency(unit, dimension,
                                       **ctx.in_header.__dict__)
Exemplo n.º 15
0
class NoteService(HydraService):
    """
        The data SOAP service
    """
    @rpc(Integer, _returns=SpyneArray(Note))
    def get_scenario_notes(ctx, scenario_id):
        """
        Get all the notes for a scenario

        Args:
            scenario_id (int): The scenario whose notes you want

        Returns:
            List(hydra_complexmodels.Note): All the scenario's notes

        """
        return _get_resource_notes('SCENARIO', scenario_id)

    @rpc(Integer, _returns=SpyneArray(Note))
    def get_network_notes(ctx, network_id):
        """
        Get all the notes for a network (NOTE: This does not return all the
        notes of resources within the network, just of the network object itself)

        Args:
            network_id (int): The network whose notes you want

        Returns:
            List(hydra_complexmodels.Note): All the network's notes
        """
        return _get_resource_notes('NETWORK', network_id)

    @rpc(Integer, _returns=SpyneArray(Note))
    def get_node_notes(ctx, node_id):
        """
        Get all the notes for a node

        Args:
            node_id (int): The node whose notes you want

        Returns:
            List(hydra_complexmodels.Note): All the node's notes

        """
        return _get_resource_notes('NODE', node_id)

    @rpc(Integer, _returns=SpyneArray(Note))
    def get_link_notes(ctx, link_id):
        """
            Get all the notes for a link 
        """
        return _get_resource_notes('LINK', link_id)

    @rpc(Integer, _returns=SpyneArray(Note))
    def get_resourcegroup_notes(ctx, group_id):
        """
        Get all the notes for a resource_group

        Args:
            link_id (int): The link whose notes you want

        Returns:
            List(hydra_complexmodels.Note): All the link's notes

        """
        return _get_resource_notes('GROUP', group_id)

    @rpc(Integer, _returns=SpyneArray(Note))
    def get_project_notes(ctx, project_id):
        """
        Get all the notes for a project

        Args:
            project_id (int): The project whose notes you want

        Returns:
            List(hydra_complexmodels.Note): All the project's notes

        """
        return _get_resource_notes('PROJECT', project_id)

    @rpc(Integer, _returns=Note)
    def get_note(ctx, note_id):
        """
        Get an individual note by its ID.

        Args:
            note_id (int): The ID of the note you want

        Returns:
            hydra_complexmodels.Note: The requested nonte

        Raises:
            ResourceNotFoundError: IF the note does not exist

        """
        note_i = notes.get_note(note_id, **ctx.in_header.__dict__)
        return Note(note_i)

    @rpc(Integer, Note, _returns=Note)
    def add_scenario_note(ctx, scenario_id, note):
        """
        Add a note to a given scenario

        Args:
            scenario_id (int)    : The ID of the scenario to receive the note
            note (hydra_complexmodels.Note): The note to attach.

        Returns:
            hydra_complexmodels.Note: The new note, complete with a new ID

        """
        return _add_note('SCENARIO', scenario_id, note,
                         **ctx.in_header.__dict__)

    @rpc(Integer, Note, _returns=Note)
    def add_network_note(ctx, network_id, note):
        """
        Add a note to a given network

        Args:
            network_id (int)    : The ID of the network to receive the note
            note (hydra_complexmodels.Note): The note to attach.

        Returns:
            hydra_complexmodels.Note: The new note, complete with a new ID

        """
        return _add_note('NETWORK', network_id, note, **ctx.in_header.__dict__)

    @rpc(Integer, Note, _returns=Note)
    def add_project_note(ctx, project_id, note):
        """
        Add a note to a given project

        Args:
            project_id (int)    : The ID of the project to receive the note
            note (hydra_complexmodels.Note): The note to attach.

        Returns:
            hydra_complexmodels.Note: The new note, complete with a new ID

        """
        return _add_note('PROJECT', project_id, note, **ctx.in_header.__dict__)

    @rpc(Integer, Note, _returns=Note)
    def add_node_note(ctx, node_id, note):
        """
        Add a note to a given node

        Args:
            node_id (int)    : The ID of the node to receive the note
            note (hydra_complexmodels.Note): The note to attach.

        Returns:
            hydra_complexmodels.Note: The new note, complete with a new ID

        """
        return _add_note('NODE', node_id, note, **ctx.in_header.__dict__)

    @rpc(Integer, Note, _returns=Note)
    def add_link_note(ctx, link_id, note):
        """
        Add a note to a given link

        Args:
            link_id (int)    : The ID of the link to receive the note
            note (hydra_complexmodels.Note): The note to attach.

        Returns:
            hydra_complexmodels.Note: The new note, complete with a new ID

        """
        return _add_note('LINK', link_id, note, **ctx.in_header.__dict__)

    @rpc(Integer, Note, _returns=Note)
    def add_resourcegroup_note(ctx, group_id, note):
        """
        Add a note to a given resourcegroup

        Args:
            group_id (int)    : The ID of the resource group to receive the note
            note (hydra_complexmodels.Note): The note to attach.

        Returns:
            hydra_complexmodels.Note: The new note, complete with a new ID

        """
        return _add_note('GROUP', group_id, note, **ctx.in_header.__dict__)

    @rpc(Note, _returns=Note)
    def update_note(ctx, note):
        """
        Update a note.

        Args:
            note (hydra_complexmodels.Note): The note to update.

        Returns:
            hydra_complexmodels.Note: The updated note

        Raises:
            ResourceNotFoundError: IF the note does not exist.

        """
        note_i = notes.update_note(note, **ctx.in_header.__dict__)
        return Note(note_i)

    @rpc(Integer, _returns=Unicode)
    def purge_note(ctx, note_id):
        """
        Remove a note permanently

        Args:
            note_id (int): The ID of the note to remove.

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: IF the note does not exist.

        """
        notes.purge_note(note_id, **ctx.in_header.__dict__)
        return 'OK'
Exemplo n.º 16
0
class DataService(HydraService):
    """
        The data SOAP service
    """
    @rpc(Dataset, _returns=Dataset)
    def add_dataset(ctx, dataset):
        """
           Add a single dataset. Return the new dataset with a dataset ID.
                .. code-block:: python

                    (Dataset){
                        value     = 123,
                        unit      = 'm^3', 
                        dimension = 'Volume', 
                        name      = 'Storage Capacity',
                        type      = 'scalar', #(others are 'descriptor', 'array' and 'timeseries')
                        metadata  = "{'measured_by':'John Doe'}", #Json encoded python dictionary
                    }

           Args:
               dataset (Dataset): The dataset complex model (see above)

           Returns:
               Dataset: The new dataset object, complete with ID

        """
        value = dataset.parse_value()
        metadata = dataset.get_metadata_as_dict(user_id=ctx.in_header.user_id)
        dataset_i = data.add_dataset(dataset.type,
                                     value,
                                     dataset.unit,
                                     dataset.dimension,
                                     metadata,
                                     dataset.name,
                                     ctx.in_header.user_id,
                                     flush=True)

        return Dataset(dataset_i)

    @rpc(SpyneArray(Integer32), _returns=SpyneArray(Dataset))
    def get_datasets(ctx, dataset_ids):
        """
        Get a list of datasets, by ID
        
        Args:
            dataset_ids (List(int)): A list of dataset IDs

        Returns:
            List(Dataset): The corresponding list of datasets. A subset will be returned if not all datasets are available.

        Raises:
            ResourceNotFoundError: If none of the requested datasets were found.
        """
        datasets = data.get_datasets(dataset_ids, **ctx.in_header.__dict__)
        ret_datasets = [Dataset(d) for d in datasets]
        return ret_datasets

    @rpc(Integer, _returns=Dataset)
    def get_dataset(ctx, dataset_id):
        """
        Get a single dataset, by ID

        Args:
            dataset_id (int): THe ID of the requested dataset

        Returns:
            Dataset: The dataset complex model

        Raises:
            ResourceNotFoundError: If the dataset does not exist.
        """

        dataset_i = data.get_dataset(dataset_id, **ctx.in_header.__dict__)

        return Dataset(dataset_i)

    @rpc(Integer, _returns=Dataset)
    def clone_dataset(ctx, dataset_id):
        """
        Clone a single dataset, by ID
    
        Args:
            dataset_id (int): THe ID of the dataset to be cloned

        Returns:
            Dataset: The newly cloned dataset complex model

        Raises:
            ResourceNotFoundError: If the dataset does not exist.

        """

        dataset_i = data.clone_dataset(dataset_id, **ctx.in_header.__dict__)

        return Dataset(dataset_i)

    @rpc(
        Integer,
        Unicode,
        Unicode,
        Unicode,
        Unicode,
        Unicode,
        Integer,
        Unicode,
        Unicode,
        Integer,
        Integer,
        Unicode,
        Unicode(pattern='[YN]', default='N'),  #include metadata flag
        Unicode(pattern='[YN]', default='N'),  # include value flag
        Integer(default=0),
        Integer(default=2000),  #start, size page flags
        _returns=SpyneArray(Dataset))
    def search_datasets(ctx, dataset_id, name, collection_name, data_type,
                        dimension, unit, scenario_id, metadata_name,
                        metadata_val, attr_id, type_id, unconnected,
                        inc_metadata, inc_val, page_start, page_size):
        """
        Search for datadets that satisfy the criteria specified.
        By default, returns a max of 2000 datasets. To return datasets from 2001 onwards,
        set page_start to 2001. 
    
        Args:
            dataset_id      (int)    : The ID of the dataset
            name            (string) : The name of the dataset
            collection_name (string) : Search for datsets in a collection with this name
            data_type       (string) : 'scalar', 'descriptor', 'array', 'timeseries'
            dimension       (string) : Datasets with this dimension
            unit            (string) : Datasets with this unit.
            scenario_id     (int)    : Datasets in this scenraio
            metadata_name   (string) : Datasets that have this metadata
            metadata_val    (string) : Datasets that have this metadata value
            attr_id         (int)    : Datasts that are associated with this attribute via resource scenario & resource attribute
            type_id         (int)    : Datasets that are associated with this type via resource scenario -> resource attribute -> attribute -> type
            unconnected     (char)   : Datasets that are not in any scenarios
            inc_metadata    (char) (default 'N')   : Return metadata with retrieved datasets. 'Y' gives a performance hit.
            inc_val         (char) (default 'N')  : Include the value with the dataset. 'Y' gives a performance hit
            page_start      (int)    : Return datasets from this point (ex: from index 2001 of 10,000)
            page_size       (int)    : Return this number of datasets in one go. default is 2000.

        Returns:
            List(Dataset): The datasets matching all the specified criteria.

        """
        datasets = data.search_datasets(
            dataset_id, name, collection_name, data_type, dimension, unit,
            scenario_id, metadata_name, metadata_val, attr_id, type_id,
            unconnected, inc_metadata, inc_val, page_start, page_size,
            **ctx.in_header.__dict__)

        cm_datasets = []
        for d in datasets:
            cm_datasets.append(Dataset(d))

        return cm_datasets

    @rpc(Integer(max_occurs="unbounded"), _returns=Unicode)
    def get_metadata(ctx, dataset_ids):
        """
        Get the metadata for a dataset or list of datasets

        Args:
            dataset_ids (List(int)): The list of dataset IDS that you want metadata for

        Returns:
            (string): A dictionary keyed on metadata name, dumped as a json string.
        """

        if type(dataset_ids) == int:
            dataset_ids = [dataset_ids]

        metadata = data.get_metadata(dataset_ids)
        metadata_dict = {}
        for m in metadata:
            metadata_dict[m.metadata_name] = m.metadata_val

        return json.dumps(metadata_dict)

    @rpc(SpyneArray(Dataset), _returns=SpyneArray(Integer))
    def bulk_insert_data(ctx, bulk_data):
        """
            Insert sereral pieces of data at once.

            Args:
                bulk_data (List(Dataset)): A list of Dataset complex models

            Returns:
                List(int): A list of new dataset IDS
        """
        datasets = data.bulk_insert_data(bulk_data, **ctx.in_header.__dict__)

        return [d.dataset_id for d in datasets]

    @rpc(_returns=SpyneArray(DatasetCollection))
    def get_all_dataset_collections(ctx):
        """
        Get all the dataset collections available.

        Args:
            None

        Returns:
            List(DatasetCollection): A list of dataset collection objects, each containing references to all the datasets inside them.

        """
        dataset_colns = data.get_all_dataset_collections(
            **ctx.in_header.__dict__)
        all_colns = []
        for d_g in dataset_colns:
            all_colns.append(DatasetCollection(d_g))
        return all_colns

    @rpc(Integer, Integer, _returns=Unicode)
    def add_dataset_to_collection(ctx, dataset_id, collection_id):
        """
        Add a single dataset to a dataset collection.

        Args:
            dataset_id (int): The dataset to add to the collection
            collection_id (int): The collection to receive the new dataset

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the dataset or collection do not exist
        """

        data.add_dataset_to_collection(dataset_id, collection_id,
                                       **ctx.in_header.__dict__)
        return 'OK'

    @rpc(SpyneArray(Integer32), Integer, _returns=Unicode)
    def add_datasets_to_collection(ctx, dataset_ids, collection_id):
        """
        Add multiple datasets to a dataset collection.

        Args:
            dataset_ids (Lsit(int)): The IDs of the datasets to add to the collection
            collection_id (int): The collection to receive the new dataset

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the collection does not exist
        """
        data.add_datasets_to_collection(dataset_ids, collection_id,
                                        **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, Integer, _returns=Unicode)
    def remove_dataset_from_collection(ctx, dataset_id, collection_id):
        """
        Remove a single dataset to a dataset collection.

        Args:
            dataset_id (int): The dataset to remove from the collection
            collection_id (int): The collection to lose the dataset

        Returns:
            string: 'OK'

        Raises:
            ResourceNotFoundError: If the dataset or collection do not exist

        """
        data.remove_dataset_from_collection(dataset_id, collection_id,
                                            **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer, Integer, _returns=Unicode(pattern='[YN]'))
    def check_dataset_in_collection(ctx, dataset_id, collection_id):
        """
        Check whether a dataset is contained inside a collection
   
        Args:
            dataset_id (int): The dataset being checked
            collection_id (int): The collection to check in

        Returns:
            char: 'Y' or 'N'

        Raises:
            ResourceNotFoundError: If the collection does not exist
        """

        result = data.check_dataset_in_collection(dataset_id, collection_id,
                                                  **ctx.in_header.__dict__)
        return result

    @rpc(Integer, _returns=DatasetCollection)
    def get_dataset_collection(ctx, collection_id):
        """
        Get a single dataset collection, by ID.
        
        Args:
            collection_id (int): The collection to retrieve

        Returns:
            DatasetCollection: A dataset collection complex model

        Raises:
            ResourceNotFoundError: If the collection does not exist

        """

        dataset_coln_i = data.get_dataset_collection(collection_id,
                                                     **ctx.in_header.__dict__)
        return DatasetCollection(dataset_coln_i)

    @rpc(Integer, _returns=Unicode)
    def delete_dataset_collection(ctx, collection_id):
        """
        Delete a single dataset collection, by ID.
   
        Args:
            collection_id (int): The collection to delete

        Returns:
            string: 'OK' 

        Raises:
            ResourceNotFoundError: If the collection does not exist


        """

        data.delete_dataset_collection(collection_id, **ctx.in_header.__dict__)
        return "OK"

    @rpc(Unicode, _returns=DatasetCollection)
    def get_dataset_collection_by_name(ctx, collection_name):
        """
        Get all the dataset collections with the provided name.

        Args:
            collection_name (string): The name of the collection to retrieve

        Returns:
            DatasetCollection: A dataset collection complex model, containing a list of DatasetCollectionItem complex models.

        Raises:
            ResourceNotFoundError: If the collection does not exist

        """
        dataset_coln_i = data.get_dataset_collection_by_name(
            collection_name, **ctx.in_header.__dict__)
        return DatasetCollection(dataset_coln_i)

    @rpc(DatasetCollection, _returns=DatasetCollection)
    def add_dataset_collection(ctx, collection):
        """
        Add a dataset collection:
        The name of the collection does NOT need to be unique, so be careful
        with the naming to ensure the collection is searchable later.

        Args:
            collection (DatasetCollection): A DatasetCollection complex model containing a list of DatasetCollectionItem objects

        Returns:
            DatasetCollection: The same collection as was sent in, but with an ID

        """

        dataset_coln_i = data.add_dataset_collection(collection,
                                                     **ctx.in_header.__dict__)

        new_coln = DatasetCollection(dataset_coln_i)
        return new_coln

    @rpc(Unicode, _returns=SpyneArray(DatasetCollection))
    def get_collections_like_name(ctx, collection_name):
        """
        Get all the dataset collections with a name like the specified name

        Args:
            collection_name (string): The collection name to search.

        Returns:
            List(DatasetCollection): All the collections with names similar to the specified name
        """
        collections = data.get_collections_like_name(collection_name,
                                                     **ctx.in_header.__dict__)
        ret_collections = [DatasetCollection(g) for g in collections]
        return ret_collections

    @rpc(Integer, _returns=SpyneArray(Dataset))
    def get_collection_datasets(ctx, collection_id):
        """
            Get all the datasets from the collection with the specified name

            Args:
                collection_id (int): The collection whose dastasets we want to retrieve

            Returns:
                List(Dataset): A list of dastaset complex models, all of them in the collection specified
        """
        collection_datasets = data.get_collection_datasets(
            collection_id, **ctx.in_header.__dict__)
        ret_data = [Dataset(d) for d in collection_datasets]

        return ret_data

    @rpc(Dataset, _returns=Dataset)
    def update_dataset(ctx, dataset):
        """
            Update a piece of data directly, rather than through a resource
            scenario.

            Args:
                dataset (Dataset): A complex model representing an existing dataset which is to be updsated (must have an id)

            Returns:
                Dataset: The updated dataset
        """
        val = dataset.parse_value()

        metadata = dataset.get_metadata_as_dict()

        updated_dataset = data.update_dataset(dataset.id, dataset.name,
                                              dataset.type, val, dataset.unit,
                                              dataset.dimension, metadata,
                                              **ctx.in_header.__dict__)

        return Dataset(updated_dataset)

    @rpc(Integer, _returns=Unicode)
    def delete_dataset(ctx, dataset_id):
        """
            Removes a piece of data from the DB.
            CAUTION! Use with care, as this cannot be undone easily.

            Args:
                dataset_id (int): The ID of the dataset to be deleted.

            Returns:
                string: 'OK'
        """
        data.delete_dataset(dataset_id, **ctx.in_header.__dict__)
        return 'OK'

    @rpc(Integer,
         Unicode(min_occurs=0, max_occurs='unbounded'),
         _returns=AnyDict)
    def get_val_at_time(ctx, dataset_id, timestamps):
        """
        Get the value of the dataset at a specified time (s).
        
        - If the dataset is not a timeseries, just return the value
        
        - If the dataset is a timeseries, return the value within the timeseries
        that is closest to the requested time(s). 
        
        - If the time specified occurs before the start of the timeseries, return None. 
        
        - If the time specified occurs after the end of the timeseries, return the last value in the timeseries.

        Args:
            dataset_id (int): The ID of the dataset being searched
            timestamps (List(timestamps)): A list of timestamps to get values for.

        Returns:
            dict: A dictionary, keyed on the timestamps requested

        """
        return data.get_val_at_time(dataset_id, timestamps,
                                    **ctx.in_header.__dict__)

    @rpc(Integer32(min_occurs=0, max_occurs='unbounded'),
         Unicode(min_occurs=0, max_occurs='unbounded'),
         _returns=AnyDict)
    def get_multiple_vals_at_time(ctx, dataset_ids, timestamps):
        """
        Similar to get_val_at_time, but perform the action on multiple datasets at once
        
        - If the dataset is not a timeseries, just return the value
        
        - If the dataset is a timeseries, return the value within the timeseries
        that is closest to the requested time(s). 
        
        - If the time specified occurs before the start of the timeseries, return None. 
        
        - If the time specified occurs after the end of the timeseries, return the last value in the timeseries.

        Args:
            dataset_ids (List(int)): The IDs of the datasets being searched
            timestamps (List(timestamps)): A list of timestamps to get values for.

        Returns:
            dict: A dictionary, keyed on the dataset_id, then by the timestamps requested

        """

        result = data.get_multiple_vals_at_time(dataset_ids, timestamps,
                                                **ctx.in_header.__dict__)
        return result

    @rpc(Integer,
         Unicode,
         Unicode,
         Unicode(values=['seconds', 'minutes', 'hours', 'days', 'months']),
         Decimal(default=1),
         _returns=AnyDict)
    def get_vals_between_times(ctx, dataset_id, start_time, end_time, timestep,
                               increment):
        """
        Retrive data between two specified times within a timeseries. The times
        need not be specified in the timeseries. This function will 'fill in the blanks'.

        Two types of data retrieval can be done.

        If the timeseries is timestamp-based, then start_time and end_time
        must be datetimes and timestep must be specified (minutes, seconds etc).
        'increment' reflects the size of the timestep -- timestep = 'minutes' and increment = 2
        means 'every 2 minutes'.

        If the timeseries is float-based (relative), then start_time and end_time
        must be decimal values. timestep is ignored and 'increment' represents the increment
        to be used between the start and end.
        Ex: start_time = 1, end_time = 5, increment = 1 will get times at 1, 2, 3, 4, 5

        Args:
            dataset_id (int): The dataset being queried
            start_time (string): The date or value from which to start the query
            end_time   (string): The date or value that ends the query
            timestep   Enum(string): 'seconds', 'minutes', 'hours', 'days', 'months':
                The increment in time that the result will be in
            increment  (decimal): The increment that the result will be in if the timeseries is not timestamp-based.

        Returns:
            (AnyDict): A dictionary, keyed on the newly created timestamps, which have been
                        created from the start time and timesteps.

        """
        return data.get_vals_between_times(dataset_id, start_time, end_time,
                                           timestep, increment,
                                           **ctx.in_header.__dict__)

    @rpc(Unicode, _returns=Unicode)
    def check_json(ctx, json_string):
        """
        Check that an incoming data string is json serialisable.
        Used for testing.

        Args:
            json_string (string): A json string to be tested for validity

        Returns:
            'OK' or '"Unable to process JSON string. error was:..."
        """
        try:
            data.check_json(json_string)
        except Exception as e:
            return "Unable to process JSON string. error was: %s" % e

        return 'OK'
Exemplo n.º 17
0
class Service(HydraService):
    """
        An example of a server-side plug-in
    """
    
    __service_name__ = "ResourceAttrCollectionService"
    
    
    @rpc(HydraResourceAttrCollection, _returns=HydraResourceAttrCollection)
    def add_resource_attr_collection(ctx, ra_collection):
        """
            Add a new resource attribute collection
        """
        ra_i = ResourceAttrCollection()
        ra_i.collection_name = ra_collection.name
        ra_i.layout          = ra_collection.layout

        for ra_id in ra_collection.resource_attr_ids:
            item_i = ResourceAttrCollectionItem()
            item_i.resource_attr_id = ra_id
            ra_i.items.append(item_i)

        DBSession.add(ra_i)
        DBSession.flush()

        return HydraResourceAttrCollection(ra_i)

    @rpc(SpyneInteger, SpyneArray(SpyneInteger), _returns=HydraResourceAttrCollection)
    def add_items_to_attr_collection(ctx, collection_id, resource_attr_ids):
        """
            Add new items to a resource attribute collection
        """
        collection_i = DBSession.query(ResourceAttrCollection).filter(ResourceAttrCollection.collection_id==collection_id).first()

        if collection_i is None:
            raise HydraError("No collection with ID %s", collection_id)

        for ra_id in resource_attr_ids:
            item_i = ResourceAttrCollectionItem()
            item_i.resource_attr_id = ra_id
            collection_i.items.append(item_i)

        DBSession.add(collection_i)
        DBSession.flush()

        return HydraResourceAttrCollection(collection_i)

    @rpc(SpyneInteger, SpyneArray(SpyneInteger), _returns=Unicode)
    def remove_items_from_attr_collection(ctx, collection_id, resource_attr_ids):
        """
            Add new items to a resource attribute collection
        """
        collection_i = DBSession.query(ResourceAttrCollection).filter(ResourceAttrCollection.collection_id==collection_id).first()

        if collection_i is None:
            raise HydraError("No collection with ID %s", collection_id)

        for item in collection_i.items:
            if item.resource_attr_id in resource_attr_ids:
                DBSession.delete(item)

        DBSession.flush()
        
        return 'OK'


    @rpc(SpyneInteger, _returns=Unicode)
    def delete_resource_attr_collection(ctx, collection_id):
        """
            Delete a resource attribute collection
        """
        collection_i = DBSession.query(ResourceAttrCollection).filter(ResourceAttrCollection.collection_id==collection_id).first()

        if collection_i is None:
            raise HydraError("No collection with ID %s", collection_id)

        DBSession.delete(collection_i)

        return 'OK'

    @rpc(SpyneInteger, _returns=HydraResourceAttrCollection)
    def get_resource_attr_collection(ctx, collection_id):
        """
            Delete a resource attribute collection
        """
        collection_i = DBSession.query(ResourceAttrCollection).filter(ResourceAttrCollection.collection_id==collection_id).first()

        if collection_i is None:
            raise HydraError("No collection with ID %s", collection_id)

        return HydraResourceAttrCollection(collection_i) 

    @rpc(HydraResourceAttrCollection, _returns=HydraResourceAttrCollection)
    def update_resource_attr_collection(ctx, resourceattrcollection):
        """
            Delete a resource attribute collection
        """

        collection_i = DBSession.query(ResourceAttrCollection).filter(ResourceAttrCollection.collection_id==resourceattrcollection.id).first()
        
        if collection_i is None:
            raise HydraError("No collection with ID %s", resourceattrcollection.id)

        collection_i.layout = resourceattrcollection.get_layout()
        collection_i.name   = resourceattrcollection.name

        DBSession.flush()

        return HydraResourceAttrCollection(collection_i) 

    @rpc(_returns=SpyneArray(HydraResourceAttrCollection))
    def get_all_resource_attr_collections(ctx):
        """
            Get all resource attribute collections
        """
        collections_i = DBSession.query(ResourceAttrCollection).all()

        return [HydraResourceAttrCollection(collection_i) for collection_i in collections_i] 

    @rpc(SpyneInteger,_returns=SpyneArray(HydraResourceAttrCollection))
    def get_resource_attr_collections_for_node(ctx, node_id):
        """
            Get all resource attribute collections containing an attribute on the specified node.
        """
        collections_i = DBSession.query(ResourceAttrCollection).filter(
                    ResourceAttrCollection.collection_id == ResourceAttrCollectionItem.collection_id,
                    ResourceAttrCollectionItem.resource_attr_id==ResourceAttr.resource_attr_id,
                    ResourceAttr.node_id == node_id
        
        )

        return [HydraResourceAttrCollection(collection_i) for collection_i in collections_i] 

    @rpc(SpyneInteger,_returns=SpyneArray(HydraResourceAttrCollection))
    def get_resource_attr_collections_for_link(ctx, link_id):
        """
            Get all resource attribute collections containing an attribute on the specified link.
        """
        collections_i = DBSession.query(ResourceAttrCollection).filter(
                    ResourceAttrCollection.collection_id == ResourceAttrCollectionItem.collection_id,
                    ResourceAttrCollectionItem.resource_attr_id==ResourceAttr.resource_attr_id,
                    ResourceAttr.link_id == link_id
        
        )

        return [HydraResourceAttrCollection(collection_i) for collection_i in collections_i] 

    @rpc(SpyneInteger,_returns=SpyneArray(HydraResourceAttrCollection))
    def get_resource_attr_collections_for_attr(ctx, attr_id):
        """
            Get all resource attribute collections containing the specified attribute.
        """
        collections_i = DBSession.query(ResourceAttrCollection).distinct(ResourceAttrCollection.collection_id).filter(
            and_(
                ResourceAttrCollection.collection_id == ResourceAttrCollectionItem.collection_id,
                and_(
                     ResourceAttrCollectionItem.resource_attr_id==ResourceAttr.resource_attr_id,
                    ResourceAttr.attr_id == attr_id
        
        ) )).all()

        
        return [HydraResourceAttrCollection(collection_i) for collection_i in collections_i] 

    @rpc(SpyneInteger,_returns=SpyneArray(HydraResourceAttrCollection))
    def get_resource_attr_collections_in_network(ctx, network_id):
        """
            Get all resource attribute collections containing an resource attribute of a resource in that network.
        """
        node_collection_qry = DBSession.query(ResourceAttrCollection).filter(
                           ResourceAttrCollection.collection_id==ResourceAttrCollectionItem.collection_id,
                            ResourceAttrCollectionItem.resource_attr_id == ResourceAttr.resource_attr_id,
                            ResourceAttr.ref_key == 'NODE',
                            ResourceAttr.node_id == Node.node_id,
                            Node.network_id == network_id
                    ).all()

        link_collection_qry = DBSession.query(ResourceAttrCollection).filter(
                           ResourceAttrCollection.collection_id==ResourceAttrCollectionItem.collection_id,
                            ResourceAttrCollectionItem.resource_attr_id == ResourceAttr.resource_attr_id,
                            ResourceAttr.ref_key == 'LINK',
                            ResourceAttr.link_id == Link.link_id,
                            Link.network_id == network_id
                    ).all()
        grp_collection_qry = DBSession.query(ResourceAttrCollection).filter(
                           ResourceAttrCollection.collection_id==ResourceAttrCollectionItem.collection_id,
                            ResourceAttrCollectionItem.resource_attr_id == ResourceAttr.resource_attr_id,
                            ResourceAttr.ref_key == 'GROUP',
                            ResourceAttr.group_id == ResourceGroup.group_id,
                            ResourceGroup.network_id == network_id
                    ).all()

        net_collection_qry = DBSession.query(ResourceAttrCollection).filter(
                           ResourceAttrCollection.collection_id==ResourceAttrCollectionItem.collection_id,
                            ResourceAttrCollectionItem.resource_attr_id == ResourceAttr.resource_attr_id,
                            ResourceAttr.ref_key == 'NETWORK',
                            ResourceAttr.network_id == network_id

                    ).all()

        collections_i = node_collection_qry + link_collection_qry + grp_collection_qry + net_collection_qry

        return [HydraResourceAttrCollection(collection_i) for collection_i in collections_i]