[ 
https://issues.apache.org/jira/browse/FELIX-4294?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13813326#comment-13813326
 ] 

Pierre De Rop edited comment on FELIX-4294 at 11/5/13 2:02 PM:
---------------------------------------------------------------

I'm pleased to attach FELIX-4294.patch, if you want to play with it and tell me 
what you think.

To install the patch:

* cd dependencymanager
* patch -p0 < FELIX-4294.patch
* rm -f shell/src/main/java/org/apache/felix/dm/shell/EquinoxDMCommand.java 
* rm -f shell/src/main/java/org/apache/felix/dm/shell/FelixDMCommand.java 
* rm -f shell/src/main/java/org/apache/felix/dm/shell/GogoDMCommand.java

Here is a complete description of the attached patch:

1) Usage:
=========

{code}

dm - List dependency manager components
   scope: dependencymanager
   flags:
      compact, cp   displays components using a compact form
      nodeps, nd   hides component dependencies
      notavail, na   only displays dependency manager unavailable components
      stats, st   displays dependency manager statistics
   options:
      bundleIds, b   list of Bundle Ids Or Bundle Symbolic Names (blank 
separated) [optional]
      componentIds, ci   component ids to display (list of longs, blank 
separated) [optional]
      components, c   regex(s) used to filter component implementation class 
names (blank separated, regex can be negated using "!" prefix) [optional]
      names, n   regex(s) used to filter  component declaration names (blank 
separated, regex can be negated using "!" prefix) [optional]
      services, s   OSGi filter used to filter OSGi services, and/or service 
properties [optional]
   parameters:
      CommandSession   
{code}

As you see, there are now some abbreviated options: compact -> cp, nodeps -> 
nd, na -> notavail, st -> stats

The "CommandSession" is automatically added by the gogo runtime, and allows to 
get the value of some variables declared in
the shell. We'll describe this later.

2) Implementation notes:
=======================

- Now, only gogo shell is supported. Adapted FELIX2955_ShellCommandTest test 
accordingly.

- Fully using powerful @Description, @Parameter gogo runtime annotations, which 
allow to automate command documentations,
and manage optional command's options. However, This means that the shell 
bundle has to compile and run with jdk1.5.
(Hope this is not a blocking problem ?)

- I had to add some methods in ComponentDeclaration, also did some minor, but 
necessary adaptations in the dependency manager core. Mainly, I added the 
following methods in the ComponentDeclaration interface:

{code}
+    /** Returns the class name of the Component implementation. */
+    public String getClassName();

+    /** Returns the service optionally provided by this component, or null */
+    public String[] getServices();

+    /** Returns the service properties, or null */
+    public Dictionary getServiceProperties();     

+    /** Returns the instance id of this component. */
+    public long getId();
{code}

- made more consistent displaying of aspect, adapters or resource adapter 
components. For instance:

{code}
g! dm nd

[8] org.apache.felix.dependencymanager.samples.annotation
 [3] Adapter for factory pid DictionaryImplFactoryPid registered
 [5] Aspect for interface 
org.apache.felix.dm.samples.annotation.DictionaryService with filter (lang=en) 
unregistered
 [6] Adapter for interface 
org.apache.felix.dm.samples.annotation.DictionaryService with filter (lang=en) 
registered
{code}

- Fixed a small issue in FactoryConfigurationAdapter, regarding 
getServiceProperties method.

3) "services" option:
====================

So, as you suggested, I added a "services" option, in order to filter on some 
OSGi service properties. You can even 
pass "objectClass" in order to filter on some service names.

Example for displaying all dictionary services:

{code}
g! dm nd s "(objectClass=*DictionaryService)"
[8] org.apache.felix.dependencymanager.samples.annotation
 [7] 
org.apache.felix.dm.samples.annotation.DictionaryService(service.pid=DictionaryImplFactoryPid.bd43cf50-01f4-4c78-8c71-ac3fd206ef4c,service.factoryPid=DictionaryImplFactoryPid,lang=en)
 registered
 [9] 
org.apache.felix.dm.samples.annotation.DictionaryService(service.pid=DictionaryImplFactoryPid.61bf07ca-ee40-4322-9db9-6098ecab034a,service.factoryPid=DictionaryImplFactoryPid,lang=fr)
 registered
{code}

Example for showing all services with lang=en:

{code}
g! dm nd s "(lang=en)"
[8] org.apache.felix.dependencymanager.samples.annotation
 [7] 
org.apache.felix.dm.samples.annotation.DictionaryService(service.pid=DictionaryImplFactoryPid.bd43cf50-01f4-4c78-8c71-ac3fd206ef4c,service.factoryPid=DictionaryImplFactoryPid,lang=en)
 registered
 [8] 
org.apache.felix.dm.samples.annotation.GogoEnglishDictionary(service.pid=DictionaryImplFactoryPid.bd43cf50-01f4-4c78-8c71-ac3fd206ef4c,service.factoryPid=DictionaryImplFactoryPid,osgi.command.function={englishCheck},lang=en,osgi.command.scope=dmsample.annotation)
 registered
{code}

