Esempio n. 1
0
    def __init__(self, username, password, con):
        log.info("Logging into DCC")
        self.comms = con
        self.con = con.wss
        self.username = username
        self.password = password
        self.proto = HelixProtocol(self.con, username, password)
        self.info_file = self._init_info()

        def on_receive_safe(msg):
            try:
                log.debug("Received msg: {0}".format(msg))
                json_msg = json.loads(msg)
                self.proto.on_receive(json.loads(msg))
                log.debug("Processed msg: {0}".format(json_msg["type"]))
                if json_msg["type"] == "connection_verified":
                    log.info("Connection verified")
                    exit()
            except Exception:
                raise
                log.exception(
                    "Error received on connecting to DCC instance. Please verify the credentials and try again.")

        thread = threading.Thread(target=self.con.run)
        self.con.on_receive = on_receive_safe
        thread.daemon = True
        thread.start()
        thread.join()
        log.info("Logged in to DCC successfully")
Esempio n. 2
0
    def __init__(self, username, password, con):
        log.info("Logging into DCC")
        self.comms = con
        self.con = con.wss
        self.username = username
        self.password = password
        self.proto = HelixProtocol(self.con, username, password)
        self._iotcc_json = self._create_iotcc_json()

        self.dev_file_path = self._get_file_storage_path("dev_file_path")
        # Liota internal entity file system path special for iotcc
        self.entity_file_path = self._get_file_storage_path("entity_file_path")
        self.file_ops_lock = Lock()

        def on_receive_safe(msg):
            try:
                log.debug("Received msg: {0}".format(msg))
                json_msg = json.loads(msg)
                self.proto.on_receive(json.loads(msg))
                log.debug("Processed msg: {0}".format(json_msg["type"]))
                if json_msg["type"] == "connection_verified":
                    log.info("Connection verified")
                    exit()
            except Exception:
                raise
                log.exception(
                    "Error received on connecting to DCC instance. Please verify the credentials and try again."
                )

        thread = threading.Thread(target=self.con.run)
        self.con.on_receive = on_receive_safe
        thread.daemon = True
        thread.start()
        thread.join()
        log.info("Logged in to DCC successfully")
Esempio n. 3
0
    def __init__(self, con):
        log.info("Logging into DCC")
        self.comms = con
        if not self.comms.identity.username:
            log.error("Username not found")
            raise ValueError("Username not found")
        elif not self.comms.identity.password:
            log.error("Password not found")
            raise ValueError("Password not found")
        thread = threading.Thread(target=self.comms.receive)
        thread.daemon = True
        # This thread will continuously run in background to receive response or actions from DCC
        thread.start()
        # Wait for Subscription to be complete and then proceed to publish message
        time.sleep(0.5)
        self.proto = HelixProtocol(self.comms, self.comms.identity.username, self.comms.identity.password)
        self._iotcc_json = self._create_iotcc_json()
        self.counter = 0
        self.recv_msg_queue = self.comms.userdata
        self.dev_file_path = self._get_file_storage_path("dev_file_path")
        # Liota internal entity file system path special for iotcc
        self.entity_file_path = self._get_file_storage_path("entity_file_path")
        self.file_ops_lock = Lock()
        try:
            def on_response(msg):
                log.debug("Received msg: {0}".format(msg))
                json_msg = json.loads(msg)
                self.proto.on_receive(json_msg)
                if json_msg["type"] == "connection_response":
                    if json_msg["body"]["result"] == "succeeded":
                        log.info("Connection verified")
                    else:
                        raise Exception("Helix Protocol Version mismatch")
                else:
                    log.debug("Processed msg: {0}".format(json_msg["type"]))
                    on_response(self.recv_msg_queue.get(True, 300))

            # Block on Queue for not more then 300 seconds else it will raise an exception
            on_response(self.recv_msg_queue.get(True, 300))
        except Exception as error:
            self.comms.client.disconnect()
            log.error("HelixProtocolException: " + repr(error))
            raise Exception("HelixProtocolException")
Esempio n. 4
0
    def __init__(self, username, password, con):
        log.info("Logging into DCC")
        self.comms = con
        self.username = username
        self.password = password
        self.proto = HelixProtocol(self.comms, username, password)
        self._iotcc_json = self._create_iotcc_json()
        self.counter = 0
        self.recv_msg_queue = self.comms.userdata

        self.dev_file_path = self._get_file_storage_path("dev_file_path")
        # Liota internal entity file system path special for iotcc
        self.entity_file_path = self._get_file_storage_path("entity_file_path")
        self.file_ops_lock = Lock()

        def on_response(msg):
            try:
                log.debug("Received msg: {0}".format(msg))
                json_msg = json.loads(msg)
                self.proto.on_receive(json_msg)
                if json_msg["type"] == "connection_response" and json_msg[
                        "body"]["result"] == "succeeded":
                    log.info("Connection verified")
                    return True
                else:
                    log.debug("Processed msg: {0}".format(json_msg["type"]))
                    on_response(self.recv_msg_queue.get(True, 10))
            except Exception as error:
                log.error("HelixProtocolException: " + repr(error))

        thread = threading.Thread(target=self.comms.receive)
        thread.daemon = True
        # This thread will continuously run in background to receive response or actions from DCC
        thread.start()
        # Block on Queue for not more then 10 seconds else it will raise an exception
        on_response(self.recv_msg_queue.get(True, 10))
        log.info("Logged in to DCC successfully")
