[jboss-as7-dev] [OSGi WAB support] webbundle: URL handler
David Bosschaert
david at redhat.com
Fri Nov 30 11:35:08 EST 2012
I was looking into it a little more too and came to the conclusion that
the whole approach via the DeploymentUnitProcessor can't work.
The problem is that things passed via a webbundle: URL don't need to be
OSGi bundles. One of the things that the webbundle: URL handler can do
is turn non-OSGi bundles (i.e. WAR files) into OSGi bundles on the fly,
so you could do something like:
bundle.install("webbundle:file://myplainold.war?Bundle-SymbolicName=foo&&Web-ContextPath=/test")
The problem is that from very early on in the process, even before it
hits the the DUPs, the bundle.install code expects the thing that is
being deployed to be a valid OSGi bundle. And I think it's right in
doing that.
So - the only clean solution that I can see is to have the URL handler
to the conversion to OSGi bundle on the fly. With that you can use these
webbundle: URLs from anywhere I think as they will work from anywhere in
the vm where you do URL().openStream().
Cheers,
David
On 30/11/2012 16:22, Thomas Diesler wrote:
> I was thinking about this a little more …
>
> We need to distinguish between two cases
>
> #1 Deployment through CLI, Console, Management API
> #2 Deployment through BundleContext.install(…)
>
> Re #1: In this case the webbundle URI needs to be passed through the
> mgmnt layer. What happens when you try this in CLI/Console? In both
> UIs there must be a way to pass in a URI that is then accessible from
> a DUP.
> Given that we can see the URI in a DUP, it can be parsed after
> OSGiBundleInfoParseProcessor but before
> BundleDeploymentProcessor. The BundleDeploymentProcessor would see
> valid OSGiMetaData and everything after would proceed as normal.
>
> Re #2: In this case the Framework already provides the Deployment
> object that is then passed to the BundleLifecycleIntegration. By that
> time the metadata is already parsed and part of the Deployment. This
> happens in AbstractBundleContext
>
> DeploymentFactoryPlugin deploymentPlugin =
> frameworkState.getDeploymentFactoryPlugin();
> dep = deploymentPlugin.createDeployment(location, rootFile);
>
> Fortunately the DeploymentFactoryPlugin is an integration point that
> exits in anticipation of a requirement like this. You would need to
> provide a "DeploymentFactoryIntegration" that parses the webbundle URI
> in createDeployment. The returned Deployment is already a valid OSGi
> deployment. No additional work is needed in the DUPs.
>
> cheers
> --thomas
>
>
> On Nov 30, 2012, at 3:35 PM, Thomas Diesler <thomas.diesler at jboss.com
> <mailto:thomas.diesler at jboss.com>> wrote:
>
>> Good progress
>>
>> > I can get the Deployment object back, given its DU.name
>>
>> You don't need to do that. Your DUP should be placed after the
>> BundleDeploymentProcessor, in which case the Deployment is readily
>> available from the DU.
>>
>> Re the Bundle.location to DU.name mapping …
>> The runtime name must be unique and at the same time simple enough to
>> be usable as bundle key on the CLI. How about using the something
>> like this
>>
>> String toRuntimeName(String location) {
>> - if location is valid URI: return URI path (i.e. strip protocol &
>> params)
>> - else if location has a suffix .???: return location without suffix
>> - else return location
>> }
>>
>>
>> On Nov 30, 2012, at 3:24 PM, David Bosschaert <david at redhat.com
>> <mailto:david at redhat.com>> wrote:
>>
>>> Ah, yes. Via a static method on BundleLifecycleIntegration I can get
>>> the Deployment object back, given its DU.name. Once I have the
>>> Deployment object I can indeed find out the original URL and read
>>> the parameters off that.
>>>
>>> The getRuntimeName() simply returns the thing after the last "/" in
>>> the installation location. This may be alright for things that come
>>> from the filesystem, but if you install something from a URL the
>>> results can be a bit random, as people can have '/'-es in their
>>> parameters, e.g.
>>> http://myhost/mybundle?param1=/whatever
>>> I will have a look at making that a bit better in that context.
>>>
>>> I noticed that the DeploymentPlanBuilder.add() has an overload where
>>> you can provide a name and a common name. This might be useful for
>>> OSGi in that for the common name we could pass in the name we
>>> currently do, but for the name we could pass in the original
>>> Bundle.location argument. I haven't fully tested this but it seems
>>> to me that that could ensure that even in the case that
>>> getRuntimeName() returns the same thing for two different bundles
>>> things will still continue to work.
>>>
>>> Cheers,
>>>
>>> David
>>>
>>> On 30/11/2012 10:55, Thomas Diesler wrote:
>>>> The DU runtime name is computed here
>>>> <https://github.com/jbosgi/jboss-as/blob/master/osgi/service/src/main/java/org/jboss/as/osgi/service/BundleLifecycleIntegration.java#L284>
>>>>
>>>> LOGGER.debugf("Install deployment: %s", dep);
>>>> String runtimeName = getRuntimeName(dep);
>>>> putDeployment(runtimeName, dep);
>>>> try {
>>>> InputStream input = dep.getRoot().openStream();
>>>> try {
>>>> ServerDeploymentHelper server = new
>>>> ServerDeploymentHelper(deploymentManager);
>>>> server.deploy(runtimeName, input);
>>>> } finally {
>>>> VFSUtils.safeClose(input);
>>>> }
>>>> } catch (RuntimeException rte) {
>>>> throw rte;
>>>> } catch (Exception ex) {
>>>> throw MESSAGES.cannotDeployBundle(ex, dep);
>>>> }
>>>>
>>>> That mapping from the Bundle.location to the DU.name is historical
>>>> and I'm not sure what the limitations currently are. Perhaps you
>>>> could find out while you're doing this and document why
>>>> getRuntimeName(dep) is doing what its doing. That name also has to
>>>> feed through the management layer as the deployment's runtimeName.
>>>> Perhaps there are some limitations at that level. Have a look at
>>>> the variations of DeploymentPlanBuilder.add(…)
>>>>
>>>> Ideally, we would like to pass the Bundle.location directly to the
>>>> DeploymentPlanBuilder API so that it becomes DU.name unchanged.
>>>>
>>>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>>>> Thomas Diesler
>>>> JBoss OSGi Lead
>>>> JBoss, a division of Red Hat
>>>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>>>>
>>>>
>>>>
>>>> On Nov 30, 2012, at 11:29 AM, Thomas Diesler
>>>> <thomas.diesler at jboss.com <mailto:thomas.diesler at jboss.com>> wrote:
>>>>
>>>>> > DeploymentUnit.getName() only returns the bare name of the item
>>>>> being deployed
>>>>>
>>>>> Is this really true? What is the DU.name when you do
>>>>> BundleContext.install("webbundle://foo?key=value", input) ?
>>>>>
>>>>> > I could not find the Deployment.location
>>>>>
>>>>> Have a look at the BundleDeploymentProcessor
>>>>> <https://github.com/jbosgi/jboss-as/blob/master/osgi/service/src/main/java/org/jboss/as/osgi/deployment/BundleDeploymentProcessor.java>
>>>>>
>>>>>
>>>>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>>>>> Thomas Diesler
>>>>> JBoss OSGi Lead
>>>>> JBoss, a division of Red Hat
>>>>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>>>>>
>>>>>
>>>>>
>>>>> On Nov 29, 2012, at 10:11 PM, David Bosschaert <david at redhat.com
>>>>> <mailto:david at redhat.com>> wrote:
>>>>>
>>>>>> Hi Thomas,
>>>>>>
>>>>>> If I can get the original location/URI back in the
>>>>>> DeploymentUnitProcessor.deploy() so I can associate them with
>>>>>> each other that would work for me too. DeploymentUnit.getName()
>>>>>> only returns the bare name of the item being deployed (e.g. just
>>>>>> "mywebapp"), which isn't really precise enough. I could not find
>>>>>> the Deployment.location that you're referring to from the
>>>>>> deploy() method, is it available as an attachment of some sort?
>>>>>>
>>>>>> Cheers,
>>>>>>
>>>>>> David
>>>>>>
>>>>>> On 29/11/2012 19:22, Thomas Diesler wrote:
>>>>>>> Hi David,
>>>>>>>
>>>>>>> The webbundle://foo?key=value URL is mainly a transport vehicle
>>>>>>> for meta data. I don't think it is intended to give access to
>>>>>>> the bytes of the war (however, we could do this too - see
>>>>>>> below). That URL spec (as a string) is the Bundle.location that
>>>>>>> is given in BundleContext(location, input). That location
>>>>>>> identifier was originally meant to be a URL that could give
>>>>>>> access to the Bundle's bytes. This is no longer the case and any
>>>>>>> string (in most cases an URI) can be given as the location.
>>>>>>> Internally, I think the location becomes the DU name. If not, it
>>>>>>> is definitely the Deployment.location.
>>>>>>>
>>>>>>> So a DUP does have access to that web bundle location. The URL
>>>>>>> handler is mainly a URI parser that is supposed to give access
>>>>>>> to the OSGi metadata that need to be put in the manifest (in our
>>>>>>> case the OSGiMetaData not the Manifest). AFAIK, the Framework
>>>>>>> tries to construct a URL from the location only if no input
>>>>>>> bytes are given. When we talk about an URLHandler we are mainly
>>>>>>> talking about a simple URI parser. A URLHandler would need to be
>>>>>>> implemented for BundleContext(location) to work.
>>>>>>>
>>>>>>> Given that the URI parsing works and that we can generate
>>>>>>> OSGiMetaData from it, the bytes that make up the WAR are
>>>>>>> maintained by the DeploymentRepository and available through the
>>>>>>> DU roots.
>>>>>>>
>>>>>>> In the unlikely case that the TCK does something like this:
>>>>>>>
>>>>>>> Manifest manifest = new Manifest(new
>>>>>>> URL("webbundle://foo?key=value").openStream());
>>>>>>> validateGeneratedManifest(manifest)
>>>>>>>
>>>>>>> we would need to feed back the generated OSGiMetaData to a byte
>>>>>>> buffer. In any case that would have to access the DU root
>>>>>>> content and amend it by a generated Manifest.
>>>>>>> I'd have to check if the above is really required.
>>>>>>>
>>>>>>> If this does not help either, give me a shout and I put together
>>>>>>> a quick prototype.
>>>>>>>
>>>>>>> cheers
>>>>>>> --thomas
>>>>>>>
>>>>>>>
>>>>>>> On Nov 29, 2012, at 12:29 PM, David Bosschaert <david at redhat.com
>>>>>>> <mailto:david at redhat.com>> wrote:
>>>>>>>
>>>>>>>> Hi Thomas,
>>>>>>>>
>>>>>>>> I have the following issues with your suggestion.
>>>>>>>>
>>>>>>>> 1. I don't fully see how the information available to the URL
>>>>>>>> handler can be associated with the information available to the
>>>>>>>> DeploymentUnitProcessor. The URL handler has the URL, that's
>>>>>>>> all, while AFAICS the original URL (or whatever was inside the
>>>>>>>> webbundle: url) is no longer available when the deploy() method
>>>>>>>> is called.
>>>>>>>> 2. If we find a way to fix 1. this will only work if people use
>>>>>>>> BundleContext.install(String location). It will fail when
>>>>>>>> people call url.openStream() on the webbundle: url and does not
>>>>>>>> work with BundleContext.install(String, InputStream).
>>>>>>>>
>>>>>>>> Another approach would be to simply let the URL handler do all
>>>>>>>> the work, i.e. modify the stream being passed through. Then
>>>>>>>> those URLs will work in any context.
>>>>>>>>
>>>>>>>> Cheers,
>>>>>>>>
>>>>>>>> David
>>>>>>>>
>>>>>>>> On 26/11/2012 17:25, Thomas Diesler wrote:
>>>>>>>>> Hi David,
>>>>>>>>>
>>>>>>>>> here a quick summary of what I suggested today:
>>>>>>>>>
>>>>>>>>> The first thing that sees the URL coming from
>>>>>>>>> BundleContext.install(...) is the Framework, which has a
>>>>>>>>> notion of pluggable URL handlers.
>>>>>>>>> In AS7 the URL handler should be an integration plugin and a
>>>>>>>>> DUP at the same time. The DUP would do nothing as long as the
>>>>>>>>> plugin
>>>>>>>>> is not activated (i.e. the framework is down). When the
>>>>>>>>> Framework activates the URL handler gets registered with the
>>>>>>>>> framework and the DUP becomes active.
>>>>>>>>>
>>>>>>>>> The DUP would then need to provide OSGiMetaData with a
>>>>>>>>> Bunde-SymbolicName and Bundle-Classpath. The Bundle-Classpath
>>>>>>>>> should point to WEB-INF/classes and
>>>>>>>>> the collection of stuff in WEB-INF/lib. For completeness it
>>>>>>>>> could generate Package-Import requirements on the
>>>>>>>>> javax.servlet.* APIs. The DUP should be placed after
>>>>>>>>> the DUP that normally provides OSGiMetaData and should do
>>>>>>>>> nothing if the OSGiMetaData is already there.
>>>>>>>>>
>>>>>>>>> Hope that helps, cheers
>>>>>>>>> --thomas
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 11/21/2012 05:58 PM, David Bosschaert wrote:
>>>>>>>>>> Hi all,
>>>>>>>>>>
>>>>>>>>>> As part of making the JBoss OSGi Web Application Support
>>>>>>>>>> compliant with
>>>>>>>>>> the spec I have started running it through the OSGi TCK.
>>>>>>>>>> I noticed that the TCK depends heavily on the webbundle: URL
>>>>>>>>>> protocol
>>>>>>>>>> which is specified in section 128.4 of the specification - it
>>>>>>>>>> is not an
>>>>>>>>>> optional piece. So in order to support this we need to
>>>>>>>>>> provide such a
>>>>>>>>>> URL handler.
>>>>>>>>>>
>>>>>>>>>> As the webbundle: handler is never part of runtime operation
>>>>>>>>>> (it only
>>>>>>>>>> converts a WAR file into a WAB file on the fly) I was looking
>>>>>>>>>> into
>>>>>>>>>> possibly using existing implementations of the URL handler
>>>>>>>>>> instead.
>>>>>>>>>> However the ones that I found are quite heavy on the
>>>>>>>>>> dependencies. The
>>>>>>>>>> implementation in Aries depends on Blueprint being present
>>>>>>>>>> and the one
>>>>>>>>>> in Pax has about 10 other dependencies (including junit) -
>>>>>>>>>> they drag in
>>>>>>>>>> too much baggage IMHO.
>>>>>>>>>>
>>>>>>>>>> So I'm starting to come to the conclusion that we need to
>>>>>>>>>> provide such
>>>>>>>>>> an implementation as part of the OSGi webbundle support in
>>>>>>>>>> AS7. The JIRA
>>>>>>>>>> is https://issues.jboss.org/browse/AS7-6006
>>>>>>>>>>
>>>>>>>>>> Any other ideas?
>>>>>>>>>>
>>>>>>>>>> Cheers,
>>>>>>>>>>
>>>>>>>>>> David
>>>>>>>>>> _______________________________________________
>>>>>>>>>> jboss-as7-dev mailing list
>>>>>>>>>> jboss-as7-dev at lists.jboss.org
>>>>>>>>>> <mailto:jboss-as7-dev at lists.jboss.org>
>>>>>>>>>> https://lists.jboss.org/mailman/listinfo/jboss-as7-dev
>>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> jboss-as7-dev mailing list
>>>>> jboss-as7-dev at lists.jboss.org <mailto:jboss-as7-dev at lists.jboss.org>
>>>>> https://lists.jboss.org/mailman/listinfo/jboss-as7-dev
>>>>
>>>
>>
>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>> Thomas Diesler
>> JBoss OSGi Lead
>> JBoss, a division of Red Hat
>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>>
>>
>>
>> _______________________________________________
>> jboss-as7-dev mailing list
>> jboss-as7-dev at lists.jboss.org <mailto:jboss-as7-dev at lists.jboss.org>
>> https://lists.jboss.org/mailman/listinfo/jboss-as7-dev
>
> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
> Thomas Diesler
> JBoss OSGi Lead
> JBoss, a division of Red Hat
> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>
>
>
More information about the jboss-as7-dev
mailing list