4) "components" option:
======================

Added a "components" option, in order to filter on some component class names, 
instead of provided services.

5) "names" option
=================

The initial intent of this issue was to be able to easily make some filters on 
every displayed components.
So, since what is displayed is the String returned by the 
ComponentDeclaration.getName(),
I added a "names" option, which is similar to the "components" option, but the 
regex(s) are applied to the component names, which are currently displayed in 
the screen.

Example: to show all components displayed in the screen and whose names are 
starting with "org.apache.felix.dm.samples.annotation.*":

{code}
g! dm nd names ".*felix.dm.samples.annotation.*" 
[8] org.apache.felix.dependencymanager.samples.annotation
 [4] 
org.apache.felix.dm.samples.annotation.SpellChecker(osgi.command.function={spellcheck},osgi.command.scope=dmsample.annotation)
 registered
 [7] 
org.apache.felix.dm.samples.annotation.DictionaryService(service.pid=DictionaryImplFactoryPid.0ea88dc1-7f09-4a17-a60e-78f6af4c378a,service.factoryPid=DictionaryImplFactoryPid,lang=en)
 registered
 [8] 
org.apache.felix.dm.samples.annotation.GogoEnglishDictionary(service.pid=DictionaryImplFactoryPid.0ea88dc1-7f09-4a17-a60e-78f6af4c378a,service.factoryPid=DictionaryImplFactoryPid,osgi.command.function={englishCheck},lang=en,osgi.command.scope=dmsample.annotation)
 registered
{code}


6) component IDs
================

It turns out that in the attached patch, a new feature has also been added: 
components are now prefixed with their component ids. 
This allows to quickly dump the state of a given component using its component 
ID (see "ci" option).

For example, When you often need to check unregistered services and inspect 
some of them, you can simply do that:

{code}
g! dm|grep unregistered
 [15] com.nextenso.mux.MuxHandler(protocol=Diameter) unregistered
 [3] com.nextenso.mux.MuxFactory(service.ranking=-2147483648,local=true) 
unregistered
 [25] com.nextenso.mux.MuxHandler(protocol=Smpp) unregistered
 [38] com.nextenso.mux.MuxHandler(protocol=Radius) unregistered
 [102] 
com.alcatel.sip.sipservlet.server.jsr289.impl.CompositeActivator$RouterActivator@4e8b72(composite.scope=1)
 unregistered
 [149] 
com.alcatel.sip.sipservlet.server.jsr289.impl.CompositeActivator$RouterActivator@b77881(composite.scope=2)
 unregistered
 [50] com.nextenso.mux.MuxHandler(protocol=Smtp) unregistered
{code}

Here, components are prefixed with their component ids (see all prefixes under 
brackets).
And to directly dump the components with id 15 and 25, just do this:

{code}
g! dm ci "15 25"
[20] com.alcatel.as.agent.diameter
 [15] com.nextenso.mux.MuxHandler(protocol=Diameter) unregistered
    java.util.Dictionary (service.pid=system) service required available
    com.alcatel.as.service.concurrent.PlatformExecutors service required 
available
    com.alcatel.as.service.concurrent.TimerService (strict=false) service 
required available
    com.nextenso.proxylet.engine.ProxyletApplication (protocol=diameter) 
service required unavailable
    com.alcatel.as.service.metering.MeteringService service required available
    com.alcatel.as.service.management.ShutdownService service required available
    com.nextenso.proxylet.diameter.DiameterRouteTable service required available
    java.util.Dictionary (service.pid=diameteragent) service required available
 [25] com.nextenso.mux.MuxHandler(protocol=Smpp) unregistered
    java.util.Dictionary (service.pid=system) service required available
    java.util.Dictionary (service.pid=smsagent) service required available
    com.alcatel.as.util.osgi.ServiceRegistry (name=com.nextenso.sms.agent) 
service required available
    com.nextenso.proxylet.engine.ProxyletApplication (protocol=smpp) service 
required unavailable
{code}

7) "notavail" option
===============

I also did another minor modification regarding the "notavail" option:

When you provide "notavail", so far, unregistered components were displayed 
including *all* available component dependencies.
But, sometimes, it is a pain to pay attention only to unavailable dependencies. 
 And what is precisely interesting is to quickly look for such unavailable 
dependencies.
So, when the "notavail option" is provided, the attached patch now displays 
unregistered component with 
only unavailable dependencies, and hides other available dependencies.

In this way, it is easier to make some diagnostics on a large framework, with 
many services.

For instance, the following component is unregistered because it has one 
missing dependency:

{code}
g! dm ci 50
[102] com.alcatel.as.agent.mail
 [50] com.nextenso.mux.MuxHandler(protocol=Smtp) unregistered
    java.util.Dictionary (service.pid=system) service required available
    java.util.Dictionary (service.pid=smtpagent) service required available
    com.alcatel.as.util.osgi.ServiceRegistry (name=com.nextenso.mail.agent) 
