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

Reply via email to