Merge "Allow subscription to all nodes with '*'"

This commit is contained in:
Zuul 2022-11-22 21:16:20 +00:00 committed by Gerrit Code Review
commit 305c706a05
5 changed files with 229 additions and 142 deletions

View File

@ -44,3 +44,6 @@ VALID_SOURCE_URI = {
SOURCE_SYNCE_LOCK_STATE_EXTENDED, SOURCE_SYNCE_LOCK_STATE_EXTENDED,
SOURCE_SYNCE_LOCK_STATE SOURCE_SYNCE_LOCK_STATE
} }
WILDCARD_CURRENT_NODE = '.'
WILDCARD_ALL_NODES = '*'

View File

@ -4,11 +4,16 @@
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
import json import logging
from notificationclientsdk.repository.node_repo import NodeRepo from notificationclientsdk.repository.node_repo import NodeRepo
from notificationclientsdk.common.helpers import constants
from notificationclientsdk.common.helpers import log_helper
LOG = logging.getLogger(__name__)
log_helper.config_logger(LOG)
class NodeInfoHelper(object): class NodeInfoHelper(object):
BROKER_NODE_ALL = '*'
residing_node_name = None residing_node_name = None
@staticmethod @staticmethod
@ -22,25 +27,23 @@ class NodeInfoHelper(object):
@staticmethod @staticmethod
def expand_node_name(node_name_pattern): def expand_node_name(node_name_pattern):
if node_name_pattern == '.': if node_name_pattern == constants.WILDCARD_CURRENT_NODE:
return NodeInfoHelper.residing_node_name return NodeInfoHelper.residing_node_name
elif node_name_pattern == NodeInfoHelper.BROKER_NODE_ALL:
return NodeInfoHelper.BROKER_NODE_ALL
else: else:
return node_name_pattern return node_name_pattern
@staticmethod @staticmethod
def default_node_name(node_name_pattern): def default_node_name(node_name_pattern):
if node_name_pattern == '.' or node_name_pattern == '*': if node_name_pattern == constants.WILDCARD_CURRENT_NODE:
return NodeInfoHelper.residing_node_name return NodeInfoHelper.residing_node_name
else: else:
return node_name_pattern return node_name_pattern
@staticmethod @staticmethod
def match_node_name(node_name_pattern, target_node_name): def match_node_name(node_name_pattern, target_node_name):
if node_name_pattern == '*': if node_name_pattern == constants.WILDCARD_ALL_NODES:
return True return True
elif node_name_pattern == '.': elif node_name_pattern == constants.WILDCARD_CURRENT_NODE:
return NodeInfoHelper.residing_node_name == target_node_name return NodeInfoHelper.residing_node_name == target_node_name
else: else:
return node_name_pattern == target_node_name return node_name_pattern == target_node_name
@ -58,14 +61,16 @@ class NodeInfoHelper(object):
try: try:
nodeinfo_repo = NodeRepo(autocommit=True) nodeinfo_repo = NodeRepo(autocommit=True)
filter = {} filter = {}
if node_name_pattern == '*': if node_name_pattern == constants.WILDCARD_ALL_NODES:
pass pass
elif not node_name_pattern or node_name_pattern == '.': elif not node_name_pattern or \
filter = { 'NodeName': NodeInfoHelper.residing_node_name } node_name_pattern == constants.WILDCARD_CURRENT_NODE:
filter = {'NodeName': NodeInfoHelper.residing_node_name}
else: else:
filter = { 'NodeName': node_name_pattern } filter = {'NodeName': node_name_pattern}
nodeinfos = [x.NodeName for x in nodeinfo_repo.get(Status=1, **filter)] nodeinfos = [x.NodeName
for x in nodeinfo_repo.get(Status=1, **filter)]
except Exception as ex: except Exception as ex:
LOG.warning("Failed to enumerate nodes:{0}".format(str(ex))) LOG.warning("Failed to enumerate nodes:{0}".format(str(ex)))