Esempio n. 5
0
    def __init__(self, con):
        log.info("Logging into DCC")
        self.comms = con
        if not self.comms.identity.username:
            log.error("Username not found")
            raise ValueError("Username not found")
        elif not self.comms.identity.password:
            log.error("Password not found")
            raise ValueError("Password not found")
        thread = threading.Thread(target=self.comms.receive)
        thread.daemon = True
        # This thread will continuously run in background to receive response or actions from DCC
        thread.start()
        # Wait for Subscription to be complete and then proceed to publish message
        time.sleep(0.5)
        self.proto = HelixProtocol(self.comms, self.comms.identity.username, self.comms.identity.password)
        self._iotcc_json = self._create_iotcc_json()
        self._iotcc_json_load_retry = int(read_liota_config('IOTCC', 'iotcc_load_retry'))
        self.counter = 0
        self.recv_msg_queue = self.comms.userdata
        self.dev_file_path = self._get_file_storage_path("dev_file_path")
        # Liota internal entity file system path special for iotcc
        self.entity_file_path = self._get_file_storage_path("entity_file_path")
        self.file_ops_lock = Lock()
        try:
            def on_response(msg):
                log.debug("Received msg: {0}".format(msg))
                json_msg = json.loads(msg)
                self.proto.on_receive(json_msg)
                if json_msg["type"] == "connection_response":
                    if json_msg["body"]["result"] == "succeeded":
                        log.info("Connection verified")
                    else:
                        raise Exception("Helix Protocol Version mismatch")
                else:
                    log.debug("Processed msg: {0}".format(json_msg["type"]))
                    on_response(self.recv_msg_queue.get(True, 300))

            # Block on Queue for not more then 300 seconds else it will raise an exception
            on_response(self.recv_msg_queue.get(True, 300))
        except Exception as error:
            self.comms.client.disconnect()
            log.error("HelixProtocolException: " + repr(error))
            raise Exception("HelixProtocolException")
