You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Philipp Höfler <Ph...@pernexas.com> on 2018/08/01 08:52:41 UTC
AW: Configurator R7 example
May I ask you again for help.
I am still stuck at the multi-tenant implementation.
As described in my last mail, I have slightly modified your suggestion.
I was busy the last couple of days. For some reason, when I try to build the project including a reference to the Map<Map<>> I am getting the following error:
[ERROR] Failed to execute goal biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default) on project my-app: Unable to resolve <<INITIAL>>: missing requirement osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)' [caused by: Unable to resolve com.my.app.rest-service version=1.0.0.201808010851: missing requirement osgi.service;filter:='(objectClass=java.util.Map)';effective:='active'] -> [Help 1]
Again, you can find the project on GitHub
https://github.com/phhoef/osgi-test/blob/master/rest-service/src/main/java/com/my/app/rest/rest/ServerInfoControllerImpl.java
Thanks
-----Ursprüngliche Nachricht-----
Von: Raymond Auge <ra...@liferay.com>
Gesendet: Dienstag, 17. Juli 2018 16:43
An: felix users <us...@felix.apache.org>
Betreff: Re: Configurator R7 example
On Tue, Jul 17, 2018 at 10:18 AM, Philipp Höfler < Philipp.Hoefler@pernexas.com> wrote:
> 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.ja
> va
Ok, I will use the terms I see in your code.
This JAXRS resource IS the router in my mind. So,
- remove all the configuration details from ServerInfoControllerImpl.java
@Component(service=ServerInfoControllerImpl.class)
@JaxrsResource
@Path("serverInfo")
public class ServerInfoControllerImpl ....
- move all these configuration details to IRepository impl:
@Component(
configurationPid = "my.config",
configurationPolicy = ConfigurationPolicy.REQUIRE
)
public class IRepositoryImpl implements IRepository ...
- make IRepository implement the security checking methods itself based on it's config
- make ServerInfoControllerImpl.java track _all_ IRepositories:
@Reference(
policy = ReferencePolicy.DYNAMIC,
policyOption = ReferencePolicyOption.GREEDY
)
private volatile Map<Map<String, Object>, IRepository> _repositories;
- make getServiceInfo(...) find a IRepository by filtering through the tracked _repositories using the inputs, something like:
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getServerInfo(@QueryParam(REPO_NAME) String repoName,
@QueryParam(SIGNATURE) String signature) {
try {
Filter filter = FrameworkUtil.createFilter("(repoName=" + repoName + ")");
IRepository repo = _repositories.entrySet().stream().filter(
e -> filter.matches(e.getKey())
).map(
Map.Entry::getValue
).findFirst().orElse(null);
if (repo != null) {
if (repo.isSecurityEnabled()) {
// do sec
return ...
}
else {
// no sec
return ...
}
}
}
catch (InvalidSyntaxException e1) {
// ignore
}
return "Not Found";
That's practically the whole impl.
I hope it helps.
- Ray
>
> Thanks,
> Philipp
>
> -----Ursprüngliche Nachricht-----
> Von: Raymond Auge <ra...@liferay.com>
> Gesendet: Montag, 16. Juli 2018 16:48
> An: felix users <us...@felix.apache.org>
> Betreff: Re: Configurator R7 example
>
> On Mon, Jul 16, 2018 at 10:42 AM, David Jencks
> <da...@gmail.com>
> wrote:
>
> > Inline...
> >
> > Sent from my iPhone
> >
> > > On Jul 16, 2018, at 6:34 AM, Raymond Auge
> > > <ra...@liferay.com>
> > wrote:
> > >
> > > On Mon, Jul 16, 2018 at 6:16 AM, Philipp Höfler <
> > > Philipp.Hoefler@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 <ra...@liferay.com>
> > >> Gesendet: Freitag, 13. Juli 2018 16:01
> > >> An: felix users <us...@felix.apache.org>
> > >> Betreff: Re: Configurator R7 example
> > >>
> > >> On Fri, Jul 13, 2018 at 4:37 AM, Philipp Höfler <
> > >> Philipp.Hoefler@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 <ra...@liferay.com>
> > >>> Gesendet: Donnerstag, 12. Juli 2018 18:23
> > >>> An: felix users <us...@felix.apache.org>
> > >>> Betreff: Re: Configurator R7 example
> > >>>
> > >>> On Thu, Jul 12, 2018 at 11:58 AM, Philipp Höfler <
> > >>> Philipp.Hoefler@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 <ra...@liferay.com>
> > >>>> Gesendet: Donnerstag, 12. Juli 2018 16:43
> > >>>> An: felix users <us...@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.Hoefler@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 <da...@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.Hoefler@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-unsubscribe@felix.apache.org
> > >>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
> > >>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
> > >> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
> > For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org
Re: Configurator R7 example
Posted by Carsten Ziegeler <cz...@apache.org>.
Hi,
for the reference you need to use:
private List<Map.Entry<Map<String, Object>, ISecurityChecker>>
_securityCheckers;
this should give you a list of tuples, where the key is the map of
properties and the value the service object. For this I think you need
to specify "field-collection-type" being "tuple" on @Reference.
Regards
Carsten
Philipp Höfler wrote
> I made some progress, based on your information.
> I set the configurationPolicy to REQUIRE, but this alone does not work.
> @RequireConfigurator
> @Component(service = ISecurityChecker.class,
> configurationPid = "my.config",
> configurationPolicy = ConfigurationPolicy.REQUIRE)
> public class SecurityChecker implements ISecurityChecker
>
> Then, I additionally set the policyOption of the reference to GREEDY.
> @Reference(policyOption = ReferencePolicyOption.GREEDY)
> private List<ISecurityChecker> _securityCheckers;
>
> Now, I am getting a List of all configurations - at least a step in the right direction.
> But I am still not getting the pid of the configuration - in my case "system1" and "system2".
> According to Ray, the type would be Map<Map<String, Object>, ISecurityChecker>,
> @Reference(policyOption = ReferencePolicyOption.GREEDY)
> private Map<Map<String, Object>, ISecurityChecker> _securityCheckers;
>
> but when doing this I am getting the following error during compilation:
> [ERROR] Failed to execute goal biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default) on project my-app: Unable to resolve <<INITIAL>>: missing requirement osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)' [caused by: Unable to resolve com.my.app.rest-service version=1.0.0.201808061255: missing requirement osgi.service;filter:='(objectClass=java.util.Map)';effective:='active'] -> [Help 1]
>
> I tried the following types, too, but the same error:
> @Reference(policyOption = ReferencePolicyOption.GREEDY)
> private Map<String, ISecurityChecker> _securityCheckers;
>
> It seems, that the key of the Map is always the problem. But I do not understand why.
> [ERROR] Failed to execute goal biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default) on project my-app: Unable to resolve <<INITIAL>>: missing requirement osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)' [caused by: Unable to resolve com.my.app.rest-service version=1.0.0.201808061258: missing requirement osgi.service;filter:='(objectClass=java.lang.String)';effective:='active'] -> [Help 1]
>
> Any ideas, how I can get the pid of the configuration?
>
> Best,
> Philipp
>
> -----Ursprüngliche Nachricht-----
> Von: Philipp Höfler <Ph...@pernexas.com>
> Gesendet: Montag, 6. August 2018 13:34
> An: users@felix.apache.org
> Betreff: AW: Configurator R7 example
>
> Thanks for your quick reply.
>
> Unfortunately, when setting the policy to required, the whole component won't be loaded.
> At least, when attaching a debugger, the activate method is never called and the reference is always null.
>
> It feels like there is still something fundamental wrong in my code. But I don't see what it is ...
>
> Philipp
>
> -----Ursprüngliche Nachricht-----
> Von: Carsten Ziegeler <cz...@apache.org>
> Gesendet: Montag, 6. August 2018 13:08
> An: users@felix.apache.org; Philipp Höfler <Ph...@pernexas.com>
> Betreff: Re: Configurator R7 example
>
> Atm I'm only guessing, but as you are specifying the configuration to be optional, this might bypass the actual configurations stored in configuration admin.
>
> I would try replacing this with the require policy. At least I have seen some working code which pretty much looks as your example, except for the policy being specified as required
>
> Carsten
>
>
> Philipp Höfler wrote
>> This is driving me nuts.
>> Could someone please help me out?
>>
>> I do not understand how to create multiple instances of a component by the configurator factory and how to reference all these instances.
>> I played around, and it seems, that the configuration is loaded successfully.
>> This is my configuration json file (OSGI-INF/configurator/text.json) {
>> // Resource Format Version
>> ":configurator:resource-version" : 1,
>>
>> // First Configuration
>> "my.config~system1":
>> {
>> "test.securityEnabled": false,
>> "test.name": "System1"
>> },
>> // Second Configuration
>> "my.config~system2":
>> {
>> "test.securityEnabled": true,
>> "test.name": "System2"
>> }
>> }
>>
>> This is my annotation proxy for holding the configuration:
>> public @interface MyConfig
>> {
>> boolean test_securityEnabled() default true;
>> String test_name() default "Empty"; }
>>
>> I've two components.
>> The first one should have access to the config.
>> So, I created a activate and modified annotated method that has a parameter of type MyConfig.
>> This is executed only once. I would have expected, that this component is created twice as I have two configurations for this factory pid, right?
>> @RequireConfigurator
>> @Component(service = ISecurityChecker.class,
>> configurationPid = "my.config",
>> configurationPolicy = ConfigurationPolicy.OPTIONAL) public
>> class SecurityChecker implements ISecurityChecker {
>> private MyConfig _myConfig;
>>
>> @Activate
>> public void activate(MyConfig config)
>> {
>> _myConfig = config;
>> }
>>
>> @Modified
>> public void modified(MyConfig config)
>> {
>> _myConfig = config;
>> }
>>
>> @Override
>> public boolean isSecure(String name, String signature)
>> {
>> if(!_myConfig.isSecurityEnabled())
>> return true;
>>
>> if(name.equals(signature))
>> // do some fancy checks
>> return true;
>>
>> throw new NotAuthorizedException("Signature check failed!");
>> }
>> }
>>
>> The other component is a JaxRS Whiteboard resource serving a small rest service.
>> I am desperately trying to reference ALL instances of the SecurityChecker class, but no matter what I am doing it does not work or only one instance is available.
>> @Component(service=ServerInfoControllerImpl.class)
>> @JaxrsResource
>> @Path("serverInfo")
>> public class ServerInfoControllerImpl
>> {
>> @Reference
>> private List<ISecurityChecker> _securityCheckers;
>>
>> ...
>> }
>>
>> When I set the policy of the reference to dynamic, as Ray suggested, the component is not loaded.
>> Also, when I set the configurationPolicy of the SecurityChecker component to REQUIRED, the SecurityChecker component is not loaded.
>>
>> BUT, when looking in the web console both configurations are available, even though obviously not bound to a bundle. Is that correct?
>>
>> test.name System1
>> test.securityEnabled false
>> Configuration Information
>> Persistent Identity (PID) my.config~system1
>> Factory Persistent Identifier (Factory PID) my.config
>> Configuration Binding ?
>>
>> test.name System2
>> test.securityEnabled true
>> Configuration Information
>> Persistent Identity (PID) my.config~system2
>> Factory Persistent Identifier (Factory PID) my.config
>> Configuration Binding ?
>>
>>
>> Any help is appreciated. 😊
>> Thanks,
>> Philipp
>>
>> -----Ursprüngliche Nachricht-----
>> Von: Philipp Höfler <Ph...@pernexas.com>
>> Gesendet: Mittwoch, 1. August 2018 10:53
>> An: users@felix.apache.org
>> Betreff: AW: Configurator R7 example
>>
>> May I ask you again for help.
>> I am still stuck at the multi-tenant implementation.
>>
>> As described in my last mail, I have slightly modified your suggestion.
>> I was busy the last couple of days. For some reason, when I try to build the project including a reference to the Map<Map<>> I am getting the following error:
>> [ERROR] Failed to execute goal
>> biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default)
>> on project my-app: Unable to resolve <<INITIAL>>: missing requirement
>> osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)'
>> [caused by: Unable to resolve com.my.app.rest-service
>> version=1.0.0.201808010851: missing requirement
>> osgi.service;filter:='(objectClass=java.util.Map)';effective:='active'
>> ] -> [Help 1]
>>
>> Again, you can find the project on GitHub
>> https://github.com/phhoef/osgi-test/blob/master/rest-service/src/main/
>> java/com/my/app/rest/rest/ServerInfoControllerImpl.java
>>
>> Thanks
>>
>> -----Ursprüngliche Nachricht-----
>> Von: Raymond Auge <ra...@liferay.com>
>> Gesendet: Dienstag, 17. Juli 2018 16:43
>> An: felix users <us...@felix.apache.org>
>> Betreff: Re: Configurator R7 example
>>
>> On Tue, Jul 17, 2018 at 10:18 AM, Philipp Höfler < Philipp.Hoefler@pernexas.com> wrote:
>>
>>> 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.j
>>> a
>>> va
>>
>>
>> Ok, I will use the terms I see in your code.
>>
>> This JAXRS resource IS the router in my mind. So,
>>
>> - remove all the configuration details from
>> ServerInfoControllerImpl.java
>>
>> @Component(service=ServerInfoControllerImpl.class)
>> @JaxrsResource
>> @Path("serverInfo")
>> public class ServerInfoControllerImpl ....
>>
>> - move all these configuration details to IRepository impl:
>>
>> @Component(
>> configurationPid = "my.config",
>> configurationPolicy = ConfigurationPolicy.REQUIRE
>> )
>> public class IRepositoryImpl implements IRepository ...
>>
>> - make IRepository implement the security checking methods itself
>> based on it's config
>> - make ServerInfoControllerImpl.java track _all_ IRepositories:
>>
>> @Reference(
>> policy = ReferencePolicy.DYNAMIC,
>> policyOption = ReferencePolicyOption.GREEDY
>> )
>> private volatile Map<Map<String, Object>, IRepository>
>> _repositories;
>>
>> - make getServiceInfo(...) find a IRepository by filtering through the tracked _repositories using the inputs, something like:
>>
>> @GET
>> @Produces(MediaType.TEXT_PLAIN)
>> public String getServerInfo(@QueryParam(REPO_NAME) String repoName,
>> @QueryParam(SIGNATURE) String signature) {
>> try {
>> Filter filter = FrameworkUtil.createFilter("(repoName=" + repoName + ")");
>> IRepository repo = _repositories.entrySet().stream().filter(
>> e -> filter.matches(e.getKey())
>> ).map(
>> Map.Entry::getValue
>> ).findFirst().orElse(null);
>>
>> if (repo != null) {
>> if (repo.isSecurityEnabled()) {
>> // do sec
>> return ...
>> }
>> else {
>> // no sec
>> return ...
>> }
>> }
>> }
>> catch (InvalidSyntaxException e1) {
>> // ignore
>> }
>> return "Not Found";
>>
>> That's practically the whole impl.
>>
>> I hope it helps.
>>
>> - Ray
>>
>>
>>>
>>> Thanks,
>>> Philipp
>>>
>>> -----Ursprüngliche Nachricht-----
>>> Von: Raymond Auge <ra...@liferay.com>
>>> Gesendet: Montag, 16. Juli 2018 16:48
>>> An: felix users <us...@felix.apache.org>
>>> Betreff: Re: Configurator R7 example
>>>
>>> On Mon, Jul 16, 2018 at 10:42 AM, David Jencks
>>> <da...@gmail.com>
>>> wrote:
>>>
>>>> Inline...
>>>>
>>>> Sent from my iPhone
>>>>
>>>>> On Jul 16, 2018, at 6:34 AM, Raymond Auge
>>>>> <ra...@liferay.com>
>>>> wrote:
>>>>>
>>>>> On Mon, Jul 16, 2018 at 6:16 AM, Philipp Höfler <
>>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>>> Gesendet: Freitag, 13. Juli 2018 16:01
>>>>>> An: felix users <us...@felix.apache.org>
>>>>>> Betreff: Re: Configurator R7 example
>>>>>>
>>>>>> On Fri, Jul 13, 2018 at 4:37 AM, Philipp Höfler <
>>>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>>>> Gesendet: Donnerstag, 12. Juli 2018 18:23
>>>>>>> An: felix users <us...@felix.apache.org>
>>>>>>> Betreff: Re: Configurator R7 example
>>>>>>>
>>>>>>> On Thu, Jul 12, 2018 at 11:58 AM, Philipp Höfler <
>>>>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>>>>> Gesendet: Donnerstag, 12. Juli 2018 16:43
>>>>>>>> An: felix users <us...@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.Hoefler@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 <da...@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.Hoefler@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-unsubscribe@felix.apache.org
>>>>>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>>>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
> --
> Carsten Ziegeler
> Adobe Research Switzerland
> cziegeler@apache.org
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
> B KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKCB [ X ܚX KK[XZ[
> \ \ ][ X ܚX P [^
> \X K ܙ B ܈Y][ۘ[ [X[ K[XZ[
> \ \ Z[ [^
> \X K ܙ B
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
--
Carsten Ziegeler
Adobe Research Switzerland
cziegeler@apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org
AW: Configurator R7 example
Posted by Philipp Höfler <Ph...@pernexas.com>.
Thank you all.
Special thanks to Carsten - that was exactly I was searching for.
My reference looks now like this:
@Reference(policyOption = ReferencePolicyOption.GREEDY, collectionType = CollectionType.TUPLE)
private volatile List<Map.Entry<Map<String, Object>, ISecurityChecker>> _securityCheckers;
As you said, I am getting a Map.Entry that contains the service.pid which is - in my case - "my.config~system1".
I am filtering based on Ray's code snippet for the right configuration:
Filter filter = FrameworkUtil.createFilter("(service.pid=my.config~"+ repoName + ")");
ISecurityChecker securityChecker = _securityCheckers.stream().filter(e -> filter.matches(e.getKey())).map(Map.Entry::getValue).findFirst().orElse(null);
I am probably building a small wrapper handles all the configuration instances as I have several rest endpoints which do all the same security check.
Big Thanks!
Philipp
-----Ursprüngliche Nachricht-----
Von: Carsten Ziegeler <cz...@apache.org>
Gesendet: Montag, 6. August 2018 17:21
An: users@felix.apache.org; Cristiano <cv...@gmail.com>; Philipp Höfler <Ph...@pernexas.com>
Betreff: Re: Configurator R7 example
I think the current @Component annotation is correct :) (sorry)
If you use factory="..." you will create a component factory as defined in the DS specification - that's in contrast to a component managed by factory configurations (which this example is about).
If you managed to get the Map of properties (which should work with the Map.Entry change I posted recently), then the full PID of the configuration is stored in a property named "service.pid" - you can then search for the tilde in there and get what you want.
Regards
Carsten
Cristiano Gavião wrote
>
>
> On 06/08/2018 11:10, Philipp Höfler wrote:
>> Sorry, pid is probably the wrong word for that. Alias might be more
>> correct.
>> I am talking about the name after the ~ in the configuration file
>> (my.config~system1).
>> In this case I would like to get "system1".
>
> Ah, now I understood.
>
> I think you won't get that since your component is not a factory. If
> I'm remember right, you need to use a FPID (factory pid), so your
> component must be declared this
> way:*@Component(factory="anFactoryPID")*
>
> Couple years ago, I used to use the ConfigAdmin directly to activate
> my mult-instance components and the information you want was only
> provided by the Configuration object returned from CM:
>
>> configuration = getConfigurationAdmin()
>> .createFactoryConfiguration(pFactoryPid, null);
>> factoryPID = configuration.getFactoryPid(); pid =
>> configuration.getPid()
>
> I just started with Configurator too, but I don't know if this FPID
> and PID information are being published in the configuration map
> currently also. CM used not do that until R6 (at least I was not able to find them).
>
>
--
Carsten Ziegeler
Adobe Research Switzerland
cziegeler@apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org
Re: Configurator R7 example
Posted by Carsten Ziegeler <cz...@apache.org>.
I thought this for two years as well...so don't worry :)
But it's actually not needed. The R6 and R7 releases have some great new
features for DS and CM. The OSGi blog at https://blog.osgi.org has some
posts about new things in R7
Regards
Carsten
Cristiano Gavião wrote
> Humm, interesting... thanks Carsten for correct me...
>
>
> Certainly I will need to upgrade my knowledge on DS and CM again :-D
>
> I really thought that in order to use a Factory PID such as
> "my.fpid~somepid" I would need a factory component.
>
>
> On 06/08/2018 12:20, Carsten Ziegeler wrote:
>> I think the current @Component annotation is correct :) (sorry)
>>
>> If you use factory="..." you will create a component factory as defined
>> in the DS specification - that's in contrast to a component managed by
>> factory configurations (which this example is about).
>>
>> If you managed to get the Map of properties (which should work with the
>> Map.Entry change I posted recently), then the full PID of the
>> configuration is stored in a property named "service.pid" - you can then
>> search for the tilde in there and get what you want.
>>
>> Regards
>>
>> Carsten
>>
>>
>> Cristiano Gavião wrote
>>>
>>> On 06/08/2018 11:10, Philipp Höfler wrote:
>>>> Sorry, pid is probably the wrong word for that. Alias might be more
>>>> correct.
>>>> I am talking about the name after the ~ in the configuration file
>>>> (my.config~system1).
>>>> In this case I would like to get "system1".
>>> Ah, now I understood.
>>>
>>> I think you won't get that since your component is not a factory. If
>>> I'm remember right, you need to use a FPID (factory pid), so your
>>> component must be declared this way:*@Component(factory="anFactoryPID")*
>>>
>>> Couple years ago, I used to use the ConfigAdmin directly to activate my
>>> mult-instance components and the information you want was only provided
>>> by the Configuration object returned from CM:
>>>
>>>> configuration = getConfigurationAdmin()
>>>> .createFactoryConfiguration(pFactoryPid, null);
>>>> factoryPID = configuration.getFactoryPid();
>>>> pid = configuration.getPid()
>>> I just started with Configurator too, but I don't know if this FPID and
>>> PID information are being published in the configuration map currently
>>> also. CM used not do that until R6 (at least I was not able to find
>>> them).
>>>
>>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
--
Carsten Ziegeler
Adobe Research Switzerland
cziegeler@apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org
Re: Configurator R7 example
Posted by Cristiano <cv...@gmail.com>.
Humm, interesting... thanks Carsten for correct me...
Certainly I will need to upgrade my knowledge on DS and CM again :-D
I really thought that in order to use a Factory PID such as
"my.fpid~somepid" I would need a factory component.
On 06/08/2018 12:20, Carsten Ziegeler wrote:
> I think the current @Component annotation is correct :) (sorry)
>
> If you use factory="..." you will create a component factory as defined
> in the DS specification - that's in contrast to a component managed by
> factory configurations (which this example is about).
>
> If you managed to get the Map of properties (which should work with the
> Map.Entry change I posted recently), then the full PID of the
> configuration is stored in a property named "service.pid" - you can then
> search for the tilde in there and get what you want.
>
> Regards
>
> Carsten
>
>
> Cristiano Gavião wrote
>>
>> On 06/08/2018 11:10, Philipp Höfler wrote:
>>> Sorry, pid is probably the wrong word for that. Alias might be more
>>> correct.
>>> I am talking about the name after the ~ in the configuration file
>>> (my.config~system1).
>>> In this case I would like to get "system1".
>> Ah, now I understood.
>>
>> I think you won't get that since your component is not a factory. If
>> I'm remember right, you need to use a FPID (factory pid), so your
>> component must be declared this way:*@Component(factory="anFactoryPID")*
>>
>> Couple years ago, I used to use the ConfigAdmin directly to activate my
>> mult-instance components and the information you want was only provided
>> by the Configuration object returned from CM:
>>
>>> configuration = getConfigurationAdmin()
>>> .createFactoryConfiguration(pFactoryPid, null);
>>> factoryPID = configuration.getFactoryPid();
>>> pid = configuration.getPid()
>> I just started with Configurator too, but I don't know if this FPID and
>> PID information are being published in the configuration map currently
>> also. CM used not do that until R6 (at least I was not able to find them).
>>
>>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org
Re: Configurator R7 example
Posted by Carsten Ziegeler <cz...@apache.org>.
I think the current @Component annotation is correct :) (sorry)
If you use factory="..." you will create a component factory as defined
in the DS specification - that's in contrast to a component managed by
factory configurations (which this example is about).
If you managed to get the Map of properties (which should work with the
Map.Entry change I posted recently), then the full PID of the
configuration is stored in a property named "service.pid" - you can then
search for the tilde in there and get what you want.
Regards
Carsten
Cristiano Gavião wrote
>
>
> On 06/08/2018 11:10, Philipp Höfler wrote:
>> Sorry, pid is probably the wrong word for that. Alias might be more
>> correct.
>> I am talking about the name after the ~ in the configuration file
>> (my.config~system1).
>> In this case I would like to get "system1".
>
> Ah, now I understood.
>
> I think you won't get that since your component is not a factory. If
> I'm remember right, you need to use a FPID (factory pid), so your
> component must be declared this way:*@Component(factory="anFactoryPID")*
>
> Couple years ago, I used to use the ConfigAdmin directly to activate my
> mult-instance components and the information you want was only provided
> by the Configuration object returned from CM:
>
>> configuration = getConfigurationAdmin()
>> .createFactoryConfiguration(pFactoryPid, null);
>> factoryPID = configuration.getFactoryPid();
>> pid = configuration.getPid()
>
> I just started with Configurator too, but I don't know if this FPID and
> PID information are being published in the configuration map currently
> also. CM used not do that until R6 (at least I was not able to find them).
>
>
--
Carsten Ziegeler
Adobe Research Switzerland
cziegeler@apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org
Re: AW: AW: Configurator R7 example
Posted by Cristiano <cv...@gmail.com>.
On 06/08/2018 11:10, Philipp Höfler wrote:
> I am receiving a rest call with a system id. Based on this id I would like to use the appropriated config from the json file.
> For example, security check is disabled for system1, but not for system2. The rest endpoint is the same but based on the configuration the security check is executed or not.
To me, the best solution for you is to use the Config Admin to query if
there are any configuration created for the "system" you want.
You need to create a filter:
> StringBuilder filter = new StringBuilder("(&");
> filter.append('(').append("service.factoryPid")
> .append('=').append(pFactoryPid).append(')');
> filter.append('(').append("service.pid").append('=')
> .append(pPid).append(')');
And then use cm to return a configuration (if one exists):
> Configuration[] configurations = getConfigurationAdmin()
> .listConfigurations(filter.toString());
Once you have the configuration, you can enable or disable it as you will.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org
Re: AW: AW: Configurator R7 example
Posted by Cristiano <cv...@gmail.com>.
On 06/08/2018 11:10, Philipp Höfler wrote:
> Sorry, pid is probably the wrong word for that. Alias might be more correct.
> I am talking about the name after the ~ in the configuration file (my.config~system1).
> In this case I would like to get "system1".
Ah, now I understood.
I think you won't get that since your component is not a factory. If
I'm remember right, you need to use a FPID (factory pid), so your
component must be declared this way:*@Component(factory="anFactoryPID")*
Couple years ago, I used to use the ConfigAdmin directly to activate my
mult-instance components and the information you want was only provided
by the Configuration object returned from CM:
> configuration = getConfigurationAdmin()
> .createFactoryConfiguration(pFactoryPid, null);
> factoryPID = configuration.getFactoryPid();
> pid = configuration.getPid()
I just started with Configurator too, but I don't know if this FPID and
PID information are being published in the configuration map currently
also. CM used not do that until R6 (at least I was not able to find them).
AW: AW: Configurator R7 example
Posted by Philipp Höfler <Ph...@pernexas.com>.
Thanks for your reply.
Sorry, pid is probably the wrong word for that. Alias might be more correct.
I am talking about the name after the ~ in the configuration file (my.config~system1).
In this case I would like to get "system1".
I am receiving a rest call with a system id. Based on this id I would like to use the appropriated config from the json file.
For example, security check is disabled for system1, but not for system2. The rest endpoint is the same but based on the configuration the security check is executed or not.
I understand Ray's answers, that the configurator can create a Map which has the alias as key and the configuration (proxy type) as value.
But maybe I am totally misunderstanding the whole thing?
Thanks for your help,
Philipp
-----Ursprüngliche Nachricht-----
Von: Cristiano <cv...@gmail.com>
Gesendet: Montag, 6. August 2018 15:56
An: users@felix.apache.org
Betreff: Re: AW: Configurator R7 example
Hi,
If you do not have a "consumer" component active for the service ISecurityChecker you won't have an instance of it created because the default is to delay the activation until someone request it.
In order to test, you can use the immediate property :
*@Component(immediate = true...*
This means that as soon as DS received a configuration from CM your component will be activated and an instance of its service will be registered.
Btw, I suggest you to start by simple examples and only then start to play with adding a Map or annotation parameter:
> @Activate
> public void activate(ComponentContext pInjectedComponentContext)
With the pInjectedComponentContext object you can access the related dictionary. I used to do that and pass it to a converter in order to obtain object from that dictionary instead to have a Map.
I do not understand what do you meant about 'how to get the PID?', since you already have defined it in your component: *configurationPid =
"my.config"*
regards
Cristiano
On 06/08/2018 10:00, Philipp Höfler wrote:
> I made some progress, based on your information.
> I set the configurationPolicy to REQUIRE, but this alone does not work.
> @RequireConfigurator
> @Component(service = ISecurityChecker.class,
> configurationPid = "my.config",
> configurationPolicy = ConfigurationPolicy.REQUIRE) public
> class SecurityChecker implements ISecurityChecker
>
> Then, I additionally set the policyOption of the reference to GREEDY.
> @Reference(policyOption = ReferencePolicyOption.GREEDY)
> private List<ISecurityChecker> _securityCheckers;
>
> Now, I am getting a List of all configurations - at least a step in the right direction.
> But I am still not getting the pid of the configuration - in my case "system1" and "system2".
> According to Ray, the type would be Map<Map<String, Object>, ISecurityChecker>,
> @Reference(policyOption = ReferencePolicyOption.GREEDY)
> private Map<Map<String, Object>, ISecurityChecker>
> _securityCheckers;
>
> but when doing this I am getting the following error during compilation:
> [ERROR] Failed to execute goal
> biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default)
> on project my-app: Unable to resolve <<INITIAL>>: missing requirement
> osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)'
> [caused by: Unable to resolve com.my.app.rest-service
> version=1.0.0.201808061255: missing requirement
> osgi.service;filter:='(objectClass=java.util.Map)';effective:='active'
> ] -> [Help 1]
>
> I tried the following types, too, but the same error:
> @Reference(policyOption = ReferencePolicyOption.GREEDY)
> private Map<String, ISecurityChecker> _securityCheckers;
>
> It seems, that the key of the Map is always the problem. But I do not understand why.
> [ERROR] Failed to execute goal
> biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default)
> on project my-app: Unable to resolve <<INITIAL>>: missing requirement
> osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)'
> [caused by: Unable to resolve com.my.app.rest-service
> version=1.0.0.201808061258: missing requirement
> osgi.service;filter:='(objectClass=java.lang.String)';effective:='acti
> ve'] -> [Help 1]
>
> Any ideas, how I can get the pid of the configuration?
>
> Best,
> Philipp
>
> -----Ursprüngliche Nachricht-----
> Von: Philipp Höfler <Ph...@pernexas.com>
> Gesendet: Montag, 6. August 2018 13:34
> An: users@felix.apache.org
> Betreff: AW: Configurator R7 example
>
> Thanks for your quick reply.
>
> Unfortunately, when setting the policy to required, the whole component won't be loaded.
> At least, when attaching a debugger, the activate method is never called and the reference is always null.
>
> It feels like there is still something fundamental wrong in my code. But I don't see what it is ...
>
> Philipp
>
> -----Ursprüngliche Nachricht-----
> Von: Carsten Ziegeler <cz...@apache.org>
> Gesendet: Montag, 6. August 2018 13:08
> An: users@felix.apache.org; Philipp Höfler
> <Ph...@pernexas.com>
> Betreff: Re: Configurator R7 example
>
> Atm I'm only guessing, but as you are specifying the configuration to be optional, this might bypass the actual configurations stored in configuration admin.
>
> I would try replacing this with the require policy. At least I have
> seen some working code which pretty much looks as your example, except
> for the policy being specified as required
>
> Carsten
>
>
> Philipp Höfler wrote
>> This is driving me nuts.
>> Could someone please help me out?
>>
>> I do not understand how to create multiple instances of a component by the configurator factory and how to reference all these instances.
>> I played around, and it seems, that the configuration is loaded successfully.
>> This is my configuration json file (OSGI-INF/configurator/text.json) {
>> // Resource Format Version
>> ":configurator:resource-version" : 1,
>>
>> // First Configuration
>> "my.config~system1":
>> {
>> "test.securityEnabled": false,
>> "test.name": "System1"
>> },
>> // Second Configuration
>> "my.config~system2":
>> {
>> "test.securityEnabled": true,
>> "test.name": "System2"
>> }
>> }
>>
>> This is my annotation proxy for holding the configuration:
>> public @interface MyConfig
>> {
>> boolean test_securityEnabled() default true;
>> String test_name() default "Empty"; }
>>
>> I've two components.
>> The first one should have access to the config.
>> So, I created a activate and modified annotated method that has a parameter of type MyConfig.
>> This is executed only once. I would have expected, that this component is created twice as I have two configurations for this factory pid, right?
>> @RequireConfigurator
>> @Component(service = ISecurityChecker.class,
>> configurationPid = "my.config",
>> configurationPolicy = ConfigurationPolicy.OPTIONAL)
>> public class SecurityChecker implements ISecurityChecker {
>> private MyConfig _myConfig;
>>
>> @Activate
>> public void activate(MyConfig config)
>> {
>> _myConfig = config;
>> }
>>
>> @Modified
>> public void modified(MyConfig config)
>> {
>> _myConfig = config;
>> }
>>
>> @Override
>> public boolean isSecure(String name, String signature)
>> {
>> if(!_myConfig.isSecurityEnabled())
>> return true;
>>
>> if(name.equals(signature))
>> // do some fancy checks
>> return true;
>>
>> throw new NotAuthorizedException("Signature check failed!");
>> }
>> }
>>
>> The other component is a JaxRS Whiteboard resource serving a small rest service.
>> I am desperately trying to reference ALL instances of the SecurityChecker class, but no matter what I am doing it does not work or only one instance is available.
>> @Component(service=ServerInfoControllerImpl.class)
>> @JaxrsResource
>> @Path("serverInfo")
>> public class ServerInfoControllerImpl {
>> @Reference
>> private List<ISecurityChecker> _securityCheckers;
>>
>> ...
>> }
>>
>> When I set the policy of the reference to dynamic, as Ray suggested, the component is not loaded.
>> Also, when I set the configurationPolicy of the SecurityChecker component to REQUIRED, the SecurityChecker component is not loaded.
>>
>> BUT, when looking in the web console both configurations are available, even though obviously not bound to a bundle. Is that correct?
>>
>> test.name System1
>> test.securityEnabled false
>> Configuration Information
>> Persistent Identity (PID) my.config~system1
>> Factory Persistent Identifier (Factory PID) my.config
>> Configuration Binding ?
>>
>> test.name System2
>> test.securityEnabled true
>> Configuration Information
>> Persistent Identity (PID) my.config~system2
>> Factory Persistent Identifier (Factory PID) my.config
>> Configuration Binding ?
>>
>>
>> Any help is appreciated. 😊
>> Thanks,
>> Philipp
>>
>> -----Ursprüngliche Nachricht-----
>> Von: Philipp Höfler <Ph...@pernexas.com>
>> Gesendet: Mittwoch, 1. August 2018 10:53
>> An: users@felix.apache.org
>> Betreff: AW: Configurator R7 example
>>
>> May I ask you again for help.
>> I am still stuck at the multi-tenant implementation.
>>
>> As described in my last mail, I have slightly modified your suggestion.
>> I was busy the last couple of days. For some reason, when I try to build the project including a reference to the Map<Map<>> I am getting the following error:
>> [ERROR] Failed to execute goal
>> biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default)
>> on project my-app: Unable to resolve <<INITIAL>>: missing requirement
>> osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)'
>> [caused by: Unable to resolve com.my.app.rest-service
>> version=1.0.0.201808010851: missing requirement
>> osgi.service;filter:='(objectClass=java.util.Map)';effective:='active'
>> ] -> [Help 1]
>>
>> Again, you can find the project on GitHub
>> https://github.com/phhoef/osgi-test/blob/master/rest-service/src/main
>> / java/com/my/app/rest/rest/ServerInfoControllerImpl.java
>>
>> Thanks
>>
>> -----Ursprüngliche Nachricht-----
>> Von: Raymond Auge <ra...@liferay.com>
>> Gesendet: Dienstag, 17. Juli 2018 16:43
>> An: felix users <us...@felix.apache.org>
>> Betreff: Re: Configurator R7 example
>>
>> On Tue, Jul 17, 2018 at 10:18 AM, Philipp Höfler < Philipp.Hoefler@pernexas.com> wrote:
>>
>>> 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.
>>> j
>>> a
>>> va
>>
>> Ok, I will use the terms I see in your code.
>>
>> This JAXRS resource IS the router in my mind. So,
>>
>> - remove all the configuration details from
>> ServerInfoControllerImpl.java
>>
>> @Component(service=ServerInfoControllerImpl.class)
>> @JaxrsResource
>> @Path("serverInfo")
>> public class ServerInfoControllerImpl ....
>>
>> - move all these configuration details to IRepository impl:
>>
>> @Component(
>> configurationPid = "my.config",
>> configurationPolicy = ConfigurationPolicy.REQUIRE
>> )
>> public class IRepositoryImpl implements IRepository ...
>>
>> - make IRepository implement the security checking methods itself
>> based on it's config
>> - make ServerInfoControllerImpl.java track _all_ IRepositories:
>>
>> @Reference(
>> policy = ReferencePolicy.DYNAMIC,
>> policyOption = ReferencePolicyOption.GREEDY
>> )
>> private volatile Map<Map<String, Object>, IRepository>
>> _repositories;
>>
>> - make getServiceInfo(...) find a IRepository by filtering through the tracked _repositories using the inputs, something like:
>>
>> @GET
>> @Produces(MediaType.TEXT_PLAIN)
>> public String getServerInfo(@QueryParam(REPO_NAME) String repoName,
>> @QueryParam(SIGNATURE) String signature) {
>> try {
>> Filter filter = FrameworkUtil.createFilter("(repoName=" + repoName + ")");
>> IRepository repo = _repositories.entrySet().stream().filter(
>> e -> filter.matches(e.getKey())
>> ).map(
>> Map.Entry::getValue
>> ).findFirst().orElse(null);
>>
>> if (repo != null) {
>> if (repo.isSecurityEnabled()) {
>> // do sec
>> return ...
>> }
>> else {
>> // no sec
>> return ...
>> }
>> }
>> }
>> catch (InvalidSyntaxException e1) {
>> // ignore
>> }
>> return "Not Found";
>>
>> That's practically the whole impl.
>>
>> I hope it helps.
>>
>> - Ray
>>
>>
>>> Thanks,
>>> Philipp
>>>
>>> -----Ursprüngliche Nachricht-----
>>> Von: Raymond Auge <ra...@liferay.com>
>>> Gesendet: Montag, 16. Juli 2018 16:48
>>> An: felix users <us...@felix.apache.org>
>>> Betreff: Re: Configurator R7 example
>>>
>>> On Mon, Jul 16, 2018 at 10:42 AM, David Jencks
>>> <da...@gmail.com>
>>> wrote:
>>>
>>>> Inline...
>>>>
>>>> Sent from my iPhone
>>>>
>>>>> On Jul 16, 2018, at 6:34 AM, Raymond Auge
>>>>> <ra...@liferay.com>
>>>> wrote:
>>>>> On Mon, Jul 16, 2018 at 6:16 AM, Philipp Höfler <
>>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>>> Gesendet: Freitag, 13. Juli 2018 16:01
>>>>>> An: felix users <us...@felix.apache.org>
>>>>>> Betreff: Re: Configurator R7 example
>>>>>>
>>>>>> On Fri, Jul 13, 2018 at 4:37 AM, Philipp Höfler <
>>>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>>>> Gesendet: Donnerstag, 12. Juli 2018 18:23
>>>>>>> An: felix users <us...@felix.apache.org>
>>>>>>> Betreff: Re: Configurator R7 example
>>>>>>>
>>>>>>> On Thu, Jul 12, 2018 at 11:58 AM, Philipp Höfler <
>>>>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>>>>> Gesendet: Donnerstag, 12. Juli 2018 16:43
>>>>>>>> An: felix users <us...@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.Hoefler@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 <da...@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.Hoefler@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-unsubscribe@felix.apache.org
>>>>>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>>>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
> --
> Carsten Ziegeler
> Adobe Research Switzerland
> cziegeler@apache.org
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
> B KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKCB [ X ܚX KK[XZ[
> \ \ ][ X ܚX P [^
> \X K ܙ B ܈Y][ۘ[ [X[ K[XZ[
> \ \ Z[ [^
> \X K ܙ B
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org
Re: AW: Configurator R7 example
Posted by Cristiano <cv...@gmail.com>.
Hi,
If you do not have a "consumer" component active for the service
ISecurityChecker you won't have an instance of it created because the
default is to delay the activation until someone request it.
In order to test, you can use the immediate property :
*@Component(immediate = true...*
This means that as soon as DS received a configuration from CM your
component will be activated and an instance of its service will be
registered.
Btw, I suggest you to start by simple examples and only then start to
play with adding a Map or annotation parameter:
> @Activate
> public void activate(ComponentContext pInjectedComponentContext)
With the pInjectedComponentContext object you can access the related
dictionary. I used to do that and pass it to a converter in order to
obtain object from that dictionary instead to have a Map.
I do not understand what do you meant about 'how to get the PID?', since
you already have defined it in your component: *configurationPid =
"my.config"*
regards
Cristiano
On 06/08/2018 10:00, Philipp Höfler wrote:
> I made some progress, based on your information.
> I set the configurationPolicy to REQUIRE, but this alone does not work.
> @RequireConfigurator
> @Component(service = ISecurityChecker.class,
> configurationPid = "my.config",
> configurationPolicy = ConfigurationPolicy.REQUIRE)
> public class SecurityChecker implements ISecurityChecker
>
> Then, I additionally set the policyOption of the reference to GREEDY.
> @Reference(policyOption = ReferencePolicyOption.GREEDY)
> private List<ISecurityChecker> _securityCheckers;
>
> Now, I am getting a List of all configurations - at least a step in the right direction.
> But I am still not getting the pid of the configuration - in my case "system1" and "system2".
> According to Ray, the type would be Map<Map<String, Object>, ISecurityChecker>,
> @Reference(policyOption = ReferencePolicyOption.GREEDY)
> private Map<Map<String, Object>, ISecurityChecker> _securityCheckers;
>
> but when doing this I am getting the following error during compilation:
> [ERROR] Failed to execute goal biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default) on project my-app: Unable to resolve <<INITIAL>>: missing requirement osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)' [caused by: Unable to resolve com.my.app.rest-service version=1.0.0.201808061255: missing requirement osgi.service;filter:='(objectClass=java.util.Map)';effective:='active'] -> [Help 1]
>
> I tried the following types, too, but the same error:
> @Reference(policyOption = ReferencePolicyOption.GREEDY)
> private Map<String, ISecurityChecker> _securityCheckers;
>
> It seems, that the key of the Map is always the problem. But I do not understand why.
> [ERROR] Failed to execute goal biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default) on project my-app: Unable to resolve <<INITIAL>>: missing requirement osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)' [caused by: Unable to resolve com.my.app.rest-service version=1.0.0.201808061258: missing requirement osgi.service;filter:='(objectClass=java.lang.String)';effective:='active'] -> [Help 1]
>
> Any ideas, how I can get the pid of the configuration?
>
> Best,
> Philipp
>
> -----Ursprüngliche Nachricht-----
> Von: Philipp Höfler <Ph...@pernexas.com>
> Gesendet: Montag, 6. August 2018 13:34
> An: users@felix.apache.org
> Betreff: AW: Configurator R7 example
>
> Thanks for your quick reply.
>
> Unfortunately, when setting the policy to required, the whole component won't be loaded.
> At least, when attaching a debugger, the activate method is never called and the reference is always null.
>
> It feels like there is still something fundamental wrong in my code. But I don't see what it is ...
>
> Philipp
>
> -----Ursprüngliche Nachricht-----
> Von: Carsten Ziegeler <cz...@apache.org>
> Gesendet: Montag, 6. August 2018 13:08
> An: users@felix.apache.org; Philipp Höfler <Ph...@pernexas.com>
> Betreff: Re: Configurator R7 example
>
> Atm I'm only guessing, but as you are specifying the configuration to be optional, this might bypass the actual configurations stored in configuration admin.
>
> I would try replacing this with the require policy. At least I have seen some working code which pretty much looks as your example, except for the policy being specified as required
>
> Carsten
>
>
> Philipp Höfler wrote
>> This is driving me nuts.
>> Could someone please help me out?
>>
>> I do not understand how to create multiple instances of a component by the configurator factory and how to reference all these instances.
>> I played around, and it seems, that the configuration is loaded successfully.
>> This is my configuration json file (OSGI-INF/configurator/text.json) {
>> // Resource Format Version
>> ":configurator:resource-version" : 1,
>>
>> // First Configuration
>> "my.config~system1":
>> {
>> "test.securityEnabled": false,
>> "test.name": "System1"
>> },
>> // Second Configuration
>> "my.config~system2":
>> {
>> "test.securityEnabled": true,
>> "test.name": "System2"
>> }
>> }
>>
>> This is my annotation proxy for holding the configuration:
>> public @interface MyConfig
>> {
>> boolean test_securityEnabled() default true;
>> String test_name() default "Empty"; }
>>
>> I've two components.
>> The first one should have access to the config.
>> So, I created a activate and modified annotated method that has a parameter of type MyConfig.
>> This is executed only once. I would have expected, that this component is created twice as I have two configurations for this factory pid, right?
>> @RequireConfigurator
>> @Component(service = ISecurityChecker.class,
>> configurationPid = "my.config",
>> configurationPolicy = ConfigurationPolicy.OPTIONAL) public
>> class SecurityChecker implements ISecurityChecker {
>> private MyConfig _myConfig;
>>
>> @Activate
>> public void activate(MyConfig config)
>> {
>> _myConfig = config;
>> }
>>
>> @Modified
>> public void modified(MyConfig config)
>> {
>> _myConfig = config;
>> }
>>
>> @Override
>> public boolean isSecure(String name, String signature)
>> {
>> if(!_myConfig.isSecurityEnabled())
>> return true;
>>
>> if(name.equals(signature))
>> // do some fancy checks
>> return true;
>>
>> throw new NotAuthorizedException("Signature check failed!");
>> }
>> }
>>
>> The other component is a JaxRS Whiteboard resource serving a small rest service.
>> I am desperately trying to reference ALL instances of the SecurityChecker class, but no matter what I am doing it does not work or only one instance is available.
>> @Component(service=ServerInfoControllerImpl.class)
>> @JaxrsResource
>> @Path("serverInfo")
>> public class ServerInfoControllerImpl
>> {
>> @Reference
>> private List<ISecurityChecker> _securityCheckers;
>>
>> ...
>> }
>>
>> When I set the policy of the reference to dynamic, as Ray suggested, the component is not loaded.
>> Also, when I set the configurationPolicy of the SecurityChecker component to REQUIRED, the SecurityChecker component is not loaded.
>>
>> BUT, when looking in the web console both configurations are available, even though obviously not bound to a bundle. Is that correct?
>>
>> test.name System1
>> test.securityEnabled false
>> Configuration Information
>> Persistent Identity (PID) my.config~system1
>> Factory Persistent Identifier (Factory PID) my.config
>> Configuration Binding ?
>>
>> test.name System2
>> test.securityEnabled true
>> Configuration Information
>> Persistent Identity (PID) my.config~system2
>> Factory Persistent Identifier (Factory PID) my.config
>> Configuration Binding ?
>>
>>
>> Any help is appreciated. 😊
>> Thanks,
>> Philipp
>>
>> -----Ursprüngliche Nachricht-----
>> Von: Philipp Höfler <Ph...@pernexas.com>
>> Gesendet: Mittwoch, 1. August 2018 10:53
>> An: users@felix.apache.org
>> Betreff: AW: Configurator R7 example
>>
>> May I ask you again for help.
>> I am still stuck at the multi-tenant implementation.
>>
>> As described in my last mail, I have slightly modified your suggestion.
>> I was busy the last couple of days. For some reason, when I try to build the project including a reference to the Map<Map<>> I am getting the following error:
>> [ERROR] Failed to execute goal
>> biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default)
>> on project my-app: Unable to resolve <<INITIAL>>: missing requirement
>> osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)'
>> [caused by: Unable to resolve com.my.app.rest-service
>> version=1.0.0.201808010851: missing requirement
>> osgi.service;filter:='(objectClass=java.util.Map)';effective:='active'
>> ] -> [Help 1]
>>
>> Again, you can find the project on GitHub
>> https://github.com/phhoef/osgi-test/blob/master/rest-service/src/main/
>> java/com/my/app/rest/rest/ServerInfoControllerImpl.java
>>
>> Thanks
>>
>> -----Ursprüngliche Nachricht-----
>> Von: Raymond Auge <ra...@liferay.com>
>> Gesendet: Dienstag, 17. Juli 2018 16:43
>> An: felix users <us...@felix.apache.org>
>> Betreff: Re: Configurator R7 example
>>
>> On Tue, Jul 17, 2018 at 10:18 AM, Philipp Höfler < Philipp.Hoefler@pernexas.com> wrote:
>>
>>> 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.j
>>> a
>>> va
>>
>> Ok, I will use the terms I see in your code.
>>
>> This JAXRS resource IS the router in my mind. So,
>>
>> - remove all the configuration details from
>> ServerInfoControllerImpl.java
>>
>> @Component(service=ServerInfoControllerImpl.class)
>> @JaxrsResource
>> @Path("serverInfo")
>> public class ServerInfoControllerImpl ....
>>
>> - move all these configuration details to IRepository impl:
>>
>> @Component(
>> configurationPid = "my.config",
>> configurationPolicy = ConfigurationPolicy.REQUIRE
>> )
>> public class IRepositoryImpl implements IRepository ...
>>
>> - make IRepository implement the security checking methods itself
>> based on it's config
>> - make ServerInfoControllerImpl.java track _all_ IRepositories:
>>
>> @Reference(
>> policy = ReferencePolicy.DYNAMIC,
>> policyOption = ReferencePolicyOption.GREEDY
>> )
>> private volatile Map<Map<String, Object>, IRepository>
>> _repositories;
>>
>> - make getServiceInfo(...) find a IRepository by filtering through the tracked _repositories using the inputs, something like:
>>
>> @GET
>> @Produces(MediaType.TEXT_PLAIN)
>> public String getServerInfo(@QueryParam(REPO_NAME) String repoName,
>> @QueryParam(SIGNATURE) String signature) {
>> try {
>> Filter filter = FrameworkUtil.createFilter("(repoName=" + repoName + ")");
>> IRepository repo = _repositories.entrySet().stream().filter(
>> e -> filter.matches(e.getKey())
>> ).map(
>> Map.Entry::getValue
>> ).findFirst().orElse(null);
>>
>> if (repo != null) {
>> if (repo.isSecurityEnabled()) {
>> // do sec
>> return ...
>> }
>> else {
>> // no sec
>> return ...
>> }
>> }
>> }
>> catch (InvalidSyntaxException e1) {
>> // ignore
>> }
>> return "Not Found";
>>
>> That's practically the whole impl.
>>
>> I hope it helps.
>>
>> - Ray
>>
>>
>>> Thanks,
>>> Philipp
>>>
>>> -----Ursprüngliche Nachricht-----
>>> Von: Raymond Auge <ra...@liferay.com>
>>> Gesendet: Montag, 16. Juli 2018 16:48
>>> An: felix users <us...@felix.apache.org>
>>> Betreff: Re: Configurator R7 example
>>>
>>> On Mon, Jul 16, 2018 at 10:42 AM, David Jencks
>>> <da...@gmail.com>
>>> wrote:
>>>
>>>> Inline...
>>>>
>>>> Sent from my iPhone
>>>>
>>>>> On Jul 16, 2018, at 6:34 AM, Raymond Auge
>>>>> <ra...@liferay.com>
>>>> wrote:
>>>>> On Mon, Jul 16, 2018 at 6:16 AM, Philipp Höfler <
>>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>>> Gesendet: Freitag, 13. Juli 2018 16:01
>>>>>> An: felix users <us...@felix.apache.org>
>>>>>> Betreff: Re: Configurator R7 example
>>>>>>
>>>>>> On Fri, Jul 13, 2018 at 4:37 AM, Philipp Höfler <
>>>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>>>> Gesendet: Donnerstag, 12. Juli 2018 18:23
>>>>>>> An: felix users <us...@felix.apache.org>
>>>>>>> Betreff: Re: Configurator R7 example
>>>>>>>
>>>>>>> On Thu, Jul 12, 2018 at 11:58 AM, Philipp Höfler <
>>>>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>>>>> Gesendet: Donnerstag, 12. Juli 2018 16:43
>>>>>>>> An: felix users <us...@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.Hoefler@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 <da...@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.Hoefler@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-unsubscribe@felix.apache.org
>>>>>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>>>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
> --
> Carsten Ziegeler
> Adobe Research Switzerland
> cziegeler@apache.org
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
> B KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKCB [ X ܚX KK[XZ[
> \ \ ][ X ܚX P [^
> \X K ܙ B ܈Y][ۘ[ [X[ K[XZ[
> \ \ Z[ [^
> \X K ܙ B
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
AW: Configurator R7 example
Posted by Philipp Höfler <Ph...@pernexas.com>.
I made some progress, based on your information.
I set the configurationPolicy to REQUIRE, but this alone does not work.
@RequireConfigurator
@Component(service = ISecurityChecker.class,
configurationPid = "my.config",
configurationPolicy = ConfigurationPolicy.REQUIRE)
public class SecurityChecker implements ISecurityChecker
Then, I additionally set the policyOption of the reference to GREEDY.
@Reference(policyOption = ReferencePolicyOption.GREEDY)
private List<ISecurityChecker> _securityCheckers;
Now, I am getting a List of all configurations - at least a step in the right direction.
But I am still not getting the pid of the configuration - in my case "system1" and "system2".
According to Ray, the type would be Map<Map<String, Object>, ISecurityChecker>,
@Reference(policyOption = ReferencePolicyOption.GREEDY)
private Map<Map<String, Object>, ISecurityChecker> _securityCheckers;
but when doing this I am getting the following error during compilation:
[ERROR] Failed to execute goal biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default) on project my-app: Unable to resolve <<INITIAL>>: missing requirement osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)' [caused by: Unable to resolve com.my.app.rest-service version=1.0.0.201808061255: missing requirement osgi.service;filter:='(objectClass=java.util.Map)';effective:='active'] -> [Help 1]
I tried the following types, too, but the same error:
@Reference(policyOption = ReferencePolicyOption.GREEDY)
private Map<String, ISecurityChecker> _securityCheckers;
It seems, that the key of the Map is always the problem. But I do not understand why.
[ERROR] Failed to execute goal biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default) on project my-app: Unable to resolve <<INITIAL>>: missing requirement osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)' [caused by: Unable to resolve com.my.app.rest-service version=1.0.0.201808061258: missing requirement osgi.service;filter:='(objectClass=java.lang.String)';effective:='active'] -> [Help 1]
Any ideas, how I can get the pid of the configuration?
Best,
Philipp
-----Ursprüngliche Nachricht-----
Von: Philipp Höfler <Ph...@pernexas.com>
Gesendet: Montag, 6. August 2018 13:34
An: users@felix.apache.org
Betreff: AW: Configurator R7 example
Thanks for your quick reply.
Unfortunately, when setting the policy to required, the whole component won't be loaded.
At least, when attaching a debugger, the activate method is never called and the reference is always null.
It feels like there is still something fundamental wrong in my code. But I don't see what it is ...
Philipp
-----Ursprüngliche Nachricht-----
Von: Carsten Ziegeler <cz...@apache.org>
Gesendet: Montag, 6. August 2018 13:08
An: users@felix.apache.org; Philipp Höfler <Ph...@pernexas.com>
Betreff: Re: Configurator R7 example
Atm I'm only guessing, but as you are specifying the configuration to be optional, this might bypass the actual configurations stored in configuration admin.
I would try replacing this with the require policy. At least I have seen some working code which pretty much looks as your example, except for the policy being specified as required
Carsten
Philipp Höfler wrote
> This is driving me nuts.
> Could someone please help me out?
>
> I do not understand how to create multiple instances of a component by the configurator factory and how to reference all these instances.
> I played around, and it seems, that the configuration is loaded successfully.
> This is my configuration json file (OSGI-INF/configurator/text.json) {
> // Resource Format Version
> ":configurator:resource-version" : 1,
>
> // First Configuration
> "my.config~system1":
> {
> "test.securityEnabled": false,
> "test.name": "System1"
> },
> // Second Configuration
> "my.config~system2":
> {
> "test.securityEnabled": true,
> "test.name": "System2"
> }
> }
>
> This is my annotation proxy for holding the configuration:
> public @interface MyConfig
> {
> boolean test_securityEnabled() default true;
> String test_name() default "Empty"; }
>
> I've two components.
> The first one should have access to the config.
> So, I created a activate and modified annotated method that has a parameter of type MyConfig.
> This is executed only once. I would have expected, that this component is created twice as I have two configurations for this factory pid, right?
> @RequireConfigurator
> @Component(service = ISecurityChecker.class,
> configurationPid = "my.config",
> configurationPolicy = ConfigurationPolicy.OPTIONAL) public
> class SecurityChecker implements ISecurityChecker {
> private MyConfig _myConfig;
>
> @Activate
> public void activate(MyConfig config)
> {
> _myConfig = config;
> }
>
> @Modified
> public void modified(MyConfig config)
> {
> _myConfig = config;
> }
>
> @Override
> public boolean isSecure(String name, String signature)
> {
> if(!_myConfig.isSecurityEnabled())
> return true;
>
> if(name.equals(signature))
> // do some fancy checks
> return true;
>
> throw new NotAuthorizedException("Signature check failed!");
> }
> }
>
> The other component is a JaxRS Whiteboard resource serving a small rest service.
> I am desperately trying to reference ALL instances of the SecurityChecker class, but no matter what I am doing it does not work or only one instance is available.
> @Component(service=ServerInfoControllerImpl.class)
> @JaxrsResource
> @Path("serverInfo")
> public class ServerInfoControllerImpl
> {
> @Reference
> private List<ISecurityChecker> _securityCheckers;
>
> ...
> }
>
> When I set the policy of the reference to dynamic, as Ray suggested, the component is not loaded.
> Also, when I set the configurationPolicy of the SecurityChecker component to REQUIRED, the SecurityChecker component is not loaded.
>
> BUT, when looking in the web console both configurations are available, even though obviously not bound to a bundle. Is that correct?
>
> test.name System1
> test.securityEnabled false
> Configuration Information
> Persistent Identity (PID) my.config~system1
> Factory Persistent Identifier (Factory PID) my.config
> Configuration Binding ?
>
> test.name System2
> test.securityEnabled true
> Configuration Information
> Persistent Identity (PID) my.config~system2
> Factory Persistent Identifier (Factory PID) my.config
> Configuration Binding ?
>
>
> Any help is appreciated. 😊
> Thanks,
> Philipp
>
> -----Ursprüngliche Nachricht-----
> Von: Philipp Höfler <Ph...@pernexas.com>
> Gesendet: Mittwoch, 1. August 2018 10:53
> An: users@felix.apache.org
> Betreff: AW: Configurator R7 example
>
> May I ask you again for help.
> I am still stuck at the multi-tenant implementation.
>
> As described in my last mail, I have slightly modified your suggestion.
> I was busy the last couple of days. For some reason, when I try to build the project including a reference to the Map<Map<>> I am getting the following error:
> [ERROR] Failed to execute goal
> biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default)
> on project my-app: Unable to resolve <<INITIAL>>: missing requirement
> osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)'
> [caused by: Unable to resolve com.my.app.rest-service
> version=1.0.0.201808010851: missing requirement
> osgi.service;filter:='(objectClass=java.util.Map)';effective:='active'
> ] -> [Help 1]
>
> Again, you can find the project on GitHub
> https://github.com/phhoef/osgi-test/blob/master/rest-service/src/main/
> java/com/my/app/rest/rest/ServerInfoControllerImpl.java
>
> Thanks
>
> -----Ursprüngliche Nachricht-----
> Von: Raymond Auge <ra...@liferay.com>
> Gesendet: Dienstag, 17. Juli 2018 16:43
> An: felix users <us...@felix.apache.org>
> Betreff: Re: Configurator R7 example
>
> On Tue, Jul 17, 2018 at 10:18 AM, Philipp Höfler < Philipp.Hoefler@pernexas.com> wrote:
>
>> 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.j
>> a
>> va
>
>
> Ok, I will use the terms I see in your code.
>
> This JAXRS resource IS the router in my mind. So,
>
> - remove all the configuration details from
> ServerInfoControllerImpl.java
>
> @Component(service=ServerInfoControllerImpl.class)
> @JaxrsResource
> @Path("serverInfo")
> public class ServerInfoControllerImpl ....
>
> - move all these configuration details to IRepository impl:
>
> @Component(
> configurationPid = "my.config",
> configurationPolicy = ConfigurationPolicy.REQUIRE
> )
> public class IRepositoryImpl implements IRepository ...
>
> - make IRepository implement the security checking methods itself
> based on it's config
> - make ServerInfoControllerImpl.java track _all_ IRepositories:
>
> @Reference(
> policy = ReferencePolicy.DYNAMIC,
> policyOption = ReferencePolicyOption.GREEDY
> )
> private volatile Map<Map<String, Object>, IRepository>
> _repositories;
>
> - make getServiceInfo(...) find a IRepository by filtering through the tracked _repositories using the inputs, something like:
>
> @GET
> @Produces(MediaType.TEXT_PLAIN)
> public String getServerInfo(@QueryParam(REPO_NAME) String repoName,
> @QueryParam(SIGNATURE) String signature) {
> try {
> Filter filter = FrameworkUtil.createFilter("(repoName=" + repoName + ")");
> IRepository repo = _repositories.entrySet().stream().filter(
> e -> filter.matches(e.getKey())
> ).map(
> Map.Entry::getValue
> ).findFirst().orElse(null);
>
> if (repo != null) {
> if (repo.isSecurityEnabled()) {
> // do sec
> return ...
> }
> else {
> // no sec
> return ...
> }
> }
> }
> catch (InvalidSyntaxException e1) {
> // ignore
> }
> return "Not Found";
>
> That's practically the whole impl.
>
> I hope it helps.
>
> - Ray
>
>
>>
>> Thanks,
>> Philipp
>>
>> -----Ursprüngliche Nachricht-----
>> Von: Raymond Auge <ra...@liferay.com>
>> Gesendet: Montag, 16. Juli 2018 16:48
>> An: felix users <us...@felix.apache.org>
>> Betreff: Re: Configurator R7 example
>>
>> On Mon, Jul 16, 2018 at 10:42 AM, David Jencks
>> <da...@gmail.com>
>> wrote:
>>
>>> Inline...
>>>
>>> Sent from my iPhone
>>>
>>>> On Jul 16, 2018, at 6:34 AM, Raymond Auge
>>>> <ra...@liferay.com>
>>> wrote:
>>>>
>>>> On Mon, Jul 16, 2018 at 6:16 AM, Philipp Höfler <
>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>> Gesendet: Freitag, 13. Juli 2018 16:01
>>>>> An: felix users <us...@felix.apache.org>
>>>>> Betreff: Re: Configurator R7 example
>>>>>
>>>>> On Fri, Jul 13, 2018 at 4:37 AM, Philipp Höfler <
>>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>>> Gesendet: Donnerstag, 12. Juli 2018 18:23
>>>>>> An: felix users <us...@felix.apache.org>
>>>>>> Betreff: Re: Configurator R7 example
>>>>>>
>>>>>> On Thu, Jul 12, 2018 at 11:58 AM, Philipp Höfler <
>>>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>>>> Gesendet: Donnerstag, 12. Juli 2018 16:43
>>>>>>> An: felix users <us...@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.Hoefler@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 <da...@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.Hoefler@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-unsubscribe@felix.apache.org
>>>>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
--
Carsten Ziegeler
Adobe Research Switzerland
cziegeler@apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org
B KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKCB [ X ܚX KK[XZ[
\ \ ][ X ܚX P [^
\X K ܙ B ܈Y][ۘ[ [X[ K[XZ[
\ \ Z[ [^
\X K ܙ B
AW: Configurator R7 example
Posted by Philipp Höfler <Ph...@pernexas.com>.
Thanks for your quick reply.
Unfortunately, when setting the policy to required, the whole component won't be loaded.
At least, when attaching a debugger, the activate method is never called and the reference is always null.
It feels like there is still something fundamental wrong in my code. But I don't see what it is ...
Philipp
-----Ursprüngliche Nachricht-----
Von: Carsten Ziegeler <cz...@apache.org>
Gesendet: Montag, 6. August 2018 13:08
An: users@felix.apache.org; Philipp Höfler <Ph...@pernexas.com>
Betreff: Re: Configurator R7 example
Atm I'm only guessing, but as you are specifying the configuration to be optional, this might bypass the actual configurations stored in configuration admin.
I would try replacing this with the require policy. At least I have seen some working code which pretty much looks as your example, except for the policy being specified as required
Carsten
Philipp Höfler wrote
> This is driving me nuts.
> Could someone please help me out?
>
> I do not understand how to create multiple instances of a component by the configurator factory and how to reference all these instances.
> I played around, and it seems, that the configuration is loaded successfully.
> This is my configuration json file (OSGI-INF/configurator/text.json) {
> // Resource Format Version
> ":configurator:resource-version" : 1,
>
> // First Configuration
> "my.config~system1":
> {
> "test.securityEnabled": false,
> "test.name": "System1"
> },
> // Second Configuration
> "my.config~system2":
> {
> "test.securityEnabled": true,
> "test.name": "System2"
> }
> }
>
> This is my annotation proxy for holding the configuration:
> public @interface MyConfig
> {
> boolean test_securityEnabled() default true;
> String test_name() default "Empty"; }
>
> I've two components.
> The first one should have access to the config.
> So, I created a activate and modified annotated method that has a parameter of type MyConfig.
> This is executed only once. I would have expected, that this component is created twice as I have two configurations for this factory pid, right?
> @RequireConfigurator
> @Component(service = ISecurityChecker.class,
> configurationPid = "my.config",
> configurationPolicy = ConfigurationPolicy.OPTIONAL) public
> class SecurityChecker implements ISecurityChecker {
> private MyConfig _myConfig;
>
> @Activate
> public void activate(MyConfig config)
> {
> _myConfig = config;
> }
>
> @Modified
> public void modified(MyConfig config)
> {
> _myConfig = config;
> }
>
> @Override
> public boolean isSecure(String name, String signature)
> {
> if(!_myConfig.isSecurityEnabled())
> return true;
>
> if(name.equals(signature))
> // do some fancy checks
> return true;
>
> throw new NotAuthorizedException("Signature check failed!");
> }
> }
>
> The other component is a JaxRS Whiteboard resource serving a small rest service.
> I am desperately trying to reference ALL instances of the SecurityChecker class, but no matter what I am doing it does not work or only one instance is available.
> @Component(service=ServerInfoControllerImpl.class)
> @JaxrsResource
> @Path("serverInfo")
> public class ServerInfoControllerImpl
> {
> @Reference
> private List<ISecurityChecker> _securityCheckers;
>
> ...
> }
>
> When I set the policy of the reference to dynamic, as Ray suggested, the component is not loaded.
> Also, when I set the configurationPolicy of the SecurityChecker component to REQUIRED, the SecurityChecker component is not loaded.
>
> BUT, when looking in the web console both configurations are available, even though obviously not bound to a bundle. Is that correct?
>
> test.name System1
> test.securityEnabled false
> Configuration Information
> Persistent Identity (PID) my.config~system1
> Factory Persistent Identifier (Factory PID) my.config
> Configuration Binding ?
>
> test.name System2
> test.securityEnabled true
> Configuration Information
> Persistent Identity (PID) my.config~system2
> Factory Persistent Identifier (Factory PID) my.config
> Configuration Binding ?
>
>
> Any help is appreciated. 😊
> Thanks,
> Philipp
>
> -----Ursprüngliche Nachricht-----
> Von: Philipp Höfler <Ph...@pernexas.com>
> Gesendet: Mittwoch, 1. August 2018 10:53
> An: users@felix.apache.org
> Betreff: AW: Configurator R7 example
>
> May I ask you again for help.
> I am still stuck at the multi-tenant implementation.
>
> As described in my last mail, I have slightly modified your suggestion.
> I was busy the last couple of days. For some reason, when I try to build the project including a reference to the Map<Map<>> I am getting the following error:
> [ERROR] Failed to execute goal
> biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default)
> on project my-app: Unable to resolve <<INITIAL>>: missing requirement
> osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)'
> [caused by: Unable to resolve com.my.app.rest-service
> version=1.0.0.201808010851: missing requirement
> osgi.service;filter:='(objectClass=java.util.Map)';effective:='active'
> ] -> [Help 1]
>
> Again, you can find the project on GitHub
> https://github.com/phhoef/osgi-test/blob/master/rest-service/src/main/
> java/com/my/app/rest/rest/ServerInfoControllerImpl.java
>
> Thanks
>
> -----Ursprüngliche Nachricht-----
> Von: Raymond Auge <ra...@liferay.com>
> Gesendet: Dienstag, 17. Juli 2018 16:43
> An: felix users <us...@felix.apache.org>
> Betreff: Re: Configurator R7 example
>
> On Tue, Jul 17, 2018 at 10:18 AM, Philipp Höfler < Philipp.Hoefler@pernexas.com> wrote:
>
>> 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.j
>> a
>> va
>
>
> Ok, I will use the terms I see in your code.
>
> This JAXRS resource IS the router in my mind. So,
>
> - remove all the configuration details from
> ServerInfoControllerImpl.java
>
> @Component(service=ServerInfoControllerImpl.class)
> @JaxrsResource
> @Path("serverInfo")
> public class ServerInfoControllerImpl ....
>
> - move all these configuration details to IRepository impl:
>
> @Component(
> configurationPid = "my.config",
> configurationPolicy = ConfigurationPolicy.REQUIRE
> )
> public class IRepositoryImpl implements IRepository ...
>
> - make IRepository implement the security checking methods itself
> based on it's config
> - make ServerInfoControllerImpl.java track _all_ IRepositories:
>
> @Reference(
> policy = ReferencePolicy.DYNAMIC,
> policyOption = ReferencePolicyOption.GREEDY
> )
> private volatile Map<Map<String, Object>, IRepository>
> _repositories;
>
> - make getServiceInfo(...) find a IRepository by filtering through the tracked _repositories using the inputs, something like:
>
> @GET
> @Produces(MediaType.TEXT_PLAIN)
> public String getServerInfo(@QueryParam(REPO_NAME) String repoName,
> @QueryParam(SIGNATURE) String signature) {
> try {
> Filter filter = FrameworkUtil.createFilter("(repoName=" + repoName + ")");
> IRepository repo = _repositories.entrySet().stream().filter(
> e -> filter.matches(e.getKey())
> ).map(
> Map.Entry::getValue
> ).findFirst().orElse(null);
>
> if (repo != null) {
> if (repo.isSecurityEnabled()) {
> // do sec
> return ...
> }
> else {
> // no sec
> return ...
> }
> }
> }
> catch (InvalidSyntaxException e1) {
> // ignore
> }
> return "Not Found";
>
> That's practically the whole impl.
>
> I hope it helps.
>
> - Ray
>
>
>>
>> Thanks,
>> Philipp
>>
>> -----Ursprüngliche Nachricht-----
>> Von: Raymond Auge <ra...@liferay.com>
>> Gesendet: Montag, 16. Juli 2018 16:48
>> An: felix users <us...@felix.apache.org>
>> Betreff: Re: Configurator R7 example
>>
>> On Mon, Jul 16, 2018 at 10:42 AM, David Jencks
>> <da...@gmail.com>
>> wrote:
>>
>>> Inline...
>>>
>>> Sent from my iPhone
>>>
>>>> On Jul 16, 2018, at 6:34 AM, Raymond Auge
>>>> <ra...@liferay.com>
>>> wrote:
>>>>
>>>> On Mon, Jul 16, 2018 at 6:16 AM, Philipp Höfler <
>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>> Gesendet: Freitag, 13. Juli 2018 16:01
>>>>> An: felix users <us...@felix.apache.org>
>>>>> Betreff: Re: Configurator R7 example
>>>>>
>>>>> On Fri, Jul 13, 2018 at 4:37 AM, Philipp Höfler <
>>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>>> Gesendet: Donnerstag, 12. Juli 2018 18:23
>>>>>> An: felix users <us...@felix.apache.org>
>>>>>> Betreff: Re: Configurator R7 example
>>>>>>
>>>>>> On Thu, Jul 12, 2018 at 11:58 AM, Philipp Höfler <
>>>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>>>> Gesendet: Donnerstag, 12. Juli 2018 16:43
>>>>>>> An: felix users <us...@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.Hoefler@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 <da...@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.Hoefler@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-unsubscribe@felix.apache.org
>>>>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
--
Carsten Ziegeler
Adobe Research Switzerland
cziegeler@apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org
Re: Configurator R7 example
Posted by Carsten Ziegeler <cz...@apache.org>.
Atm I'm only guessing, but as you are specifying the configuration to be
optional, this might bypass the actual configurations stored in
configuration admin.
I would try replacing this with the require policy. At least I have seen
some working code which pretty much looks as your example, except for
the policy being specified as required
Carsten
Philipp Höfler wrote
> This is driving me nuts.
> Could someone please help me out?
>
> I do not understand how to create multiple instances of a component by the configurator factory and how to reference all these instances.
> I played around, and it seems, that the configuration is loaded successfully.
> This is my configuration json file (OSGI-INF/configurator/text.json)
> {
> // Resource Format Version
> ":configurator:resource-version" : 1,
>
> // First Configuration
> "my.config~system1":
> {
> "test.securityEnabled": false,
> "test.name": "System1"
> },
> // Second Configuration
> "my.config~system2":
> {
> "test.securityEnabled": true,
> "test.name": "System2"
> }
> }
>
> This is my annotation proxy for holding the configuration:
> public @interface MyConfig
> {
> boolean test_securityEnabled() default true;
> String test_name() default "Empty";
> }
>
> I've two components.
> The first one should have access to the config.
> So, I created a activate and modified annotated method that has a parameter of type MyConfig.
> This is executed only once. I would have expected, that this component is created twice as I have two configurations for this factory pid, right?
> @RequireConfigurator
> @Component(service = ISecurityChecker.class,
> configurationPid = "my.config",
> configurationPolicy = ConfigurationPolicy.OPTIONAL)
> public class SecurityChecker implements ISecurityChecker
> {
> private MyConfig _myConfig;
>
> @Activate
> public void activate(MyConfig config)
> {
> _myConfig = config;
> }
>
> @Modified
> public void modified(MyConfig config)
> {
> _myConfig = config;
> }
>
> @Override
> public boolean isSecure(String name, String signature)
> {
> if(!_myConfig.isSecurityEnabled())
> return true;
>
> if(name.equals(signature))
> // do some fancy checks
> return true;
>
> throw new NotAuthorizedException("Signature check failed!");
> }
> }
>
> The other component is a JaxRS Whiteboard resource serving a small rest service.
> I am desperately trying to reference ALL instances of the SecurityChecker class, but no matter what I am doing it does not work or only one instance is available.
> @Component(service=ServerInfoControllerImpl.class)
> @JaxrsResource
> @Path("serverInfo")
> public class ServerInfoControllerImpl
> {
> @Reference
> private List<ISecurityChecker> _securityCheckers;
>
> ...
> }
>
> When I set the policy of the reference to dynamic, as Ray suggested, the component is not loaded.
> Also, when I set the configurationPolicy of the SecurityChecker component to REQUIRED, the SecurityChecker component is not loaded.
>
> BUT, when looking in the web console both configurations are available, even though obviously not bound to a bundle. Is that correct?
>
> test.name System1
> test.securityEnabled false
> Configuration Information
> Persistent Identity (PID) my.config~system1
> Factory Persistent Identifier (Factory PID) my.config
> Configuration Binding ?
>
> test.name System2
> test.securityEnabled true
> Configuration Information
> Persistent Identity (PID) my.config~system2
> Factory Persistent Identifier (Factory PID) my.config
> Configuration Binding ?
>
>
> Any help is appreciated. 😊
> Thanks,
> Philipp
>
> -----Ursprüngliche Nachricht-----
> Von: Philipp Höfler <Ph...@pernexas.com>
> Gesendet: Mittwoch, 1. August 2018 10:53
> An: users@felix.apache.org
> Betreff: AW: Configurator R7 example
>
> May I ask you again for help.
> I am still stuck at the multi-tenant implementation.
>
> As described in my last mail, I have slightly modified your suggestion.
> I was busy the last couple of days. For some reason, when I try to build the project including a reference to the Map<Map<>> I am getting the following error:
> [ERROR] Failed to execute goal biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default) on project my-app: Unable to resolve <<INITIAL>>: missing requirement osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)' [caused by: Unable to resolve com.my.app.rest-service version=1.0.0.201808010851: missing requirement osgi.service;filter:='(objectClass=java.util.Map)';effective:='active'] -> [Help 1]
>
> Again, you can find the project on GitHub https://github.com/phhoef/osgi-test/blob/master/rest-service/src/main/java/com/my/app/rest/rest/ServerInfoControllerImpl.java
>
> Thanks
>
> -----Ursprüngliche Nachricht-----
> Von: Raymond Auge <ra...@liferay.com>
> Gesendet: Dienstag, 17. Juli 2018 16:43
> An: felix users <us...@felix.apache.org>
> Betreff: Re: Configurator R7 example
>
> On Tue, Jul 17, 2018 at 10:18 AM, Philipp Höfler < Philipp.Hoefler@pernexas.com> wrote:
>
>> 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.ja
>> va
>
>
> Ok, I will use the terms I see in your code.
>
> This JAXRS resource IS the router in my mind. So,
>
> - remove all the configuration details from ServerInfoControllerImpl.java
>
> @Component(service=ServerInfoControllerImpl.class)
> @JaxrsResource
> @Path("serverInfo")
> public class ServerInfoControllerImpl ....
>
> - move all these configuration details to IRepository impl:
>
> @Component(
> configurationPid = "my.config",
> configurationPolicy = ConfigurationPolicy.REQUIRE
> )
> public class IRepositoryImpl implements IRepository ...
>
> - make IRepository implement the security checking methods itself based on it's config
> - make ServerInfoControllerImpl.java track _all_ IRepositories:
>
> @Reference(
> policy = ReferencePolicy.DYNAMIC,
> policyOption = ReferencePolicyOption.GREEDY
> )
> private volatile Map<Map<String, Object>, IRepository> _repositories;
>
> - make getServiceInfo(...) find a IRepository by filtering through the tracked _repositories using the inputs, something like:
>
> @GET
> @Produces(MediaType.TEXT_PLAIN)
> public String getServerInfo(@QueryParam(REPO_NAME) String repoName,
> @QueryParam(SIGNATURE) String signature) {
> try {
> Filter filter = FrameworkUtil.createFilter("(repoName=" + repoName + ")");
> IRepository repo = _repositories.entrySet().stream().filter(
> e -> filter.matches(e.getKey())
> ).map(
> Map.Entry::getValue
> ).findFirst().orElse(null);
>
> if (repo != null) {
> if (repo.isSecurityEnabled()) {
> // do sec
> return ...
> }
> else {
> // no sec
> return ...
> }
> }
> }
> catch (InvalidSyntaxException e1) {
> // ignore
> }
> return "Not Found";
>
> That's practically the whole impl.
>
> I hope it helps.
>
> - Ray
>
>
>>
>> Thanks,
>> Philipp
>>
>> -----Ursprüngliche Nachricht-----
>> Von: Raymond Auge <ra...@liferay.com>
>> Gesendet: Montag, 16. Juli 2018 16:48
>> An: felix users <us...@felix.apache.org>
>> Betreff: Re: Configurator R7 example
>>
>> On Mon, Jul 16, 2018 at 10:42 AM, David Jencks
>> <da...@gmail.com>
>> wrote:
>>
>>> Inline...
>>>
>>> Sent from my iPhone
>>>
>>>> On Jul 16, 2018, at 6:34 AM, Raymond Auge
>>>> <ra...@liferay.com>
>>> wrote:
>>>>
>>>> On Mon, Jul 16, 2018 at 6:16 AM, Philipp Höfler <
>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>> Gesendet: Freitag, 13. Juli 2018 16:01
>>>>> An: felix users <us...@felix.apache.org>
>>>>> Betreff: Re: Configurator R7 example
>>>>>
>>>>> On Fri, Jul 13, 2018 at 4:37 AM, Philipp Höfler <
>>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>>> Gesendet: Donnerstag, 12. Juli 2018 18:23
>>>>>> An: felix users <us...@felix.apache.org>
>>>>>> Betreff: Re: Configurator R7 example
>>>>>>
>>>>>> On Thu, Jul 12, 2018 at 11:58 AM, Philipp Höfler <
>>>>>> Philipp.Hoefler@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 <ra...@liferay.com>
>>>>>>> Gesendet: Donnerstag, 12. Juli 2018 16:43
>>>>>>> An: felix users <us...@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.Hoefler@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 <da...@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.Hoefler@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-unsubscribe@felix.apache.org
>>>>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
--
Carsten Ziegeler
Adobe Research Switzerland
cziegeler@apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org
AW: Configurator R7 example
Posted by Philipp Höfler <Ph...@pernexas.com>.
This is driving me nuts.
Could someone please help me out?
I do not understand how to create multiple instances of a component by the configurator factory and how to reference all these instances.
I played around, and it seems, that the configuration is loaded successfully.
This is my configuration json file (OSGI-INF/configurator/text.json)
{
// Resource Format Version
":configurator:resource-version" : 1,
// First Configuration
"my.config~system1":
{
"test.securityEnabled": false,
"test.name": "System1"
},
// Second Configuration
"my.config~system2":
{
"test.securityEnabled": true,
"test.name": "System2"
}
}
This is my annotation proxy for holding the configuration:
public @interface MyConfig
{
boolean test_securityEnabled() default true;
String test_name() default "Empty";
}
I've two components.
The first one should have access to the config.
So, I created a activate and modified annotated method that has a parameter of type MyConfig.
This is executed only once. I would have expected, that this component is created twice as I have two configurations for this factory pid, right?
@RequireConfigurator
@Component(service = ISecurityChecker.class,
configurationPid = "my.config",
configurationPolicy = ConfigurationPolicy.OPTIONAL)
public class SecurityChecker implements ISecurityChecker
{
private MyConfig _myConfig;
@Activate
public void activate(MyConfig config)
{
_myConfig = config;
}
@Modified
public void modified(MyConfig config)
{
_myConfig = config;
}
@Override
public boolean isSecure(String name, String signature)
{
if(!_myConfig.isSecurityEnabled())
return true;
if(name.equals(signature))
// do some fancy checks
return true;
throw new NotAuthorizedException("Signature check failed!");
}
}
The other component is a JaxRS Whiteboard resource serving a small rest service.
I am desperately trying to reference ALL instances of the SecurityChecker class, but no matter what I am doing it does not work or only one instance is available.
@Component(service=ServerInfoControllerImpl.class)
@JaxrsResource
@Path("serverInfo")
public class ServerInfoControllerImpl
{
@Reference
private List<ISecurityChecker> _securityCheckers;
...
}
When I set the policy of the reference to dynamic, as Ray suggested, the component is not loaded.
Also, when I set the configurationPolicy of the SecurityChecker component to REQUIRED, the SecurityChecker component is not loaded.
BUT, when looking in the web console both configurations are available, even though obviously not bound to a bundle. Is that correct?
test.name System1
test.securityEnabled false
Configuration Information
Persistent Identity (PID) my.config~system1
Factory Persistent Identifier (Factory PID) my.config
Configuration Binding ?
test.name System2
test.securityEnabled true
Configuration Information
Persistent Identity (PID) my.config~system2
Factory Persistent Identifier (Factory PID) my.config
Configuration Binding ?
Any help is appreciated. 😊
Thanks,
Philipp
-----Ursprüngliche Nachricht-----
Von: Philipp Höfler <Ph...@pernexas.com>
Gesendet: Mittwoch, 1. August 2018 10:53
An: users@felix.apache.org
Betreff: AW: Configurator R7 example
May I ask you again for help.
I am still stuck at the multi-tenant implementation.
As described in my last mail, I have slightly modified your suggestion.
I was busy the last couple of days. For some reason, when I try to build the project including a reference to the Map<Map<>> I am getting the following error:
[ERROR] Failed to execute goal biz.aQute.bnd:bnd-export-maven-plugin:4.1.0-SNAPSHOT:export (default) on project my-app: Unable to resolve <<INITIAL>>: missing requirement osgi.identity;filter:='(osgi.identity=com.my.app.rest-service)' [caused by: Unable to resolve com.my.app.rest-service version=1.0.0.201808010851: missing requirement osgi.service;filter:='(objectClass=java.util.Map)';effective:='active'] -> [Help 1]
Again, you can find the project on GitHub https://github.com/phhoef/osgi-test/blob/master/rest-service/src/main/java/com/my/app/rest/rest/ServerInfoControllerImpl.java
Thanks
-----Ursprüngliche Nachricht-----
Von: Raymond Auge <ra...@liferay.com>
Gesendet: Dienstag, 17. Juli 2018 16:43
An: felix users <us...@felix.apache.org>
Betreff: Re: Configurator R7 example
On Tue, Jul 17, 2018 at 10:18 AM, Philipp Höfler < Philipp.Hoefler@pernexas.com> wrote:
> 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.ja
> va
Ok, I will use the terms I see in your code.
This JAXRS resource IS the router in my mind. So,
- remove all the configuration details from ServerInfoControllerImpl.java
@Component(service=ServerInfoControllerImpl.class)
@JaxrsResource
@Path("serverInfo")
public class ServerInfoControllerImpl ....
- move all these configuration details to IRepository impl:
@Component(
configurationPid = "my.config",
configurationPolicy = ConfigurationPolicy.REQUIRE
)
public class IRepositoryImpl implements IRepository ...
- make IRepository implement the security checking methods itself based on it's config
- make ServerInfoControllerImpl.java track _all_ IRepositories:
@Reference(
policy = ReferencePolicy.DYNAMIC,
policyOption = ReferencePolicyOption.GREEDY
)
private volatile Map<Map<String, Object>, IRepository> _repositories;
- make getServiceInfo(...) find a IRepository by filtering through the tracked _repositories using the inputs, something like:
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getServerInfo(@QueryParam(REPO_NAME) String repoName,
@QueryParam(SIGNATURE) String signature) {
try {
Filter filter = FrameworkUtil.createFilter("(repoName=" + repoName + ")");
IRepository repo = _repositories.entrySet().stream().filter(
e -> filter.matches(e.getKey())
).map(
Map.Entry::getValue
).findFirst().orElse(null);
if (repo != null) {
if (repo.isSecurityEnabled()) {
// do sec
return ...
}
else {
// no sec
return ...
}
}
}
catch (InvalidSyntaxException e1) {
// ignore
}
return "Not Found";
That's practically the whole impl.
I hope it helps.
- Ray
>
> Thanks,
> Philipp
>
> -----Ursprüngliche Nachricht-----
> Von: Raymond Auge <ra...@liferay.com>
> Gesendet: Montag, 16. Juli 2018 16:48
> An: felix users <us...@felix.apache.org>
> Betreff: Re: Configurator R7 example
>
> On Mon, Jul 16, 2018 at 10:42 AM, David Jencks
> <da...@gmail.com>
> wrote:
>
> > Inline...
> >
> > Sent from my iPhone
> >
> > > On Jul 16, 2018, at 6:34 AM, Raymond Auge
> > > <ra...@liferay.com>
> > wrote:
> > >
> > > On Mon, Jul 16, 2018 at 6:16 AM, Philipp Höfler <
> > > Philipp.Hoefler@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 <ra...@liferay.com>
> > >> Gesendet: Freitag, 13. Juli 2018 16:01
> > >> An: felix users <us...@felix.apache.org>
> > >> Betreff: Re: Configurator R7 example
> > >>
> > >> On Fri, Jul 13, 2018 at 4:37 AM, Philipp Höfler <
> > >> Philipp.Hoefler@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 <ra...@liferay.com>
> > >>> Gesendet: Donnerstag, 12. Juli 2018 18:23
> > >>> An: felix users <us...@felix.apache.org>
> > >>> Betreff: Re: Configurator R7 example
> > >>>
> > >>> On Thu, Jul 12, 2018 at 11:58 AM, Philipp Höfler <
> > >>> Philipp.Hoefler@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 <ra...@liferay.com>
> > >>>> Gesendet: Donnerstag, 12. Juli 2018 16:43
> > >>>> An: felix users <us...@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.Hoefler@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 <da...@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.Hoefler@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-unsubscribe@felix.apache.org
> > >>>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
> > >>>> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
> > >> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
> > For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@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-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org