service required available
    com.nextenso.proxylet.engine.ProxyletApplication (protocol=smtp) service 
required unavailable 
{code}

So, if you type dm notavail on the component id 50, you will then quickly see 
the missing dependency:

{code}
g! dm na ci 50
[102] com.alcatel.as.agent.mail                                                 
                                                                                
        
 [50] com.nextenso.mux.MuxHandler(protocol=Smtp) unregistered                   
                                                                                
        
    com.nextenso.proxylet.engine.ProxyletApplication (protocol=smtp) service 
required unavailable                                                            
           
{code}

Here, We only display the missing dependency on the missing 
com.nextenso.proxylet.engine.ProxyletApplication service.

8) passing options using special gogo shell variables
==========================================

The "compact" option can also be set from shell, using a special 
"dependencymanager.compact" variable.
This is useful to avoid passing the "compact" option on every commands:

{code}
g! dependencymanager.compact=true

g! dm 
[2] o.a.m.conf
 [0] o.o.s.c.M.p.a.t.factory) R(o.a.m.TenantFactoryConfiguration S RA 
o.o.s.l.LogService S OA)
{code}

Same applies for "components", "services", and "names" options:

{code}
g! dependencymanager.components="!.*amdatu.*"
!.*amdatu.*
{code}

Now, all dm commands are implicitely using the "components" option specified 
from the shell variable:

{code}
g! dm
[2] org.amdatu.multitenant.conf
 [0] 
org.osgi.service.cm.ManagedServiceFactory(service.pid=org.amdatu.tenant.factory)
 registered
    org.amdatu.multitenant.TenantFactoryConfiguration service required available
    org.osgi.service.log.LogService service optional available
[16] pierre.multitenant.tenant
 [37] pierre.multitenant.tenant.Tenant2 registered
 [40] pierre.multitenant.tenant.Tenant2 registered
[17] pierre.multitenant.platform
 [29] pierre.multitenant.platform.Platform registered
    org.osgi.service.log.LogService service required available
    pierre.multitenant.both.Both service required available
[18] pierre.multitenant.both
 [33] pierre.multitenant.both.Both registered
 [31] pierre.multitenant.both.Both registered
 [35] pierre.multitenant.both.Both registered
{code}



was (Author: pderop):
I'm pleased to attach FELIX-4294.patch, if you want to play with it and tell me 
what you think.

To install the patch:

* cd dependencymanager
* patch -p0 < FELIX-4294.patch
* rm -f shell/src/main/java/org/apache/felix/dm/shell/EquinoxDMCommand.java 
* rm -f shell/src/main/java/org/apache/felix/dm/shell/FelixDMCommand.java 
* rm -f shell/src/main/java/org/apache/felix/dm/shell/GogoDMCommand.java

Here is a complete description of the attached patch:

1) Usage:
=========

{code}

dm - List dependency manager components
   scope: dependencymanager
   flags:
      compact, cp   displays components using a compact form
      nodeps, nd   hides component dependencies
      notavail, na   only displays dependency manager unavailable components
      stats, st   displays dependency manager statistics
   options:
      bundleIds, b   list of Bundle Ids Or Bundle Symbolic Names (blank 
separated) [optional]
      componentIds, ci   component ids to display (list of longs, blank 
separated) [optional]
      components, c   regex(s) used to filter on some component implementation 
class names (blank separated, regex can be negated using "!" prefix) [optional]
      names, n   regex(s) used to filter on either some component declaration 
names (blank separated, regex can be negated using "!" prefix) [optional]
      services, s   OSGi filter used to filter some service properties 
[optional]
   parameters:
      CommandSession   
{code}

As you see, there are now some abbreviated options: compact -> cp, nodeps -> 
nd, na -> notavail, st -> stats

The "CommandSession" is automatically added by the gogo runtime, and allows to 
get the value of some variables declared in
the shell. We'll describe this later.

2) Implementation notes:
=======================

- Now, only gogo shell is supported. Adapted FELIX2955_ShellCommandTest test 
accordingly.

- Fully using powerful @Description, @Parameter gogo runtime annotations, which 
allow to automate command documentations,
and manage optional command's options. However, This means that the shell 
bundle has to compile and run with jdk1.5.
(Hope this is not a blocking problem ?)

- I had to add some methods in ComponentDeclaration, also did some minor, but 
necessary adaptations in the dependency manager core. Mainly, I added the 
following methods in the ComponentDeclaration interface:

{code}
+    /** Returns the class name of the Component implementation. */
+    public String getClassName();

+    /** Returns the service optionally provided by this component, or null */
+    public String[] getServices();

+    /** Returns the service properties, or null */
+    public Dictionary getServiceProperties();     

+    /** Returns the instance id of this component. */
+    public long getId();
{code}

- made more consistent displaying of aspect, adapters or resource adapter 
components. For instance:

{code}
g! dm nd

[8] org.apache.felix.dependencymanager.samples.annotation
 [3] Adapter for factory pid DictionaryImplFactoryPid registered
 [5] Aspect for interface 