Esempio n. 6
0
class IotControlCenter(DataCenterComponent):
    """ The implementation of IoTCC cloud provider solution

    """
    def __init__(self, username, password, con):
        log.info("Logging into DCC")
        self.comms = con
        self.username = username
        self.password = password
        thread = threading.Thread(target=self.comms.receive)
        thread.daemon = True
        # This thread will continuously run in background to receive response or actions from DCC
        thread.start()
        self.proto = HelixProtocol(self.comms, username, password)
        self._iotcc_json = self._create_iotcc_json()
        self.counter = 0
        self.recv_msg_queue = self.comms.userdata
        self.dev_file_path = self._get_file_storage_path("dev_file_path")
        # Liota internal entity file system path special for iotcc
        self.entity_file_path = self._get_file_storage_path("entity_file_path")
        self.file_ops_lock = Lock()

        def on_response(msg):
            try:
                log.debug("Received msg: {0}".format(msg))
                json_msg = json.loads(msg)
                self.proto.on_receive(json_msg)
                if json_msg["type"] == "connection_response" and json_msg[
                        "body"]["result"] == "succeeded":
                    log.info("Connection verified")
                    return True
                else:
                    log.debug("Processed msg: {0}".format(json_msg["type"]))
                    on_response(self.recv_msg_queue.get(True, 300))
            except Exception as error:
                log.error("HelixProtocolException: " + repr(error))

        # Block on Queue for not more then 300 seconds else it will raise an exception
        on_response(self.recv_msg_queue.get(True, 300))
        log.info("Logged in to DCC successfully")

    def register(self, entity_obj):
        """ Register the objects

        """
        if isinstance(entity_obj, Metric):
            # reg_entity_id should be parent's one: not known here yet
            # will add in creat_relationship(); publish_unit should be done inside
            return RegisteredMetric(entity_obj, self, None)
        else:
            # finally will create a RegisteredEntity
            log.info("Registering resource with IoTCC {0}".format(
                entity_obj.name))

            def on_response(msg):
                try:
                    log.debug("Received msg: {0}".format(msg))
                    json_msg = json.loads(msg)
                    log.debug("Processed msg: {0}".format(json_msg["type"]))
                    if json_msg["type"] == "create_or_find_resource_response" and json_msg["body"]["uuid"] != "null" and \
                                    json_msg["body"]["id"] == entity_obj.entity_id:
                        log.info("FOUND RESOURCE: {0}".format(
                            json_msg["body"]["uuid"]))
                        self.reg_entity_id = json_msg["body"]["uuid"]
                    else:
                        log.info("Waiting for resource creation")
                        on_response(self.recv_msg_queue.get(True, 300))
                except:
                    raise Exception("Exception while registering resource")

            if entity_obj.entity_type == "EdgeSystem":
                entity_obj.entity_type = "HelixGateway"
            self.comms.send(
                json.dumps(
                    self._registration(self.next_id(), entity_obj.entity_id,
                                       entity_obj.name,
                                       entity_obj.entity_type)))
            on_response(self.recv_msg_queue.get(True, 300))
            if not self.reg_entity_id:
                raise RegistrationFailure()
            log.info("Resource Registered {0}".format(entity_obj.name))
            if entity_obj.entity_type == "HelixGateway":
                self.store_reg_entity_details(entity_obj.entity_type,
                                              entity_obj.name,
                                              self.reg_entity_id)
                store_edge_system_uuid(entity_name=entity_obj.name,
                                       entity_id=entity_obj.entity_id,
                                       reg_entity_id=self.reg_entity_id)
                with self.file_ops_lock:
                    self.store_reg_entity_attributes("EdgeSystem",
                                                     entity_obj.name,
                                                     self.reg_entity_id, None,
                                                     None)
            else:
                self.store_reg_entity_details(entity_obj.entity_type,
                                              entity_obj.name,
                                              self.reg_entity_id)
                # get dev_type, and prop_dict if possible
                with self.file_ops_lock:
                    self.store_reg_entity_attributes("Devices",
                                                     entity_obj.name,
                                                     self.reg_entity_id,
                                                     entity_obj.entity_type,
                                                     None)

            return RegisteredEntity(entity_obj, self, self.reg_entity_id)

    def unregister(self, entity_obj):
        """ Unregister the objects
        """
        log.info("Unregistering resource with IoTCC {0}".format(
            entity_obj.ref_entity.name))

        def on_response(msg):
            try:
                log.debug("Received msg: {0}".format(msg))
                json_msg = json.loads(msg)
                log.debug("Processed msg: {0}".format(json_msg["type"]))
                if json_msg["type"] == "remove_resource_response" and json_msg[
                        "body"]["result"] == "succeeded":
                    log.info(
                        "Unregistration of resource {0} with IoTCC succeeded".
                        format(entity_obj.ref_entity.name))
                else:
                    log.info(
                        "Unregistration of resource {0} with IoTCC failed".
                        format(entity_obj.ref_entity.name))
            except:
                raise Exception("Exception while unregistering resource")

        self.comms.send(
            json.dumps(
                self._unregistration(self.next_id(),
                                     entity_obj.reg_entity_id)))
        on_response(self.recv_msg_queue.get(True, 20))
        self.remove_reg_entity_details(entity_obj.ref_entity.name,
                                       entity_obj.reg_entity_id)
        if entity_obj.ref_entity.entity_type != "HelixGateway":
            self.store_device_info(entity_obj.reg_entity_id,
                                   entity_obj.ref_entity.name,
                                   entity_obj.ref_entity.entity_type, None,
                                   True)
        log.info("Unregistration of resource {0} with IoTCC complete".format(
            entity_obj.ref_entity.name))

    def create_relationship(self, reg_entity_parent, reg_entity_child):
        """ This function initializes all relations between Registered Entities.

            Parameters:
            - obj: The object that has just obtained an UUID
        """
        # sanity check: must be RegisteredEntity or RegisteredMetricRegisteredMetric
        if (not isinstance(reg_entity_parent, RegisteredEntity) \
                    and not isinstance(reg_entity_parent, RegisteredMetric)) \
                or (not isinstance(reg_entity_child, RegisteredEntity) \
                            and not isinstance(reg_entity_child, RegisteredMetric)):
            raise TypeError()

        reg_entity_child.parent = reg_entity_parent
        if isinstance(reg_entity_child, RegisteredMetric):
            # should save parent's reg_entity_id
            reg_entity_child.reg_entity_id = reg_entity_parent.reg_entity_id
            entity_obj = reg_entity_child.ref_entity
            self.publish_unit(reg_entity_child, entity_obj.name,
                              entity_obj.unit)
        else:
            self.comms.send(
                json.dumps(
                    self._relationship(self.next_id(),
                                       reg_entity_parent.reg_entity_id,
                                       reg_entity_child.reg_entity_id)))

    def _registration(self, msg_id, res_id, res_name, res_kind):
        return {
            "transactionID": msg_id,
            "type": "create_or_find_resource_request",
            "body": {
                "kind": res_kind,
                "id": res_id,
                "name": res_name
            }
        }

    def _relationship(self, msg_id, parent_res_uuid, child_res_uuid):
        return {
            "transactionID": msg_id,
            "type": "create_relationship_request",
            "body": {
                "parent": parent_res_uuid,
                "child": child_res_uuid
            }
        }

    def _properties(self, msg_id, res_uuid, res_kind, timestamp, properties):
        msg = {
            "transationID": msg_id,
            "type": "add_properties",
            "uuid": res_uuid,
            "body": {
                "kind": res_kind,
                "timestamp": timestamp,
                "property_data": []
            }
        }
        for key, value in properties.items():
            msg["body"]["property_data"].append({
                "propertyKey": key,
                "propertyValue": value
            })
        return msg

    def _format_data(self, reg_metric):
        met_cnt = reg_metric.values.qsize()
        if met_cnt == 0:
            return
        _timestamps = []
        _values = []
        for _ in range(met_cnt):
            m = reg_metric.values.get(block=True)
            if m is not None:
                _timestamps.append(m[0])
                _values.append(m[1])
        if _timestamps == []:
            return
        return json.dumps({
            "type":
            "add_stats",
            "uuid":
            reg_metric.reg_entity_id,
            "metric_data": [{
                "statKey": reg_metric.ref_entity.name,
                "timestamps": _timestamps,
                "data": _values
            }]
        })

    def set_organization_group_properties(self, reg_entity_name, reg_entity_id,
                                          reg_entity_type, properties):
        log.info(
            "Organization Group Properties defined for resource {0}".format(
                reg_entity_name))
        self.comms.send(
            json.dumps(
                self._properties(self.next_id(), reg_entity_id,
                                 reg_entity_type, getUTCmillis(), properties)))

    def set_properties(self, reg_entity_obj, properties):
        # RegisteredMetric get parent's resid; RegisteredEntity gets own resid
        reg_entity_id = reg_entity_obj.reg_entity_id

        if isinstance(reg_entity_obj, RegisteredMetric):
            entity = reg_entity_obj.parent.ref_entity
        else:
            entity = reg_entity_obj.ref_entity

        log.info("Properties defined for resource {0}".format(entity.name))
        self.comms.send(
            json.dumps(
                self._properties(self.next_id(),
                                 reg_entity_id, entity.entity_type,
                                 getUTCmillis(), properties)))
        if entity.entity_type == "HelixGateway":
            with self.file_ops_lock:
                self.store_reg_entity_attributes("EdgeSystem", entity.name,
                                                 reg_entity_obj.reg_entity_id,
                                                 None, properties)
        else:
            # get dev_type, and prop_dict if possible
            with self.file_ops_lock:
                self.store_reg_entity_attributes("Devices", entity.name,
                                                 reg_entity_obj.reg_entity_id,
                                                 entity.entity_type,
                                                 properties)

    def publish_unit(self, reg_entity_obj, metric_name, unit):
        str_prefix, str_unit_name = parse_unit(unit)
        if not isinstance(str_prefix, basestring):
            str_prefix = ""
        if not isinstance(str_unit_name, basestring):
            str_unit_name = ""
        properties_added = {
            metric_name + "_unit": str_unit_name,
            metric_name + "_prefix": str_prefix
        }
        self.set_properties(reg_entity_obj, properties_added)
        log.info("Published metric unit with prefix to IoTCC")

    def prettify(self, elem):
        """Return a pretty-printed XML string for the Element.
        """
        rough_string = ET.tostring(elem)
        reparsed = minidom.parseString(rough_string)
        return reparsed.toprettyxml(indent="    ")

    def _create_iotcc_json(self):
        msg = {
            "iotcc": {
                "EdgeSystem": {
                    "SystemName": "",
                    "EntityType": "",
                    "uuid": ""
                },
                "OGProperties": {
                    "OrganizationGroup": ""
                },
                "Devices": []
            }
        }

        iotcc_path = read_liota_config('IOTCC_PATH', 'iotcc_path')
        path = os.path.dirname(iotcc_path)
        mkdir(path)
        try:
            with open(iotcc_path, 'w') as f:
                json.dump(msg, f, sort_keys=True, indent=4, ensure_ascii=False)
                log.debug('Initialized ' + iotcc_path)
            f.close()
        except IOError, err:
            log.error('Could not open {0} file '.format(iotcc_path) + err)
        return iotcc_path
