def update(self, data=None):
        """
        Updates topology
        Links are not deleted straightaway but set as "down"
        """
        Link, Node = self.link_model, self.node_model
        diff = self.diff(data)

        status = {'added': 'up', 'removed': 'down', 'changed': 'up'}
        action = {'added': 'add', 'changed': 'change', 'removed': 'remove'}

        try:
            added_nodes = diff['added']['nodes']
        except TypeError:
            added_nodes = []

        for node_dict in added_nodes:
            node = Node.count_address(node_dict['id'], topology=self)
            # if node exists skip to next iteration
            if node:  # pragma no cover
                continue
            # if node doesn't exist create new
            addresses = [node_dict['id']]
            addresses += node_dict.get('local_addresses', [])
            properties = node_dict.get('properties', {})
            node = self._create_node(addresses=addresses,
                                     properties=properties)
            if 'label' in node_dict:
                node.label = node_dict.get('label')
            node.full_clean()
            node.save()

        for section, graph in sorted(diff.items()):
            # if graph is empty skip to next one
            if not graph:
                continue
            for link_dict in graph['links']:
                changed = False
                link = Link.get_from_nodes(link_dict['source'],
                                           link_dict['target'],
                                           topology=self)
                # if link does not exist create new
                if not link:
                    source = Node.get_from_address(link_dict['source'], self)
                    target = Node.get_from_address(link_dict['target'], self)
                    link = self._create_link(
                        source=source,
                        target=target,
                        cost=link_dict['cost'],
                        properties=link_dict.get('properties', {}),
                        topology=self,
                    )
                    changed = True
                # if status of link is changed
                if self.link_status_changed(link, status[section]):
                    link.status = status[section]
                    changed = True
                # if cost of link has changed
                if link.cost != link_dict['cost']:
                    link.cost = link_dict['cost']
                    changed = True
                # perform writes only if needed
                if changed:
                    with log_failure(action[section], link):
                        link.full_clean()
                        link.save()
    def update(self):
        """
        Updates topology
        Links are not deleted straightaway but set as "down"
        """
        from . import Link, Node  # avoid circular dependency
        diff = self.diff()

        status = {
            'added': 'up',
            'removed': 'down',
            'changed': 'up'
        }
        action = {
            'added': 'add',
            'changed': 'change',
            'removed': 'remove'
        }

        try:
            added_nodes = diff['added']['nodes']
        except TypeError:
            added_nodes = []

        for node_dict in added_nodes:
            node = Node.count_address(node_dict['id'])
            if node:  # pragma no cover
                continue
            addresses = '{0};'.format(node_dict['id'])
            addresses += ';'.join(node_dict.get('local_addresses', []))
            properties = node_dict.get('properties', {})
            node = Node(addresses=addresses,
                        properties=properties)
            node.full_clean()
            node.save()

        for section, graph in sorted(diff.items()):
            # if graph is empty skip to next one
            if not graph:
                continue
            for link_dict in graph['links']:
                changed = False
                link = Link.get_from_nodes(link_dict['source'],
                                           link_dict['target'])
                if not link:
                    source = Node.get_from_address(link_dict['source'])
                    target = Node.get_from_address(link_dict['target'])
                    link = Link(source=source,
                                target=target,
                                cost=link_dict['cost'],
                                properties=link_dict.get('properties', {}),
                                topology=self)
                    changed = True
                # links in changed and removed sections
                # are always changing therefore needs to be saved
                if section in ['changed', 'removed']:
                    link.status = status[section]
                    link.cost = link_dict['cost']
                    changed = True
                # perform writes only if needed
                if changed:
                    with log_on_fail(action[section], link):
                        link.full_clean()
                        link.save()
    def update(self, data=None):
        """
        Updates topology
        Links are not deleted straightaway but set as "down"
        """
        Link, Node = self.link_model, self.node_model
        diff = self.diff(data)

        status = {
            'added': 'up',
            'removed': 'down',
            'changed': 'up'
        }
        action = {
            'added': 'add',
            'changed': 'change',
            'removed': 'remove'
        }

        try:
            added_nodes = diff['added']['nodes']
        except TypeError:
            added_nodes = []

        for node_dict in added_nodes:
            node = Node.count_address(node_dict['id'], topology=self)
            # if node exists skip to next iteration
            if node:  # pragma no cover
                continue
            # if node doesn't exist create new
            addresses = '{0};'.format(node_dict['id'])
            addresses += ';'.join(node_dict.get('local_addresses', []))
            properties = node_dict.get('properties', {})
            node = Node(addresses=addresses,
                        properties=properties,
                        topology=self)
            node.truncate_addresses()
            node.full_clean()
            node.save()

        for section, graph in sorted(diff.items()):
            # if graph is empty skip to next one
            if not graph:
                continue
            for link_dict in graph['links']:
                changed = False
                link = Link.get_from_nodes(link_dict['source'],
                                           link_dict['target'],
                                           topology=self)
                # if link does not exist create new
                if not link:
                    source = Node.get_from_address(link_dict['source'], self)
                    target = Node.get_from_address(link_dict['target'], self)
                    link = Link(source=source,
                                target=target,
                                cost=link_dict['cost'],
                                properties=link_dict.get('properties', {}),
                                topology=self)
                    changed = True
                # if status of link is changed
                if self.link_status_changed(link, status[section]):
                    link.status = status[section]
                    changed = True
                # if cost of link has changed
                if link.cost != link_dict['cost']:
                    link.cost = link_dict['cost']
                    changed = True
                # perform writes only if needed
                if changed:
                    with log_failure(action[section], link):
                        link.full_clean()
                        link.save()