On Mon, Apr 12, 2010 at 17:22, Lin Sun <[email protected]> wrote: > Hi Guillaume > > I have the following questions regarding the SPI - > Regarding Session, can you define what is the behavior for > process/dropped/commit/rollback/prepare? I have a hard time to think > about what can we find out in prepare phase to see if the bundle or > subsystem is installable, without actually running through the > installation. Also, what is considered rollback, in the case of > subsystem or bundle update? Seems we would have to get the > bundle/subsystem to its previous state before the update but we may > not be able to always honor that. >
I initially simply borrowed this interface from the DeployementAdmin spec, but I agree I'm not really sure how the prepare phase could be used in a smart way. I'd have no problem to remove if at this point. In the case of updates, you're right that the goal would be to revert to the last state. In the current code, a bundle processor will be called for each updated or new bundle. I was assuming (but haven't really thought about that in details), that a bundle would be updated only of the version is already installed and the RESOURCE_UPDATE_ATTRIBUTE is set on the resource. The goal of this attribute is to force the update in case the content of the bundle has changed, but the version has not. This would be true for maven snapshots for example. In such a case, the bundle would be updated, but in all other cases, the bundle would either be untouched, or a new one installed (with a different version). In the case of an update, I agree we can't revert, but then, it's a snapshot, and i would think it's not that big a problem to not really revert them. For subsystems, I think it should be possible to revert to the previous state if we keep the list of constituents before starting the update and somehow revert to those. We might be able to recreate the current list of constituents from the header too. Not really sure. Also, in case of a subsystem update, I'm not sure what to do with resources that would be provisioned in the parent context ... Another thing that came to my mind, is that the parent context may not be the best place to put all those dependencies. A peer subsystem with an Export-All policy might be better manageable, as those would be located in a well defined place instead of bloating the parent context. > Regarding API, for SubsystemEvent, there is a type called RESOLVED. I > could not figure out when we could emit that type, as the framework > can resolve a bundle any time. > I would suppose we could listen to the composite state and fire the event when the composite itself enters the RESOLVED state. There may be little need for this event, not sure about the use cases yet. > > Thanks > > Lin > > On Wed, Mar 31, 2010 at 7:42 PM, Guillaume Nodet <[email protected]> wrote: > > Renaming the subject of this thread. > > > > FWIW, I've just committed a rough SPI proposal which is based on the > > following: > > * a Resource abstraction which is some data that is identified, > versioned > > and typed > > such as a bundle, subsystem or any other data that can be accessed > > remotely or > > put into an archive > > * ResourceProcessor: the processor is able to install the resource into > > the subsystem. > > this comes from the DeploymentAdmin spec which is a nice read (and > > would be a nice > > spec without the non sharing policy problem around bundles). This > > allow populating > > the ConfigAdmin with some configuration for example or deploying > bundles > > and nested > > subsystems > > * ResourceConverter: which is able to transform a resource into another > > kind of > > resource (for example a blueprint xml definition into an osgi bundle, > > or a web app into a > > wab). > > * ResourceResolver: used to create Resource objects from a string > > representation (usually a > > clause from one of the header of the subsystem, something like > > symbolicname;version=1.0;type=bundle > > The resolver is also used to compute the transitive closure of the > > subsystem, i.e. find all the > > resources that need to be installed in addition to the key ones. > Those > > resources will then > > be processed by various processors depending on their type. > > > > So this is the rough idea. > > > > Note that the two most important interfaces are Resource and > > ResourceProcessor imho, because > > I would assume processors could be defined outside of the subsystem > > implementation. > > Converters are here for ease of use, as we could always imagine that the > > transformation is done > > offline instead of on the fly. As for the resolver, I'm still not sure > if > > this should be a public interface > > from the API or something at a lower level (such as a SPI which would be > > specific to a given > > implementation). At least, adding this interface allow us to talk about > it > > and that would even be > > beneficial when explaining what happens because we have something to put > a > > name onto for the > > piece of code that compute the transitive dependencies. > > > > Anyway, there's a ton of things to be fleshed out about how the > > SubsystemAdmin would find and > > use those objects, but I wanted to check those in sooner rather than > later > > to once again gather > > feedback. > > > > Last but not least, the approach i've taken is quite different than the > > application api/spi. The main > > difference is that I don't like the idea to write an object model to > > represent the subsystem metadata. > > I think this is an implementation detail and if put in the api/spi would > be > > redundant with the > > definition of the constants and mostly the headers, which is what the > user > > will actually manipulate. > > I'd like to go down to the minimum set of interfaces which are necessary > and > > useful. > > > > On Thu, Apr 1, 2010 at 00:59, Guillaume Nodet <[email protected]> wrote: > > > >> Hi Lin, thx for this very good feedback. See further comments inline. > >> > >> On Wed, Mar 31, 2010 at 22:39, Lin Sun <[email protected]> wrote: > >> > >>> Hi Guillaume, > >>> > >>> Thanks for updating the APIs. I have the following comments - > >>> > >>> 1. SubsystemAdmin.getSubsystem(id). I wonder if we can provide a > >>> method like getSubsystem(String scope). subsystemScope can be > >>> calculated using subsystem symbolic name + "_" + subsystem version, > >>> and it can be used to uniquely identify subsystems instead of (or in > >>> addition to) a long id. Whenever a subsystem gets updated, we would > >>> need some way to tell which of the existing sybsystem it is updating. > >>> To me, it is easy to tell that by the subsystem scope which can be > >>> simply calculated from the bundle location. Another thought is to use > >>> bundle location, but I don't think that is guaranteed to be unique, > >>> when people are using install(location, inputstream) to install the > >>> subsystem. > >>> > >>> > >> The first question that comes to my mind is about the use of the > >> scope/identifier. > >> I don't have any problem adding such an identifier to a subsystem (or > >> replace the > >> long identifier by a string), however, I'm concerned about using the > >> symbolic name > >> + version as the identifier. The problem is that when updating the > >> subsystem with > >> a more recent version, the id would either change (which would be > >> problematic) or > >> become inconsistent (which would be bad too). In addition a user could > >> choose > >> to have the same subsystem (identified by its symbolic name) running in > two > >> different versions. The question becomes what would happen if the user > try > >> to > >> update the first one using the more up to date subsystem. For bundles, > it > >> would > >> fail afaik. In addition, the id would have been mapped to the > underlying > >> composite > >> id, leading to a simple way to access the composite if needed. > >> > >> So i'd like to understand how you see this scope being used. If you > want a > >> generated id, > >> then what about using a UUID ? If what you want is something that can > >> easily be undestand > >> and linked to the symbolicname / version, then is that really an unique > >> identifier ? because it > >> may change over time. Actually, I think it would be ok to update the > >> subsystem and have > >> the updated version have a different symbolic name. > >> > >> > >>> 2. SubsystemAdmin.getSubsystems() returns Collection<Subsystem>. I > >>> wonder if it is more convenient to return Map<String, Subsystem> where > >>> the key is the subsystem scope. > >>> > >> > >> Right, that makes sense. I think I was trying to avoid having to build > a > >> read-only map, > >> but there's no real point here. Having the map would be sufficient, and > we > >> should then > >> remove the getSubsystem(long) method imho. > >> > >> > >>> > >>> 3. Subsystem.install(location). I think this should be install(String > >>> location, BundleContext bc) instead, because we would need the bundle > >>> context to get the CompositeAdmin service from OSGi service registry, > >>> assuming we would use that to install the composite. We would also > >>> need bundle context to install constituents. > >>> > >>> 4. similar as No. 3, Subsyste.install(location, content) should be > >>> install(String location, InputStream content, BundleContext bc) > >>> > >>> > >> Ok, so I think those two points are related to nested subsystems. My > idea > >> was > >> to follow what composites do, not necessarily because we would use > those, > >> but > >> because I think users will rarely have to deal with nested subsystems > >> directly. > >> Let me explain: subsystems are defined by the user and deployed. I > don't > >> think > >> we should encourage users to manually install new bundles into the > created > >> subsystem, > >> because i would assume those would be uninstalled as soon as the > subsystem > >> is > >> updated (or do we want to actually track the changes done by the user so > >> that we don't > >> rollback manual changes?). My idea was that if the user want to add / > >> remove bundles > >> from the composite, he needs to update the subsystem. I don't think we > >> should forbid > >> such changes, just that we should not track and manage those changes. > >> Nested subsystems are imho the same problem. Nested subsystems would be > >> installed > >> because a subsystem references another subsystem in its key content I > >> think. So you > >> would not really want the user to manually install a subsystem inside an > >> existing subsystem. > >> > >> Now, if what you were thinking was about installing subsystems from > inside > >> a composite, > >> the problem is a bit different. My idea was that the subsystem would be > >> installed from inside > >> the composite where the SubsystemAdmin service you use comes from. So > if > >> you have a composite > >> and you want to install a subsystem into it, you retrieve the > >> SubsystemAdmin from this composite > >> and simply call one of the install method. This means that either: > >> * the subsystem implementation has been installed directly in this > >> composite > >> * or the subsystem impl has been installed in a parent composite and > the > >> composite service policy has been > >> written to allow the service goes through > >> From an implementation pov, I think it's quite easy to achieve by using > a > >> ServiceFactory and using the > >> bundle context from the requesting bundle. > >> > >> > >>> 5. Subsystem.getState(). I wonder if we should reinvent here. Is > >>> there any reason why we don't make the return type of int, and just > >>> delegate this to the compositeBundle.getState(). Also, what if the > >>> composite bundle and constituents have different states. Does this > >>> method only work when the states are consistent among these bundles? > >>> > >> > >> My original idea was also to map closely to the composite state, so I > don't > >> have any problem > >> using an int instead of an enum, though I think the state of composite > is > >> an int because a composite > >> *is* a bundle and enums did not exist at the time the bundle interface > has > >> been created. > >> However, Subsystem do not inherit the Bundle or CompositeBundle > interface, > >> so we could decide to > >> use an enum (because the state is semantically an enum). > >> > >> That being said, the question you raise about the constituents state is > >> important. We need to choose > >> whether we want to represent the state of the subsystem as an aggregate > of > >> the constituents state or not. > >> That would surely be interesting, because you would know the real state > of > >> your subsystem much more > >> easily. The problem is i'm not sure what would happen if one of the > >> bundle can't start or is manually > >> stopped by the user. Would this leave the subsystem in the STARTING > state > >> until the start or stop > >> method is called ? > >> > >> > >>> 6. Subsystem.start() or stop(), I think it should throw either > >>> BundleException or SubsystemException. > >>> > >> > >> Yeah, SubsystemException would be fine. Currently I've defined > >> SubsystemException as being > >> a RuntimeException though ... > >> > >>> > >>> 7. The return type of Subsystem.getHeaders, do we want to use > >>> Dictionary<String, String> or Dictionary to be consistent with > >>> Bundle.getHeaders()? when we implement this method, we can just > >>> delegate to compositeBundle.getHeaders. > >>> > >> > >> Two things here. First, I'm not sure we would want to return the > composite > >> headers. > >> First because composite headers can't be localized, and second because i > >> was thinking > >> about returning the headers from the subsystem manifest as it was > >> installed, not of the > >> underlying composite (which includes computed headers for package and > >> service policies). > >> So if we return directly the composite headers, it would surely make > more > >> sense to use the > >> same type, but if we don't, i think using Map is more natural. OSGi is > >> really the only place > >> that uses Dictionary instead of Map ;-) > >> > >> > >>> > >>> 8. I'd like the add the following methods to Subsystem.java: > >>> > >>> + void uninstall() throws SubsystemException; > >>> + > >>> + String getScope(); > >>> + > >>> + void update() throws SubsystemException; > >>> + > >>> + void update(InputStream content) throws SubsystemException; > >>> > >>> I think the uninstall(), update() are needed, because the > >>> SubsystemAdmin.uninstall/update can just delegate the work to the > >>> actual subsystem. In fact, the SubsustemAdmin cannot really do the > >>> work, unless we make the composite bundle available out of the > >>> Subsystem. > >>> > >> > >> I agree to your point from an implementation point of view. > >> I initially put those methods on the Subsystem, but later moved them > >> to the SubsystemAdmin. I did that because it leads to a cleaner > separation > >> between the actors and the responsibilities. In my mind, the > >> SubsystemAdmin > >> is responsible for managing the content of subsystems (installation / > >> update / creation), > >> whereas the subsystem does not perform such modifications and the only > >> methods > >> available are start() and stop(). I had the exact same objection on > the > >> application > >> api some time ago and Alasdair said the design was more service oriented > >> rather than > >> object oriented. And now, I think it makes more sense to do it that > way. > >> > >> > >>> > >>> I am also attaching a patch for stuff described above. I'd love to > >>> help on implementing these APIs if that is ok with you. > >>> > >> > >> Do you mind discussing the changes a bit more ? > >> > >> > >>> > >>> Thanks > >>> > >>> Lin > >>> > >>> > >>> > >>> On Mon, Mar 29, 2010 at 6:34 PM, Guillaume Nodet <[email protected]> > >>> wrote: > >>> > FWIW, I've slightly updated the API with some feedback here and > mostly > >>> two > >>> > other changes: > >>> > * moved some management methods from Subsystem to SubsystemAdmin > >>> (update > >>> > and uninstall) > >>> > * make SubsystemConstants a non instantiable class instead of an > >>> interface > >>> > > >>> > On Fri, Mar 26, 2010 at 16:27, Guillaume Nodet <[email protected]> > >>> wrote: > >>> > > >>> >> Sorry, forgot to give a pointer: > >>> >> > >>> >> > >>> > http://svn.apache.org/repos/asf/incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/ > >>> >> > >>> >> > >>> >> On Fri, Mar 26, 2010 at 15:27, Guillaume Nodet <[email protected]> > >>> wrote: > >>> >> > >>> >>> I've just checked in a user-oriented API for subsystems (which I > hope > >>> can > >>> >>> be a superset of applications). > >>> >>> This is not the SPI part, but simply what the user needs to > manipulate > >>> >>> subsystems at runtime. > >>> >>> The design has been chosen to be much more familiar to the OSGi API > >>> for > >>> >>> bundles. > >>> >>> > >>> >>> I'm planning to continue on this area when time permits, but I > welcome > >>> >>> everyone to have a look and give feedback. > >>> >>> > >>> >>> On Thu, Mar 18, 2010 at 18:16, Jarek Gawor <[email protected]> > wrote: > >>> >>> > >>> >>>> Hi all, > >>> >>>> > >>> >>>> I have a few questions / comments on the Aries Application API. > >>> >>>> Specifically, about AriesApplicationManager and > >>> >>>> AriesApplicationContextManager API. > >>> >>>> > >>> >>>> The application-management module provides a default > implementation > >>> >>>> for the AriesApplicationManager API while the application-runtime > >>> >>>> module provides an example implementation of the > >>> >>>> AriesApplicationContextManager API. It is expected (as indicated > by > >>> >>>> JavaDoc) that different server runtimes will provide their own > >>> >>>> implementations of the AriesApplicationContextManager API. > >>> >>>> > >>> >>>> So it seems to me like the AriesApplicationContextManager is more > of > >>> a > >>> >>>> SPI - something that user shouldn't/wouldn't normally use. If so, > the > >>> >>>> user would only interact with the AriesApplicationManager API to > >>> >>>> perform application operations. If that's true then the > >>> >>>> AriesApplicationManager is missing methods for getting all > >>> >>>> AriesApplicationContexts or finding one by name. And at the same > time > >>> >>>> the AriesApplicationContextManager would probably need to be > >>> >>>> completely reworked. For example to be named > >>> >>>> AriesApplicationManagerProvider and have corresponding > >>> >>>> install/uninstall/getContexts/findContext operations. > >>> >>>> Or maybe we should just get rid off the > >>> AriesApplicationContextManager > >>> >>>> completely and let folks implement the AriesApplicationManager API > >>> >>>> directly? > >>> >>>> > >>> >>>> Btw, by 'user' I meant some code that uses these API to perform > some > >>> >>>> application operations. For example, in my case, I would like to > have > >>> >>>> some osgi shell commands that use these API to > >>> >>>> install/uninstall/start/stop applications. > >>> >>>> > >>> >>>> Jarek > >>> >>>> > >>> >>> > >>> >>> > >>> >>> > >>> >>> -- > >>> >>> Cheers, > >>> >>> Guillaume Nodet > >>> >>> ------------------------ > >>> >>> Blog: http://gnodet.blogspot.com/ > >>> >>> ------------------------ > >>> >>> Open Source SOA > >>> >>> http://fusesource.com > >>> >>> > >>> >>> > >>> >>> > >>> >> > >>> >> > >>> >> -- > >>> >> Cheers, > >>> >> Guillaume Nodet > >>> >> ------------------------ > >>> >> Blog: http://gnodet.blogspot.com/ > >>> >> ------------------------ > >>> >> Open Source SOA > >>> >> http://fusesource.com > >>> >> > >>> >> > >>> >> > >>> > > >>> > > >>> > -- > >>> > Cheers, > >>> > Guillaume Nodet > >>> > ------------------------ > >>> > Blog: http://gnodet.blogspot.com/ > >>> > ------------------------ > >>> > Open Source SOA > >>> > http://fusesource.com > >>> > > >>> > >> > >> > >> > >> -- > >> Cheers, > >> Guillaume Nodet > >> ------------------------ > >> Blog: http://gnodet.blogspot.com/ > >> ------------------------ > >> Open Source SOA > >> http://fusesource.com > >> > >> > >> > > > > > > -- > > Cheers, > > Guillaume Nodet > > ------------------------ > > Blog: http://gnodet.blogspot.com/ > > ------------------------ > > Open Source SOA > > http://fusesource.com > > > -- Cheers, Guillaume Nodet ------------------------ Blog: http://gnodet.blogspot.com/ ------------------------ Open Source SOA http://fusesource.com