Esempio n. 7
0
class IotControlCenter(DataCenterComponent):
    """ The implementation of IoTCC cloud provider solution

    """

    def __init__(self, username, password, con):
        log.info("Logging into DCC")
        self.comms = con
        self.con = con.wss
        self.username = username
        self.password = password
        self.proto = HelixProtocol(self.con, username, password)
        self.info_file = self._init_info()

        def on_receive_safe(msg):
            try:
                log.debug("Received msg: {0}".format(msg))
                json_msg = json.loads(msg)
                self.proto.on_receive(json.loads(msg))
                log.debug("Processed msg: {0}".format(json_msg["type"]))
                if json_msg["type"] == "connection_verified":
                    log.info("Connection verified")
                    exit()
            except Exception:
                raise
                log.exception(
                    "Error received on connecting to DCC instance. Please verify the credentials and try again.")

        thread = threading.Thread(target=self.con.run)
        self.con.on_receive = on_receive_safe
        thread.daemon = True
        thread.start()
        thread.join()
        log.info("Logged in to DCC successfully")

    def register(self, entity_obj):
        """ Register the objects

        """
        if isinstance(entity_obj, Metric):
            # reg_entity_id should be parent's one: not known here yet
            # will add in creat_relationship(); publish_unit should be done inside
            return RegisteredMetric(entity_obj, self, None)
        else:
            # finally will create a RegisteredEntity
            log.info("Registering resource with IoTCC {0}".format(entity_obj.name))

            def on_receive_safe(msg):
                try:
                    log.debug("Received msg: {0}".format(msg))
                    if msg != "":
                        json_msg = json.loads(msg)
                        self.proto.on_receive(json.loads(msg))
                        log.debug("Processed msg: {0}".format(json_msg["type"]))
                        if json_msg["type"] == "create_or_find_resource_response":
                            if json_msg["body"]["uuid"] != "null":
                                log.info("FOUND RESOURCE: {0}".format(json_msg["body"]["uuid"]))
                                self.reg_entity_id = json_msg["body"]["uuid"]
                                exit()
                            else:
                                log.info("Waiting for resource creation")
                                time.sleep(5)
                                self.con.send(
                                    self._registration(self.con.next_id(), entity_obj.entity_id, entity_obj.name,
                                                       entity_obj.entity_type))
                except:
                    raise

            thread = threading.Thread(target=self.con.run)
            self.con.on_receive = on_receive_safe
            thread.daemon = True
            thread.start()
            if entity_obj.entity_type == "EdgeSystem":
                entity_obj.entity_type = "HelixGateway"
            self.con.send(
                self._registration(self.con.next_id(), entity_obj.entity_id, entity_obj.name, entity_obj.entity_type))
            thread.join()
            if not hasattr(self, 'reg_entity_id'):
                raise RegistrationFailure()
            log.info("Resource Registered {0}".format(entity_obj.name))
            if entity_obj.entity_type == "HelixGateway":
                self.store_reg_entity_details("EdgeSystem", entity_obj.name, self.reg_entity_id)
                self.store_edge_system_uuid(entity_obj.name, self.reg_entity_id)
            else:
                self.store_reg_entity_details("Devices", entity_obj.name, self.reg_entity_id)
            return RegisteredEntity(entity_obj, self, self.reg_entity_id)

    def create_relationship(self, reg_entity_parent, reg_entity_child):
        """ This function initializes all relations between Registered Entities.

            Parameters:
            - obj: The object that has just obtained an UUID
        """
        # sanity check: must be RegisteredEntity or RegisteredMetricRegisteredMetric
        if (not isinstance(reg_entity_parent, RegisteredEntity) \
            and not isinstance(reg_entity_parent, RegisteredMetric)) \
            or (not isinstance(reg_entity_child, RegisteredEntity) \
                and not isinstance(reg_entity_child, RegisteredMetric)):
            raise TypeError()

        reg_entity_child.parent = reg_entity_parent
        if isinstance(reg_entity_child, RegisteredMetric):
            # should save parent's reg_entity_id
            reg_entity_child.reg_entity_id = reg_entity_parent.reg_entity_id
            entity_obj = reg_entity_child.ref_entity
            self.publish_unit(reg_entity_child, entity_obj.name, entity_obj.unit)
        else:
            self.con.send(self._relationship(self.con.next_id(),
                reg_entity_parent.reg_entity_id, reg_entity_child.reg_entity_id))

    def _registration(self, msg_id, res_id, res_name, res_kind):
        return {
            "transactionID": msg_id,
            "type": "create_or_find_resource_request",
            "body": {
                "kind": res_kind,
                "id": res_id,
                "name": res_name
            }
        }

    def _relationship(self, msg_id, parent_res_uuid, child_res_uuid):
        return {
            "transactionID": msg_id,
            "type": "create_relationship_request",
            "body": {
                "parent": parent_res_uuid,
                "child": child_res_uuid
            }
        }

    def _properties(self, msg_id, res_uuid, res_kind, timestamp, properties):
        msg = {
            "transationID": msg_id,
            "type": "add_properties",
            "uuid": res_uuid,
            "body": {
                "kind": res_kind,
                "timestamp": timestamp,
                "property_data": []
            }
        }
        for key, value in properties.items():
            msg["body"]["property_data"].append({"propertyKey": key, "propertyValue": value})
        return msg

    def _format_data(self, reg_metric):
        met_cnt = reg_metric.values.qsize()
        if met_cnt == 0:
            return
        _timestamps = []
        _values = []
        for _ in range(met_cnt):
            m = reg_metric.values.get(block=True)
            if m is not None:
                _timestamps.append(m[0])
                _values.append(m[1])
        if _timestamps == []:
            return
        return {
            "type": "add_stats",
            "uuid": reg_metric.reg_entity_id,
            "metric_data": [{
                "statKey": reg_metric.ref_entity.name,
                "timestamps": _timestamps,
                "data": _values
            }],
        }

    def set_properties(self, reg_entity_obj, properties):
        # RegisteredMetric get parent's resid; RegisteredEntity gets own resid
        reg_entity_id = reg_entity_obj.reg_entity_id

        if isinstance(reg_entity_obj, RegisteredMetric):
            entity = reg_entity_obj.parent.ref_entity
        else:
            entity = reg_entity_obj.ref_entity

        log.info("Properties defined for resource {0}".format(entity.name))
        self.con.send(
            self._properties(self.con.next_id(), reg_entity_id, entity.entity_type,
                             getUTCmillis(), properties))

    def publish_unit(self, reg_entity_obj, metric_name, unit):
        str_prefix, str_unit_name = parse_unit(unit)
        if not isinstance(str_prefix, basestring):
            str_prefix = ""
        if not isinstance(str_unit_name, basestring):
            str_unit_name = ""
        properties_added = {
            metric_name + "_unit": str_unit_name,
            metric_name + "_prefix": str_prefix
        }
        self.set_properties(reg_entity_obj, properties_added)
        log.info("Published metric unit with prefix to IoTCC")

    def _init_info(self):
        msg = {
            "iotcc": {
                "EdgeSystem": {"SystemName": "", "uuid": ""},
                "Devices": []
            }
        }
        config = ConfigParser.RawConfigParser()
        fullPath = LiotaConfigPath().get_liota_fullpath()
        iotcc_path = ''
        if fullPath != '':
            try:
                if config.read(fullPath) != []:
                    try:
                        iotcc_path = config.get('IOTCC_PATH', 'iotcc_path')
                    except ConfigParser.ParsingError, err:
                        log.error('Could not open config file')
                else:
                    raise IOError('Could not open config file ' + fullPath)
            except IOError, err:
                log.error('Could not open config file ' + err)
