Implement ORAN v2 api on notificationserver
The commit added the support to publish ptp status for v2 API in the notification-service. It also renamed the previously name v0 API to v1 API. Test Plan: Pass: PTP status push notification v2 API Pass: PTP status push notification v1 API Pass: Subscribe/List/Delete subscription in v2 API Pass: Subscribe/List/Delete subscription in v1 API Story: 2010056 Task: 45809 Signed-off-by: Teresa Ho <teresa.ho@windriver.com> Change-Id: Id5a1ff955eade59d68b6bcadfea4ffe6ed1567cd
This commit is contained in:
parent
84b5114027
commit
67452b94db
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
@ -58,12 +58,12 @@ class NotificationServiceClient(BrokerClientBase):
|
||||
return
|
||||
|
||||
def query_resource_status(self, resource_type,
|
||||
timeout=None, retry=None, resource_qualifier_json=None):
|
||||
timeout=None, retry=None, resource_qualifier_json=None, resource_address=None):
|
||||
topic = '{0}-Status'.format(resource_type)
|
||||
server = '{0}-Tracking-{1}'.format(resource_type, self.target_node_name)
|
||||
return self.call(
|
||||
topic, server, 'QueryStatus', timeout=timeout, retry=retry,
|
||||
QualifierJson=resource_qualifier_json)
|
||||
QualifierJson=resource_qualifier_json, ResourceAddress=resource_address)
|
||||
|
||||
def add_resource_status_listener(self, resource_type, status_handler=None):
|
||||
if not status_handler:
|
||||
|
@ -0,0 +1,32 @@
|
||||
#
|
||||
# Copyright (c) 2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
SPEC_VERSION = "1.0"
|
||||
DATA_TYPE_NOTIFICATION = "notification"
|
||||
DATA_TYPE_METRIC = "metric"
|
||||
VALUE_TYPE_ENUMERATION = "enumeration"
|
||||
VALUE_TYPE_METRIC = "metric"
|
||||
|
||||
SOURCE_SYNC_ALL = '/sync'
|
||||
SOURCE_SYNC_GNSS_SYNC_STATUS = '/sync/gnss-status/gnss-sync-status'
|
||||
SOURCE_SYNC_PTP_CLOCK_CLASS = '/sync/ptp-status/clock-class'
|
||||
SOURCE_SYNC_PTP_LOCK_STATE = '/sync/ptp-status/lock-state'
|
||||
SOURCE_SYNC_OS_CLOCK = '/sync/sync-status/os-clock-sync-state'
|
||||
SOURCE_SYNC_SYNC_STATE = '/sync/sync-status/sync-state'
|
||||
SOURCE_SYNCE_CLOCK_QUALITY = '/sync/synce-status/clock-quality'
|
||||
SOURCE_SYNCE_LOCK_STATE_EXTENDED = '/sync/synce-status/lock-state-extended'
|
||||
SOURCE_SYNCE_LOCK_STATE = '/sync/synce-status/lock-state'
|
||||
|
||||
VALID_SOURCE_URI = {
|
||||
SOURCE_SYNC_ALL,
|
||||
SOURCE_SYNC_GNSS_SYNC_STATUS,
|
||||
SOURCE_SYNC_PTP_CLOCK_CLASS,
|
||||
SOURCE_SYNC_PTP_LOCK_STATE,
|
||||
SOURCE_SYNC_OS_CLOCK,
|
||||
SOURCE_SYNC_SYNC_STATE,
|
||||
SOURCE_SYNCE_CLOCK_QUALITY,
|
||||
SOURCE_SYNCE_LOCK_STATE_EXTENDED,
|
||||
SOURCE_SYNCE_LOCK_STATE
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
#coding=utf-8
|
||||
#
|
||||
# Copyright (c) 2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
@ -59,7 +58,7 @@ def parse_resource_address(resource_address):
|
||||
# Assume no optional hierarchy for now
|
||||
clusterName = resource_address.split('/')[1]
|
||||
nodeName = resource_address.split('/')[2]
|
||||
resource_path = re.split('[/]', resource_address, 3)[3]
|
||||
resource_path = '/' + re.split('[/]', resource_address, 3)[3]
|
||||
|
||||
return clusterName, nodeName, resource_path
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
#
|
||||
# Copyright (c) 2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV0
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV1
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV2
|
||||
from notificationclientsdk.model.dto.subscription import ResourceQualifierPtp
|
||||
|
||||
from wsme.rest.json import tojson
|
||||
|
||||
@tojson.when_object(SubscriptionInfoV0)
|
||||
@tojson.when_object(SubscriptionInfoV1)
|
||||
def subscriptioninfo_tojson(datatype, value):
|
||||
if value is None:
|
||||
return None
|
||||
@ -22,7 +22,7 @@ def resourcequalifierptp_tojson(datatype, value):
|
||||
return None
|
||||
return value.to_dict()
|
||||
|
||||
@tojson.when_object(SubscriptionInfoV1)
|
||||
@tojson.when_object(SubscriptionInfoV2)
|
||||
def subscriptioninfo_tojson(datatype, value):
|
||||
if value is None:
|
||||
return None
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding=utf-8
|
||||
#
|
||||
# Copyright (c) 2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
@ -45,7 +45,7 @@ class ResourceQualifierPtp(ResourceQualifierBase):
|
||||
'''
|
||||
ViewModel of Subscription
|
||||
'''
|
||||
class SubscriptionInfoV0(wtypes.Base):
|
||||
class SubscriptionInfoV1(wtypes.Base):
|
||||
SubscriptionId = wtypes.text
|
||||
UriLocation = wtypes.text
|
||||
ResourceType = EnumResourceType
|
||||
@ -99,7 +99,7 @@ class SubscriptionInfoV0(wtypes.Base):
|
||||
}
|
||||
return d
|
||||
|
||||
class SubscriptionInfoV1(wtypes.Base):
|
||||
class SubscriptionInfoV2(wtypes.Base):
|
||||
SubscriptionId = wtypes.text
|
||||
UriLocation = wtypes.text
|
||||
EndpointUri = wtypes.text
|
||||
|
@ -1,13 +1,13 @@
|
||||
#
|
||||
# Copyright (c) 2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
import json
|
||||
import logging
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV0
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV1
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV2
|
||||
from notificationclientsdk.model.dto.resourcetype import ResourceType
|
||||
from notificationclientsdk.common.helpers.nodeinfo_helper import NodeInfoHelper
|
||||
from notificationclientsdk.common.helpers import subscription_helper
|
||||
@ -96,9 +96,8 @@ class BrokerStateManager:
|
||||
changed = False
|
||||
broker_name = None
|
||||
|
||||
LOG.info("__refresh_by_subscription: subscription_orm={}".format(subscription_orm))
|
||||
if getattr(subscription_orm, 'ResourceType') is not None:
|
||||
subscription = SubscriptionInfoV0(subscription_orm)
|
||||
subscription = SubscriptionInfoV1(subscription_orm)
|
||||
resource = subscription.ResourceType
|
||||
# assume PTP and not wildcard
|
||||
if resource == ResourceType.TypePTP:
|
||||
@ -108,22 +107,22 @@ class BrokerStateManager:
|
||||
LOG.debug("Ignore the subscription for: {0}".format(subscription_orm.SubscriptionId))
|
||||
return False
|
||||
else:
|
||||
subscription = SubscriptionInfoV1(subscription_orm)
|
||||
subscription = SubscriptionInfoV2(subscription_orm)
|
||||
_, nodename, resource = subscription_helper.parse_resource_address(subscription.ResourceAddress)
|
||||
broker_name = nodename
|
||||
|
||||
LOG.info("subscription:{0}, Status:{1}".format(subscription.to_dict(), subscription_orm.Status))
|
||||
LOG.debug("subscription:{0}, Status:{1}".format(subscription.to_dict(), subscription_orm.Status))
|
||||
if subscription_orm.Status != 1:
|
||||
return False
|
||||
|
||||
if not broker_name:
|
||||
# ignore the subscription due to unsupported type
|
||||
LOG.info("Ignore the subscription for: {0}".format(subscription.SubscriptionId))
|
||||
LOG.debug("Ignore the subscription for: {0}".format(subscription.SubscriptionId))
|
||||
return False
|
||||
|
||||
enumerated_broker_names = NodeInfoHelper.enumerate_nodes(broker_name)
|
||||
if not enumerated_broker_names:
|
||||
LOG.info("Failed to enumerate broker names for {0}".format(broker_name))
|
||||
LOG.debug("Failed to enumerate broker names for {0}".format(broker_name))
|
||||
return False
|
||||
|
||||
for expanded_broker_name in enumerated_broker_names:
|
||||
|
@ -1,6 +1,5 @@
|
||||
|
||||
#
|
||||
# Copyright (c) 2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
@ -10,9 +9,10 @@ import logging
|
||||
|
||||
import multiprocessing as mp
|
||||
import threading
|
||||
import time
|
||||
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV0
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV1
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV2
|
||||
from notificationclientsdk.model.dto.resourcetype import ResourceType
|
||||
|
||||
from notificationclientsdk.repository.subscription_repo import SubscriptionRepo
|
||||
@ -48,32 +48,38 @@ class NotificationHandler(NotificationHandlerBase):
|
||||
self.notification_lock.acquire()
|
||||
subscription_repo = SubscriptionRepo(autocommit=True)
|
||||
resource_type = notification_info.get('ResourceType', None)
|
||||
resource_address = notification_info.get('ResourceAddress', None)
|
||||
# Get nodename from resource address
|
||||
if resource_address:
|
||||
_,node_name,_ = subscription_helper.parse_resource_address(resource_address)
|
||||
else:
|
||||
if resource_type:
|
||||
node_name = notification_info.get('ResourceQualifier', {}).get('NodeName', None)
|
||||
if not resource_type:
|
||||
raise Exception("abnormal notification@{0}".format(node_name))
|
||||
|
||||
if not resource_type in self.__supported_resource_types:
|
||||
raise Exception("notification with unsupported resource type:{0}".format(resource_type))
|
||||
this_delivery_time = notification_info['EventTimestamp']
|
||||
else:
|
||||
source = notification_info.get('source', None)
|
||||
values = notification_info.get('data', {}).get('values', [])
|
||||
resource_address = values[0].get('ResourceAddress', None)
|
||||
if not resource_address:
|
||||
raise Exception("No resource address in notification source".format(source))
|
||||
_,node_name,_ = subscription_helper.parse_resource_address(resource_address)
|
||||
this_delivery_time = notification_info['time']
|
||||
# Change time from float to ascii format
|
||||
notification_info['time'] = time.strftime('%Y-%m-%dT%H:%M:%SZ',
|
||||
time.gmtime(this_delivery_time))
|
||||
|
||||
this_delivery_time = notification_info['EventTimestamp']
|
||||
|
||||
entries = subscription_repo.get(ResourceType=resource_type, Status=1)
|
||||
entries = subscription_repo.get(Status=1)
|
||||
for entry in entries:
|
||||
subscriptionid = entry.SubscriptionId
|
||||
if entry.ResourceAddress:
|
||||
_,entry_node_name,_ = subscription_helper.parse_resource_address(entry.ResourceAddress)
|
||||
subscription_dto2 = SubscriptionInfoV1(entry)
|
||||
subscription_dto2 = SubscriptionInfoV2(entry)
|
||||
else:
|
||||
ResourceQualifierJson = entry.ResourceQualifierJson or '{}'
|
||||
ResourceQualifier = json.loads(ResourceQualifierJson)
|
||||
# qualify by NodeName
|
||||
entry_node_name = ResourceQualifier.get('NodeName', None)
|
||||
subscription_dto2 = SubscriptionInfoV0(entry)
|
||||
subscription_dto2 = SubscriptionInfoV1(entry)
|
||||
node_name_matched = NodeInfoHelper.match_node_name(entry_node_name, node_name)
|
||||
if not node_name_matched:
|
||||
continue
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
@ -20,7 +20,7 @@ from notificationclientsdk.common.helpers import rpc_helper, hostfile_helper
|
||||
from notificationclientsdk.common.helpers.nodeinfo_helper import NodeInfoHelper
|
||||
|
||||
from notificationclientsdk.model.dto.rpc_endpoint import RpcEndpointInfo
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV0
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV1
|
||||
from notificationclientsdk.model.dto.resourcetype import ResourceType
|
||||
from notificationclientsdk.model.dto.location import LocationInfo
|
||||
|
||||
@ -242,7 +242,7 @@ class NotificationWorker:
|
||||
|
||||
for s in subs:
|
||||
if s.ResourceType:
|
||||
subinfo = SubscriptionInfoV0(s)
|
||||
subinfo = SubscriptionInfoV1(s)
|
||||
# assume resource type being PTP and not wildcard
|
||||
resource_type = s.ResourceType
|
||||
if resource_type == ResourceType.TypePTP:
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
@ -9,16 +9,17 @@ import logging
|
||||
import json
|
||||
import kombu
|
||||
|
||||
from notificationclientsdk.client.notificationservice import NotificationServiceClient
|
||||
from notificationclientsdk.common.helpers import subscription_helper
|
||||
from notificationclientsdk.common.helpers.nodeinfo_helper import NodeInfoHelper
|
||||
from notificationclientsdk.model.dto.resourcetype import ResourceType
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV1
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV2
|
||||
from notificationclientsdk.model.orm.subscription import Subscription as SubscriptionOrm
|
||||
from notificationclientsdk.repository.node_repo import NodeRepo
|
||||
from notificationclientsdk.repository.subscription_repo import SubscriptionRepo
|
||||
from notificationclientsdk.model.dto.resourcetype import ResourceType
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV0
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV1
|
||||
from notificationclientsdk.common.helpers.nodeinfo_helper import NodeInfoHelper
|
||||
from notificationclientsdk.model.orm.subscription import Subscription as SubscriptionOrm
|
||||
from notificationclientsdk.client.notificationservice import NotificationServiceClient
|
||||
from notificationclientsdk.services.daemon import DaemonControl
|
||||
from notificationclientsdk.common.helpers import subscription_helper
|
||||
|
||||
|
||||
from notificationclientsdk.exception import client_exception
|
||||
|
||||
@ -70,7 +71,7 @@ class PtpService(object):
|
||||
finally:
|
||||
del nodeinfo_repo
|
||||
|
||||
def query(self, broker_name):
|
||||
def query(self, broker_name, resource_address=None):
|
||||
default_node_name = NodeInfoHelper.default_node_name(broker_name)
|
||||
broker_pod_ip, supported_resource_types = self.__get_node_info(default_node_name)
|
||||
|
||||
@ -83,9 +84,9 @@ class PtpService(object):
|
||||
ResourceType.TypePTP, default_node_name))
|
||||
raise client_exception.ResourceNotAvailable(broker_name, ResourceType.TypePTP)
|
||||
|
||||
return self._query(default_node_name, broker_pod_ip)
|
||||
return self._query(default_node_name, broker_pod_ip, resource_address)
|
||||
|
||||
def _query(self, broker_name, broker_pod_ip):
|
||||
def _query(self, broker_name, broker_pod_ip, resource_address=None):
|
||||
broker_host = "[{0}]".format(broker_pod_ip)
|
||||
broker_transport_endpoint = "rabbit://{0}:{1}@{2}:{3}".format(
|
||||
self.daemon_control.daemon_context['NOTIFICATION_BROKER_USER'],
|
||||
@ -97,7 +98,7 @@ class PtpService(object):
|
||||
notificationservice_client = NotificationServiceClient(
|
||||
broker_name, broker_transport_endpoint, broker_pod_ip)
|
||||
resource_status = notificationservice_client.query_resource_status(
|
||||
ResourceType.TypePTP, timeout=5, retry=10)
|
||||
ResourceType.TypePTP, timeout=5, retry=10, resource_address=resource_address)
|
||||
return resource_status
|
||||
except oslo_messaging.exceptions.MessagingTimeout as ex:
|
||||
LOG.warning("ptp status is not available @node {0} due to {1}".format(
|
||||
@ -144,9 +145,9 @@ class PtpService(object):
|
||||
|
||||
# Delivery the initial notification of ptp status
|
||||
if hasattr(subscription_dto, 'ResourceType'):
|
||||
subscription_dto2 = SubscriptionInfoV0(entry)
|
||||
else:
|
||||
subscription_dto2 = SubscriptionInfoV1(entry)
|
||||
else:
|
||||
subscription_dto2 = SubscriptionInfoV2(entry)
|
||||
|
||||
try:
|
||||
subscription_helper.notify(subscription_dto2, ptpstatus)
|
||||
|
@ -1,6 +1,5 @@
|
||||
#coding=utf-8
|
||||
#
|
||||
# Copyright (c) 2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
@ -14,9 +13,10 @@ from wsmeext.pecan import wsexpose
|
||||
|
||||
THIS_NODE_NAME = os.environ.get("THIS_NODE_NAME",'controller-0')
|
||||
|
||||
from sidecar.controllers.v1.subscriptions import SubscriptionsControllerV0
|
||||
from sidecar.controllers.v1.subscriptions import SubscriptionsControllerV1
|
||||
from sidecar.controllers.v2.subscriptions import SubscriptionsControllerV2
|
||||
from sidecar.controllers.v1.resource.ptp import PtpController
|
||||
from sidecar.controllers.v2.resource_address import ResourceAddressController
|
||||
import logging
|
||||
LOG = logging.getLogger(__name__)
|
||||
from notificationclientsdk.common.helpers import log_helper
|
||||
@ -40,21 +40,33 @@ class V1Controller(rest.RestController):
|
||||
|
||||
@expose("json")
|
||||
def _lookup(self, primary_key, *remainder):
|
||||
LOG.info("_lookup: primary_key={} remainder={}".format(primary_key, remainder))
|
||||
payload = None
|
||||
if request.is_body_readable:
|
||||
payload = request.json_body
|
||||
LOG.info("_lookup: payload={}".format(payload))
|
||||
if primary_key:
|
||||
if 'ptp' == primary_key.lower():
|
||||
return PtpController(), remainder
|
||||
elif 'subscriptions' == primary_key.lower():
|
||||
if payload and 'ResourceType' in payload:
|
||||
return SubscriptionsControllerV0(), remainder
|
||||
else:
|
||||
return SubscriptionsControllerV1(), remainder
|
||||
return SubscriptionsControllerV1(), remainder
|
||||
abort(404)
|
||||
|
||||
class V2Controller(rest.RestController):
|
||||
|
||||
@wsexpose(wtypes.text)
|
||||
def get(self):
|
||||
return 'v2controller'
|
||||
|
||||
@expose("json")
|
||||
def _lookup(self, primary_key, *remainder):
|
||||
if primary_key:
|
||||
if 'subscriptions' == primary_key.lower():
|
||||
return SubscriptionsControllerV2(), remainder
|
||||
else:
|
||||
if 'currentstate' == remainder[-1].lower():
|
||||
resource_address_array = remainder[:-1]
|
||||
resource_address = '/' + primary_key + '/' + '/'.join(resource_address_array)
|
||||
remainder = remainder[-1:]
|
||||
return ResourceAddressController(resource_address), remainder
|
||||
abort(404)
|
||||
|
||||
|
||||
class ocloudDaemonController(rest.RestController):
|
||||
|
||||
# All supported API versions
|
||||
@ -73,6 +85,8 @@ class ocloudDaemonController(rest.RestController):
|
||||
if primary_key:
|
||||
if 'v1' == primary_key.lower():
|
||||
return V1Controller(), remainder
|
||||
elif 'v2' == primary_key.lower():
|
||||
return V2Controller(), remainder
|
||||
abort(404)
|
||||
|
||||
class RootController(object):
|
||||
|
@ -1,6 +1,6 @@
|
||||
#coding=utf-8
|
||||
#
|
||||
# Copyright (c) 2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
@ -16,7 +16,6 @@ from wsme import types as wtypes
|
||||
from wsmeext.pecan import wsexpose
|
||||
|
||||
from notificationclientsdk.model.dto.resourcetype import ResourceType
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV0
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV1
|
||||
|
||||
from notificationclientsdk.repository.subscription_repo import SubscriptionRepo
|
||||
@ -33,9 +32,9 @@ log_helper.config_logger(LOG)
|
||||
|
||||
THIS_NODE_NAME = os.environ.get("THIS_NODE_NAME",'controller-0')
|
||||
|
||||
class SubscriptionsControllerV0(rest.RestController):
|
||||
class SubscriptionsControllerV1(rest.RestController):
|
||||
|
||||
@wsexpose(SubscriptionInfoV0, body=SubscriptionInfoV0, status_code=201)
|
||||
@wsexpose(SubscriptionInfoV1, body=SubscriptionInfoV1, status_code=201)
|
||||
def post(self, subscription):
|
||||
# decode the request body
|
||||
try:
|
||||
@ -49,7 +48,7 @@ class SubscriptionsControllerV0(rest.RestController):
|
||||
subscription.ResourceType))
|
||||
abort(404)
|
||||
|
||||
if not self._validateV0(subscription):
|
||||
if not self._validateV1(subscription):
|
||||
LOG.warning(' Invalid Request data:{0}'.format(subscription.to_dict()))
|
||||
abort(400)
|
||||
|
||||
@ -88,87 +87,6 @@ class SubscriptionsControllerV0(rest.RestController):
|
||||
LOG.error("Exception:{0}@{1}".format(type(ex),str(ex)))
|
||||
abort(500)
|
||||
|
||||
@expose('json')
|
||||
def get(self):
|
||||
try:
|
||||
repo = SubscriptionRepo(defaults['dbcontext'].get_session(), autocommit = False)
|
||||
entries = repo.get(Status=1)
|
||||
|
||||
response.status = 200
|
||||
return [SubscriptionInfoV0(x).to_dict() for x in entries if x.Status == 1]
|
||||
except HTTPException as ex:
|
||||
LOG.warning("Client side error:{0},{1}".format(type(ex), str(ex)))
|
||||
raise ex
|
||||
except HTTPServerError as ex:
|
||||
LOG.error("Server side error:{0},{1}".format(type(ex), str(ex)))
|
||||
raise ex
|
||||
except Exception as ex:
|
||||
LOG.error("Exception:{0}@{1}".format(type(ex),str(ex)))
|
||||
abort(500)
|
||||
|
||||
@expose()
|
||||
def _lookup(self, subscription_id, *remainder):
|
||||
return SubscriptionController(subscription_id), remainder
|
||||
|
||||
def _validateV0(self, subscription_request):
|
||||
try:
|
||||
assert subscription_request.ResourceType == 'PTP'
|
||||
assert subscription_request.EndpointUri
|
||||
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
class SubscriptionsControllerV1(rest.RestController):
|
||||
|
||||
@wsexpose(SubscriptionInfoV1, body=SubscriptionInfoV1, status_code=201)
|
||||
def post(self, subscription):
|
||||
# decode the request body
|
||||
try:
|
||||
if subscription.ResourceAddress:
|
||||
LOG.info(' subscribe: ResourceAddress {0} with callback uri {1}'.format(
|
||||
subscription.ResourceAddress,
|
||||
subscription.EndpointUri))
|
||||
|
||||
if not self._validateV1(subscription):
|
||||
LOG.warning(' Invalid Request data:{0}'.format(subscription.to_dict()))
|
||||
abort(400)
|
||||
|
||||
subscription.UriLocation = "{0}://{1}:{2}/ocloudNotifications/v1/subscriptions".format(
|
||||
conf.server.get('protocol','http'),
|
||||
conf.server.get('host', '127.0.0.1'),
|
||||
conf.server.get('port', '8080')
|
||||
)
|
||||
if subscription.ResourceAddress:
|
||||
ptpservice = PtpService(notification_control)
|
||||
entry = ptpservice.add_subscription(subscription)
|
||||
del ptpservice
|
||||
if not entry:
|
||||
abort(404)
|
||||
subscription.SubscriptionId = entry.SubscriptionId
|
||||
subscription.UriLocation = entry.UriLocation
|
||||
LOG.info('created subscription: {0}'.format(subscription.to_dict()))
|
||||
|
||||
return subscription
|
||||
except client_exception.InvalidSubscription as ex:
|
||||
abort(400)
|
||||
except client_exception.InvalidEndpoint as ex:
|
||||
abort(400)
|
||||
except client_exception.NodeNotAvailable as ex:
|
||||
abort(404)
|
||||
except client_exception.ResourceNotAvailable as ex:
|
||||
abort(404)
|
||||
except HTTPException as ex:
|
||||
LOG.warning("Client side error:{0},{1}".format(type(ex), str(ex)))
|
||||
abort(400)
|
||||
except HTTPServerError as ex:
|
||||
LOG.error("Server side error:{0},{1}".format(type(ex), str(ex)))
|
||||
abort(500)
|
||||
except Exception as ex:
|
||||
LOG.error("Exception:{0}@{1}".format(type(ex),str(ex)))
|
||||
abort(500)
|
||||
|
||||
@expose('json')
|
||||
def get(self):
|
||||
try:
|
||||
@ -178,9 +96,7 @@ class SubscriptionsControllerV1(rest.RestController):
|
||||
subs = []
|
||||
for x in entries:
|
||||
if x.Status == 1:
|
||||
if getattr(x, 'ResourceType', None):
|
||||
subs.append(SubscriptionInfoV0(x).to_dict())
|
||||
else:
|
||||
if getattr(x, 'ResourceType', None) is not None:
|
||||
subs.append(SubscriptionInfoV1(x).to_dict())
|
||||
return subs
|
||||
except HTTPException as ex:
|
||||
@ -199,13 +115,14 @@ class SubscriptionsControllerV1(rest.RestController):
|
||||
|
||||
def _validateV1(self, subscription_request):
|
||||
try:
|
||||
assert subscription_request.ResourceAddress
|
||||
assert subscription_request.ResourceType == 'PTP'
|
||||
assert subscription_request.EndpointUri
|
||||
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
class SubscriptionController(rest.RestController):
|
||||
def __init__(self, subscription_id):
|
||||
self.subscription_id = subscription_id
|
||||
@ -220,10 +137,7 @@ class SubscriptionController(rest.RestController):
|
||||
abort(404)
|
||||
else:
|
||||
response.status = 200
|
||||
if getattr(entry, 'ResourceType', None):
|
||||
return SubscriptionInfoV0(entry).to_dict()
|
||||
else:
|
||||
return SubscriptionInfoV1(entry).to_dict()
|
||||
return SubscriptionInfoV1(entry).to_dict()
|
||||
except HTTPException as ex:
|
||||
LOG.warning("Client side error:{0},{1}".format(type(ex), str(ex)))
|
||||
raise ex
|
||||
|
@ -0,0 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
@ -0,0 +1,69 @@
|
||||
#
|
||||
# Copyright (c) 2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from pecan import expose, redirect, rest, route, response, abort
|
||||
from webob.exc import HTTPException, HTTPNotFound, HTTPBadRequest, HTTPClientError, HTTPServerError
|
||||
|
||||
from wsme import types as wtypes
|
||||
from wsmeext.pecan import wsexpose
|
||||
|
||||
import os
|
||||
import logging
|
||||
import oslo_messaging
|
||||
|
||||
from notificationclientsdk.common.helpers import constants
|
||||
from notificationclientsdk.common.helpers import subscription_helper
|
||||
from notificationclientsdk.services.ptp import PtpService
|
||||
from notificationclientsdk.exception import client_exception
|
||||
|
||||
from sidecar.repository.notification_control import notification_control
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
from notificationclientsdk.common.helpers import log_helper
|
||||
log_helper.config_logger(LOG)
|
||||
|
||||
THIS_NODE_NAME = os.environ.get("THIS_NODE_NAME",'controller-0')
|
||||
|
||||
class ResourceAddressController(object):
|
||||
def __init__(self, resource_address):
|
||||
self.resource_address = resource_address
|
||||
|
||||
@expose('json')
|
||||
def CurrentState(self):
|
||||
try:
|
||||
# validate resource address
|
||||
_, nodename, resource = subscription_helper.parse_resource_address(self.resource_address)
|
||||
if nodename != THIS_NODE_NAME and nodename != '.':
|
||||
LOG.warning("Node {} is not available".format(nodename))
|
||||
abort(404)
|
||||
if resource not in constants.VALID_SOURCE_URI:
|
||||
LOG.warning("Resource {} is not valid".format(resource))
|
||||
abort(404)
|
||||
ptpservice = PtpService(notification_control)
|
||||
ptpstatus = ptpservice.query(THIS_NODE_NAME, self.resource_address)
|
||||
return ptpstatus
|
||||
except client_exception.NodeNotAvailable as ex:
|
||||
LOG.warning("Node is not available:{0}".format(str(ex)))
|
||||
abort(404)
|
||||
except client_exception.ResourceNotAvailable as ex:
|
||||
LOG.warning("Resource is not available:{0}".format(str(ex)))
|
||||
abort(404)
|
||||
except oslo_messaging.exceptions.MessagingTimeout as ex:
|
||||
LOG.warning("Resource is not reachable:{0}".format(str(ex)))
|
||||
abort(404)
|
||||
except HTTPException as ex:
|
||||
LOG.warning("Client side error:{0},{1}".format(type(ex), str(ex)))
|
||||
# raise ex
|
||||
abort(400)
|
||||
except HTTPServerError as ex:
|
||||
LOG.error("Server side error:{0},{1}".format(type(ex), str(ex)))
|
||||
# raise ex
|
||||
abort(500)
|
||||
except Exception as ex:
|
||||
LOG.error("Exception:{0}@{1}".format(type(ex),str(ex)))
|
||||
abort(500)
|
||||
|
@ -0,0 +1,168 @@
|
||||
#
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from pecan import conf
|
||||
from pecan import expose, rest, response, abort
|
||||
from webob.exc import HTTPException, HTTPNotFound, HTTPBadRequest, HTTPClientError, HTTPServerError
|
||||
|
||||
import os
|
||||
import logging
|
||||
|
||||
from wsme import types as wtypes
|
||||
from wsmeext.pecan import wsexpose
|
||||
|
||||
from notificationclientsdk.model.dto.resourcetype import ResourceType
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV2
|
||||
|
||||
from notificationclientsdk.repository.subscription_repo import SubscriptionRepo
|
||||
from notificationclientsdk.services.ptp import PtpService
|
||||
from notificationclientsdk.exception import client_exception
|
||||
|
||||
from sidecar.repository.notification_control import notification_control
|
||||
from sidecar.repository.dbcontext_default import defaults
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
from notificationclientsdk.common.helpers import log_helper
|
||||
log_helper.config_logger(LOG)
|
||||
|
||||
THIS_NODE_NAME = os.environ.get("THIS_NODE_NAME",'controller-0')
|
||||
|
||||
class SubscriptionsControllerV2(rest.RestController):
|
||||
|
||||
@wsexpose(SubscriptionInfoV2, body=SubscriptionInfoV2, status_code=201)
|
||||
def post(self, subscription):
|
||||
# decode the request body
|
||||
try:
|
||||
if subscription.ResourceAddress:
|
||||
LOG.info(' subscribe: ResourceAddress {0} with callback uri {1}'.format(
|
||||
subscription.ResourceAddress,
|
||||
subscription.EndpointUri))
|
||||
|
||||
if not self._validateV2(subscription):
|
||||
LOG.warning(' Invalid Request data:{0}'.format(subscription.to_dict()))
|
||||
abort(400)
|
||||
|
||||
subscription.UriLocation = "{0}://{1}:{2}/ocloudNotifications/v2/subscriptions".format(
|
||||
conf.server.get('protocol','http'),
|
||||
conf.server.get('host', '127.0.0.1'),
|
||||
conf.server.get('port', '8080')
|
||||
)
|
||||
if subscription.ResourceAddress:
|
||||
ptpservice = PtpService(notification_control)
|
||||
entry = ptpservice.add_subscription(subscription)
|
||||
del ptpservice
|
||||
if not entry:
|
||||
abort(404)
|
||||
subscription.SubscriptionId = entry.SubscriptionId
|
||||
subscription.UriLocation = entry.UriLocation
|
||||
LOG.info('created subscription: {0}'.format(subscription.to_dict()))
|
||||
|
||||
return subscription
|
||||
except client_exception.InvalidSubscription as ex:
|
||||
abort(400)
|
||||
except client_exception.InvalidEndpoint as ex:
|
||||
abort(400)
|
||||
except client_exception.NodeNotAvailable as ex:
|
||||
abort(404)
|
||||
except client_exception.ResourceNotAvailable as ex:
|
||||
abort(404)
|
||||
except HTTPException as ex:
|
||||
LOG.warning("Client side error:{0},{1}".format(type(ex), str(ex)))
|
||||
abort(400)
|
||||
except HTTPServerError as ex:
|
||||
LOG.error("Server side error:{0},{1}".format(type(ex), str(ex)))
|
||||
abort(500)
|
||||
except Exception as ex:
|
||||
LOG.error("Exception:{0}@{1}".format(type(ex),str(ex)))
|
||||
abort(500)
|
||||
|
||||
@expose('json')
|
||||
def get(self):
|
||||
try:
|
||||
repo = SubscriptionRepo(defaults['dbcontext'].get_session(), autocommit = False)
|
||||
entries = repo.get(Status=1)
|
||||
response.status = 200
|
||||
subs = []
|
||||
for x in entries:
|
||||
if x.Status == 1:
|
||||
if getattr(x, 'ResourceAddress', None) is not None:
|
||||
subs.append(SubscriptionInfoV2(x).to_dict())
|
||||
return subs
|
||||
except HTTPException as ex:
|
||||
LOG.warning("Client side error:{0},{1}".format(type(ex), str(ex)))
|
||||
raise ex
|
||||
except HTTPServerError as ex:
|
||||
LOG.error("Server side error:{0},{1}".format(type(ex), str(ex)))
|
||||
raise ex
|
||||
except Exception as ex:
|
||||
LOG.error("Exception:{0}@{1}".format(type(ex),str(ex)))
|
||||
abort(500)
|
||||
|
||||
@expose()
|
||||
def _lookup(self, subscription_id, *remainder):
|
||||
return SubscriptionController(subscription_id), remainder
|
||||
|
||||
def _validateV2(self, subscription_request):
|
||||
try:
|
||||
assert subscription_request.ResourceAddress
|
||||
assert subscription_request.EndpointUri
|
||||
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
class SubscriptionController(rest.RestController):
|
||||
def __init__(self, subscription_id):
|
||||
self.subscription_id = subscription_id
|
||||
|
||||
@expose('json')
|
||||
def get(self):
|
||||
try:
|
||||
repo = SubscriptionRepo(defaults['dbcontext'].get_session(), autocommit = False)
|
||||
entry = repo.get_one(SubscriptionId=self.subscription_id, Status=1)
|
||||
|
||||
if not entry:
|
||||
abort(404)
|
||||
else:
|
||||
response.status = 200
|
||||
if getattr(entry, 'ResourceAddress', None):
|
||||
return SubscriptionInfoV2(entry).to_dict()
|
||||
|
||||
except HTTPException as ex:
|
||||
LOG.warning("Client side error:{0},{1}".format(type(ex), str(ex)))
|
||||
raise ex
|
||||
except HTTPServerError as ex:
|
||||
LOG.error("Server side error:{0},{1}".format(type(ex), str(ex)))
|
||||
raise ex
|
||||
except Exception as ex:
|
||||
LOG.error("Exception:{0}@{1}".format(type(ex),str(ex)))
|
||||
abort(500)
|
||||
|
||||
@wsexpose(status_code=204)
|
||||
def delete(self):
|
||||
try:
|
||||
repo = SubscriptionRepo(defaults['dbcontext'].get_session(), autocommit = False)
|
||||
entry = repo.get_one(SubscriptionId=self.subscription_id)
|
||||
if entry:
|
||||
if entry.SubscriptionId:
|
||||
ptpservice = PtpService(notification_control)
|
||||
ptpservice.remove_subscription(entry.SubscriptionId)
|
||||
del ptpservice
|
||||
return
|
||||
else:
|
||||
repo.delete_one(SubscriptionId=self.subscription_id)
|
||||
return
|
||||
abort(404)
|
||||
except HTTPException as ex:
|
||||
LOG.warning("Client side error:{0},{1}".format(type(ex), str(ex)))
|
||||
raise ex
|
||||
except HTTPServerError as ex:
|
||||
LOG.error("Server side error:{0},{1}".format(type(ex), str(ex)))
|
||||
raise ex
|
||||
except Exception as ex:
|
||||
LOG.error("Exception:{0}@{1}".format(type(ex),str(ex)))
|
||||
abort(500)
|
@ -4,13 +4,13 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV0
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV1
|
||||
from notificationclientsdk.model.dto.subscription import SubscriptionInfoV2
|
||||
from notificationclientsdk.model.dto.subscription import ResourceQualifierPtp
|
||||
|
||||
from pecan.jsonify import jsonify
|
||||
|
||||
@jsonify.register(SubscriptionInfoV0)
|
||||
@jsonify.register(SubscriptionInfoV1)
|
||||
def jsonify_subscriptioninfo(subscriptionInfo):
|
||||
return subscriptionInfo.to_dict()
|
||||
|
||||
@ -18,7 +18,7 @@ def jsonify_subscriptioninfo(subscriptionInfo):
|
||||
def jsonify_resourcequalifierptp(resourceQualifierPtp):
|
||||
return resourceQualifierPtp.to_dict()
|
||||
|
||||
@jsonify.register(SubscriptionInfoV1)
|
||||
@jsonify.register(SubscriptionInfoV2)
|
||||
def jsonify_subscriptioninfo(subscriptionInfo):
|
||||
return subscriptionInfo.to_dict()
|
||||
|
||||
|
@ -11,6 +11,7 @@ RUN set -ex ;\
|
||||
-y \
|
||||
gcc python3-devel python3-pip \
|
||||
&& pip3 install --user pecan \
|
||||
&& pip3 install pygtail \
|
||||
&& pip3 install oslo-config \
|
||||
&& pip3 install oslo-messaging \
|
||||
&& pip3 install WSME
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
@ -37,7 +37,7 @@ class PtpEventProducer(object):
|
||||
return None
|
||||
|
||||
def TriggerDelivery(self, ctx, **rpc_kwargs):
|
||||
LOG.debug ("PtpEventProducer TriggerDelivery called %s" %rpc_kwargs)
|
||||
LOG.debug("PtpEventProducer TriggerDelivery called %s" %rpc_kwargs)
|
||||
if self.handler:
|
||||
return self.handler.trigger_delivery(**rpc_kwargs)
|
||||
else:
|
||||
@ -71,10 +71,10 @@ class PtpEventProducer(object):
|
||||
result2 = self.publish_status_all(ptpstatus, retry) if self.registration_broker_client else result
|
||||
return result1, result2
|
||||
|
||||
def publish_status_local(self, ptpstatus, retry=3):
|
||||
def publish_status_local(self, ptpstatus, source, retry=3):
|
||||
if not self.local_broker_client:
|
||||
return False
|
||||
topic='PTP-Event-{0}'.format(self.node_name)
|
||||
topic='{0}-Event-{1}'.format(source, self.node_name)
|
||||
server = None
|
||||
isretrystopped = False
|
||||
while not isretrystopped:
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
@ -46,3 +46,20 @@ PHC2SYS_TOLERANCE_HIGH = 37000001000
|
||||
|
||||
# testing values
|
||||
CGU_PATH_VALID = "/sys/kernel/debug/ice/0000:18:00.0/cgu"
|
||||
|
||||
SPEC_VERSION = "1.0"
|
||||
DATA_VERSION = "1.0"
|
||||
DATA_TYPE_NOTIFICATION = "notification"
|
||||
DATA_TYPE_METRIC = "metric"
|
||||
VALUE_TYPE_ENUMERATION = "enumeration"
|
||||
VALUE_TYPE_METRIC = "metric"
|
||||
|
||||
SOURCE_SYNC_ALL = '/sync'
|
||||
SOURCE_SYNC_GNSS_SYNC_STATUS = '/sync/gnss-status/gnss-sync-status'
|
||||
SOURCE_SYNC_PTP_CLOCK_CLASS = '/sync/ptp-status/clock-class'
|
||||
SOURCE_SYNC_PTP_LOCK_STATE = '/sync/ptp-status/lock-state'
|
||||
SOURCE_SYNC_OS_CLOCK = '/sync/sync-status/os-clock-sync-state'
|
||||
SOURCE_SYNC_SYNC_STATE = '/sync/sync-status/sync-state'
|
||||
SOURCE_SYNCE_CLOCK_QUALITY = '/sync/synce-status/clock-quality'
|
||||
SOURCE_SYNCE_LOCK_STATE_EXTENDED = '/sync/synce-status/lock-state-extended'
|
||||
SOURCE_SYNCE_LOCK_STATE = '/sync/synce-status/lock-state'
|
||||
|
@ -1,6 +1,6 @@
|
||||
#! /usr/bin/python3
|
||||
#
|
||||
# Copyright (c) 2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
@ -14,6 +14,7 @@
|
||||
#
|
||||
import errno, os
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
import datetime
|
||||
@ -196,3 +197,17 @@ def ptp_status(holdover_time, freq, sync_state, event_time):
|
||||
else:
|
||||
new_event = "false"
|
||||
return new_event, sync_state, event_time
|
||||
|
||||
def parse_resource_address(resource_address):
|
||||
# The format of resource address is:
|
||||
# /{clusterName}/{siteName}(/optional/hierarchy/..)/{nodeName}/{resource}
|
||||
# Assume no optional hierarchy for now
|
||||
clusterName = resource_address.split('/')[1]
|
||||
nodeName = resource_address.split('/')[2]
|
||||
resource_path = '/' + re.split('[/]', resource_address, 3)[3]
|
||||
return clusterName, nodeName, resource_path
|
||||
|
||||
def format_resource_address(node_name, resource):
|
||||
# Return a resource_address
|
||||
resource_address = '/./' + node_name + resource
|
||||
return resource_address
|
||||
|
@ -9,12 +9,15 @@ import json
|
||||
import time
|
||||
import oslo_messaging
|
||||
from oslo_config import cfg
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
import logging
|
||||
|
||||
import multiprocessing as mp
|
||||
import threading
|
||||
|
||||
from trackingfunctionsdk.client.ptpeventproducer import PtpEventProducer
|
||||
from trackingfunctionsdk.common.helpers import constants
|
||||
from trackingfunctionsdk.common.helpers import ptpsync
|
||||
from trackingfunctionsdk.common.helpers import log_helper
|
||||
from trackingfunctionsdk.common.helpers.dmesg_watcher import DmesgWatcher
|
||||
@ -36,6 +39,18 @@ log_helper.config_logger(LOG)
|
||||
|
||||
THIS_NODE_NAME = os.environ.get("THIS_NODE_NAME",'controller-0')
|
||||
|
||||
# Event source to event type mapping
|
||||
source_type = {
|
||||
'/sync/gnss-status/gnss-sync-status': 'event.sync.gnss-status.gnss-state-change',
|
||||
'/sync/ptp-status/clock-class': 'event.sync.ptp-status.ptp-clock-class-change',
|
||||
'/sync/ptp-status/lock-state': 'event.sync.ptp-status.ptp-state-change',
|
||||
'/sync/sync-status/os-clock-sync-state': 'event.sync.sync-status.os-clock-sync-state-change',
|
||||
'/sync/sync-status/sync-state': 'event.sync.sync-status.synchronization-state-change',
|
||||
'/sync/synce-status/clock-quality': 'event.sync.synce-status.synce-clock-quality-change',
|
||||
'/sync/synce-status/lock-state-extended': 'event.sync.synce-status.synce-state-change-extended',
|
||||
'/sync/synce-status/lock-state': 'event.sync.synce-status.synce-state-change',
|
||||
'/sync/synce-status/lock-state': 'event.sync.synce-status.synce-state-change',
|
||||
}
|
||||
|
||||
'''Entry point of Default Process Worker'''
|
||||
def ProcessWorkerDefault(event, sqlalchemy_conf_json, broker_transport_endpoint):
|
||||
@ -61,16 +76,38 @@ class PtpWatcherDefault:
|
||||
last_event_time = self.watcher.ptptracker_context.get('last_event_time', time.time())
|
||||
self.watcher.ptptracker_context_lock.release()
|
||||
|
||||
lastStatus = {
|
||||
'ResourceType': ResourceType.TypePTP,
|
||||
'EventData': {
|
||||
'State': sync_state
|
||||
},
|
||||
'ResourceQualifier': {
|
||||
'NodeName': self.watcher.node_name
|
||||
},
|
||||
'EventTimestamp': last_event_time
|
||||
}
|
||||
resource_address = rpc_kwargs.get('ResourceAddress', None)
|
||||
if resource_address:
|
||||
_, nodename, resource_path = ptpsync.parse_resource_address(resource_address)
|
||||
lastStatus = {
|
||||
'id': uuidutils.generate_uuid(),
|
||||
'specversion': constants.SPEC_VERSION,
|
||||
'source': resource_path,
|
||||
'type': source_type[resource_path],
|
||||
'time': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(last_event_time)),
|
||||
'data': {
|
||||
'version': constants.DATA_VERSION,
|
||||
'values': [
|
||||
{
|
||||
'data_type': constants.DATA_TYPE_NOTIFICATION,
|
||||
'ResourceAddress': resource_address,
|
||||
'value_type': constants.VALUE_TYPE_ENUMERATION,
|
||||
'value': sync_state
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
else:
|
||||
lastStatus = {
|
||||
'ResourceType': ResourceType.TypePTP,
|
||||
'EventData': {
|
||||
'State': sync_state
|
||||
},
|
||||
'ResourceQualifier': {
|
||||
'NodeName': self.watcher.node_name
|
||||
},
|
||||
'EventTimestamp': last_event_time
|
||||
}
|
||||
return lastStatus
|
||||
|
||||
def trigger_delivery(self, **rpc_kwargs):
|
||||
@ -183,7 +220,7 @@ class PtpWatcherDefault:
|
||||
holdover_time, freq, sync_state, last_event_time)
|
||||
return new_event, sync_state, new_event_time
|
||||
|
||||
'''announce location'''
|
||||
'''publish ptp status'''
|
||||
def __publish_ptpstatus(self, forced=False):
|
||||
holdover_time = float(self.ptptracker_context['holdover_seconds'])
|
||||
freq = float(self.ptptracker_context['poll_freq_seconds'])
|
||||
@ -200,7 +237,7 @@ class PtpWatcherDefault:
|
||||
self.ptptracker_context['last_event_time'] = new_event_time
|
||||
self.ptptracker_context_lock.release()
|
||||
|
||||
# publish new event
|
||||
# publish new event in API version v1 format
|
||||
LOG.debug("publish ptp status to clients")
|
||||
lastStatus = {
|
||||
'ResourceType': 'PTP',
|
||||
@ -212,7 +249,31 @@ class PtpWatcherDefault:
|
||||
},
|
||||
'EventTimestamp': new_event_time
|
||||
}
|
||||
self.ptpeventproducer.publish_status(lastStatus)
|
||||
self.ptpeventproducer.publish_status(lastStatus, 'PTP')
|
||||
|
||||
# publish new event in API version v2 format
|
||||
resource_address = ptpsync.format_resource_address(
|
||||
self.node_name, constants.SOURCE_SYNC_SYNC_STATE)
|
||||
lastStatus = {
|
||||
'id': uuidutils.generate_uuid(),
|
||||
'specversion': constants.SPEC_VERSION,
|
||||
'source': constants.SOURCE_SYNC_SYNC_STATE,
|
||||
'type': source_type[constants.SOURCE_SYNC_SYNC_STATE],
|
||||
'time': new_event_time,
|
||||
'data': {
|
||||
'version': constants.DATA_VERSION,
|
||||
'values': [
|
||||
{
|
||||
'data_type': constants.DATA_TYPE_NOTIFICATION,
|
||||
'ResourceAddress': resource_address,
|
||||
'value_type': constants.VALUE_TYPE_ENUMERATION,
|
||||
'value': sync_state
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
self.ptpeventproducer.publish_status(lastStatus, constants.SOURCE_SYNC_SYNC_STATE)
|
||||
self.ptpeventproducer.publish_status(lastStatus, constants.SOURCE_SYNC_ALL)
|
||||
return
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user