View File

@ -8,21 +8,20 @@ import time
import oslo_messaging import oslo_messaging
import logging import logging
from notificationclientsdk.model.dto.rpc_endpoint import RpcEndpointInfo from notificationclientsdk.model.dto.rpc_endpoint import RpcEndpointInfo
from notificationclientsdk.common.helpers.nodeinfo_helper import NodeInfoHelper from notificationclientsdk.common.helpers import constants
from notificationclientsdk.model.dto.broker_state import BrokerState from notificationclientsdk.common.helpers import log_helper
from notificationclientsdk.client.locationservice import LocationServiceClient from notificationclientsdk.client.locationservice import LocationServiceClient
from notificationclientsdk.client.notificationservice import NotificationServiceClient from notificationclientsdk.client.notificationservice \
import NotificationServiceClient
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
from notificationclientsdk.common.helpers import log_helper
log_helper.config_logger(LOG) log_helper.config_logger(LOG)
class BrokerConnectionManager: class BrokerConnectionManager:
def __init__(self, broker_location_handler, notification_handler, broker_connection_contexts): def __init__(self, broker_location_handler, notification_handler,
broker_connection_contexts):
''' '''
broker_watchers: { broker_watchers: {
"<broker name1>": { "<broker name1>": {
@ -37,7 +36,8 @@ class BrokerConnectionManager:
self.registration_endpoint = RpcEndpointInfo( self.registration_endpoint = RpcEndpointInfo(
self.shared_broker_context['REGISTRATION_TRANSPORT_ENDPOINT']) self.shared_broker_context['REGISTRATION_TRANSPORT_ENDPOINT'])
self.broker_watchers = {} self.broker_watchers = {}
self.location_watcher = LocationServiceClient(self.registration_endpoint.TransportEndpoint) self.location_watcher = LocationServiceClient(
self.registration_endpoint.TransportEndpoint)
self.__broker_location_handler = broker_location_handler self.__broker_location_handler = broker_location_handler
self.__notification_handler = notification_handler self.__notification_handler = notification_handler
@ -71,42 +71,50 @@ class BrokerConnectionManager:
self.location_watcher.add_location_listener( self.location_watcher.add_location_listener(
broker_name, broker_name,
location_handler=self.__broker_location_handler) location_handler=self.__broker_location_handler)
LOG.debug("Start watching location announcement of notificationservice@{0}" LOG.debug("Start watching location announcement of "
.format(broker_name)) "notificationservice@{0}".format(broker_name))
# try to update location by query # try to update location by query
try: try:
location_info = self.location_watcher.query_location(broker_name, timeout=5, retry=2) location_info = self.location_watcher.query_location(
LOG.debug("Pulled location info@{0}:{1}".format(broker_name, location_info)) broker_name, timeout=5, retry=2)
LOG.debug("Pulled location info@{0}:{1}".format(
broker_name, location_info))
if location_info: if location_info:
podip = location_info.get("PodIP", None) podip = location_info.get("PodIP", None)
resourcetypes = location_info.get("ResourceTypes", None) resourcetypes = location_info.get("ResourceTypes",
None)
brokerstate.update_broker_ip(podip) brokerstate.update_broker_ip(podip)
brokerstate.update_resources(resourcetypes) brokerstate.update_resources(resourcetypes)
else: else:
return False return False
except Exception as ex: except Exception as ex:
LOG.warning("Failed to update location of node:{0} due to: {1}".format( LOG.warning("Failed to update location of node:{0} "
broker_name, str(ex))) "due to: {1}".format(broker_name, str(ex)))
raise ex raise ex
# 2, create broker connection # 2, create broker connection
broker_watcher = self.broker_watchers.get(broker_name, {}) broker_watcher = self.broker_watchers.get(broker_name, {})
broker_client = broker_watcher.get("broker_client", None) broker_client = broker_watcher.get("broker_client", None)
if not broker_client: if not broker_client:
LOG.debug("Start watching notifications from notificationservice@{0}".format(broker_name)) LOG.debug("Start watching notifications from "
broker_client = self.__create_client(broker_name, brokerstate.BrokerIP) "notificationservice@{0}".format(broker_name))
broker_client = self.__create_client(broker_name,
brokerstate.BrokerIP)
broker_watcher["broker_client"] = broker_client broker_watcher["broker_client"] = broker_client
self.broker_watchers[broker_name] = broker_watcher self.broker_watchers[broker_name] = broker_watcher
# 3, update watching resources # 3, update watching resources
result = self.__update_watching_resources(broker_watcher, broker_client, brokerstate) result = self.__update_watching_resources(broker_watcher,
broker_client,
brokerstate)
return result return result
except Exception as ex: except Exception as ex:
LOG.warning("failed to start watching:{0},{1}".format( LOG.warning("failed to start watching:{0},{1}".format(
brokerstate, str(ex))) brokerstate, str(ex)))
return False return False
def __stop_watching_broker_resource(self, broker_client, broker_name, resource_type): def __stop_watching_broker_resource(self, broker_client, broker_name,
resource_type):
try: try:
if broker_client.is_listening_on_resource(resource_type): if broker_client.is_listening_on_resource(resource_type):
broker_client.remove_resource_status_listener(resource_type) broker_client.remove_resource_status_listener(resource_type)
@ -116,12 +124,14 @@ class BrokerConnectionManager:
broker_name, resource_type, str(ex))) broker_name, resource_type, str(ex)))
return False return False
def __start_watching_broker_resource(self, broker_client, broker_name, resource_type): def __start_watching_broker_resource(self, broker_client, broker_name,
resource_type):
try: try:
if not broker_client.is_listening_on_resource(resource_type): if not broker_client.is_listening_on_resource(resource_type):
broker_client.add_resource_status_listener( broker_client.add_resource_status_listener(
resource_type, status_handler=self.__notification_handler) resource_type, status_handler=self.__notification_handler)
LOG.debug("Start watching {0}@{1}".format(resource_type, broker_name)) LOG.debug("Start watching {0}@{1}".format(resource_type,
broker_name))
return True return True
except Exception as ex: except Exception as ex:
@ -135,7 +145,7 @@ class BrokerConnectionManager:
if self.location_watcher.is_listening_on_location(broker_name): if self.location_watcher.is_listening_on_location(broker_name):
self.location_watcher.remove_location_listener(broker_name) self.location_watcher.remove_location_listener(broker_name)
LOG.debug("Stop watching location announcement for broker@{0}" LOG.debug("Stop watching location announcement for broker@{0}"
.format(broker_name)) "".format(broker_name))
# 2, remove broker client # 2, remove broker client
broker_watcher = self.broker_watchers.get(broker_name, {}) broker_watcher = self.broker_watchers.get(broker_name, {})
@ -145,7 +155,8 @@ class BrokerConnectionManager:
del broker_client del broker_client
broker_client = None broker_client = None
self.broker_watchers.pop(broker_name, None) self.broker_watchers.pop(broker_name, None)
LOG.debug("Stop watching notificationservice@{0}".format(broker_name)) LOG.debug("Stop watching notificationservice@{0}".format(
broker_name))
return True return True
except Exception as ex: except Exception as ex:
@ -156,7 +167,8 @@ class BrokerConnectionManager:
def restart_watching_broker(self, brokerstate): def restart_watching_broker(self, brokerstate):
try: try:
broker_name = brokerstate.BrokerName broker_name = brokerstate.BrokerName
LOG.debug("Try to restart watching notificationservice@{0}".format(broker_name)) LOG.debug("Try to restart watching notificationservice@{0}".format(
broker_name))
broker_watcher = self.broker_watchers.get(broker_name, {}) broker_watcher = self.broker_watchers.get(broker_name, {})
broker_client = broker_watcher.get("broker_client", None) broker_client = broker_watcher.get("broker_client", None)
if broker_client: if broker_client:
@ -172,10 +184,13 @@ class BrokerConnectionManager:
def update_watching_resources(self, brokerstate): def update_watching_resources(self, brokerstate):
try: try:
broker_watcher = self.broker_watchers.get(brokerstate.BrokerName, {}) broker_watcher = self.broker_watchers.get(brokerstate.BrokerName,
{})
broker_client = broker_watcher.get("broker_client", None) broker_client = broker_watcher.get("broker_client", None)
if broker_client: if broker_client:
result = self.__update_watching_resources(broker_watcher, broker_client, brokerstate) result = self.__update_watching_resources(broker_watcher,
broker_client,
brokerstate)
return result return result
return False return False
except Exception as ex: except Exception as ex:
@ -183,26 +198,32 @@ class BrokerConnectionManager:
brokerstate, str(ex))) brokerstate, str(ex)))
return False return False
def __update_watching_resources(self, broker_watcher, broker_client, brokerstate): def __update_watching_resources(self, broker_watcher, broker_client,
brokerstate):
try: try:
result = True result = True
# 1, filter out those unsubscribed resources # 1, filter out those unsubscribed resources
subscribed_resource_list = broker_watcher.get("subscribed_resource_list",[]) subscribed_resource_list = broker_watcher.get(
"subscribed_resource_list", [])
if subscribed_resource_list != brokerstate.ResourceTypesSubscribed: if subscribed_resource_list != brokerstate.ResourceTypesSubscribed:
# stop watching those uninterested # stop watching those uninterested
for resource_type in subscribed_resource_list: for resource_type in subscribed_resource_list:
if resource_type not in brokerstate.ResourceTypesSubscribed: if resource_type not in \
brokerstate.ResourceTypesSubscribed:
result = self.__stop_watching_broker_resource( result = self.__stop_watching_broker_resource(
broker_client, brokerstate.BrokerName, resource_type) broker_client, brokerstate.BrokerName,
resource_type)
# 2, update the list # 2, update the list
subscribed_resource_list = brokerstate.ResourceTypesSubscribed subscribed_resource_list = brokerstate.ResourceTypesSubscribed
broker_watcher["subscribed_resource_list"] = subscribed_resource_list broker_watcher["subscribed_resource_list"] = \
subscribed_resource_list
# 3, start watching the subscribed resources # 3, start watching the subscribed resources
for resource_type in subscribed_resource_list: for resource_type in subscribed_resource_list:
result = self.__start_watching_broker_resource( result = self.__start_watching_broker_resource(
broker_client, brokerstate.BrokerName, resource_type) and result broker_client, brokerstate.BrokerName, resource_type) and \
result
return result return result
except Exception as ex: except Exception as ex:
LOG.warning("failed to update resources:{0},{1}".format( LOG.warning("failed to update resources:{0},{1}".format(
@ -221,8 +242,9 @@ class BrokerConnectionManager:
resource_type) if broker_client else False resource_type) if broker_client else False
def __create_client(self, broker_name, broker_pod_ip): def __create_client(self, broker_name, broker_pod_ip):
if broker_name == NodeInfoHelper.BROKER_NODE_ALL: if broker_name == constants.WILDCARD_ALL_NODES:
# special case: if monitor all node, then use the same broker as locationservice # special case: if monitor all node, then use the same broker as
# locationservice
return self.location_watcher return self.location_watcher
broker_host = "[{0}]".format(broker_pod_ip) broker_host = "[{0}]".format(broker_pod_ip)
broker_transport_endpoint = "rabbit://{0}:{1}@{2}:{3}".format( broker_transport_endpoint = "rabbit://{0}:{1}@{2}:{3}".format(
@ -230,31 +252,34 @@ class BrokerConnectionManager:
self.shared_broker_context['NOTIFICATION_BROKER_PASS'], self.shared_broker_context['NOTIFICATION_BROKER_PASS'],
broker_host, broker_host,
self.shared_broker_context['NOTIFICATION_BROKER_PORT']) self.shared_broker_context['NOTIFICATION_BROKER_PORT'])
return NotificationServiceClient(broker_name, broker_transport_endpoint, broker_pod_ip) return NotificationServiceClient(broker_name,
broker_transport_endpoint,
broker_pod_ip)
def __start_watch_all_nodes(self, retry_interval=5): def __start_watch_all_nodes(self, retry_interval=5):
try: try:
LOG.debug( LOG.debug("Start watching location announcement of "
"Start watching location announcement of notificationservice@{0}" "notificationservice@{0}".format(
.format(NodeInfoHelper.BROKER_NODE_ALL)) constants.WILDCARD_ALL_NODES))
while not self.location_watcher.is_listening_on_location( while not self.location_watcher.is_listening_on_location(
NodeInfoHelper.BROKER_NODE_ALL): constants.WILDCARD_ALL_NODES):
# start watching on the location announcement # start watching on the location announcement
self.location_watcher.add_location_listener( self.location_watcher.add_location_listener(
NodeInfoHelper.BROKER_NODE_ALL, constants.WILDCARD_ALL_NODES,
location_handler=self.__broker_location_handler) location_handler=self.__broker_location_handler)
if not self.location_watcher.is_listening_on_location( if not self.location_watcher.is_listening_on_location(
NodeInfoHelper.BROKER_NODE_ALL): constants.WILDCARD_ALL_NODES):
# retry later and forever # retry later and forever
LOG.debug( LOG.debug(
"Retry indefinitely to start listening to {0}..." "Retry indefinitely to start listening to {0}..."
.format(NodeInfoHelper.BROKER_NODE_ALL)) .format(constants.WILDCARD_ALL_NODES))
time.sleep(retry_interval) time.sleep(retry_interval)
LOG.debug( LOG.debug(
"Trigger the location announcement of notificationservice@{0}" "Trigger the location announcement of notificationservice@{0}"
.format(NodeInfoHelper.BROKER_NODE_ALL)) .format(constants.WILDCARD_ALL_NODES))
self.location_watcher.trigger_location_annoucement(timeout=20, retry=10) self.location_watcher.trigger_location_annoucement(timeout=20,
retry=10)
except Exception as ex: except Exception as ex:
LOG.warning("exception: {0}".format(str(ex))) LOG.warning("exception: {0}".format(str(ex)))
pass pass
@ -265,11 +290,13 @@ class BrokerConnectionManager:
def __stop_watch_all_nodes(self): def __stop_watch_all_nodes(self):
pass pass
def __syncup_data_by_resourcetype(self, broker_client, broker_name, resource_type): def __syncup_data_by_resourcetype(self, broker_client, broker_name,
resource_type):
# check to sync up resource status on a node # check to sync up resource status on a node
LOG.debug("try to sync up data for {0}@{1}".format(resource_type, broker_name)) LOG.debug("try to sync up data for {0}@{1}".format(
resource_type, broker_name))
try: try:
if broker_name == NodeInfoHelper.BROKER_NODE_ALL: if broker_name == constants.WILDCARD_ALL_NODES:
self.location_watcher.trigger_publishing_status( self.location_watcher.trigger_publishing_status(
resource_type, timeout=5, retry=10) resource_type, timeout=5, retry=10)
return True return True
@ -277,11 +304,13 @@ class BrokerConnectionManager:
# 1, query resource status # 1, query resource status
broker_client = self.broker_watchers.get(broker_name, None) broker_client = self.broker_watchers.get(broker_name, None)
if not broker_client: if not broker_client:
raise Exception("watcher is not ready for broker: {0}".format(broker_name)) raise Exception("watcher is not ready for broker: {0}".format(
broker_name))
resource_status = broker_client.query_resource_status( resource_status = broker_client.query_resource_status(
resource_type, timeout=5, retry=10) resource_type, timeout=5, retry=10)
# 2, deliver resource by comparing LastDelivery time with EventTimestamp # 2, deliver resource by comparing LastDelivery time with
# EventTimestamp
# 3, update the LastDelivery with EventTimestamp # 3, update the LastDelivery with EventTimestamp
self.__notification_handler.handle(resource_status) self.__notification_handler.handle(resource_status)
except oslo_messaging.exceptions.MessagingTimeout as ex: except oslo_messaging.exceptions.MessagingTimeout as ex:
@ -302,7 +331,8 @@ class BrokerConnectionManager:
try: try:
broker_watcher = self.broker_watchers.get(broker_name, {}) broker_watcher = self.broker_watchers.get(broker_name, {})
broker_client = broker_watcher.get("broker_client", None) broker_client = broker_watcher.get("broker_client", None)
subscribed_resource_list = broker_watcher.get("subscribed_resource_list",[]) subscribed_resource_list = broker_watcher.get(
"subscribed_resource_list", [])
for resource_type in subscribed_resource_list: for resource_type in subscribed_resource_list:
if not brokerstate.is_data_syncup(resource_type): if not brokerstate.is_data_syncup(resource_type):
continue continue

View File

@ -129,34 +129,119 @@ class PtpService(object):
def add_subscription(self, subscription_dto): def add_subscription(self, subscription_dto):
resource_address = None resource_address = None
if hasattr(subscription_dto, 'ResourceAddress'): if hasattr(subscription_dto, 'ResourceAddress'):
version = 2
_, nodename, _, _, _ = subscription_helper.parse_resource_address( _, nodename, _, _, _ = subscription_helper.parse_resource_address(
subscription_dto.ResourceAddress) subscription_dto.ResourceAddress)
broker_name = nodename LOG.debug("nodename in ResourceAddress is '%s', residing is %s" %
(nodename, self.daemon_control.get_residing_nodename()))
resource_address = subscription_dto.ResourceAddress resource_address = subscription_dto.ResourceAddress
LOG.debug('Looking for existing subscription for EndpointUri %s '
'ResourceAddress %s' % (subscription_dto.EndpointUri,
resource_address))
entry = self.subscription_repo.get_one(
EndpointUri=subscription_dto.EndpointUri,
ResourceAddress=resource_address)
if entry is None:
# Did not find matched duplicated, but needs to look for other
# cases...
if nodename != constants.WILDCARD_ALL_NODES:
# There may be a subscription for all nodes already in
# place
resource_address_star = \
subscription_helper.set_nodename_in_resource_address(
resource_address, constants.WILDCARD_ALL_NODES)
LOG.debug('Additional lookup for existing subscription '
'for EndpointUri %s ResourceAddress %s'
% (subscription_dto.EndpointUri,
resource_address_star))
if self.subscription_repo.get_one(
EndpointUri=subscription_dto.EndpointUri,
ResourceAddress=resource_address_star) is not None:
LOG.debug('Found existing %s entry in subscription '
'repo' % constants.WILDCARD_ALL_NODES)
raise client_exception.ServiceError(409)
if nodename == constants.WILDCARD_CURRENT_NODE:
# There may be a subscription for the residing (current)
# node already in place
resource_address_synonym = \
subscription_helper.set_nodename_in_resource_address(
resource_address,
self.daemon_control.get_residing_nodename())
LOG.debug('In addition, looking for existing subscription '
'for EndpointUri %s ResourceAddress %s' % (
subscription_dto.EndpointUri,
resource_address_synonym))
entry = self.subscription_repo.get_one(
EndpointUri=subscription_dto.EndpointUri,
ResourceAddress=resource_address_synonym)
if nodename == self.daemon_control.get_residing_nodename():
# There may be a subscription for '.' (current node)
# already in place
resource_address_synonym = \
subscription_helper.set_nodename_in_resource_address(
resource_address, constants.WILDCARD_CURRENT_NODE)
LOG.debug('In addition, looking for existing subscription '
'for EndpointUri %s ResourceAddress %s' % (
subscription_dto.EndpointUri,
resource_address_synonym))
entry = self.subscription_repo.get_one(
EndpointUri=subscription_dto.EndpointUri,
ResourceAddress=resource_address_synonym)
if entry is not None:
LOG.debug('Found existing v2 entry in subscription repo')
raise client_exception.ServiceError(409)
if nodename == constants.WILDCARD_ALL_NODES:
broker_names = self.daemon_control.list_of_service_nodenames()
else:
broker_names = [nodename]
elif hasattr(subscription_dto, 'ResourceType'): elif hasattr(subscription_dto, 'ResourceType'):
broker_name = subscription_dto.ResourceQualifier.NodeName version = 1
default_node_name = NodeInfoHelper.default_node_name(broker_name)
broker_pod_ip, supported_resource_types = self.__get_node_info( resource_qualifier_dto = \
default_node_name) subscription_dto.ResourceQualifier.to_dict()
LOG.debug('Looking for existing subscription for EndpointUri %s '
'ResourceQualifier %s' % (subscription_dto.EndpointUri,
resource_qualifier_dto))
entries = self.subscription_repo.get(
EndpointUri=subscription_dto.EndpointUri)
for entry in entries:
resource_qualifier_json = entry.ResourceQualifierJson or '{}'
resource_qualifier_repo = json.loads(resource_qualifier_json)
if resource_qualifier_dto == resource_qualifier_repo:
LOG.debug('Found existing v1 entry in subscription repo')
raise client_exception.ServiceError(409)
if not broker_pod_ip: broker_names = [subscription_dto.ResourceQualifier.NodeName]
LOG.warning("Node {0} is not available yet".format(
default_node_name))
raise client_exception.NodeNotAvailable(broker_name)
if ResourceType.TypePTP not in supported_resource_types: nodes = {} # node-ptpstatus pairs
LOG.warning("Resource {0}@{1} is not available yet".format( for broker in broker_names:
ResourceType.TypePTP, default_node_name)) default_node_name = NodeInfoHelper.default_node_name(broker)
raise client_exception.ResourceNotAvailable(broker_name, broker_pod_ip, supported_resource_types = self.__get_node_info(
ResourceType.TypePTP) default_node_name)
# get initial resource status if not broker_pod_ip:
if default_node_name: LOG.warning("Node {0} is not available yet".format(
ptpstatus = None default_node_name))
raise client_exception.NodeNotAvailable(broker)
if ResourceType.TypePTP not in supported_resource_types:
LOG.warning("Resource {0}@{1} is not available yet".format(
ResourceType.TypePTP, default_node_name))
raise client_exception.ResourceNotAvailable(
broker, ResourceType.TypePTP)
# get initial resource status
ptpstatus = self._query(default_node_name, broker_pod_ip, ptpstatus = self._query(default_node_name, broker_pod_ip,
resource_address, optional=None) resource_address, optional=None)
LOG.info("initial ptpstatus:{0}".format(ptpstatus)) LOG.info("Initial ptpstatus for {0}:{1}".format(default_node_name,
ptpstatus))
# construct subscription entry # construct subscription entry
if constants.PTP_V1_KEY in ptpstatus: if constants.PTP_V1_KEY in ptpstatus:
@ -171,74 +256,38 @@ class PtpService(object):
ptpstatus[item]['time']).strftime( ptpstatus[item]['time']).strftime(
'%Y-%m-%dT%H:%M:%S%fZ') '%Y-%m-%dT%H:%M:%S%fZ')
# avoid duplicated subscription nodes[default_node_name] = ptpstatus
entry = None
if hasattr(subscription_dto, 'ResourceType'):
version = 1
resource_qualifier_dto = \
subscription_dto.ResourceQualifier.to_dict()
LOG.debug('Looking for existing subscription for '
'EndpointUri %s ResourceQualifier %s'
% (subscription_dto.EndpointUri,
resource_qualifier_dto))
entries = self.subscription_repo.get(
EndpointUri=subscription_dto.EndpointUri
)
for e in entries:
resource_qualifier_json = e.ResourceQualifierJson or '{}'
resource_qualifier_repo = json.loads(
resource_qualifier_json)
if resource_qualifier_dto == resource_qualifier_repo:
entry = e
break
else:
version = 2
# Replace eventual '.' in ResourceAddress by the actual subscription_orm = SubscriptionOrm(**subscription_dto.to_orm())
# nodename subscription_orm.InitialDeliveryTimestamp = timestamp
subscription_dto.ResourceAddress = \ entry = self.subscription_repo.add(subscription_orm)
subscription_helper.set_nodename_in_resource_address(
subscription_dto.ResourceAddress, default_node_name)
LOG.debug('Looking for existing subscription for ' # Delivery the initial notification of ptp status
'EndpointUri %s ResourceAddress %s' if version == 1:
% (subscription_dto.EndpointUri, subscription_dto2 = SubscriptionInfoV1(entry)
subscription_dto.ResourceAddress)) else:
entry = self.subscription_repo.get_one( subscription_dto2 = SubscriptionInfoV2(entry)
EndpointUri=subscription_dto.EndpointUri,
ResourceAddress=subscription_dto.ResourceAddress
)
if entry:
LOG.debug('Found existing entry in subscription repo')
raise client_exception.ServiceError(409)
subscription_orm = SubscriptionOrm(**subscription_dto.to_orm())
subscription_orm.InitialDeliveryTimestamp = timestamp
entry = self.subscription_repo.add(subscription_orm)
# Delivery the initial notification of ptp status
if version == 1:
subscription_dto2 = SubscriptionInfoV1(entry)
else:
subscription_dto2 = SubscriptionInfoV2(entry)
for node in nodes.items():
try: try:
subscription_helper.notify(subscription_dto2, ptpstatus) subscription_helper.notify(subscription_dto2, node[1])
LOG.info("initial ptpstatus is delivered successfully") LOG.info("Initial ptpstatus of {0} is delivered successfully"
"".format(node[0]))
except Exception as ex: except Exception as ex:
LOG.warning("initial ptpstatus is not delivered:{0}".format( LOG.warning("Initial ptpstatus of {0} is not delivered:{1}"
str(ex))) "".format(node[0], str(ex)))
raise client_exception.InvalidEndpoint( raise client_exception.InvalidEndpoint(
subscription_dto.EndpointUri) subscription_dto.EndpointUri)
try: try:
# commit the subscription entry # commit the subscription entry
self.subscription_repo.commit() self.subscription_repo.commit()
self.daemon_control.refresh() self.daemon_control.refresh()
except Exception as ex: except Exception as ex:
LOG.warning("subscription is not added successfully:" LOG.warning("subscription is not added successfully:"
"{0}".format(str(ex))) "{0}".format(str(ex)))
raise ex raise ex
return subscription_dto2 return subscription_dto2
def remove_subscription(self, subscriptionid): def remove_subscription(self, subscriptionid):

View File

@ -34,7 +34,7 @@ class ResourceAddressController(object):
_, nodename, resource, optional, self.resource_address = \ _, nodename, resource, optional, self.resource_address = \
subscription_helper.parse_resource_address( subscription_helper.parse_resource_address(
self.resource_address) self.resource_address)
if nodename == '.': if nodename == constants.WILDCARD_CURRENT_NODE:
nodename = notification_control.get_residing_nodename() nodename = notification_control.get_residing_nodename()
LOG.debug('Nodename to query: %s' % nodename) LOG.debug('Nodename to query: %s' % nodename)
if not notification_control.in_service_nodenames(nodename): if not notification_control.in_service_nodenames(nodename):