[
https://issues.apache.org/jira/browse/AXIS2-5721?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17015209#comment-17015209
]
Jeff Thomas edited comment on AXIS2-5721 at 1/14/20 4:39 PM:
-------------------------------------------------------------
This issues is pretty old (2015) but is exactly the behavior we are
encountering now - applies to current trunk version as well. It appears to be
a design 'feature' :)
Engaging a module from any service-operation adds it to the corresponding
flow-phase. All calls run through all phases for the relevant flow (ie.
InFlow) .
So we have two scenarios.. assume a Module 'foobar' is defined with a handler
associated to phase _Security_.
* If module 'foobar' is engaged for _ServiceA_ its handler will be added to
the _Security_ phase and will _*always*_ be invoked for _ServiceA_ but also for
_ServiceB, ServiceC,_ etc.
* If module 'foobar' is disengaged at runtime on _ServiceA_ its handler will
be removed from the _Security_ phase and will _*never*_ be invoked... even if
it is still engaged for _ServiceB, ServiceC_ etc.
*_NOTE: Based on the two points above I would encourage you *NOT_* _to use
axis2-admin tools to engage/disengage modules at runtime - if two or more
services/operations engage the same module then the 'engaged' status and the
handlers that are *really* defined for a phase will not match._*
One workaround on a handler-by-handler basis is to check if a handler is
_really_ engaged in the _doInvoke(..._) method of the handler and return false
if not. (see note about the AxisDescription _engagedModules_ lookup below).
The workaround I am testing at the moment I have added to _Phase.java_ to test
if the handler belongs to a parent module and if so check if the module is
enaged relative to the message-context (service-group, service, operation,
etc.).
{{public final InvocationResponse invoke(MessageContext msgctx) throws
AxisFault {}}
{{ ...}}
{{ int handlersSize = handlers.size();}}
{{ for (int i= currentIndex; i < handlersSize; i++) {}}
{{ Handler handler = (Handler) handlers.get(i);}}
{{ *{color:#de350b}ParameterInclude handlerParent =
handler.getHandlerDesc().getParent();{color}*}}
{{ *{color:#de350b}if (handlerParent instanceof AxisModule) {{color}*}}
{{ *{color:#de350b}AxisModule module = (AxisModule)
handlerParent;{color}*}}
{{ *{color:#de350b}if (!msgctx.isEngaged(module.getName())) {{color}*}}
{{ *{color:#de350b}continue;
{color}*}}{{ }}}
}
{{ ...}}
}
IMPORTANT: A parallel change has to be made to AxisDescription.java. The
default implementation maps the modules in the _engagedModules<String,
AxisModule>_ map using the module archive name as a key (ie.
'_addressing-1.7.4_').
This means you have to know the name of the archive to call
'_isEnaged("addressing-1.7.4_"). Nobody is ever going to know the name of the
archive at runtime and if you code to this key your code will break as soon as
the module version changes. So I changed the code to key by the generic
module name - this also makes sense because you configure and engage modules by
this common name (ie. '_addressing_').
{{public void engageModule(AxisModule axisModule, AxisDescription source)
throws AxisFault {}}
{{ ...}}
{{ // removed - engagedModules.put(axisModule.getArchiveName(), axisModule)
and replaced with:}}
{{ engagedModules.put(*{color:#de350b}axisModule.getName(){color}*,
axisModule);}}
{{}}}
{{public boolean isEngaged(AxisModule axisModule) {}}
{{ String id = {color:#de350b}*axisModule.getName()*{color}; // changed from
axisModule.getArchiveName()}}
{{ return engagedModules != null && engagedModules.keySet().contains(id);}}
{{}}}
I am still testing the above but I am pretty confident it will work :)
was (Author: jwt007):
This issues is pretty old (2015) but is exactly the behavior we are
encountering now - applies to current trunk version as well. It appears to be
a design 'feature' :)
Engaging a module from any service-operation adds it to the corresponding
flow-phase. All calls run through all phases for the relevant flow (ie.
InFlow) .
So we have two scenarios.. assume a Module 'foobar' is defined with a handler
associated to phase _Security_.
* If module 'foobar' is engaged for _ServiceA_ its handler will be added to
the _Security_ phase and will _*always*_ be invoked for _ServiceA_ but also for
_ServiceB, ServiceC,_ etc.
* If module 'foobar' is disengaged at runtime on _ServiceA_ its handler will
be removed from the _Security_ phase and will _*never*_ be invoked... even if
it is still engaged for _ServiceB, ServiceC_ etc.
*_NOTE: Based on the two points above I would encourage you *NOT* to use
axis2-admin tools to engage/disengage modules at runtime - if two or more
services/operations engage the same module then the 'engaged' status and the
handlers that are *really* defined for a phase will not match._*
One workaround on a handler-by-handler basis is to check if a handler is
_really_ engaged in the _doInvoke(..._) method of the handler and return false
if not. (see note about the AxisDescription _engagedModules_ lookup below).
The workaround I am testing at the moment I have added to _Phase.java_ to test
if the handler belongs to a parent module and if so check if the module is
enaged relative to the message-context (service-group, service, operation,
etc.).
{{public final InvocationResponse invoke(MessageContext msgctx) throws
AxisFault {}}
{{ ...}}
{{ int handlersSize = handlers.size();}}
{{ for (int i= currentIndex; i < handlersSize; i++) {}}
{{ Handler handler = (Handler) handlers.get(i);}}
{{ *{color:#de350b}ParameterInclude handlerParent =
handler.getHandlerDesc().getParent();{color}*}}
{{ *{color:#de350b}if (handlerParent instanceof AxisModule) {{color}*}}
{{ *{color:#de350b}AxisModule module = (AxisModule)
handlerParent;{color}*}}
{{ *{color:#de350b}if (!msgctx.isEngaged(module.getName())) {{color}*}}
{{ *{color:#de350b}continue;{color}*}}
{{ *{color:#de350b}}{color}*}}
{{ *{color:#de350b}}{color}*}}
{{ }}}
{{ ...}}
{{ }}}
IMPORTANT: A parallel change has to be made to AxisDescription.java. The
default implementation maps the modules in the _engagedModules<String,
AxisModule>_ map using the module archive name as a key (ie.
'_addressing-1.7.4_').
This means you have to know the name of the archive to call
'_isEnaged("addressing-1.7.4_"). Nobody is ever going to know the name of the
archive at runtime and if you code to this key your code will break as soon as
the module version changes. So I changed the code to key by the generic
module name - this also makes sense because you configure and engage modules by
this common name (ie. '_addressing_').
{{public void engageModule(AxisModule axisModule, AxisDescription source)
throws AxisFault {}}
{{ ...}}
{{ // removed - engagedModules.put(axisModule.getArchiveName(), axisModule)
and replaced with:}}
{{ engagedModules.put(*{color:#de350b}axisModule.getName(){color}*,
axisModule);}}
{{}}}
{{public boolean isEngaged(AxisModule axisModule) {}}
{{ String id = {color:#de350b}*axisModule.getName()*{color}; // changed from
axisModule.getArchiveName()}}
{{ return engagedModules != null && engagedModules.keySet().contains(id);}}
{{}}}
I am still testing the above but I am pretty confident it will work :)
> Module engaged at the service level is used globally
> ----------------------------------------------------
>
> Key: AXIS2-5721
> URL: https://issues.apache.org/jira/browse/AXIS2-5721
> Project: Axis2
> Issue Type: Bug
> Components: modules
> Affects Versions: 1.6.3
> Reporter: Victor
> Priority: Major
>
> Hi,
> Maybe I misunderstood how Axis2 was meant to work, but I have addressing and
> rampart present in my modules directory, they are made available in the
> AxisConfiguration object, then addressing is globally engaged because it is
> present in the axis2.xml file.
> Later I engage rampart manually on a specific service (by calling
> engageModule() on the AxisService object) and then the rampart handlers are
> executed for every request, even not those of the aforementioned service.
> I looked at the code and apparently, engageModule() goes down to call
> PhaseResolver.engageModuleToOperation(AxisOperation, AxisModule, int) on all
> the operations of the AxisService, gather all the phases from the global
> AxisConfiguration object and then add the Handler to the needed phases
> (Security in this case) within the method
> PhaseHolder.addHandler(HandlerDescription).
> Obviously, being in an Object-Oriented language, modifying the Phase without
> cloning it first will impact also the global AxisConfiguration that have
> references to them as well as all the other PhaseHolder for all the
> operations that have references to them…
> Is that meant to be? I don't think so but I may be mistaken :)
> Thank you
--
This message was sent by Atlassian Jira
(v8.3.4#803005)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]