On Mon, Jul 16, 2018 at 6:16 AM, Philipp Höfler <
philipp.hoef...@pernexas.com> wrote:

> Hallo Ray,
>
> thanks for your detailed explanation. You're right, I think one can
> consider this scenario as multi-tenant.
> This sounds pretty promising.
>
> The following points are unclear to me:
> * Even if I decouple the configuration from the endpoint, the security
> check has to be done in the endpoint, as it depends on the function that is
> invoked.
> I've several classes / endpoints for handling different functions.
> Basically, it is about the CRUD functions, but there are also some
> additional ones.
> Is it still possible to handle the security check based on the
> configuration in the endpoint itself, but "route" the call to the right
> instance of the endpoint based on the ID coming from the rest call?
>

First off let me answer your second bullet, the two interfaces I used were
just "mock" types based on your example. The Endpoint is whatever you
endpoint object was. The Tenant was just an object I made up which should
encompass the instance of your configuration with which you can make
security checks.


> * I was trying to implement your suggestion, but I am facing problems.
> What is Endpoint and Tenant for interfaces? Are they part of the JAX-RS
> framework or osgi or are they custom interfaces?
>

See above, they are just pseudo code of your design.


> * Can I still use endpoints with the annotations (@Path, @Get, etc)?
>

Yeah! this is what Endpoint was suppose to represent, again in pseudo code.


> * You have a map of tenants in the endpoint A. How do you create and fill
> these tenants? Is this done automagically be the factory configuration?
>

DS supports tuples of services (as in my example), and it's maintained for
you. Then you have each "Tenant" created for you by configuration admin
from a component that requires factory configuration, automagically ;)

Sincerely,
- Ray


> Again, thanks for your help.
> Philipp
>
>
> -----Ursprüngliche Nachricht-----
> Von: Raymond Auge <raymond.a...@liferay.com>
> Gesendet: Freitag, 13. Juli 2018 16:01
> An: felix users <users@felix.apache.org>
> Betreff: Re: Configurator R7 example
>
> 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)
>
> ---------------------------------------------------------------------
> 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)

Reply via email to