org.apache.felix.dm.samples.annotation.DictionaryService with filter (lang=en) 
unregistered
 [6] Adapter for interface 
org.apache.felix.dm.samples.annotation.DictionaryService with filter (lang=en) 
registered
{code}

- Fixed a small issue in FactoryConfigurationAdapter, regarding 
getServiceProperties method.

3) "services" option:
====================

So, as you suggested, I added a "services" option, in order to filter on some 
OSGi service properties. You can even 
pass "objectClass" in order to filter on some service names.

Example for displaying all dictionary services:

{code}
g! dm nd s "(objectClass=*DictionaryService)"
[8] org.apache.felix.dependencymanager.samples.annotation
 [7] 
org.apache.felix.dm.samples.annotation.DictionaryService(service.pid=DictionaryImplFactoryPid.bd43cf50-01f4-4c78-8c71-ac3fd206ef4c,service.factoryPid=DictionaryImplFactoryPid,lang=en)
 registered
 [9] 
org.apache.felix.dm.samples.annotation.DictionaryService(service.pid=DictionaryImplFactoryPid.61bf07ca-ee40-4322-9db9-6098ecab034a,service.factoryPid=DictionaryImplFactoryPid,lang=fr)
 registered
{code}

Example for showing all services with lang=en:

{code}
g! dm nd s "(lang=en)"
[8] org.apache.felix.dependencymanager.samples.annotation
 [7] 
org.apache.felix.dm.samples.annotation.DictionaryService(service.pid=DictionaryImplFactoryPid.bd43cf50-01f4-4c78-8c71-ac3fd206ef4c,service.factoryPid=DictionaryImplFactoryPid,lang=en)
 registered
 [8] 
org.apache.felix.dm.samples.annotation.GogoEnglishDictionary(service.pid=DictionaryImplFactoryPid.bd43cf50-01f4-4c78-8c71-ac3fd206ef4c,service.factoryPid=DictionaryImplFactoryPid,osgi.command.function={englishCheck},lang=en,osgi.command.scope=dmsample.annotation)
 registered
{code}

4) "components" option:
======================

Added a "components" option, in order to filter on some component class names, 
instead of provided services.

5) "names" option
=================

The initial intent of this issue was to be able to easily make some filters on 
every displayed components.
So, since what is displayed is the String returned by the 
ComponentDeclaration.getName(),
I added a "names" option, which is similar to the "components" option, but the 
regex(s) are applied to the component names, which are currently displayed in 
the screen.

Example: to show all components displayed in the screen and whose names are 
starting with "org.apache.felix.dm.samples.annotation.*":

{code}
g! dm nd names ".*felix.dm.samples.annotation.*" 
[8] org.apache.felix.dependencymanager.samples.annotation
 [4] 
org.apache.felix.dm.samples.annotation.SpellChecker(osgi.command.function={spellcheck},osgi.command.scope=dmsample.annotation)
 registered
 [7] 
org.apache.felix.dm.samples.annotation.DictionaryService(service.pid=DictionaryImplFactoryPid.0ea88dc1-7f09-4a17-a60e-78f6af4c378a,service.factoryPid=DictionaryImplFactoryPid,lang=en)
 registered
 [8] 
org.apache.felix.dm.samples.annotation.GogoEnglishDictionary(service.pid=DictionaryImplFactoryPid.0ea88dc1-7f09-4a17-a60e-78f6af4c378a,service.factoryPid=DictionaryImplFactoryPid,osgi.command.function={englishCheck},lang=en,osgi.command.scope=dmsample.annotation)
 registered
{code}


6) component IDs
================

It turns out that in the attached patch, a new feature has also been added: 
components are now prefixed with their component ids. 
This allows to quickly dump the state of a given component using its component 
ID (see "ci" option).

For example, When you often need to check unregistered services and inspect 
some of them, you can simply do that:

{code}
g! dm|grep unregistered
 [15] com.nextenso.mux.MuxHandler(protocol=Diameter) unregistered
 [3] com.nextenso.mux.MuxFactory(service.ranking=-2147483648,local=true) 
unregistered
 [25] com.nextenso.mux.MuxHandler(protocol=Smpp) unregistered
 [38] com.nextenso.mux.MuxHandler(protocol=Radius) unregistered
 [102] 
com.alcatel.sip.sipservlet.server.jsr289.impl.CompositeActivator$RouterActivator@4e8b72(composite.scope=1)
 unregistered
 [149] 
com.alcatel.sip.sipservlet.server.jsr289.impl.CompositeActivator$RouterActivator@b77881(composite.scope=2)
 unregistered
 [50] com.nextenso.mux.MuxHandler(protocol=Smtp) unregistered
{code}

Here, components are prefixed with their component ids (see all prefixes under 
brackets).
And to directly dump the components with id 15 and 25, just do this:

{code}
g! dm ci "15 25"
[20] com.alcatel.as.agent.diameter
 [15] com.nextenso.mux.MuxHandler(protocol=Diameter) unregistered
    java.util.Dictionary (service.pid=system) service required available
    com.alcatel.as.service.concurrent.PlatformExecutors service required 
