On Fri, Jul 13, 2018 at 4:37 AM, Philipp Höfler <
philipp.hoef...@pernexas.com> wrote:

> I've tested the factory configuration and I am afraid that my problem is
> not being solved with this approach.
>
> I think I might have to explain the problem in more detail, that you'll
> get a better understanding.
> I am implementing a REST service using the HTTP Whiteboard mechanism. This
> interface is described in a quite old standard.
> Each call contains an identifier. I would like to configure my service
> based on this identifier.
> Meaning, depending on this identifier I would like to use different
> configuration.
>
> Example:
> I am receiving a call with identifier for S1 (System 1).
> {
>         // Resource Format Version
>     ":configurator:resource-version" : 1,
>
>     // First Configuration
>     "my.config~system1":
>     {
>                          "test.securityEnabled": false,
>                          "test.test": false
>                  },
>          // Second Configuration
>     "my.config~system2":
>     {
>                          "test.securityEnabled": true,
>                          "test.test": false
>                  }
>          }
>  }
>
> Then, I would like to disable the security when the call comes from System
> 1.
> But when the call comes from System 2 the security should be enabled.
>
> Maybe I am still misunderstanding the factory configuration.
>

No I think you have understood it well. However I think what you need is to
break up the concerns a little.

If if were me building your system, I would:

- decouple the configuration from the rest endpoint. Let's call the
endpoint A and the configuration Tenants (because it sounds like you are
building a multi-tenant system):
    @Component
    class A implements Endpoint {
        @Reference(
            policy = ReferencePolicy.DYNAMIC,
            policyOption = ReferencePolicyOption.GREEDY
        )
        private volatile Map<Map<String, Object>, Tenant> _tenants;

        String handleRequest(String tenantId) {
            try {
                Filter filter = FrameworkUtil.createFilter("(tenantId=" +
tenantId + ")");
                return _tenants.entrySet().stream().filter(
                    e -> filter.matches(e.getKey())
                ).map(
                    Map.Entry::getValue
                ).findFirst().orElse("Not Found");
            }
            catch (InvalidSyntaxException e1) {
                // ignore
            }
            return "Not Found";
        }
    }

- create a component managed through factory configuration as above
   @Component(
        configurationPid = "my.config",
        configurationPolicy = ConfigurationPolicy.REQUIRE
   )
   class TenantImpl implements Tenant {
       private TenantConfig config;
       @Activate
       void activate(TenantConfig config) {
          this.config = config;
       }
   }
 this becomes a "service" for every factory configuration instance which is
then tracked by A

Create new tenants as needed.

I hope that illustrates the model a little better.

- Ray



