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. 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