Adding some more constraints to cron trigger
* User was able to create some triggers with different names but the same first-time and count. Now it is fixed. Closes-Bug: #1449514 Change-Id: Ifde94b2f183faad8c9a5bb8723f11945da5bc08a
This commit is contained in:
@@ -0,0 +1,46 @@
|
|||||||
|
# Copyright 2015 OpenStack Foundation.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""cron_trigger_constraints
|
||||||
|
|
||||||
|
Revision ID: 003
|
||||||
|
Revises: 002
|
||||||
|
Create Date: 2015-05-25 13:09:50.190136
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '003'
|
||||||
|
down_revision = '002'
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.add_column(
|
||||||
|
'cron_triggers_v2',
|
||||||
|
sa.Column('first_execution_time', sa.DateTime(), nullable=True)
|
||||||
|
)
|
||||||
|
op.drop_index('workflow_input_hash', table_name='cron_triggers_v2')
|
||||||
|
op.drop_index('workflow_input_hash_2', table_name='cron_triggers_v2')
|
||||||
|
op.create_unique_constraint(
|
||||||
|
None,
|
||||||
|
'cron_triggers_v2', [
|
||||||
|
'workflow_input_hash', 'workflow_name', 'pattern',
|
||||||
|
'project_id', 'workflow_params_hash', 'remaining_executions',
|
||||||
|
'first_execution_time'
|
||||||
|
]
|
||||||
|
)
|
||||||
@@ -793,6 +793,12 @@ def create_cron_trigger(values, session=None):
|
|||||||
"Duplicate entry for cron trigger %s: %s"
|
"Duplicate entry for cron trigger %s: %s"
|
||||||
% (cron_trigger.name, e.columns)
|
% (cron_trigger.name, e.columns)
|
||||||
)
|
)
|
||||||
|
# TODO(nmakhotkin): Remove this 'except' after fixing
|
||||||
|
# https://bugs.launchpad.net/oslo.db/+bug/1458583.
|
||||||
|
except db_exc.DBError as e:
|
||||||
|
raise exc.DBDuplicateEntry(
|
||||||
|
"Duplicate entry for cron trigger: %s" % e
|
||||||
|
)
|
||||||
|
|
||||||
return cron_trigger
|
return cron_trigger
|
||||||
|
|
||||||
|
|||||||
@@ -248,13 +248,19 @@ class CronTrigger(mb.MistralSecureModelBase):
|
|||||||
sa.UniqueConstraint('name', 'project_id'),
|
sa.UniqueConstraint('name', 'project_id'),
|
||||||
sa.UniqueConstraint(
|
sa.UniqueConstraint(
|
||||||
'workflow_input_hash', 'workflow_name', 'pattern', 'project_id',
|
'workflow_input_hash', 'workflow_name', 'pattern', 'project_id',
|
||||||
'workflow_params_hash'
|
'workflow_params_hash', 'remaining_executions',
|
||||||
|
'first_execution_time'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
id = mb.id_column()
|
id = mb.id_column()
|
||||||
name = sa.Column(sa.String(200))
|
name = sa.Column(sa.String(200))
|
||||||
pattern = sa.Column(sa.String(100))
|
pattern = sa.Column(
|
||||||
|
sa.String(100),
|
||||||
|
nullable=True,
|
||||||
|
default='0 0 30 2 0' # Set default to 'never'.
|
||||||
|
)
|
||||||
|
first_execution_time = sa.Column(sa.DateTime, nullable=True)
|
||||||
next_execution_time = sa.Column(sa.DateTime, nullable=False)
|
next_execution_time = sa.Column(sa.DateTime, nullable=False)
|
||||||
workflow_name = sa.Column(sa.String(80))
|
workflow_name = sa.Column(sa.String(80))
|
||||||
remaining_executions = sa.Column(sa.Integer)
|
remaining_executions = sa.Column(sa.Integer)
|
||||||
@@ -281,6 +287,7 @@ class CronTrigger(mb.MistralSecureModelBase):
|
|||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
d = super(CronTrigger, self).to_dict()
|
d = super(CronTrigger, self).to_dict()
|
||||||
|
|
||||||
|
mb.datetime_to_str(d, 'first_execution_time')
|
||||||
mb.datetime_to_str(d, 'next_execution_time')
|
mb.datetime_to_str(d, 'next_execution_time')
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ def create_cron_trigger(name, workflow_name, workflow_input,
|
|||||||
values = {
|
values = {
|
||||||
'name': name,
|
'name': name,
|
||||||
'pattern': pattern,
|
'pattern': pattern,
|
||||||
|
'first_execution_time': first_time,
|
||||||
'next_execution_time': next_time,
|
'next_execution_time': next_time,
|
||||||
'remaining_executions': count,
|
'remaining_executions': count,
|
||||||
'workflow_name': workflow_name,
|
'workflow_name': workflow_name,
|
||||||
|
|||||||
@@ -70,6 +70,57 @@ class TriggerServiceV2Test(base.DbTestCase):
|
|||||||
|
|
||||||
self.assertEqual(datetime.datetime(2010, 8, 25, 0, 10), next_time)
|
self.assertEqual(datetime.datetime(2010, 8, 25, 0, 10), next_time)
|
||||||
|
|
||||||
|
def test_trigger_create_the_same_first_time_or_count(self):
|
||||||
|
t_s.create_cron_trigger(
|
||||||
|
'test',
|
||||||
|
self.wf.name,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
'*/5 * * * *',
|
||||||
|
"4242-12-25 13:37",
|
||||||
|
2,
|
||||||
|
datetime.datetime(2010, 8, 25)
|
||||||
|
)
|
||||||
|
|
||||||
|
t_s.create_cron_trigger(
|
||||||
|
'test2',
|
||||||
|
self.wf.name,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
'*/5 * * * *',
|
||||||
|
"4242-12-25 13:37",
|
||||||
|
4,
|
||||||
|
datetime.datetime(2010, 8, 25)
|
||||||
|
)
|
||||||
|
|
||||||
|
t_s.create_cron_trigger(
|
||||||
|
'test3',
|
||||||
|
self.wf.name,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
'*/5 * * * *',
|
||||||
|
"5353-12-25 13:37",
|
||||||
|
2,
|
||||||
|
datetime.datetime(2010, 8, 25)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Creations above should be ok.
|
||||||
|
|
||||||
|
# But creation with the same count and first time
|
||||||
|
# simultaneously leads to error.
|
||||||
|
self.assertRaises(
|
||||||
|
exc.DBDuplicateEntry,
|
||||||
|
t_s.create_cron_trigger,
|
||||||
|
'test4',
|
||||||
|
self.wf.name,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
'*/5 * * * *',
|
||||||
|
"4242-12-25 13:37",
|
||||||
|
2,
|
||||||
|
None
|
||||||
|
)
|
||||||
|
|
||||||
def test_trigger_create_wrong_workflow_input(self):
|
def test_trigger_create_wrong_workflow_input(self):
|
||||||
wf_with_input = """---
|
wf_with_input = """---
|
||||||
version: '2.0'
|
version: '2.0'
|
||||||
Reference in New Issue
Block a user