def _set_nodes_for_spec(self,
                            context,
                            spec_db,
                            nodes_id_list,
                            set_params=True):
        if not nodes_id_list:
            spec_db.nodes = []
            spec_db.config_param_names = '[]'
            return
        with context.session.begin(subtransactions=True):
            # We will first check if the new list of nodes is valid
            filters = {'id': [n_id for n_id in nodes_id_list]}
            nodes_in_db = self._get_collection_query(context,
                                                     ServiceChainNode,
                                                     filters=filters)
            nodes_list = [n_db['id'] for n_db in nodes_in_db]
            for node_id in nodes_id_list:
                if node_id not in nodes_list:
                    # If we find an invalid node id in the list we
                    # do not perform the update
                    raise schain.ServiceChainNodeNotFound(sc_node_id=node_id)
            # New list of nodes is valid so we will first reset the
            #  existing list and then add each node in order.
            # Note that the list could be empty in which case we interpret
            # it as clearing existing nodes.
            spec_db.nodes = []
            if set_params:
                spec_db.config_param_names = '[]'
            for node_id in nodes_id_list:
                if set_params:
                    sc_node = self.get_servicechain_node(context, node_id)
                    node_dict = jsonutils.loads(sc_node['config'])
                    config_params = (node_dict.get('parameters')
                                     or node_dict.get('Parameters'))
                    if config_params:
                        if not spec_db.config_param_names:
                            spec_db.config_param_names = str(
                                config_params.keys())
                        else:
                            config_param_names = ast.literal_eval(
                                spec_db.config_param_names)
                            config_param_names.extend(config_params.keys())
                            spec_db.config_param_names = str(
                                config_param_names)

                assoc = SpecNodeAssociation(servicechain_spec_id=spec_db.id,
                                            node_id=node_id)
                spec_db.nodes.append(assoc)
 def _get_servicechain_node(self, context, node_id):
     try:
         return self._get_by_id(context, ServiceChainNode, node_id)
     except exc.NoResultFound:
         raise schain.ServiceChainNodeNotFound(sc_node_id=node_id)