Hallo Ray, I am sorry, I do not understand your pseudo code example. I've modified my test project to show you my current structure.
From my point of view, I would need something like a "Router" to route the Requests to the right instance of the controller. According to my current understanding, I will have several controllers for each configuration due to the configuration factory, right? Would you mind looking over my example and guide me through? This is the RestController: https://github.com/phhoef/osgi-test/blob/master/rest-service/src/main/java/com/my/app/rest/rest/ServerInfoControllerImpl.java Thanks, Philipp -----Ursprüngliche Nachricht----- Von: Raymond Auge <raymond.a...@liferay.com> Gesendet: Montag, 16. Juli 2018 16:48 An: felix users <users@felix.apache.org> Betreff: Re: Configurator R7 example On Mon, Jul 16, 2018 at 10:42 AM, David Jencks <david.a.jen...@gmail.com> wrote: > Inline... > > Sent from my iPhone > > > On Jul 16, 2018, at 6:34 AM, Raymond Auge <raymond.a...@liferay.com> > wrote: > > > > 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 ;) > > > Don’t you mean something like... > Specify the “Require” configuration policy for your DS tenant component. > Then, when a management agent creates a factory configuration for each > tenant, DS will create a corresponding instance of the tenant component. > ? > Config admin isn’t going to create component instances for you. This > is close to nitpicking, but if you aren’t familiar with who does what > even a little imprecision can be very confusing, at least to me. > Of course you're right David. I was trying to describe effects rather than exact mechanics :) - Ray > Thanks > David Jencks > > 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) > > --------------------------------------------------------------------- > 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