available
    com.alcatel.as.service.concurrent.TimerService (strict=false) service 
required available
    com.nextenso.proxylet.engine.ProxyletApplication (protocol=diameter) 
service required unavailable
    com.alcatel.as.service.metering.MeteringService service required available
    com.alcatel.as.service.management.ShutdownService service required available
    com.nextenso.proxylet.diameter.DiameterRouteTable service required available
    java.util.Dictionary (service.pid=diameteragent) service required available
 [25] com.nextenso.mux.MuxHandler(protocol=Smpp) unregistered
    java.util.Dictionary (service.pid=system) service required available
    java.util.Dictionary (service.pid=smsagent) service required available
    com.alcatel.as.util.osgi.ServiceRegistry (name=com.nextenso.sms.agent) 
service required available
    com.nextenso.proxylet.engine.ProxyletApplication (protocol=smpp) service 
required unavailable
{code}

7) "notavail" option
===============

I also did another minor modification regarding the "notavail" option:

When you provide "notavail", so far, unregistered components were displayed 
including *all* available component dependencies.
But, sometimes, it is a pain to pay attention only to unavailable dependencies. 
 And what is precisely interesting is to quickly look for such unavailable 
dependencies.
So, when the "notavail option" is provided, the attached patch now displays 
unregistered component with 
only unavailable dependencies, and hides other available dependencies.

In this way, it is easier to make some diagnostics on a large framework, with 
many services.

For instance, the following component is unregistered because it has one 
missing dependency:

{code}
g! dm ci 50
[102] com.alcatel.as.agent.mail
 [50] com.nextenso.mux.MuxHandler(protocol=Smtp) unregistered
    java.util.Dictionary (service.pid=system) service required available
    java.util.Dictionary (service.pid=smtpagent) service required available
    com.alcatel.as.util.osgi.ServiceRegistry (name=com.nextenso.mail.agent) 
service required available
    com.nextenso.proxylet.engine.ProxyletApplication (protocol=smtp) service 
required unavailable 
{code}

So, if you type dm notavail on the component id 50, you will then quickly see 
the missing dependency:

{code}
g! dm na ci 50
[102] com.alcatel.as.agent.mail                                                 
                                                                                
        
 [50] com.nextenso.mux.MuxHandler(protocol=Smtp) unregistered                   
                                                                                
        
    com.nextenso.proxylet.engine.ProxyletApplication (protocol=smtp) service 
required unavailable                                                            
           
{code}

Here, We only display the missing dependency on the missing 
com.nextenso.proxylet.engine.ProxyletApplication service.

8) passing options using special gogo shell variables
==========================================

The "compact" option can also be set from shell, using a special 
"dependencymanager.compact" variable.
This is useful to avoid passing the "compact" option on every commands:

{code}
g! dependencymanager.compact=true

g! dm 
[2] o.a.m.conf
 [0] o.o.s.c.M.p.a.t.factory) R(o.a.m.TenantFactoryConfiguration S RA 
o.o.s.l.LogService S OA)
{code}

Same applies for "components", "services", and "names" options:

{code}
g! dependencymanager.components="!.*amdatu.*"
!.*amdatu.*
{code}

Now, all dm commands are implicitely using the "components" option specified 
from the shell variable:

{code}
g! dm
[2] org.amdatu.multitenant.conf
 [0] 
org.osgi.service.cm.ManagedServiceFactory(service.pid=org.amdatu.tenant.factory)
 registered
    org.amdatu.multitenant.TenantFactoryConfiguration service required available
    org.osgi.service.log.LogService service optional available
[16] pierre.multitenant.tenant
 [37] pierre.multitenant.tenant.Tenant2 registered
 [40] pierre.multitenant.tenant.Tenant2 registered
[17] pierre.multitenant.platform
 [29] pierre.multitenant.platform.Platform registered
    org.osgi.service.log.LogService service required available
    pierre.multitenant.both.Both service required available
[18] pierre.multitenant.both
 [33] pierre.multitenant.both.Both registered
 [31] pierre.multitenant.both.Both registered
 [35] pierre.multitenant.both.Both registered
{code}


