Commit 58744781 authored by Roque's avatar Roque

CMFActivity: move getCurrentNode and getServerAddress methods outside ActivityTool class

- involved methods can be directly imported from CMFActivity
- calls to deprecated methods removed
- warnings added
- corresponding unittests added
parent fd43d37b
......@@ -94,9 +94,10 @@ class TestERP5(ERP5TypeTestCase):
self.login()
def getOtherZopeNode(self):
from Products.CMFActivity.ActivityTool import getCurrentNode
activity_tool = self.portal.portal_activities
node_list = list(activity_tool.getProcessingNodeList())
node_list.remove(activity_tool.getCurrentNode())
node_list.remove(getCurrentNode())
assert node_list, "this unit test must be run with at least 2 Zope nodes"
return node_list[0]
......
......@@ -126,6 +126,46 @@ def activity_timing_method(method, args, kw):
end = time()
activity_timing_logger.info('%.02fs: %r(*%r, **%r)' % (end - begin, method, args, kw))
def getServerAddress():
"""
Return current server address
"""
global _server_address
if _server_address is None:
ip = port = ''
from asyncore import socket_map
for k, v in socket_map.items():
if hasattr(v, 'addr'):
# see Zope/lib/python/App/ApplicationManager.py: def getServers(self)
type = str(getattr(v, '__class__', 'unknown'))
if type == 'ZServer.HTTPServer.zhttp_server':
ip, port = v.addr
break
if ip == '0.0.0.0':
ip = socket.gethostbyname(socket.gethostname())
_server_address = '%s:%s' %(ip, port)
return _server_address
def getCurrentNode():
""" Return current node identifier """
global currentNode
if currentNode is None:
currentNode = getattr(
getConfiguration(),
'product_config',
{},
).get('cmfactivity', {}).get('node-id')
if currentNode is None:
warnings.warn('Node name auto-generation is deprecated, please add a'
'\n'
'<product-config CMFActivity>\n'
' node-id = ...\n'
'</product-config>\n'
'section in your zope.conf, replacing "..." with a cluster-unique '
'node identifier.', DeprecationWarning)
currentNode = getServerAddress()
return currentNode
# Here go ActivityBuffer instances
# Structure:
# global_activity_buffer[activity_tool_path][thread_id] = ActivityBuffer
......@@ -359,7 +399,7 @@ Method: %s
Arguments: %r
Named Parameters: %r
""" % (email_from_name, activity_tool.email_from_address, user_email, message,
path, self.method_id, activity_tool.getCurrentNode(), fail_count,
path, self.method_id, getCurrentNode(), fail_count,
self.user_name, self.line.uid, path, self.method_id, self.args, self.kw)
if self.traceback:
mail_text += '\nException:\n' + self.traceback
......@@ -819,42 +859,18 @@ class ActivityTool (Folder, UniqueObject):
"""
Backward-compatibility code only.
"""
global _server_address
if _server_address is None:
ip = port = ''
from asyncore import socket_map
for k, v in socket_map.items():
if hasattr(v, 'addr'):
# see Zope/lib/python/App/ApplicationManager.py: def getServers(self)
type = str(getattr(v, '__class__', 'unknown'))
if type == 'ZServer.HTTPServer.zhttp_server':
ip, port = v.addr
break
if ip == '0.0.0.0':
ip = socket.gethostbyname(socket.gethostname())
_server_address = '%s:%s' %(ip, port)
return _server_address
LOG('ActivityTool', WARNING,
'"getServerAddress" class method is deprecated, use "getServerAddress" module-level function instead.')
return getServerAddress()
security.declareProtected(CMFCorePermissions.ManagePortal, 'getCurrentNode')
def getCurrentNode(self):
""" Return current node identifier """
global currentNode
if currentNode is None:
currentNode = getattr(
getConfiguration(),
'product_config',
{},
).get('cmfactivity', {}).get('node-id')
if currentNode is None:
warnings.warn('Node name auto-generation is deprecated, please add a'
'\n'
'<product-config CMFActivity>\n'
' node-id = ...\n'
'</product-config>\n'
'section in your zope.conf, replacing "..." with a cluster-unique '
'node identifier.', DeprecationWarning)
currentNode = self.getServerAddress()
return currentNode
"""
Backward-compatibility code only.
"""
LOG('ActivityTool', WARNING,
'"getCurrentNode" class method is deprecated, use "getCurrentNode" module-level function instead.')
return getCurrentNode()
security.declareProtected(CMFCorePermissions.ManagePortal, 'getDistributingNode')
def getDistributingNode(self):
......@@ -884,7 +900,7 @@ class ActivityTool (Folder, UniqueObject):
if node_dict:
# BBB: check if our node was known by address (processing and/or
# distribution), and migrate it.
server_address = self.getServerAddress()
server_address = getServerAddress()
role = node_dict.pop(server_address, ROLE_IDLE)
if self.distributingNode == server_address:
self.distributingNode = node
......@@ -1022,7 +1038,7 @@ class ActivityTool (Folder, UniqueObject):
user = self.portal_catalog.getWrappedOwner()
newSecurityManager(self.REQUEST, user)
currentNode = self.getCurrentNode()
currentNode = getCurrentNode()
self.registerNode(currentNode)
processing_node_list = self.getNodeList(role=ROLE_PROCESSING)
......
......@@ -53,6 +53,10 @@ import random
import threading
import weakref
import transaction
from Products.CMFActivity.ActivityTool import getCurrentNode, getServerAddress
from App.config import getConfiguration
from asyncore import socket_map
import socket
class CommitFailed(Exception):
pass
......@@ -2949,6 +2953,33 @@ class TestCMFActivity(ERP5TypeTestCase, LogInterceptor):
skin.manage_delObjects([script_id])
self.tic()
def testGetCurrentNode(self):
current_node = getattr(getConfiguration(),'product_config',{},).get('cmfactivity', {}).get('node-id')
if not current_node:
current_node = getServerAddress()
node = getCurrentNode()
self.assertEqual(node, current_node)
portal = self.getPortal()
activity_node = portal.portal_activities.getCurrentNode()
self.assertEqual(activity_node, current_node)
def testGetServerAddress(self):
ip = port = ''
for k, v in socket_map.items():
if hasattr(v, 'addr'):
type = str(getattr(v, '__class__', 'unknown'))
if type == 'ZServer.HTTPServer.zhttp_server':
ip, port = v.addr
break
if ip == '0.0.0.0':
ip = socket.gethostbyname(socket.gethostname())
server_address = '%s:%s' %(ip, port)
address = getServerAddress()
self.assertEqual(address, server_address)
portal = self.getPortal()
activity_address = portal.portal_activities.getServerAddress()
self.assertEqual(activity_address, server_address)
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestCMFActivity))
......
......@@ -93,10 +93,11 @@ class TestInvalidationBug(ERP5TypeTestCase):
def testLateInvalidationFromZEO(self):
### Check unit test is run properly
from ZEO.ClientStorage import ClientStorage
from Products.CMFActivity.ActivityTool import getCurrentNode
storage = self.portal._p_jar._storage
activity_tool = self.portal.portal_activities
node_list = list(activity_tool.getProcessingNodeList())
node_list.remove(activity_tool.getCurrentNode())
node_list.remove(getCurrentNode())
assert node_list and isinstance(storage, ClientStorage), \
"this unit test must be run with at least 2 ZEO clients"
......
......@@ -233,8 +233,7 @@ class FolderMixIn(ExtensionClass.Base):
of objects inside a module using activities
We also append random id
"""
activity_tool = self.getPortalObject().portal_activities
new_id = "%s-%s" %(activity_tool.getCurrentNode().replace("-", "_"),
new_id = "%s-%s" %(getCurrentNode().replace("-", "_"),
self._generateRandomId())
try:
checkValidId(self, new_id)
......@@ -250,7 +249,7 @@ class FolderMixIn(ExtensionClass.Base):
"""
activity_tool = self.getPortalObject().portal_activities
node_list = list(activity_tool.getNodeList())
current_node = activity_tool.getCurrentNode()
current_node = getCurrentNode()
try:
node_number = node_list.index(current_node) + 1
except ValueError:
......@@ -266,7 +265,7 @@ class FolderMixIn(ExtensionClass.Base):
"""
activity_tool = self.getPortalObject().portal_activities
node_list = list(activity_tool.getNodeList())
current_node = activity_tool.getCurrentNode()
current_node = getCurrentNode()
try:
node_number = node_list.index(current_node) + 1
except ValueError:
......@@ -1679,6 +1678,8 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
pass
return '%s/%s' % (url, icon)
from Products.CMFActivity.ActivityTool import getCurrentNode
# We browse all used class from btree and hbtree and set not implemented
# class if one method defined on a class is not defined on other, thus if
# new method appears in one class if will raise in the other one
......
......@@ -10,6 +10,7 @@ from zLOG import LOG, ERROR
from Products.CMFActivity.Activity.Queue import VALIDATION_ERROR_DELAY
from Products.ERP5Type.tests.utils import addUserToDeveloperRole
from Products.ERP5Type.tests.utils import createZServer
from Products.CMFActivity.ActivityTool import getCurrentNode
class DictPersistentWrapper(IterableUserDict, object):
......@@ -86,7 +87,7 @@ def patchActivityTool():
def tic(self, processing_node=1, force=0):
processing_node_list = self.getProcessingNodeList()
if len(processing_node_list) > 1 and \
self.getCurrentNode() == self.getDistributingNode():
getCurrentNode() == self.getDistributingNode():
# Sleep between each distribute.
time.sleep(0.3)
transaction.commit()
......@@ -166,7 +167,7 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase):
except AttributeError:
from Products.CMFActivity.ActivityTool import ActivityTool
activity_tool = ActivityTool().__of__(self.app)
currentNode = activity_tool.getCurrentNode()
currentNode = getCurrentNode()
if distributing:
activity_tool.manage_setDistributingNode(currentNode)
elif currentNode == activity_tool.getDistributingNode():
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment