[AAA-169] Web API impl PaxWebServer as OSGi service instead of utility Created: 13/Mar/18  Updated: 14/Mar/18  Resolved: 14/Mar/18

Status: Resolved
Project: aaa
Component/s: General
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Medium
Reporter: Michael Vorburger Assignee: Tom Pantelis
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

This Improvement JIRA issue captures analysis, discussion and conclusion re. evolving https://git.opendaylight.org/gerrit/#/c/68840/ with the Web API impl PaxWebServer as OSGi service instead of utility.

I'll raise a follow-up change to c/68840 which makes PaxWebServer an OSGi service and provide details re. how that fails here.

This is how according to you test AAA (according to Ryan):

curl -u admin:adminX http://localhost:8181/auth/v1/users



 Comments   
Comment by Michael Vorburger [ 13/Mar/18 ]

https://git.opendaylight.org/gerrit/#/c/69453/1/ (Patch Set 1) fails the SFT of odl-aaa-shiro with this:

-------------------------------------------------------
Running org.opendaylight.odlparent.featuretest.SingleFeatureTest
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 49.086 sec <<< FAILURE! - in org.opendaylight.odlparent.featuretest.SingleFeatureTest
installFeatureCatchAndLog(org.opendaylight.odlparent.featuretest.SingleFeatureTest)[repoUrl: file:/home/vorburger/dev/ODL/git/aaa/features/odl-aaa-shiro/target/feature/feature.xml, Feature: odl-aaa-shiro 0.8.0.SNAPSHOT]  Time elapsed: 48.194 sec  <<< ERROR!
org.opendaylight.odlparent.bundlestest.lib.SystemStateFailureException: diag failed; some bundles failed to start
diag: Failure {Installed=0, Resolved=6, Unknown=0, GracePeriod=0, Waiting=0, Starting=0, Active=344, Stopping=0, Failure=1}
1. NOK org.opendaylight.aaa.shiro:0.8.0.SNAPSHOT: OSGi state = Active, Karaf bundleState = Failure, due to: Blueprint
13/3/18 6:27 PM
Exception: 
Error when instantiating bean webInitializer of class org.opendaylight.aaa.shiro.web.env.WebInitializer
org.osgi.service.blueprint.container.ComponentDefinitionException: Error when instantiating bean webInitializer of class org.opendaylight.aaa.shiro.web.env.WebInitializer
	at org.apache.aries.blueprint.container.BeanRecipe.wrapAsCompDefEx(BeanRecipe.java:361)
	at org.apache.aries.blueprint.container.BeanRecipe.getInstanceFromType(BeanRecipe.java:351)
	at org.apache.aries.blueprint.container.BeanRecipe.getInstance(BeanRecipe.java:282)
	at org.apache.aries.blueprint.container.BeanRecipe.internalCreate2(BeanRecipe.java:830)
	at org.apache.aries.blueprint.container.BeanRecipe.internalCreate(BeanRecipe.java:811)
	at org.apache.aries.blueprint.di.AbstractRecipe$1.call(AbstractRecipe.java:79)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at org.apache.aries.blueprint.di.AbstractRecipe.create(AbstractRecipe.java:88)
	at org.apache.aries.blueprint.container.BlueprintRepository.createInstances(BlueprintRepository.java:255)
	at org.apache.aries.blueprint.container.BlueprintRepository.createAll(BlueprintRepository.java:186)
	at org.apache.aries.blueprint.container.BlueprintContainerImpl.instantiateEagerComponents(BlueprintContainerImpl.java:704)
	at org.apache.aries.blueprint.container.BlueprintContainerImpl.doRun(BlueprintContainerImpl.java:410)
	at org.apache.aries.blueprint.container.BlueprintContainerImpl.run(BlueprintContainerImpl.java:275)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at org.apache.aries.blueprint.container.ExecutorServiceWrapper.run(ExecutorServiceWrapper.java:106)
	at org.apache.aries.blueprint.utils.threading.impl.DiscardableRunnable.run(DiscardableRunnable.java:48)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalStateException: There is already a Shiro environment associated with the current ServletContext.  Check if you have multiple EnvironmentLoader* definitions in your web.xml!
	at org.apache.shiro.web.env.EnvironmentLoader.initEnvironment(EnvironmentLoader.java:124)
	at org.apache.shiro.web.env.EnvironmentLoaderListener.contextInitialized(EnvironmentLoaderListener.java:58)
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext$3.call(HttpServiceContext.java:352)
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext$3.call(HttpServiceContext.java:348)
	at org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60)
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.callContextInitialized(HttpServiceContext.java:347)
	at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:816)
	at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:345)
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.startContext(HttpServiceContext.java:432)
	at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:778)
	at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:262)
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doStart(HttpServiceContext.java:258)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at org.ops4j.pax.web.service.jetty.internal.JettyServerImpl$1.start(JettyServerImpl.java:306)
	at org.ops4j.pax.web.service.internal.HttpServiceStarted.end(HttpServiceStarted.java:1204)
	at org.ops4j.pax.web.service.internal.HttpServiceProxy.end(HttpServiceProxy.java:445)
	at Proxy5e1e3137_2bb2_4c0b_a106_5f1a4753fe8a.end(Unknown Source)
	at org.opendaylight.aaa.web.osgi.PaxWebServer$WebContextImpl.<init>(PaxWebServer.java:110)
	at org.opendaylight.aaa.web.osgi.PaxWebServer.registerWebContext(PaxWebServer.java:66)
	at Proxy27e80265_14ac_48e9_8bb3_dbdaab7f01f8.registerWebContext(Unknown Source)
	at Proxy023b2847_edf2_4472_a773_f2d2981d9f3c.registerWebContext(Unknown Source)
	at org.opendaylight.aaa.shiro.web.env.WebInitializer.<init>(WebInitializer.java:34)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.apache.aries.blueprint.utils.ReflectionUtils.newInstance(ReflectionUtils.java:331)
	at org.apache.aries.blueprint.container.BeanRecipe.newInstance(BeanRecipe.java:984)
	at org.apache.aries.blueprint.container.BeanRecipe.getInstanceFromType(BeanRecipe.java:349)
	... 22 more

