Add unique constraint on vnfd_id column
In Vnf LCM, when user will call create vnf instance API, vnfdId will be passed in the CreateVnfRequest as per SOL002, section 5.5.2.3 [1]. Based on this vnfdId, it will look for the vnf package to load the csar package at the time of instantiating vnf instance. So it's important that vnfdId is unique in the ``vnf_package_vnfd`` dbb table. Added ``vnfd_id`` and ``deleted`` columns as unique key in ``vnf_package_vnfd`` db table. [1] : https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/002/02.06.01_60/gs_nfv-sol002v020601p.pdf Change-Id: I2da2acf256bec307b606c5a152c0d47af24ad525 Blueprint: support-etsi-nfv-specs
This commit is contained in:
parent
dcbeac526b
commit
55b96c51e3
|
@ -207,6 +207,10 @@ class VnfPackageNotFound(NotFound):
|
|||
message = _("No vnf package with id %(id)s.")
|
||||
|
||||
|
||||
class VnfPackageVnfdIdDuplicate(TackerException):
|
||||
message = _("Vnf package with vnfd id %(vnfd_id)s already exists.")
|
||||
|
||||
|
||||
class VnfDeploymentFlavourNotFound(NotFound):
|
||||
message = _("No vnf deployment flavour with id %(id)s.")
|
||||
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
# under the License.
|
||||
|
||||
from oslo_db.sqlalchemy import models
|
||||
from oslo_utils import timeutils
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import DateTime
|
||||
from sqlalchemy import orm
|
||||
|
||||
from tacker.db import model_base
|
||||
|
@ -96,11 +98,27 @@ class VnfDeploymentFlavour(model_base.BASE, models.SoftDeleteMixin,
|
|||
'VnfSoftwareImage.deleted == 0)')
|
||||
|
||||
|
||||
class VnfPackageVnfd(model_base.BASE, models.SoftDeleteMixin,
|
||||
class VnfPackageVnfdSoftDeleteMixin(object):
|
||||
deleted_at = sa.Column(DateTime)
|
||||
deleted = sa.Column(sa.String(36), default='0')
|
||||
|
||||
def soft_delete(self, session):
|
||||
"""Mark this object as deleted."""
|
||||
self.deleted = self.id
|
||||
self.deleted_at = timeutils.utcnow()
|
||||
self.save(session=session)
|
||||
|
||||
|
||||
class VnfPackageVnfd(model_base.BASE, VnfPackageVnfdSoftDeleteMixin,
|
||||
models.TimestampMixin, models_v1.HasId):
|
||||
"""Contains all info about vnf packages VNFD."""
|
||||
|
||||
__tablename__ = 'vnf_package_vnfd'
|
||||
__table_args__ = (
|
||||
sa.schema.UniqueConstraint("vnfd_id", "deleted",
|
||||
name="uniq_vnf_package_vnfd0vnfd_id0deleted"),
|
||||
)
|
||||
|
||||
package_uuid = sa.Column(sa.String(36),
|
||||
sa.ForeignKey('vnf_packages.id'),
|
||||
nullable=False)
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
# Copyright (C) 2020 NTT DATA
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
"""Add unique constraints on vnfd_id,deleted in vnf_package_vnfd
|
||||
|
||||
Revision ID: 975e28392888
|
||||
Revises: abbef484b34c
|
||||
Create Date: 2019-12-10 02:40:12.966027
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '975e28392888'
|
||||
down_revision = 'abbef484b34c'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def _migrate_duplicate_vnf_package_vnfd_id(table):
|
||||
|
||||
meta = sa.MetaData(bind=op.get_bind())
|
||||
t = sa.Table(table, meta, autoload=True)
|
||||
|
||||
session = sa.orm.Session(bind=op.get_bind())
|
||||
with session.begin(subtransactions=True):
|
||||
dup_vnfd_ids = session.query(t.c.vnfd_id).group_by(
|
||||
t.c.vnfd_id).having(sa.func.count() > 1).all()
|
||||
if dup_vnfd_ids:
|
||||
for vnfd_id in dup_vnfd_ids:
|
||||
duplicate_obj_query = session.query(t).filter(
|
||||
t.c.vnfd_id == vnfd_id[0]).all()
|
||||
for dup_obj in duplicate_obj_query:
|
||||
if dup_obj.deleted == '1':
|
||||
session.execute(t.update().where(
|
||||
t.c.id == dup_obj.id).values(deleted=dup_obj.id))
|
||||
session.commit()
|
||||
|
||||
op.create_unique_constraint(
|
||||
constraint_name='uniq_%s0vnfd_id0deleted' % table,
|
||||
table_name=table,
|
||||
columns=['vnfd_id', 'deleted'])
|
||||
|
||||
|
||||
def upgrade(active_plugins=None, options=None):
|
||||
op.alter_column('vnf_package_vnfd',
|
||||
'deleted',
|
||||
type_=sa.String(36), default="0")
|
||||
_migrate_duplicate_vnf_package_vnfd_id('vnf_package_vnfd')
|
|
@ -1 +1 @@
|
|||
abbef484b34c
|
||||
975e28392888
|
||||
|
|
|
@ -216,7 +216,7 @@ def _destroy_vnf_package(context, package_uuid):
|
|||
update(updated_values, synchronize_session=False)
|
||||
api.model_query(context, models.VnfPackageVnfd). \
|
||||
filter_by(package_uuid=package_uuid). \
|
||||
update(updated_values, synchronize_session=False)
|
||||
soft_delete(synchronize_session=False)
|
||||
api.model_query(context, models.VnfPackage).\
|
||||
filter_by(id=package_uuid). \
|
||||
update(updated_values, synchronize_session=False)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_db import exception as db_exc
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from tacker.common import exceptions
|
||||
|
@ -26,7 +27,12 @@ def _vnf_package_vnfd_create(context, values):
|
|||
vnf_package_vnfd = models.VnfPackageVnfd()
|
||||
|
||||
vnf_package_vnfd.update(values)
|
||||
vnf_package_vnfd.save(context.session)
|
||||
try:
|
||||
vnf_package_vnfd.save(context.session)
|
||||
except db_exc.DBDuplicateEntry as e:
|
||||
if 'vnfd_id' in e.columns:
|
||||
raise exceptions.VnfPackageVnfdIdDuplicate(
|
||||
vnfd_id=values.get('vnfd_id'))
|
||||
|
||||
return vnf_package_vnfd
|
||||
|
||||
|
|
Loading…
Reference in New Issue