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)