Hi Thomas,
If I understand things correctly this code uses a change in the framework so that the
actual bytes you install using context.installBundle() don't have to be a valid bundle
as the bundle metadata could be provided using other means (i.e. the URL parameters)?
Yes, the content given to BundleContext.install(…) does not have to be a bundle. As a
result, OSGi meta data can come from elsewhere (i.e. not necessarily from the manifest).
This has been a fundamental design decision from the beginning. It is also true for other
deployment types in AS7. The metadata can be constructed from multiple sources (i.e.
descriptors, annotations, overlays, etc). IIRC, we've always been doing it like this
in AS even in the very early versions.
I will play a little bit more with this. One of the things that needs a little bit more
work is supporting context.installBundle("webbundle:file://somewhere?params").
I.e. without providing the inputstream param. I think this can probably be done by
registering a 'real' URL handler that does nothing but provide the inputstream for
the embedded URL piece.
Yes, exactly. It should work as soon as you register that URLHandler. We do not need to
support this use case on the management code paths (i.e. CLI/Console).
Cheers,
David
On 01/12/2012 05:14, Thomas Diesler wrote:
> Please have a look at #3559 It shows how both use cases
>
>>> #1 Deployment through CLI, Console, Management API
>>> #2 Deployment through BundleContext.install(…)
>
> work with the approach I suggested below.
>
> cheers
> --thomas
>
> On Nov 30, 2012, at 5:41 PM, Thomas Diesler <thomas.diesler(a)jboss.com> wrote:
>
>> ok, you'll get the prototype ;-)
>>
>> have a nice weekend
>>
>> On Nov 30, 2012, at 5:35 PM, David Bosschaert <david(a)redhat.com> wrote:
>>
>>> 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(a)jboss.com
<mailto:thomas.diesler@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(a)redhat.com
<mailto:david@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...
>>>>>>>
>>>>>>> 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(a)jboss.com <mailto:thomas.diesler@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...
>>>>>>>>
>>>>>>>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>>>>>>>> Thomas Diesler
>>>>>>>> JBoss OSGi Lead
>>>>>>>> JBoss, a division of Red Hat
>>>>>>>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Nov 29, 2012, at 10:11 PM, David Bosschaert
<david(a)redhat.com <mailto:david@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(a)redhat.com <mailto:david@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(a)lists.jboss.org
<mailto:jboss-as7-dev@lists.jboss.org>
>>>>>>>>>>>>>
https://lists.jboss.org/mailman/listinfo/jboss-as7-dev
>>>>>>>>>
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> jboss-as7-dev mailing list
>>>>>>>> jboss-as7-dev(a)lists.jboss.org
<mailto:jboss-as7-dev@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(a)lists.jboss.org
<mailto:jboss-as7-dev@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
>>>>
>>>>
>>>>
>>>
>>
>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>> Thomas Diesler
>> JBoss OSGi Lead
>> JBoss, a division of Red Hat
>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>>
>>
>>
>>
>> _______________________________________________
>> jboss-as7-dev mailing list
>> jboss-as7-dev(a)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(a)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