> But according to my current understanding, osgi will create two rest
> endpoints for each configuration, right?
> When the rest call arrives, only one instance handles it, as the URL is
> the same.
> I do not know the identifier at compile time.
>
> To summarize:
> I basically want to load/use the config, based on a parameter coming with
> the request.
> If possible at all, I do not want to limit the amount of systems.
> Could you imagine any easy solution for that problem?
>
>
> -----Ursprüngliche Nachricht-----
> Von: Raymond Auge <raymond.a...@liferay.com>
> Gesendet: Donnerstag, 12. Juli 2018 18:23
> An: felix users <users@felix.apache.org>
> Betreff: Re: Configurator R7 example
>
> On Thu, Jul 12, 2018 at 11:58 AM, Philipp Höfler <
> philipp.hoef...@pernexas.com> wrote:
>
> > Right, this is missing.
> > I added the @RquireConfigurator annotation to the GoGo Command class.
> > Is that a suitable place for it?
> > The json is now being loaded. The value is set to false.
> >
> > Could you please explain, how this is working?
> >
> It's not completely clear to me, why the @interface MyConfig is
> > automatically used to hold the configuration.
> >
>
> DS is merely creating a proxy of the annotation type which fronts (or is
> backed by) the configuration dictionary, using the default values as well,
> default values if that particular property is not defined or if no
> configuration is available.
>
>
> > In each class, that needs access to the config I've a activate and
> > modified method with this signature: public void modified(MyConfig
> > config)
> >
> > Is the type resolved based on the pid and the param type of the method?
> >
>
> The Component Property Type will be backed by whatever configuration is
> associated with the component. so if you use the same Component Property
> Types on two different components which refer to two different pids, the
> proxies will show different values (based on the backing configuration
> dictionary of the component).
>
>
>
> >
> > ---
> > Back to my root problem:
> > Is it now possible to have the following configuration?
> > {
> >         // Resource Format Version
> >     ":configurator:resource-version" : 1,
> >
> >         // First Configuration
> >    "my.config":
> >    {
> >                 "system1":
> >         {
> >                         "test.securityEnabled": false,
> >                         "test.test": false
> >                 },
> >                 "system2":
> >         {
> >                         "test.securityEnabled": false,
> >                         "test.test": false
> >                 }
> >         }
> > }
> >
>
> Sure in this case the configuration dictionary will hold values:
>
> system1 = {"test.securityEnabled": false, "test.test": false}
> system2 = {"test.securityEnabled": false, "test.test": false}
>
> which is probably not what you intended.
>
> IF what you want is to create N instances of the component, one per set of
> configuration properties, you'd want to use Factory Configurations like so:
>
> {
> >         // Resource Format Version
> >     ":configurator:resource-version" : 1,
> >
> >         // First Configuration
> >    "my.config~system1":
> >    {
> >                         "test.securityEnabled": false,
> >                         "test.test": false
> >                 },
> >         // Second Configuration
> >    "my.config~system2":
> >    {
> >                         "test.securityEnabled": true,
> >                         "test.test": false
> >                 }
> >         }
> > }
> >
>
> Then you will have 2 component activations; one for each system1, system2,
> each with a MyConfig instance backing a different factory configuration
> instance.
>
> HTH
> - Ray
>
>
> >
> > Is it possible to have such a config with n systems?
> > Meaning, I do not know the amount of systems at compile time.
> >
> > Further, how would the @interface MyConfig annotation look like?
> > Is it possible to expect an array of MyConfig for the
> > modified(MyConfig[]
> > configs) method?
> >
> > Thanks for your help,
> > Philipp
> >
> > -----Ursprüngliche Nachricht-----
> > Von: Raymond Auge <raymond.a...@liferay.com>
> > Gesendet: Donnerstag, 12. Juli 2018 16:43
> > An: felix users <users@felix.apache.org>
> > Betreff: Re: Configurator R7 example
> >
> > Did you add the requirement to your configuration bundle?
> >
> > Require-Capability: osgi.extender; \
> >      filter:="(&(osgi.extender=osgi.configurator) \
> >              (version>=1.0
> > <https://osgi.org/specification/osgi.cmpn/7.0.0/
> > service.configurator.html#org.osgi.service.configurator>)(!(
> > version>=2.0)))"
> >
> > That or on some bit of code in the configuration bundle add the
> annotation:
> >
> > @org.osgi.service.configurator.annotations.RequireConfigurator
> >
> > - Ray
> >
> >
> > On Thu, Jul 12, 2018 at 10:23 AM, Philipp Höfler <
> > philipp.hoef...@pernexas.com> wrote:
> >
> > > Hallo David,
> > >
> > > thanks for the explanation.
> > > So, the configurator is just a "wrapper" for the ConfigAdminService
> > > to read json and transfer it into a key value format, right?
> > >
> > > I still have problems to use the
> > > I put a test.json file in the OSGI-INF/configurator folder of a
> > > bundle with the following content:
> > > {
> > >   // Resource Format Version
> > >   ":configurator:resource-version" : 1,
> > >
> > >   // First Configuration
> > >   "my.config":
> > >   {
> > >     "test.securityEnabled": false,
> > >     "test.test": false
> > >   }
> > > }
> > >
> > > In addition, I have an annotation for holding the values:
> > > public @interface MyConfig
> > > {
> > >     boolean test_securityEnabled () default true;
> > >     boolean test_test() default true; }
> > >
> > > Besides that, I've a custom GoGo command for configuration. But I am
> > > not sure, if this is really needed for loading the json?
> > >
> > > Unfortunately, the json is obviously not loaded.
> > > Both values are set to true, according to the default value.
> > >
> > > Do I have to do something in addition to load the json file?
> > >
> > > Thanks,
> > > Philipp
> > >
> > > -----Ursprüngliche Nachricht-----
> > > Von: David Bosschaert <david.bosscha...@gmail.com>
> > > Gesendet: Donnerstag, 12. Juli 2018 11:15
> > > An: users@felix.apache.org
> > > Betreff: Re: Configurator R7 example
> > >
> > > Hi Philipp,
> > >
> > > In the end the configuration specified with the Configurator will
> > > end up in OSGi Configuration Admin, so the Configurator is limited
> > > to the same types as ConfigAdmin. The Configurator allows complex
> > > JSON values to be specified, they will end up as JSON text in
> > > Configuration Admin if they go beyond what ConfigAdmin supports
> natively.
> > >
> > > So to use the Configurator you need the Configurator bundle plus the
> > > ConfigAdmin bundle.
> > >
> > > The Configurator handles configuration resources in
> > > OSGI-INF/configurator inside bundles but can also be provided with
> > > external configuration via the configurator.initial framework/system
> > > property. This is described in sections 150.4 and 150.5 in [1]. To
> > > provide Configurator configuration into the system you don't need to
> > > write any classes, but depending on how you use the configuration
> > > you may have to add classes that consume it. But again, the
> > > consumption can be done by anything that understands ConfigAdmin
> > > configs, so there
> > are a lot of options for this.
> > >
> > > I'm not aware of a complete tutorial on this topic yet. I agree it
> > > would be nice to have that.
> > >
> > > Hope this helps,
> > >
> > > David
> > >
> > > [1] https://osgi.org/specification/osgi.cmpn/7.0.0/
> > > service.configurator.html
> > >
> > > On Thu, 12 Jul 2018 at 10:55, Philipp Höfler
> > > <philipp.hoef...@pernexas.com
> > > >
> > > wrote:
> > >
> > > > Hi,
> > > >
> > > > I am searching for a possibility to load complex configurations.
> > > > I tried the ConfigurationAdminService, but key value pairs are not
> > > > sufficient as I need complex types.
> > > >
> > > > Raymond pointed out that I should have a look at the Configurator
> > > > Specification.
> > > > https://osgi.org/specification/osgi.cmpn/7.0.0/service.configurator.
> > > > ht
> > > > ml
> > > >
> > > > I read the specification and it sounds promising.
> > > > But I am stuck how to use the Configuration in my project.
> > > > I understand that I've to add the following dependency.
> > > > org.apache.felix.configurator
> > > >
> > > > But I don't understand if I've to add some classes, where the json
> > > > file has to be placed and if it's possible to place it outside of
> > > > the
> > > bundle?
> > > >
> > > > Is there any tutorial or sample project out there?
> > > >
> > > > Thanks,
> > > > Philipp
> > > >
> > >
> > > --------------------------------------------------------------------
> > > - To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
> > > For additional commands, e-mail: users-h...@felix.apache.org
> > >
> >
> >
> >
> > --
> > *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
> >  (@rotty3000)
> > Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
> >  (@Liferay)
> > Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org>
> > (@OSGiAlliance)
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
> > For additional commands, e-mail: users-h...@felix.apache.org
> >
>
>
>
> --
> *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
>  (@rotty3000)
> Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
>  (@Liferay)
> Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org>
> (@OSGiAlliance)
>



-- 
*Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
 (@rotty3000)
Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
 (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org> (@OSGiAlliance)

Reply via email to