karaf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Guillaume Nodet <gno...@gmail.com>
Subject Re: Simpler karaf shell command/action definition
Date Wed, 09 May 2012 16:05:29 GMT
That's what we the namespace handler does.  The <action/> are actually
templates.
The service publishing is needed at some point so that the shell knows
about the commands.

I don't really understand how you can really simply the minimum definition
we have now:
    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.0.0">
        <command>
            <action class="..."/>
        </command>
    </command-bundle>


On Wed, May 9, 2012 at 5:54 PM, Christian Schneider <chris@die-schneider.net
> wrote:

> The idea is to use the object from the service only as a prototype. So we
> would retrieve the object from the service and clone it in some way.
> If the action is defined in blueprint we could use the blueprint prototype
> support for that.
>
> Perhaps we can even do that without the service publishing. Is it possible
> to react on the blueprint context that is created and check for beans of
> type action?
> That would make the syntax even simpler as we then only have the bean
> definition.
>
> Perhaps the cleanest way would be to use:
>
> <actions xmlns="...">
> <bean class="MyAction>
> </bean>
> </actions>
>
> So we would use a BP namespace but inside use plain beans which people
> understand easily. As the beans would be inlined I think they would even
> default to prototype scope. Honestly this is not too far from what we have
> now...
>
> Btw. Is it possible to use a bean as a kind of template like in spring? We
> have many cases where many commands need the same injections and currently
> we have to define the injects for each bean.
>
> Christian
>
> Am 09.05.2012 17:24, schrieb Guillaume Nodet:
>
>> Second point, the action is purposely not published as an OSGi service
>> because it would have a big incompatible consequence, which is that the
>> action would have to be stateless and thread safe.  Given the action
>> parameters are injected when the action is created, I don't really see how
>> it could be done.
>>
>> On Wed, May 9, 2012 at 5:08 PM, Christian Schneider<chris@die-schneider.*
>> *net <chris@die-schneider.net>
>>
>>> wrote:
>>> We currently either use the blueprint namespace or the AbstractCommand
>>> and
>>> a service definition to define commands. This has some shortcomings:
>>> - The blueprint namespace definition is a bit verbose and at first I did
>>> not understand that actions in the xml can be injected like beans
>>> Example:
>>>
>>>    <command-bundle xmlns="http://karaf.apache.****
>>> org/xmlns/shell/v1.1.0<http://**karaf.apache.org/xmlns/shell/**v1.1.0<http://karaf.apache.org/xmlns/shell/v1.1.0>
>>> >
>>> ">
>>>        <command>
>>>             <action class="org.apache.karaf.shell.****
>>>
>>> commands.impl.WatchAction">
>>>                <property name="commandProcessor" ref="commandProcessor"/>
>>>            </action>
>>>            <completers>
>>>                <ref component-id="****commandCompleter" />
>>>
>>>                <null/>
>>>            </completers>
>>>        </command>
>>>    </command-bundle>
>>>
>>> - The other way using AbstractCommand and a service def is even more
>>> verbose and exposes a lot of implementation details like the
>>> DefaultActionPreparator
>>>
>>> <bean id="commandCompleter" class="org.apache.karaf.shell.****
>>> console.completer.****CommandsCompleter"/>
>>>    <service>
>>>        <interfaces>
>>>            <value>org.apache.felix.****service.command.Function</****
>>> value>
>>>            <value>org.apache.karaf.shell.**
>>> **console.CompletableFunction<**/**
>>> value>
>>>        </interfaces>
>>>        <service-properties>
>>>            <entry key="osgi.command.scope" value="*"/>
>>>            <entry key="osgi.command.function" value="help"/>
>>>        </service-properties>
>>>        <bean class="org.apache.karaf.shell.****console.commands.**
>>>
>>> BlueprintCommand">
>>>            <property name="blueprintContainer" ref="blueprintContainer"/>
>>>            <property name="blueprintConverter" ref="blueprintConverter"/>
>>>            <property name="actionId" value="help"/>
>>>            <property name="completers">
>>>                <list>
>>>                    <bean class="org.apache.karaf.shell.****
>>> console.completer.****CommandNamesCompleter"/>
>>>                </list>
>>>            </property>
>>>        </bean>
>>>    </service>
>>>
>>>    <bean id="help" class="org.apache.karaf.shell.**
>>> **help.impl.HelpAction"
>>>
>>> activation="lazy" scope="prototype">
>>>        <property name="provider" ref="helpSystem"/>
>>>    </bean>
>>>
>>>
>>> So here is what I propose:
>>>
>>> The first thing is to add a complerers property to the @Commands
>>> annotation. This is the last bit we need to make sure the annotations
>>> provide all metadata of an action.
>>> Then the idea is to simply define the action as a blueprint bean and
>>> publish it as an OSGi service. We then have an extender that adapts these
>>> to the felix gogo commands.
>>>
>>> So the blueprint code for the help example above would look like:
>>> <service interface="org.apache.karaf.****shell.commands.Action">
>>> <bean id="help" class="org.apache.karaf.shell.****help.impl.HelpAction"
>>> activation="lazy" scope="prototype">
>>> <property name="provider" ref="helpSystem"/>
>>> </bean>
>>> </service>
>>>
>>> With the upcoming blueprint annotations we could simply annotate the
>>> Action class and need no blueprint code at all. The above style would
>>> also
>>> work much better with declarative services. If you look at the scr module
>>> in karaf you see how complicated it is till now to create a command in
>>> ds.
>>>
>>> One problem with the aproach is of course that the Action has to be
>>> created per execution. So we need to find a good way to clone the Action
>>> object. To a degree this problem is already present int the current
>>> solution.
>>>
>>> So what are the advantages:
>>> - The user code only depends on some very few interfaces like Action and
>>> the annotations. AbstractCommand and similar are not needed anymore and
>>> the
>>> impls can be private
>>> - The blueprint syntax is quite concise and does not need a special
>>> namespace
>>> - Using BP annotations the syntax is even more concise as no xml is
>>> needed. This would not be possible with the current way
>>>
>>> So what do you think?
>>>
>>> Christian
>>>
>>> --
>>> Christian Schneider
>>> http://www.liquid-reality.de
>>>
>>> Open Source Architect
>>> Talend Application Integration Division http://www.talend.com
>>>
>>>
>>>
>>
>
> --
>
> Christian Schneider
> http://www.liquid-reality.de
>
> Open Source Architect
> Talend Application Integration Division http://www.talend.com
>
>


-- 
------------------------
Guillaume Nodet
------------------------
Blog: http://gnodet.blogspot.com/
------------------------
FuseSource, Integration everywhere
http://fusesource.com

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message