Added action_plan.create|update|delete notifs
In this changeset, I added 3 notifications: - action_plan.create - action_plan.update - action_plan.delete Partially Implements: blueprint action-plan-versioned-notifications-api Change-Id: I8821fc6f47e7486037839d81bed9e28020b02fdd
This commit is contained in:
261
watcher/tests/notifications/test_action_plan_notification.py
Normal file
261
watcher/tests/notifications/test_action_plan_notification.py
Normal file
@@ -0,0 +1,261 @@
|
||||
# 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.
|
||||
|
||||
import freezegun
|
||||
import mock
|
||||
import oslo_messaging as om
|
||||
|
||||
from watcher.common import exception
|
||||
from watcher.common import rpc
|
||||
from watcher import notifications
|
||||
from watcher import objects
|
||||
from watcher.tests.db import base
|
||||
from watcher.tests.objects import utils
|
||||
|
||||
|
||||
@freezegun.freeze_time('2016-10-18T09:52:05.219414')
|
||||
class TestActionPlanNotification(base.DbTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestActionPlanNotification, self).setUp()
|
||||
p_get_notifier = mock.patch.object(rpc, 'get_notifier')
|
||||
m_get_notifier = p_get_notifier.start()
|
||||
self.addCleanup(p_get_notifier.stop)
|
||||
self.m_notifier = mock.Mock(spec=om.Notifier)
|
||||
|
||||
def fake_get_notifier(publisher_id):
|
||||
self.m_notifier.publisher_id = publisher_id
|
||||
return self.m_notifier
|
||||
|
||||
m_get_notifier.side_effect = fake_get_notifier
|
||||
self.goal = utils.create_test_goal(mock.Mock())
|
||||
self.audit = utils.create_test_audit(mock.Mock(), interval=None)
|
||||
self.strategy = utils.create_test_strategy(mock.Mock())
|
||||
|
||||
def test_send_invalid_action_plan(self):
|
||||
action_plan = utils.get_test_action_plan(
|
||||
mock.Mock(), state='DOESNOTMATTER', audit_id=1)
|
||||
|
||||
self.assertRaises(
|
||||
exception.InvalidActionPlan,
|
||||
notifications.action_plan.send_update,
|
||||
mock.MagicMock(), action_plan, host='node0')
|
||||
|
||||
def test_send_action_plan_update(self):
|
||||
action_plan = utils.create_test_action_plan(
|
||||
mock.Mock(), state=objects.action_plan.State.ONGOING,
|
||||
audit_id=self.audit.id, strategy_id=self.strategy.id,
|
||||
audit=self.audit, strategy=self.strategy)
|
||||
notifications.action_plan.send_update(
|
||||
mock.MagicMock(), action_plan, host='node0',
|
||||
old_state=objects.action_plan.State.PENDING)
|
||||
|
||||
# The 1st notification is because we created the object.
|
||||
# The 2nd notification is because we created the action plan object.
|
||||
self.assertEqual(3, self.m_notifier.info.call_count)
|
||||
notification = self.m_notifier.info.call_args[1]
|
||||
payload = notification['payload']
|
||||
|
||||
self.assertEqual("infra-optim:node0", self.m_notifier.publisher_id)
|
||||
self.assertDictEqual(
|
||||
{
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
"watcher_object.data": {
|
||||
"global_efficacy": {},
|
||||
"strategy_uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
|
||||
"strategy": {
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
"watcher_object.data": {
|
||||
"updated_at": None,
|
||||
"uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
|
||||
"name": "TEST",
|
||||
"parameters_spec": {},
|
||||
"created_at": "2016-10-18T09:52:05Z",
|
||||
"display_name": "test strategy",
|
||||
"deleted_at": None
|
||||
},
|
||||
"watcher_object.name": "StrategyPayload"
|
||||
},
|
||||
"uuid": "76be87bd-3422-43f9-93a0-e85a577e3061",
|
||||
"audit_uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||
"audit": {
|
||||
"watcher_object.data": {
|
||||
"interval": None,
|
||||
"parameters": {},
|
||||
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||
"strategy_uuid": None,
|
||||
"goal_uuid": (
|
||||
"f7ad87ae-4298-91cf-93a0-f35a852e3652"),
|
||||
"deleted_at": None,
|
||||
"scope": [],
|
||||
"state": "PENDING",
|
||||
"updated_at": None,
|
||||
"created_at": "2016-10-18T09:52:05Z",
|
||||
"audit_type": "ONESHOT"
|
||||
},
|
||||
"watcher_object.name": "TerseAuditPayload",
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0"
|
||||
},
|
||||
"deleted_at": None,
|
||||
"state": "ONGOING",
|
||||
"updated_at": None,
|
||||
"created_at": "2016-10-18T09:52:05Z",
|
||||
"state_update": {
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
"watcher_object.data": {
|
||||
"old_state": "PENDING",
|
||||
"state": "ONGOING"
|
||||
},
|
||||
"watcher_object.name": "ActionPlanStateUpdatePayload"
|
||||
},
|
||||
},
|
||||
"watcher_object.name": "ActionPlanUpdatePayload"
|
||||
},
|
||||
payload
|
||||
)
|
||||
|
||||
def test_send_action_plan_create(self):
|
||||
action_plan = utils.get_test_action_plan(
|
||||
mock.Mock(), state=objects.action_plan.State.PENDING,
|
||||
audit_id=self.audit.id, strategy_id=self.strategy.id,
|
||||
audit=self.audit.as_dict(), strategy=self.strategy.as_dict())
|
||||
notifications.action_plan.send_create(
|
||||
mock.MagicMock(), action_plan, host='node0')
|
||||
|
||||
self.assertEqual(2, self.m_notifier.info.call_count)
|
||||
notification = self.m_notifier.info.call_args[1]
|
||||
payload = notification['payload']
|
||||
|
||||
self.assertEqual("infra-optim:node0", self.m_notifier.publisher_id)
|
||||
self.assertDictEqual(
|
||||
{
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
"watcher_object.data": {
|
||||
"global_efficacy": {},
|
||||
"strategy_uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
|
||||
"strategy": {
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
"watcher_object.data": {
|
||||
"updated_at": None,
|
||||
"uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
|
||||
"name": "TEST",
|
||||
"parameters_spec": {},
|
||||
"created_at": "2016-10-18T09:52:05Z",
|
||||
"display_name": "test strategy",
|
||||
"deleted_at": None
|
||||
},
|
||||
"watcher_object.name": "StrategyPayload"
|
||||
},
|
||||
"uuid": "76be87bd-3422-43f9-93a0-e85a577e3061",
|
||||
"audit_uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||
"audit": {
|
||||
"watcher_object.data": {
|
||||
"interval": None,
|
||||
"parameters": {},
|
||||
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||
"strategy_uuid": None,
|
||||
"goal_uuid": (
|
||||
"f7ad87ae-4298-91cf-93a0-f35a852e3652"),
|
||||
"deleted_at": None,
|
||||
"scope": [],
|
||||
"state": "PENDING",
|
||||
"updated_at": None,
|
||||
"created_at": "2016-10-18T09:52:05Z",
|
||||
"audit_type": "ONESHOT"
|
||||
},
|
||||
"watcher_object.name": "TerseAuditPayload",
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0"
|
||||
},
|
||||
"deleted_at": None,
|
||||
"state": "PENDING",
|
||||
"updated_at": None,
|
||||
"created_at": None,
|
||||
},
|
||||
"watcher_object.name": "ActionPlanCreatePayload"
|
||||
},
|
||||
payload
|
||||
)
|
||||
|
||||
def test_send_action_plan_delete(self):
|
||||
action_plan = utils.create_test_action_plan(
|
||||
mock.Mock(), state=objects.action_plan.State.DELETED,
|
||||
audit_id=self.audit.id, strategy_id=self.strategy.id)
|
||||
notifications.action_plan.send_delete(
|
||||
mock.MagicMock(), action_plan, host='node0')
|
||||
|
||||
# The 1st notification is because we created the audit object.
|
||||
# The 2nd notification is because we created the action plan object.
|
||||
self.assertEqual(3, self.m_notifier.info.call_count)
|
||||
notification = self.m_notifier.info.call_args[1]
|
||||
payload = notification['payload']
|
||||
|
||||
self.assertEqual("infra-optim:node0", self.m_notifier.publisher_id)
|
||||
self.assertDictEqual(
|
||||
{
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
"watcher_object.data": {
|
||||
"global_efficacy": {},
|
||||
"strategy_uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
|
||||
"strategy": {
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
"watcher_object.data": {
|
||||
"updated_at": None,
|
||||
"uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
|
||||
"name": "TEST",
|
||||
"parameters_spec": {},
|
||||
"created_at": "2016-10-18T09:52:05Z",
|
||||
"display_name": "test strategy",
|
||||
"deleted_at": None
|
||||
},
|
||||
"watcher_object.name": "StrategyPayload"
|
||||
},
|
||||
"uuid": "76be87bd-3422-43f9-93a0-e85a577e3061",
|
||||
"audit_uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||
"audit": {
|
||||
"watcher_object.data": {
|
||||
"interval": None,
|
||||
"parameters": {},
|
||||
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||
"strategy_uuid": None,
|
||||
"goal_uuid": (
|
||||
"f7ad87ae-4298-91cf-93a0-f35a852e3652"),
|
||||
"deleted_at": None,
|
||||
"scope": [],
|
||||
"state": "PENDING",
|
||||
"updated_at": None,
|
||||
"created_at": "2016-10-18T09:52:05Z",
|
||||
"audit_type": "ONESHOT"
|
||||
},
|
||||
"watcher_object.name": "TerseAuditPayload",
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0"
|
||||
},
|
||||
"deleted_at": None,
|
||||
"state": "DELETED",
|
||||
"updated_at": None,
|
||||
"created_at": "2016-10-18T09:52:05Z",
|
||||
},
|
||||
"watcher_object.name": "ActionPlanDeletePayload"
|
||||
},
|
||||
payload
|
||||
)
|
||||
@@ -43,8 +43,8 @@ class TestAuditNotification(base.DbTestCase):
|
||||
self.strategy = utils.create_test_strategy(mock.Mock())
|
||||
|
||||
def test_send_invalid_audit(self):
|
||||
audit = utils.get_test_audit(mock.Mock(), state='DOESNOTMATTER',
|
||||
goal_id=1)
|
||||
audit = utils.get_test_audit(
|
||||
mock.Mock(), interval=None, state='DOESNOTMATTER', goal_id=1)
|
||||
|
||||
self.assertRaises(
|
||||
exception.InvalidAudit,
|
||||
@@ -53,7 +53,7 @@ class TestAuditNotification(base.DbTestCase):
|
||||
|
||||
def test_send_audit_update_with_strategy(self):
|
||||
audit = utils.create_test_audit(
|
||||
mock.Mock(), state=objects.audit.State.ONGOING,
|
||||
mock.Mock(), interval=None, state=objects.audit.State.ONGOING,
|
||||
goal_id=self.goal.id, strategy_id=self.strategy.id,
|
||||
goal=self.goal, strategy=self.strategy)
|
||||
notifications.audit.send_update(
|
||||
@@ -71,7 +71,8 @@ class TestAuditNotification(base.DbTestCase):
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
"watcher_object.data": {
|
||||
"interval": 3600,
|
||||
"interval": None,
|
||||
"strategy_uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
|
||||
"strategy": {
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
@@ -88,6 +89,7 @@ class TestAuditNotification(base.DbTestCase):
|
||||
},
|
||||
"parameters": {},
|
||||
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||
"goal_uuid": "f7ad87ae-4298-91cf-93a0-f35a852e3652",
|
||||
"goal": {
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
@@ -125,7 +127,7 @@ class TestAuditNotification(base.DbTestCase):
|
||||
|
||||
def test_send_audit_update_without_strategy(self):
|
||||
audit = utils.get_test_audit(
|
||||
mock.Mock(), state=objects.audit.State.ONGOING,
|
||||
mock.Mock(), interval=None, state=objects.audit.State.ONGOING,
|
||||
goal_id=self.goal.id, goal=self.goal)
|
||||
notifications.audit.send_update(
|
||||
mock.MagicMock(), audit, host='node0',
|
||||
@@ -141,9 +143,10 @@ class TestAuditNotification(base.DbTestCase):
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
"watcher_object.data": {
|
||||
"interval": 3600,
|
||||
"interval": None,
|
||||
"parameters": {},
|
||||
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||
"goal_uuid": "f7ad87ae-4298-91cf-93a0-f35a852e3652",
|
||||
"goal": {
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
@@ -158,6 +161,7 @@ class TestAuditNotification(base.DbTestCase):
|
||||
},
|
||||
"watcher_object.name": "GoalPayload"
|
||||
},
|
||||
"strategy_uuid": None,
|
||||
"strategy": None,
|
||||
"deleted_at": None,
|
||||
"scope": [],
|
||||
@@ -182,7 +186,7 @@ class TestAuditNotification(base.DbTestCase):
|
||||
|
||||
def test_send_audit_create(self):
|
||||
audit = utils.get_test_audit(
|
||||
mock.Mock(), state=objects.audit.State.PENDING,
|
||||
mock.Mock(), interval=None, state=objects.audit.State.PENDING,
|
||||
goal_id=self.goal.id, strategy_id=self.strategy.id,
|
||||
goal=self.goal.as_dict(), strategy=self.strategy.as_dict())
|
||||
notifications.audit.send_create(
|
||||
@@ -198,7 +202,8 @@ class TestAuditNotification(base.DbTestCase):
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
"watcher_object.data": {
|
||||
"interval": 3600,
|
||||
"interval": None,
|
||||
"strategy_uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
|
||||
"strategy": {
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
@@ -215,6 +220,7 @@ class TestAuditNotification(base.DbTestCase):
|
||||
},
|
||||
"parameters": {},
|
||||
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||
"goal_uuid": "f7ad87ae-4298-91cf-93a0-f35a852e3652",
|
||||
"goal": {
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
@@ -243,7 +249,7 @@ class TestAuditNotification(base.DbTestCase):
|
||||
|
||||
def test_send_audit_delete(self):
|
||||
audit = utils.create_test_audit(
|
||||
mock.Mock(), state=objects.audit.State.DELETED,
|
||||
mock.Mock(), interval=None, state=objects.audit.State.DELETED,
|
||||
goal_id=self.goal.id, strategy_id=self.strategy.id)
|
||||
notifications.audit.send_delete(
|
||||
mock.MagicMock(), audit, host='node0')
|
||||
@@ -259,7 +265,8 @@ class TestAuditNotification(base.DbTestCase):
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
"watcher_object.data": {
|
||||
"interval": 3600,
|
||||
"interval": None,
|
||||
"strategy_uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
|
||||
"strategy": {
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
@@ -276,6 +283,7 @@ class TestAuditNotification(base.DbTestCase):
|
||||
},
|
||||
"parameters": {},
|
||||
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
|
||||
"goal_uuid": "f7ad87ae-4298-91cf-93a0-f35a852e3652",
|
||||
"goal": {
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0",
|
||||
@@ -304,7 +312,7 @@ class TestAuditNotification(base.DbTestCase):
|
||||
|
||||
def test_send_audit_action(self):
|
||||
audit = utils.create_test_audit(
|
||||
mock.Mock(), state=objects.audit.State.ONGOING,
|
||||
mock.Mock(), interval=None, state=objects.audit.State.ONGOING,
|
||||
goal_id=self.goal.id, strategy_id=self.strategy.id,
|
||||
goal=self.goal, strategy=self.strategy)
|
||||
notifications.audit.send_action_notification(
|
||||
@@ -326,6 +334,7 @@ class TestAuditNotification(base.DbTestCase):
|
||||
"created_at": "2016-10-18T09:52:05Z",
|
||||
"deleted_at": None,
|
||||
"fault": None,
|
||||
"goal_uuid": "f7ad87ae-4298-91cf-93a0-f35a852e3652",
|
||||
"goal": {
|
||||
"watcher_object.data": {
|
||||
"created_at": "2016-10-18T09:52:05Z",
|
||||
@@ -340,10 +349,12 @@ class TestAuditNotification(base.DbTestCase):
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0"
|
||||
},
|
||||
"interval": 3600,
|
||||
"interval": None,
|
||||
"parameters": {},
|
||||
"scope": [],
|
||||
"state": "ONGOING",
|
||||
"strategy_uuid": (
|
||||
"cb3d0b58-4415-4d90-b75b-1e96878730e3"),
|
||||
"strategy": {
|
||||
"watcher_object.data": {
|
||||
"created_at": "2016-10-18T09:52:05Z",
|
||||
@@ -371,7 +382,7 @@ class TestAuditNotification(base.DbTestCase):
|
||||
|
||||
def test_send_audit_action_with_error(self):
|
||||
audit = utils.create_test_audit(
|
||||
mock.Mock(), state=objects.audit.State.ONGOING,
|
||||
mock.Mock(), interval=None, state=objects.audit.State.ONGOING,
|
||||
goal_id=self.goal.id, strategy_id=self.strategy.id,
|
||||
goal=self.goal, strategy=self.strategy)
|
||||
|
||||
@@ -407,6 +418,7 @@ class TestAuditNotification(base.DbTestCase):
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0"
|
||||
},
|
||||
"goal_uuid": "f7ad87ae-4298-91cf-93a0-f35a852e3652",
|
||||
"goal": {
|
||||
"watcher_object.data": {
|
||||
"created_at": "2016-10-18T09:52:05Z",
|
||||
@@ -421,10 +433,12 @@ class TestAuditNotification(base.DbTestCase):
|
||||
"watcher_object.namespace": "watcher",
|
||||
"watcher_object.version": "1.0"
|
||||
},
|
||||
"interval": 3600,
|
||||
"interval": None,
|
||||
"parameters": {},
|
||||
"scope": [],
|
||||
"state": "ONGOING",
|
||||
"strategy_uuid": (
|
||||
"cb3d0b58-4415-4d90-b75b-1e96878730e3"),
|
||||
"strategy": {
|
||||
"watcher_object.data": {
|
||||
"created_at": "2016-10-18T09:52:05Z",
|
||||
|
||||
@@ -250,10 +250,11 @@ class TestNotificationBase(testbase.TestCase):
|
||||
|
||||
|
||||
expected_notification_fingerprints = {
|
||||
'EventType': '1.2-633c2d32fa849d2a6f8bda3b0db88332',
|
||||
'EventType': '1.3-4258a2c86eca79fd34a7dffe1278eab9',
|
||||
'ExceptionNotification': '1.0-9b69de0724fda8310d05e18418178866',
|
||||
'ExceptionPayload': '1.0-4516ae282a55fe2fd5c754967ee6248b',
|
||||
'NotificationPublisher': '1.0-bbbc1402fb0e443a3eb227cc52b61545',
|
||||
'TerseAuditPayload': '1.0-aaf31166b8698f08d12cae98c380b8e0',
|
||||
'AuditPayload': '1.0-30c85c834648c8ca11f54fc5e084d86b',
|
||||
'AuditStateUpdatePayload': '1.0-1a1b606bf14a2c468800c2b010801ce5',
|
||||
'AuditUpdateNotification': '1.0-9b69de0724fda8310d05e18418178866',
|
||||
@@ -266,6 +267,15 @@ expected_notification_fingerprints = {
|
||||
'AuditActionPayload': '1.0-09f5d005f94ba9e5f6b9200170332c52',
|
||||
'GoalPayload': '1.0-fa1fecb8b01dd047eef808ded4d50d1a',
|
||||
'StrategyPayload': '1.0-94f01c137b083ac236ae82573c1fcfc1',
|
||||
'ActionPlanActionPayload': '1.0-34871caf18e9b43a28899953c1c9733a',
|
||||
'ActionPlanCreateNotification': '1.0-9b69de0724fda8310d05e18418178866',
|
||||
'ActionPlanCreatePayload': '1.0-ffc3087acd73351b14f3dcc30e105027',
|
||||
'ActionPlanDeleteNotification': '1.0-9b69de0724fda8310d05e18418178866',
|
||||
'ActionPlanDeletePayload': '1.0-ffc3087acd73351b14f3dcc30e105027',
|
||||
'ActionPlanPayload': '1.0-ffc3087acd73351b14f3dcc30e105027',
|
||||
'ActionPlanStateUpdatePayload': '1.0-1a1b606bf14a2c468800c2b010801ce5',
|
||||
'ActionPlanUpdateNotification': '1.0-9b69de0724fda8310d05e18418178866',
|
||||
'ActionPlanUpdatePayload': '1.0-7912a45fe53775c721f42aa87f06a023',
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user