> Dependency Manager Shell improvements
> -------------------------------------
>
>                 Key: FELIX-4294
>                 URL: https://issues.apache.org/jira/browse/FELIX-4294
>             Project: Felix
>          Issue Type: Improvement
>          Components: Dependency Manager
>    Affects Versions: dependencymanager-3.1.0
>            Reporter: Pierre De Rop
>            Assignee: Pierre De Rop
>            Priority: Minor
>         Attachments: FELIX-4294.patch
>
>
> This issue proposes two enhancements regarding the dependency manager shell.
> 1) display component names more consistently
> =====================================
> - some components are sometimes displayed with a "class " prefix, while 
> others are not:
> class org.amdatu.multitenant.adapter.TenantAdapter registered
> org.amdatu.multitenant.adapter.BundleDataStore(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM,bundle.id=18)
>  registered
> For readability, the "class " could be just removed.
> - When a component does not contain any service properties, an empty "()" is 
> displayed after the component name
> pierre.multitenant.both.Both() registered
>  org.amdatu.multitenant.TenantLifeCycleListener(org.amdatu.tenant.binding=3) 
> registered
> As in previous case and for readability, it makes sense to not append an 
> empty "()" after the component name, if it has no properties.
> 2) add "filter" and "nofilters" options for filter displayed components
> =====================================================
> By default, the  "dm"  shell command dumps all components. But sometimes, it 
> is desirable to display a subset of all components, 
> using a regular expression on the component name or on the component service 
> properties.
> We can of course do this using gogo shell "grep", but the problem is that we 
> may miss some important informations, like the component bundle id, or the 
> component dependencies.
> As an example, let's assume we are using the AMDATU mutli-tenancy framework. 
> With AMDATU MT, many internal AMDATU components are instantiated behind the 
> scene for a given tenant bundle.
> In the following example, we have three tenant bundles, and if we type "dm", 
> then we are getting a long list of components, including:
>   - application tenant components: pierre.multitenant.*
>   - some internal amdatu mt components (org.amdatu.multitenant.*):
> g! dm
> [2] org.amdatu.multitenant.conf
>   
> org.osgi.service.cm.ManagedServiceFactory(service.pid=org.amdatu.tenant.factory)
>  registered
>     org.amdatu.multitenant.TenantFactoryConfiguration service required 
> available
>     org.osgi.service.log.LogService service optional available
> [3] org.amdatu.multitenant.factory
>   org.amdatu.multitenant.TenantFactoryConfiguration() registered
>     org.osgi.service.log.LogService service optional available
>     org.amdatu.multitenant.TenantLifeCycleListener service optional available
>   
> org.amdatu.multitenant.Tenant(service.pid=org.amdatu.tenant.factory.91a788f0-da4f-405d-a643-b220f4b2bcee,org.amdatu.tenant.pid=org.amdatu.tenant.factory.91a788f0-da4f-405d-a643-b220f4b2bcee,service.factoryPid=org.amdatu.tenant.factory,org.amdatu.tenant.name=bar2,felix.fileinstall.filename=file:/home/nxuser/work/osgi/amdatu/felix-framework-4.2.1/load/org.amdatu.tenant.factory-2.cfg,foo=bar)
>  registered
>   
> org.amdatu.multitenant.Tenant(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM,org.amdatu.tenant.name=Platform
>  Tenant) registered
>   
> org.amdatu.multitenant.Tenant(service.pid=org.amdatu.tenant.factory.f4d53487-5a51-480c-9f67-ba64d657986c,org.amdatu.tenant.pid=org.amdatu.tenant.factory.f4d53487-5a51-480c-9f67-ba64d657986c,service.factoryPid=org.amdatu.tenant.factory,felix.fileinstall.filename=file:/home/nxuser/work/osgi/amdatu/felix-framework-4.2.1/load/org.amdatu.tenant.factory-1.cfg,foo=bar2)
>  registered
> [5] org.amdatu.multitenant.org.apache.felix.dependencymanager.runtime
>   class org.apache.felix.dm.runtime.DependencyManagerRuntime registered
>     org.osgi.service.log.LogService service optional unavailable
>     active (DependencyManager-Component=*) bundle optional unavailable
>   org.amdatu.multitenant.TenantLifeCycleListener(org.amdatu.tenant.binding=3) 
> registered
>   Adapter for interface org.amdatu.multitenant.Tenant registered
>     org.amdatu.multitenant.Tenant service optional available
>     org.osgi.service.log.LogService service optional available
>   class org.amdatu.multitenant.adapter.TenantAdapter registered
>     org.amdatu.multitenant.Tenant 
> (|(service.id=32)(org.apache.felix.dependencymanager.aspect=32)) service 
> required available
>     org.osgi.service.log.LogService service optional available
>     org.amdatu.multitenant.adapter.BundleDataStore 
> (&(org.amdatu.tenant.pid=org.amdatu.tenant.factory.91a788f0-da4f-405d-a643-b220f4b2bcee)(bundle.id=5))
>  service required available
>   class org.amdatu.multitenant.adapter.TenantAdapter registered
>     org.amdatu.multitenant.Tenant 
> (|(service.id=33)(org.apache.felix.dependencymanager.aspect=33)) service 
> required available
>     org.osgi.service.log.LogService service optional available
>     org.amdatu.multitenant.adapter.BundleDataStore 
> (&(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM)(bundle.id=5)) service 
> required available
>   class org.amdatu.multitenant.adapter.TenantAdapter registered
>     org.amdatu.multitenant.Tenant 
> (|(service.id=34)(org.apache.felix.dependencymanager.aspect=34)) service 
> required available
>     org.osgi.service.log.LogService service optional available
>     org.amdatu.multitenant.adapter.BundleDataStore 
> (&(org.amdatu.tenant.pid=org.amdatu.tenant.factory.f4d53487-5a51-480c-9f67-ba64d657986c)(bundle.id=5))
>  service required available
>   
> org.amdatu.multitenant.adapter.BundleDataStore(org.amdatu.tenant.pid=org.amdatu.tenant.factory.91a788f0-da4f-405d-a643-b220f4b2bcee,bundle.id=5)
>  registered
>   
> org.amdatu.multitenant.adapter.BundleDataStore(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM,bundle.id=5)
>  registered
>   
> org.amdatu.multitenant.adapter.BundleDataStore(org.amdatu.tenant.pid=org.amdatu.tenant.factory.f4d53487-5a51-480c-9f67-ba64d657986c,bundle.id=5)
>  registered
>   class org.apache.felix.dm.runtime.DependencyManagerRuntime registered
>     org.osgi.service.log.LogService service optional unavailable
>     active (DependencyManager-Component=*) bundle optional unavailable
>   class org.apache.felix.dm.runtime.DependencyManagerRuntime registered
>     org.osgi.service.log.LogService service optional unavailable
>     active (DependencyManager-Component=*) bundle optional unavailable
> [16] pierre.multitenant.tenant
>   pierre.multitenant.tenant.Tenant2() registered
>   class pierre.multitenant.tenant.Tenant1 registered
>     pierre.multitenant.tenant.Tenant2 service required available
>     org.osgi.service.log.LogService service required available
>     pierre.multitenant.both.Both service required available
>     pierre.multitenant.platform.Platform service required available
>   pierre.multitenant.tenant.Tenant2() registered
>   class pierre.multitenant.tenant.Tenant1 registered
>     pierre.multitenant.tenant.Tenant2 service required available
>     org.osgi.service.log.LogService service required available
>     pierre.multitenant.both.Both service required available
>     pierre.multitenant.platform.Platform service required available
>   org.amdatu.multitenant.TenantLifeCycleListener(org.amdatu.tenant.binding=2) 
> registered
>   Adapter for interface org.amdatu.multitenant.Tenant with filter 
> (!(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM)) registered
>     org.amdatu.multitenant.Tenant 
> (!(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM)) service optional 
> available
>     org.osgi.service.log.LogService service optional available
>   class org.amdatu.multitenant.adapter.TenantAdapter registered
>     org.amdatu.multitenant.Tenant 
> (|(service.id=32)(org.apache.felix.dependencymanager.aspect=32)) service 
> required available
>     org.osgi.service.log.LogService service optional available
>     org.amdatu.multitenant.adapter.BundleDataStore 
> (&(org.amdatu.tenant.pid=org.amdatu.tenant.factory.91a788f0-da4f-405d-a643-b220f4b2bcee)(bundle.id=16))
>  service required available
>   class org.amdatu.multitenant.adapter.TenantAdapter registered
>     org.amdatu.multitenant.Tenant 
> (|(service.id=34)(org.apache.felix.dependencymanager.aspect=34)) service 
> required available
>     org.osgi.service.log.LogService service optional available
>     org.amdatu.multitenant.adapter.BundleDataStore 
> (&(org.amdatu.tenant.pid=org.amdatu.tenant.factory.f4d53487-5a51-480c-9f67-ba64d657986c)(bundle.id=16))
>  service required available
>   
> org.amdatu.multitenant.adapter.BundleDataStore(org.amdatu.tenant.pid=org.amdatu.tenant.factory.91a788f0-da4f-405d-a643-b220f4b2bcee,bundle.id=16)
>  registered
>   
> org.amdatu.multitenant.adapter.BundleDataStore(org.amdatu.tenant.pid=org.amdatu.tenant.factory.f4d53487-5a51-480c-9f67-ba64d657986c,bundle.id=16)
>  registered
> [17] pierre.multitenant.platform
>   org.amdatu.multitenant.TenantLifeCycleListener(org.amdatu.tenant.binding=1) 
> registered
>   Adapter for interface org.amdatu.multitenant.Tenant with filter 
> (org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM) registered
>     org.amdatu.multitenant.Tenant 
> (org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM) service optional available
>     org.osgi.service.log.LogService service optional available
>   class org.amdatu.multitenant.adapter.TenantAdapter registered
>     org.amdatu.multitenant.Tenant 
> (|(service.id=33)(org.apache.felix.dependencymanager.aspect=33)) service 
> required available
>     org.osgi.service.log.LogService service optional available
>     org.amdatu.multitenant.adapter.BundleDataStore 
> (&(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM)(bundle.id=17)) service 
> required available
>   
> org.amdatu.multitenant.adapter.BundleDataStore(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM,bundle.id=17)
>  registered
>   pierre.multitenant.platform.Platform() registered
>     org.osgi.service.log.LogService service required available
>     pierre.multitenant.both.Both service required available
> [18] pierre.multitenant.both
>   pierre.multitenant.both.Both() registered
>   org.amdatu.multitenant.TenantLifeCycleListener(org.amdatu.tenant.binding=3) 
> registered
>   Adapter for interface org.amdatu.multitenant.Tenant registered
>     org.amdatu.multitenant.Tenant service optional available
>     org.osgi.service.log.LogService service optional available
>   class org.amdatu.multitenant.adapter.TenantAdapter registered
>     org.amdatu.multitenant.Tenant 
> (|(service.id=32)(org.apache.felix.dependencymanager.aspect=32)) service 
> required available
>     org.osgi.service.log.LogService service optional available
>     org.amdatu.multitenant.adapter.BundleDataStore 
> (&(org.amdatu.tenant.pid=org.amdatu.tenant.factory.91a788f0-da4f-405d-a643-b220f4b2bcee)(bundle.id=18))
>  service required available
>   class org.amdatu.multitenant.adapter.TenantAdapter registered
>     org.amdatu.multitenant.Tenant 
> (|(service.id=33)(org.apache.felix.dependencymanager.aspect=33)) service 
> required available
>     org.osgi.service.log.LogService service optional available
>     org.amdatu.multitenant.adapter.BundleDataStore 
> (&(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM)(bundle.id=18)) service 
> required available
>   class org.amdatu.multitenant.adapter.TenantAdapter registered
>     org.amdatu.multitenant.Tenant 
> (|(service.id=34)(org.apache.felix.dependencymanager.aspect=34)) service 
> required available
>     org.osgi.service.log.LogService service optional available
>     org.amdatu.multitenant.adapter.BundleDataStore 
> (&(org.amdatu.tenant.pid=org.amdatu.tenant.factory.f4d53487-5a51-480c-9f67-ba64d657986c)(bundle.id=18))
>  service required available
>   
> org.amdatu.multitenant.adapter.BundleDataStore(org.amdatu.tenant.pid=org.amdatu.tenant.factory.91a788f0-da4f-405d-a643-b220f4b2bcee,bundle.id=18)
>  registered
>   
> org.amdatu.multitenant.adapter.BundleDataStore(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM,bundle.id=18)
>  registered
>   
> org.amdatu.multitenant.adapter.BundleDataStore(org.amdatu.tenant.pid=org.amdatu.tenant.factory.f4d53487-5a51-480c-9f67-ba64d657986c,bundle.id=18)
>  registered
>   pierre.multitenant.both.Both() registered
>   pierre.multitenant.both.Both() registered
> So, what we would like to do is to be able to filter the displayed components 
> with a new filter option.
> For example: To display only the application components matching 
> "pierre.multitenant.*:
> g! dm filter pierre.multitenant.*
> Current component filters:[pierre.multitenant.*]
> g! dm
> [16] pierre.multitenant.tenant
>   pierre.multitenant.tenant.Tenant2() registered
>   pierre.multitenant.tenant.Tenant2() registered
> [17] pierre.multitenant.platform
>   pierre.multitenant.platform.Platform() registered
>     org.osgi.service.log.LogService service required available
>     pierre.multitenant.both.Both service required available
> [18] pierre.multitenant.both
>   pierre.multitenant.both.Both() registered
>   pierre.multitenant.both.Both() registered
>   pierre.multitenant.both.Both() registered
> To display all PLATFORM tenants:
> g! dm nofilters
> g! dm filter .*pid=org.amdatu.tenant.PLATFORM.*
> g! dm
> [3] org.amdatu.multitenant.factory
>   
> org.amdatu.multitenant.Tenant(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM,org.amdatu.tenant.name=Platform
>  Tenant) registered
> [5] org.amdatu.multitenant.org.apache.felix.dependencymanager.runtime
>   
> org.amdatu.multitenant.adapter.BundleDataStore(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM,bundle.id=5)
>  registered
> [16] pierre.multitenant.tenant
>   Adapter for interface org.amdatu.multitenant.Tenant with filter 
> (!(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM)) registered
>     org.amdatu.multitenant.Tenant 
> (!(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM)) service optional 
> available
>     org.osgi.service.log.LogService service optional available
> [17] pierre.multitenant.platform
>   Adapter for interface org.amdatu.multitenant.Tenant with filter 
> (org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM) registered
>     org.amdatu.multitenant.Tenant 
> (org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM) service optional available
>     org.osgi.service.log.LogService service optional available
>   
> org.amdatu.multitenant.adapter.BundleDataStore(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM,bundle.id=17)
>  registered
> [18] pierre.multitenant.both
>   
> org.amdatu.multitenant.adapter.BundleDataStore(org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM,bundle.id=18)
>  registered
> To display every components except any components having the service property 
> "org.amdatu.tenant.name=bar2":
> g! dm nofilters
> g! dm filter !.*org.amdatu.tenant.name=bar2.*
> - Filters are cumulative: you can call "dm filter XXX" multiple times and 
> each filter can have multiple regex (space separated).
> - Components are displayed only if their name or their service properties are 
> matching at least one of the the specified filter.
> - Filters can be negated, using the special "!" prefix.
> - "dm filter" without any arguments just displays the current filters.
> - "dm nofilters" disable every previously added filter.



--
This message was sent by Atlassian JIRA
(v6.1#6144)

Reply via email to