but this is is just the impact (confusing), ignore above; the more interesting relevant part is that if you run with mvn -Dkaraf.keep.unpack=true clean install then in aaa/features/odl-aaa-shiro/target/pax/*/data/log/karaf.log you find this:

2018-03-13T18:43:42,588 | ERROR | Blueprint Extender: 2 | EnvironmentLoader                | 160 - org.apache.shiro.web - 1.3.2 | Shiro environment initialization failed
org.apache.shiro.config.ConfigurationException: Unable to instantiate class [org.opendaylight.aaa.shiro.realm.TokenAuthRealm] for object named 'tokenAuthRealm'.  Please ensure you've specified the fully qualified class name correctly.
	at org.apache.shiro.config.ReflectionBuilder.createNewInstance(ReflectionBuilder.java:309) ~[?:?]
	at org.apache.shiro.config.ReflectionBuilder$InstantiationStatement.doExecute(ReflectionBuilder.java:927) ~[?:?]
	at org.apache.shiro.config.ReflectionBuilder$Statement.execute(ReflectionBuilder.java:887) ~[?:?]
	at org.apache.shiro.config.ReflectionBuilder$BeanConfigurationProcessor.execute(ReflectionBuilder.java:765) ~[?:?]
	at org.apache.shiro.config.ReflectionBuilder.buildObjects(ReflectionBuilder.java:260) ~[?:?]
	at org.apache.shiro.config.IniSecurityManagerFactory.buildInstances(IniSecurityManagerFactory.java:167) ~[?:?]
	at org.apache.shiro.config.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:130) ~[?:?]
	at org.apache.shiro.config.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:108) ~[?:?]
	at org.apache.shiro.config.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:94) ~[?:?]
	at org.apache.shiro.config.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:46) ~[?:?]
	at org.apache.shiro.config.IniFactorySupport.createInstance(IniFactorySupport.java:123) ~[?:?]
	at org.apache.shiro.util.AbstractFactory.getInstance(AbstractFactory.java:47) ~[?:?]
	at org.opendaylight.aaa.shiro.web.env.KarafIniWebEnvironment.createIniFromClusteredAppConfig(KarafIniWebEnvironment.java:60) ~[?:?]
	at org.opendaylight.aaa.shiro.web.env.KarafIniWebEnvironment.init(KarafIniWebEnvironment.java:72) ~[?:?]
	at org.apache.shiro.util.LifecycleUtils.init(LifecycleUtils.java:45) ~[?:?]
	at org.apache.shiro.util.LifecycleUtils.init(LifecycleUtils.java:40) ~[?:?]
	at org.apache.shiro.web.env.EnvironmentLoader.createEnvironment(EnvironmentLoader.java:221) ~[?:?]
	at org.apache.shiro.web.env.EnvironmentLoader.initEnvironment(EnvironmentLoader.java:133) ~[?:?]
	at org.apache.shiro.web.env.EnvironmentLoaderListener.contextInitialized(EnvironmentLoaderListener.java:58) ~[?:?]
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext$3.call(HttpServiceContext.java:352) ~[325:org.ops4j.pax.web.pax-web-jetty:6.0.7]
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext$3.call(HttpServiceContext.java:348) ~[325:org.ops4j.pax.web.pax-web-jetty:6.0.7]
	at org.ops4j.pax.swissbox.core.ContextClassLoaderUtils.doWithClassLoader(ContextClassLoaderUtils.java:60) ~[325:org.ops4j.pax.web.pax-web-jetty:6.0.7]
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.callContextInitialized(HttpServiceContext.java:347) ~[325:org.ops4j.pax.web.pax-web-jetty:6.0.7]
	at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:816) ~[176:org.eclipse.jetty.server:9.3.14.v20161028]
	at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:345) ~[177:org.eclipse.jetty.servlet:9.3.14.v20161028]
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.startContext(HttpServiceContext.java:432) ~[325:org.ops4j.pax.web.pax-web-jetty:6.0.7]
	at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:778) ~[176:org.eclipse.jetty.server:9.3.14.v20161028]
	at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:262) ~[177:org.eclipse.jetty.servlet:9.3.14.v20161028]
	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doStart(HttpServiceContext.java:258) ~[325:org.ops4j.pax.web.pax-web-jetty:6.0.7]
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) ~[179:org.eclipse.jetty.util:9.3.14.v20161028]
	at org.ops4j.pax.web.service.jetty.internal.JettyServerImpl$1.start(JettyServerImpl.java:306) ~[325:org.ops4j.pax.web.pax-web-jetty:6.0.7]
	at org.ops4j.pax.web.service.internal.HttpServiceStarted.registerFilter(HttpServiceStarted.java:620) ~[?:?]
	at org.ops4j.pax.web.service.internal.HttpServiceStarted.registerFilter(HttpServiceStarted.java:592) ~[?:?]
	at org.ops4j.pax.web.service.internal.HttpServiceProxy.registerFilter(HttpServiceProxy.java:208) ~[?:?]
	at Proxy3bbb2595_68aa_4c3e_87a0_77692ed1d73c.registerFilter(Unknown Source) ~[?:?]
	at org.opendaylight.aaa.web.osgi.PaxWebServer$WebContextImpl.registerFilter(PaxWebServer.java:118) ~[206:org.opendaylight.aaa.web.osgi-impl:0.8.0.SNAPSHOT]
	at org.opendaylight.aaa.web.osgi.PaxWebServer$WebContextImpl.lambda$new$1(PaxWebServer.java:101) ~[206:org.opendaylight.aaa.web.osgi-impl:0.8.0.SNAPSHOT]
	at java.util.ArrayList.forEach(ArrayList.java:1257) [?:?]
	at java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1080) [?:?]
	at org.opendaylight.aaa.web.osgi.PaxWebServer$WebContextImpl.<init>(PaxWebServer.java:100) [206:org.opendaylight.aaa.web.osgi-impl:0.8.0.SNAPSHOT]
	at org.opendaylight.aaa.web.osgi.PaxWebServer.registerWebContext(PaxWebServer.java:66) [206:org.opendaylight.aaa.web.osgi-impl:0.8.0.SNAPSHOT]
	at Proxyee179a92_63e8_41ff_8c2d_0221bd713d1c.registerWebContext(Unknown Source) [?:?]
	at Proxy9290277a_840a_452c_940e_c4af96e018f9.registerWebContext(Unknown Source) [?:?]
	at org.opendaylight.aaa.shiro.web.env.WebInitializer.<init>(WebInitializer.java:34) [203:org.opendaylight.aaa.shiro:0.8.0.SNAPSHOT]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) [?:?]
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) [?:?]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423) [?:?]
	at org.apache.aries.blueprint.utils.ReflectionUtils.newInstance(ReflectionUtils.java:331) [17:org.apache.aries.blueprint.core:1.8.3]
	at org.apache.aries.blueprint.container.BeanRecipe.newInstance(BeanRecipe.java:984) [17:org.apache.aries.blueprint.core:1.8.3]
	at org.apache.aries.blueprint.container.BeanRecipe.getInstanceFromType(BeanRecipe.java:349) [17:org.apache.aries.blueprint.core:1.8.3]
	at org.apache.aries.blueprint.container.BeanRecipe.getInstance(BeanRecipe.java:282) [17:org.apache.aries.blueprint.core:1.8.3]
	at org.apache.aries.blueprint.container.BeanRecipe.internalCreate2(BeanRecipe.java:830) [17:org.apache.aries.blueprint.core:1.8.3]
	at org.apache.aries.blueprint.container.BeanRecipe.internalCreate(BeanRecipe.java:811) [17:org.apache.aries.blueprint.core:1.8.3]
	at org.apache.aries.blueprint.di.AbstractRecipe$1.call(AbstractRecipe.java:79) [17:org.apache.aries.blueprint.core:1.8.3]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:?]
	at org.apache.aries.blueprint.di.AbstractRecipe.create(AbstractRecipe.java:88) [17:org.apache.aries.blueprint.core:1.8.3]
	at org.apache.aries.blueprint.container.BlueprintRepository.createInstances(BlueprintRepository.java:255) [17:org.apache.aries.blueprint.core:1.8.3]
	at org.apache.aries.blueprint.container.BlueprintRepository.createAll(BlueprintRepository.java:186) [17:org.apache.aries.blueprint.core:1.8.3]
	at org.apache.aries.blueprint.container.BlueprintContainerImpl.instantiateEagerComponents(BlueprintContainerImpl.java:704) [17:org.apache.aries.blueprint.core:1.8.3]
	at org.apache.aries.blueprint.container.BlueprintContainerImpl.doRun(BlueprintContainerImpl.java:410) [17:org.apache.aries.blueprint.core:1.8.3]
	at org.apache.aries.blueprint.container.BlueprintContainerImpl.run(BlueprintContainerImpl.java:275) [17:org.apache.aries.blueprint.core:1.8.3]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:?]
	at org.apache.aries.blueprint.container.ExecutorServiceWrapper.run(ExecutorServiceWrapper.java:106) [17:org.apache.aries.blueprint.core:1.8.3]
	at org.apache.aries.blueprint.utils.threading.impl.DiscardableRunnable.run(DiscardableRunnable.java:48) [17:org.apache.aries.blueprint.core:1.8.3]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]
	at java.lang.Thread.run(Thread.java:748) [?:?]
Caused by: org.apache.shiro.util.UnknownClassException: Unable to load class named [org.opendaylight.aaa.shiro.realm.TokenAuthRealm] from the thread context, current, or system/application ClassLoaders.  All heuristics have been exhausted.  Class could not be found.
	at org.apache.shiro.util.ClassUtils.forName(ClassUtils.java:152) ~[?:?]
	at org.apache.shiro.util.ClassUtils.newInstance(ClassUtils.java:168) ~[?:?]
	at org.apache.shiro.config.ReflectionBuilder.createNewInstance(ReflectionBuilder.java:302) ~[?:?]
	... 72 more

When you debug this, you find that ultimately this is that TCCL class loading issue which I had initially hit. As explained on the review of c/68840, simply setting the TCCL ourselves does not help, because Pax Web will overwrite it.

Just for the record, I'll copy/paste this from c/68840:

I have no doubt that it is possible to one way or another do something very smart and eventually get Shiro working with more time, but I think it's the wrong approach here, because of what I explained above: It should be simple to use this and switch from declarative web.xml to this API. We cannot have to debug every 3rd party web framework to make more OSGi compliant than it would have to be if one had used web.xml. To the best of my abilities, this as-is achieves that. The fact that PaxWebServer is not registered as an OSGi service but is used directly by bundles is a very minor detail, to me. I'm loosing interest in further tweaking this, and am against requring future migration from web.xml to this API in other projects require a Ph.D. in classloadology.

Comment by Michael Vorburger [ 14/Mar/18 ]

https://git.opendaylight.org/gerrit/#/c/69475/

Generated at Wed Feb 07 19:08:49 UTC 2024 using Jira 8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d.