Esempio n. 8
0
class IotControlCenter(DataCenterComponent):
    """ The implementation of IoTCC cloud provider solution

    """

    def __init__(self, con):
        log.info("Logging into DCC")
        self.comms = con
        if not self.comms.identity.username:
            log.error("Username not found")
            raise ValueError("Username not found")
        elif not self.comms.identity.password:
            log.error("Password not found")
            raise ValueError("Password not found")
        thread = threading.Thread(target=self.comms.receive)
        thread.daemon = True
        # This thread will continuously run in background to receive response or actions from DCC
        thread.start()
        # Wait for Subscription to be complete and then proceed to publish message
        time.sleep(0.5)
        self.proto = HelixProtocol(self.comms, self.comms.identity.username, self.comms.identity.password)
        self._iotcc_json = self._create_iotcc_json()
        self._iotcc_json_load_retry = int(read_liota_config('IOTCC', 'iotcc_load_retry'))
        self.counter = 0
        self.recv_msg_queue = self.comms.userdata
        self.dev_file_path = self._get_file_storage_path("dev_file_path")
        # Liota internal entity file system path special for iotcc
        self.entity_file_path = self._get_file_storage_path("entity_file_path")
        self.file_ops_lock = Lock()
        try:
            def on_response(msg):
                log.debug("Received msg: {0}".format(msg))
                json_msg = json.loads(msg)
                self.proto.on_receive(json_msg)
                if json_msg["type"] == "connection_response":
                    if json_msg["body"]["result"] == "succeeded":
                        log.info("Connection verified")
                    else:
                        raise Exception("Helix Protocol Version mismatch")
                else:
                    log.debug("Processed msg: {0}".format(json_msg["type"]))
                    on_response(self.recv_msg_queue.get(True, 300))

            # Block on Queue for not more then 300 seconds else it will raise an exception
            on_response(self.recv_msg_queue.get(True, 300))
        except Exception as error:
            self.comms.client.disconnect()
            log.error("HelixProtocolException: " + repr(error))
            raise Exception("HelixProtocolException")

    def register(self, entity_obj):
        """ Register the objects

        """
        if isinstance(entity_obj, Metric):
            # reg_entity_id should be parent's one: not known here yet
            # will add in creat_relationship(); publish_unit should be done inside
            return RegisteredMetric(entity_obj, self, None)
        else:
            # finally will create a RegisteredEntity
            log.info("Registering resource with IoTCC {0}".format(entity_obj.name))

            def on_response(msg):
                try:
                    log.debug("Received msg: {0}".format(msg))
                    json_msg = json.loads(msg)
                    log.debug("Processed msg: {0}".format(json_msg["type"]))
                    if json_msg["type"] == "create_or_find_resource_response" and json_msg["body"]["uuid"] != "null" and \
                                    json_msg["body"]["id"] == entity_obj.entity_id:
                        log.info("FOUND RESOURCE: {0}".format(json_msg["body"]["uuid"]))
                        self.reg_entity_id = json_msg["body"]["uuid"]
                    else:
                        log.info("Waiting for resource creation")
                        on_response(self.recv_msg_queue.get(True, 300))
                except:
                    raise Exception("Exception while registering resource")

            if entity_obj.entity_type == "EdgeSystem":
                entity_obj.entity_type = "HelixGateway"
            self.comms.send(json.dumps(
                self._registration(self.next_id(), entity_obj.entity_id, entity_obj.name, entity_obj.entity_type)))
            on_response(self.recv_msg_queue.get(True, 300))
            if not self.reg_entity_id:
                raise RegistrationFailure()
            log.info("Resource Registered {0}".format(entity_obj.name))
            if entity_obj.entity_type == "HelixGateway":
                with self.file_ops_lock:
                    self.store_reg_entity_details(entity_obj.entity_type, entity_obj.name, self.reg_entity_id,
                                              entity_obj.entity_id)
                    self.store_reg_entity_attributes("EdgeSystem", entity_obj.name,
                                                     self.reg_entity_id, None, None)
            else:
                # get dev_type, and prop_dict if possible
                with self.file_ops_lock:
                    self.store_reg_entity_attributes("Devices", entity_obj.name, self.reg_entity_id,
                                                     entity_obj.entity_type, None)

            return RegisteredEntity(entity_obj, self, self.reg_entity_id)

    def unregister(self, entity_obj):
        """ Unregister the objects
        """
        log.info("Unregistering resource with IoTCC {0}".format(entity_obj.ref_entity.name))

        def on_response(msg):
            try:
                log.debug("Received msg: {0}".format(msg))
                json_msg = json.loads(msg)
                log.debug("Processed msg: {0}".format(json_msg["type"]))
                if json_msg["type"] == "remove_resource_response" and json_msg["body"]["result"] == "succeeded":
                    log.info("Unregistration of resource {0} with IoTCC succeeded".format(entity_obj.ref_entity.name))
                else:
                    log.info("Unregistration of resource {0} with IoTCC failed".format(entity_obj.ref_entity.name))
            except:
                raise Exception("Exception while unregistering resource")

        self.comms.send(json.dumps(self._unregistration(self.next_id(), entity_obj.ref_entity)))
        on_response(self.recv_msg_queue.get(True, 20))
        if entity_obj.ref_entity.entity_type != "HelixGateway":
            self.store_device_info(entity_obj.reg_entity_id, entity_obj.ref_entity.name,
                                   entity_obj.ref_entity.entity_type, None, True)
        else:
            self.remove_reg_entity_details(entity_obj.ref_entity.name, entity_obj.reg_entity_id)
            self.store_device_info(entity_obj.reg_entity_id, entity_obj.ref_entity.name, None, None, True)

        log.info("Unregistration of resource {0} with IoTCC complete".format(entity_obj.ref_entity.name))

    def create_relationship(self, reg_entity_parent, reg_entity_child):
        """ This function initializes all relations between Registered Entities.

            Parameters:
            - obj: The object that has just obtained an UUID
        """
        # sanity check: must be RegisteredEntity or RegisteredMetricRegisteredMetric
        if (not isinstance(reg_entity_parent, RegisteredEntity) \
                    and not isinstance(reg_entity_parent, RegisteredMetric)) \
                or (not isinstance(reg_entity_child, RegisteredEntity) \
                            and not isinstance(reg_entity_child, RegisteredMetric)):
            raise TypeError()

        reg_entity_child.parent = reg_entity_parent
        if isinstance(reg_entity_child, RegisteredMetric):
            # should save parent's reg_entity_id
            reg_entity_child.reg_entity_id = reg_entity_parent.reg_entity_id
            entity_obj = reg_entity_child.ref_entity
            self.publish_unit(reg_entity_child, entity_obj.name, entity_obj.unit)
        else:
            self.comms.send(json.dumps(self._relationship(self.next_id(),
                                                          reg_entity_parent.reg_entity_id,
                                                          reg_entity_child.reg_entity_id)))

    def _registration(self, msg_id, res_id, res_name, res_kind):
        return {
            "transactionID": msg_id,
            "type": "create_or_find_resource_request",
            "body": {
                "kind": res_kind,
                "id": res_id,
                "name": res_name
            }
        }

    def _relationship(self, msg_id, parent_res_uuid, child_res_uuid):
        return {
            "transactionID": msg_id,
            "type": "create_relationship_request",
            "body": {
                "parent": parent_res_uuid,
                "child": child_res_uuid
            }
        }

    def _properties(self, msg_id, entity_type, entity_id, entity_name, timestamp, properties):
        msg = {
            "transationID": msg_id,
            "type": "add_properties",
            "body": {
                "kind": entity_type,
                "id": entity_id,
                "name": entity_name,
                "timestamp": timestamp,
                "property_data": []
            }
        }
        for key, value in properties.items():
            msg["body"]["property_data"].append({"propertyKey": key, "propertyValue": value})
        return msg

    def _format_data(self, reg_metric):
        met_cnt = reg_metric.values.qsize()
        if met_cnt == 0:
            return
        _timestamps = []
        _values = []
        for _ in range(met_cnt):
            m = reg_metric.values.get(block=True)
            if m is not None:
                _timestamps.append(m[0])
                _values.append(m[1])
        if _timestamps == []:
            return
        return json.dumps({
            "type": "add_stats",
            "body": {
                "kind": reg_metric.parent.ref_entity.entity_type,
                "id": reg_metric.parent.ref_entity.entity_id,
                "name": reg_metric.parent.ref_entity.name
            },
            "metric_data": [{
                "statKey": reg_metric.ref_entity.name,
                "timestamps": _timestamps,
                "data": _values
            }]
        })

    def set_organization_group_properties(self, reg_entity_name, reg_entity_id, reg_entity_type, entity_local_uuid,
                                          properties):
        log.info("Organization Group Properties defined for resource {0}".format(reg_entity_name))
        self.comms.send(json.dumps(
            self._properties(self.next_id(), reg_entity_type, entity_local_uuid, reg_entity_name,
                             getUTCmillis(), properties)))

    def set_properties(self, reg_entity_obj, properties):
        # RegisteredMetric get parent's resid; RegisteredEntity gets own resid
        reg_entity_id = reg_entity_obj.reg_entity_id

        if isinstance(reg_entity_obj, RegisteredMetric):
            entity = reg_entity_obj.parent.ref_entity
        else:
            entity = reg_entity_obj.ref_entity

        log.info("Properties defined for resource {0}".format(entity.name))
        self.comms.send(json.dumps(
            self._properties(self.next_id(), entity.entity_type, entity.entity_id, entity.name,
                             getUTCmillis(), properties)))
        if entity.entity_type == "HelixGateway":
            with self.file_ops_lock:
                self.store_reg_entity_attributes("EdgeSystem", entity.name,
                                                 reg_entity_obj.reg_entity_id, None, properties)
        else:
            # get dev_type, and prop_dict if possible
            with self.file_ops_lock:
                self.store_reg_entity_attributes("Devices", entity.name, reg_entity_obj.reg_entity_id,
                                                 entity.entity_type, properties)

    def publish_unit(self, reg_entity_obj, metric_name, unit):
        str_prefix, str_unit_name = parse_unit(unit)
        if not isinstance(str_prefix, basestring):
            str_prefix = ""
        if not isinstance(str_unit_name, basestring):
            str_unit_name = ""
        properties_added = {
            metric_name + "_unit": str_unit_name,
            metric_name + "_prefix": str_prefix
        }
        self.set_properties(reg_entity_obj, properties_added)
        log.info("Published metric unit with prefix to IoTCC")

    def _create_iotcc_json(self):
        msg = {
            "iotcc": {
                "EdgeSystem": {"SystemName": "", "EntityType": "", "uuid": "", "LocalUuid": ""},
                "OGProperties": {"OrganizationGroup": ""},
                "Devices": []
            }
        }

        iotcc_path = read_liota_config('IOTCC_PATH', 'iotcc_path')
        path = os.path.dirname(iotcc_path)
        mkdir(path)
        try:
            with open(iotcc_path, 'w') as f:
                json.dump(msg, f, sort_keys=True, indent=4, ensure_ascii=False)
                log.debug('Initialized ' + iotcc_path)
            f.close()
        except IOError, err:
            log.error('Could not open {0} file '.format(iotcc_path) + err)
        return iotcc_path