Re: Use LoginModuleProxy (was: Make Whiteboard accessible through ContentRepository)

2014-02-14 Thread Chetan Mehrotra
On Thu, Feb 13, 2014 at 11:49 PM, Tobias Bocanegra tri...@apache.org wrote:
 this callback would rely on some sort of (non-osgi) list of
 pre-configured factories, right?
 eg some sort of LoginModuleFactoryRegistryImpl that is added to the
 authentication configuration?

Sort of. As Jukka mentioned the code which configures Oak
programatically in non OSGi env can also provide a list of
LoginModuleFactory as part of Security setup. In OSGi env get them via
DS

 this has one caveat, that you could register 1 factory per class (if
 you are using the factories class name as identifier). otherwise you
 would need to introduce some kind of factory pid.

Yup. For completeness and to cover all cases you can have some factory
property (similar to service property in OSGi). And that can be passed
to LoginModuleFactory as argument so that it can instantiate right LM
impl

Chetan Mehrotra


Re: Make Whiteboard accessible through ContentRepository

2014-02-13 Thread Chetan Mehrotra
On Thu, Feb 13, 2014 at 12:45 PM, Tobias Bocanegra tri...@apache.org wrote:
 I don't quite follow. can you give an example of what would be in the
 jaas.conf and where you instantiate the ProxyLoginModule ?

A rough sketch would be ...

jaas.config


oakAuth {
org.apache.jackrabbit.oak.security.ProxyLoginModule REQUIRED

loginModuleFactoryClass=org.apache.jackrabbit.oak.security.LdapLoginModuleFactory
authIdentity={USERNAME}
useSSL=false
debug=true;
};


public class ProxyLoginModule implements LoginModule{
private LoginModule delegate;

public void initialize(Subject subject, CallbackHandler callbackHandler,
MapString, ? sharedState, MapString, ? options){
LMFactoryProviderCallBack lmfcb = new LMFactoryProviderCallBack()
factory =  callbackHandler.handle([lmfcb]);
LoginModuleFactory factory = lmfcb.getLoginModuleFactoryProvider()

.getFactory(options.get(loginModuleFactoryClass));
delegate = factory.createLoginModule();
delegate.initialize(subject, callbackHandler, sharedState, options);
}

...
//Use delegate for other operations
}

The flow would involve following steps

1. User mentions the ProxyLoginModule in jaas entry and provide the
factory class name in the config. JAAS logic would be instantiating
the Proxy LM
2. Oak provides a callback using which Proxy LM can obtain the factory
3. Upon init the proxy would initialize the delegate from factory
4. The delegate is used for later calls
5. LM if required can still use the config from jaas or ot is
configured via factory itself

Note here I preferred using the callback to get LM access the outer
layer services instead of using a custom config.

The custom config mode works fine in standalone case where the
application is the sole user of JAAS system. Hence it works fine for
Karaf/OSGi env But that might not work properly in App server env
where app server itself uses jaas. So to avoid interfering in embedded
mode callback should be preferred.

Chetan Mehrotra


Re: Make Whiteboard accessible through ContentRepository

2014-02-13 Thread Tobias Bocanegra
hi,

On Thursday, February 13, 2014, Chetan Mehrotra chetan.mehro...@gmail.com
wrote:

 On Thu, Feb 13, 2014 at 12:45 PM, Tobias Bocanegra 
 tri...@apache.orgjavascript:;
 wrote:
  I don't quite follow. can you give an example of what would be in the
  jaas.conf and where you instantiate the ProxyLoginModule ?

 A rough sketch would be ...

 jaas.config

 
 oakAuth {
 org.apache.jackrabbit.oak.security.ProxyLoginModule REQUIRED

 loginModuleFactoryClass=org.apache.jackrabbit.oak.security.LdapLoginModuleFactory
 authIdentity={USERNAME}
 useSSL=false
 debug=true;
 };
 

 public class ProxyLoginModule implements LoginModule{
 private LoginModule delegate;

 public void initialize(Subject subject, CallbackHandler
 callbackHandler,
 MapString, ? sharedState, MapString, ? options){
 LMFactoryProviderCallBack lmfcb = new LMFactoryProviderCallBack()
 factory =  callbackHandler.handle([lmfcb]);
 LoginModuleFactory factory = lmfcb.getLoginModuleFactoryProvider()

 .getFactory(options.get(loginModuleFactoryClass));
 delegate = factory.createLoginModule();
 delegate.initialize(subject, callbackHandler, sharedState,
 options);
 }

 ...
 //Use delegate for other operations
 }

 The flow would involve following steps

 1. User mentions the ProxyLoginModule in jaas entry and provide the
 factory class name in the config. JAAS logic would be instantiating
 the Proxy LM
 2. Oak provides a callback using which Proxy LM can obtain the factory
 3. Upon init the proxy would initialize the delegate from factory
 4. The delegate is used for later calls
 5. LM if required can still use the config from jaas or ot is
 configured via factory itself

 Note here I preferred using the callback to get LM access the outer
 layer services instead of using a custom config.

 The custom config mode works fine in standalone case where the
 application is the sole user of JAAS system. Hence it works fine for
 Karaf/OSGi env But that might not work properly in App server env
 where app server itself uses jaas. So to avoid interfering in embedded
 mode callback should be preferred.

 Chetan Mehrotra

ok, that how I thought it would be. if we can live with the restriction
that we need to use a proxy login module for our LMs, we're good.

btw: if you look at the current ExternalLoginModule , I already used a LMF
but only for the osgi case. if we could use a ProxyLM, that would simplify
the code a lot.

regards Toby


Re: Make Whiteboard accessible through ContentRepository

2014-02-13 Thread Jukka Zitting
Hi,

On Wed, Feb 12, 2014 at 10:15 AM, Tobias Bocanegra tri...@apache.org wrote:
 But this LoginBackend is in the end something similar like a
 specialized ServiceRegistry. So why not use the whiteboard instead?

You're seeing service registries everywhere. :-)

No, the idea of the LoginBackend is to be contain all the
authentication logic that uses whatever dependencies that are needed.
See the end of this message for a quick draft of how this could work.
Or we could even use a delegate LoginModule like in the
ProxyLoginModule case Chetan described.

BR,

Jukka Zitting


// MyLoginModule.java

public class MyLoginModule implements LoginModule {

private Subject subject;

private CallbackHandler callbackHandler;

private LoginBackend backend;

private boolean success;

private final SetPrincipal principals = newHashSet();

private final SetObject credentials = newHashSet();

// can be overridden to work with LoginModuleFactory, or other
binding mechanisms
protected LoginBackend getLoginBackend(MapString, ? options) {
return (LoginBackend) options.get(LoginBackend.class.getName());
}

@Override
public void initialize(
Subject subject, CallbackHandler callbackHandler,
MapString, ? sharedState, MapString, ? options) {
this.subject = subject;
this.callbackHandler = callbackHandler;
this.backend = getLoginBackend(options);
this.success = false;
}

@Override
public boolean login() throws LoginException {
if (backend == null) {
return false;
}

// Perform login using credential information from callbackHandler.
// Return authenticated principals and the used credentials in the
// given sets. Throw LoginException if authentication fails.
backend.login(callbackHandler, principals, credentials);
success = true;
return true;
}

@Override
public boolean commit() throws LoginException {
if (backend == null) {
return false;
}

if (success) {
// add login details to the subject
subject.getPrincipals().addAll(principals);
subject.getPublicCredentials().addAll(credentials);
} else {
// clear state
principals.clear();
credentials.clear();
}
return true;
}

@Override
public boolean abort() throws LoginException {
if (backend == null) {
return false;
}

// clear state
principals.clear();
credentials.clear();
success = false;
return false;
}

@Override
public boolean logout() throws LoginException {
if (backend == null) {
return false;
}

if (success) {
// remove login details from the subject
subject.getPrincipals().removeAll(principals);
subject.getPublicCredentials().removeAll(credentials);
}

// clear state
principals.clear();
credentials.clear();
success = false;
return true;
}

}


Re: Make Whiteboard accessible through ContentRepository

2014-02-13 Thread Jukka Zitting
Hi,

On Thu, Feb 13, 2014 at 4:11 AM, Chetan Mehrotra
chetan.mehro...@gmail.com wrote:
 Note here I preferred using the callback to get LM access the outer
 layer services instead of using a custom config.

 The custom config mode works fine in standalone case where the
 application is the sole user of JAAS system. Hence it works fine for
 Karaf/OSGi env But that might not work properly in App server env
 where app server itself uses jaas. So to avoid interfering in embedded
 mode callback should be preferred.

The problem with using a CallbackHandler for such things is that it
forces the client code (that controls the CallbackHandler) to
understand about the LoginModule implementation. Thus you can't use
such a LoginModule with a client that relies only on the standard JAAS
API.

As mentioned in a previous message, it's better to use the options map
that comes from the runtime environment and can thus be controlled
without touching the client code.

BR,

Jukka Zitting


Re: Make Whiteboard accessible through ContentRepository

2014-02-13 Thread Tobias Bocanegra
Hi,

On Thu, Feb 13, 2014 at 8:34 AM, Jukka Zitting jukka.zitt...@gmail.com wrote:
 On Wed, Feb 12, 2014 at 10:15 AM, Tobias Bocanegra tri...@apache.org wrote:
 But this LoginBackend is in the end something similar like a
 specialized ServiceRegistry. So why not use the whiteboard instead?

 You're seeing service registries everywhere. :-)
I'm having nightmares of them :-) !

 No, the idea of the LoginBackend is to be contain all the
 authentication logic that uses whatever dependencies that are needed.
 See the end of this message for a quick draft of how this could work.

Well, but the LoginBackend would be specific to the type of
LoginModule. For LDAP its the LDAP backend, for repository users, its
the OakUserLoginBackend, etc. How would you wire this to the specific
LoginModule instance?

 Or we could even use a delegate LoginModule like in the
 ProxyLoginModule case Chetan described.
(I'll fork that thread and respond there)

Regards, Toby


 BR,

 Jukka Zitting


 // MyLoginModule.java

 public class MyLoginModule implements LoginModule {

 private Subject subject;

 private CallbackHandler callbackHandler;

 private LoginBackend backend;

 private boolean success;

 private final SetPrincipal principals = newHashSet();

 private final SetObject credentials = newHashSet();

 // can be overridden to work with LoginModuleFactory, or other
 binding mechanisms
 protected LoginBackend getLoginBackend(MapString, ? options) {
 return (LoginBackend) options.get(LoginBackend.class.getName());
 }

 @Override
 public void initialize(
 Subject subject, CallbackHandler callbackHandler,
 MapString, ? sharedState, MapString, ? options) {
 this.subject = subject;
 this.callbackHandler = callbackHandler;
 this.backend = getLoginBackend(options);
 this.success = false;
 }

 @Override
 public boolean login() throws LoginException {
 if (backend == null) {
 return false;
 }

 // Perform login using credential information from callbackHandler.
 // Return authenticated principals and the used credentials in the
 // given sets. Throw LoginException if authentication fails.
 backend.login(callbackHandler, principals, credentials);
 success = true;
 return true;
 }

 @Override
 public boolean commit() throws LoginException {
 if (backend == null) {
 return false;
 }

 if (success) {
 // add login details to the subject
 subject.getPrincipals().addAll(principals);
 subject.getPublicCredentials().addAll(credentials);
 } else {
 // clear state
 principals.clear();
 credentials.clear();
 }
 return true;
 }

 @Override
 public boolean abort() throws LoginException {
 if (backend == null) {
 return false;
 }

 // clear state
 principals.clear();
 credentials.clear();
 success = false;
 return false;
 }

 @Override
 public boolean logout() throws LoginException {
 if (backend == null) {
 return false;
 }

 if (success) {
 // remove login details from the subject
 subject.getPrincipals().removeAll(principals);
 subject.getPublicCredentials().removeAll(credentials);
 }

 // clear state
 principals.clear();
 credentials.clear();
 success = false;
 return true;
 }

 }


Use LoginModuleProxy (was: Make Whiteboard accessible through ContentRepository)

2014-02-13 Thread Tobias Bocanegra
Hi,

On Thu, Feb 13, 2014 at 8:55 AM, Jukka Zitting jukka.zitt...@gmail.com wrote:
 Hi,
 On Thu, Feb 13, 2014 at 4:11 AM, Chetan Mehrotra
 chetan.mehro...@gmail.com wrote:
 Note here I preferred using the callback to get LM access the outer
 layer services instead of using a custom config.

 The custom config mode works fine in standalone case where the
 application is the sole user of JAAS system. Hence it works fine for
 Karaf/OSGi env But that might not work properly in App server env
 where app server itself uses jaas. So to avoid interfering in embedded
 mode callback should be preferred.

 The problem with using a CallbackHandler for such things is that it
 forces the client code (that controls the CallbackHandler) to
 understand about the LoginModule implementation. Thus you can't use
 such a LoginModule with a client that relies only on the standard JAAS
 API.
well yes. but I think the LMs are never generic. They need to
understand the host application they are running in; especially with
more complex setup of different LMs. In reality, I don't think that a
LM that doesn't extend from Oak's AbstractLoginModule really works
great.

 As mentioned in a previous message, it's better to use the options map
 that comes from the runtime environment and can thus be controlled
 without touching the client code.
I think both are needed. As I wrote above, I think tightly Oak coupled
login modules even benefit from a fixed set of callback handlers. i.e.
it is more robust to write:

RepositoryCallback rcb = new RepositoryCallback();
callbackHandler.handle(new Callback[]{rcb});
securityProvider = rcb.getSecurityProvider();

than:

securityProvider = options.get(SecurityProvider.class.getName());

It is more transparent to the developer what backend objects are
retrievable, IMO.


Use LoginModuleProxy (was: Make Whiteboard accessible through ContentRepository)

2014-02-13 Thread Tobias Bocanegra
Hi,

On Thu, Feb 13, 2014 at 1:11 AM, Chetan Mehrotra
chetan.mehro...@gmail.com wrote:
 On Thu, Feb 13, 2014 at 12:45 PM, Tobias Bocanegra tri...@apache.org wrote:
 I don't quite follow. can you give an example of what would be in the
 jaas.conf and where you instantiate the ProxyLoginModule ?

 A rough sketch would be ...

 jaas.config

 
 oakAuth {
 org.apache.jackrabbit.oak.security.ProxyLoginModule REQUIRED
 
 loginModuleFactoryClass=org.apache.jackrabbit.oak.security.LdapLoginModuleFactory
 authIdentity={USERNAME}
 useSSL=false
 debug=true;
 };
 

 public class ProxyLoginModule implements LoginModule{
 private LoginModule delegate;

 public void initialize(Subject subject, CallbackHandler callbackHandler,
 MapString, ? sharedState, MapString, ? options){
 LMFactoryProviderCallBack lmfcb = new LMFactoryProviderCallBack()
 factory =  callbackHandler.handle([lmfcb]);
 LoginModuleFactory factory = lmfcb.getLoginModuleFactoryProvider()

 .getFactory(options.get(loginModuleFactoryClass));
 delegate = factory.createLoginModule();
 delegate.initialize(subject, callbackHandler, sharedState, options);
 }

 ...
 //Use delegate for other operations
 }

 The flow would involve following steps

 1. User mentions the ProxyLoginModule in jaas entry and provide the
 factory class name in the config. JAAS logic would be instantiating
 the Proxy LM
 2. Oak provides a callback using which Proxy LM can obtain the factory

this callback would rely on some sort of (non-osgi) list of
pre-configured factories, right?
eg some sort of LoginModuleFactoryRegistryImpl that is added to the
authentication configuration?

 3. Upon init the proxy would initialize the delegate from factory
 4. The delegate is used for later calls
 5. LM if required can still use the config from jaas or ot is
 configured via factory itself

this has one caveat, that you could register 1 factory per class (if
you are using the factories class name as identifier). otherwise you
would need to introduce some kind of factory pid.

 Note here I preferred using the callback to get LM access the outer
 layer services instead of using a custom config.

 The custom config mode works fine in standalone case where the
 application is the sole user of JAAS system. Hence it works fine for
 Karaf/OSGi env But that might not work properly in App server env
 where app server itself uses jaas. So to avoid interfering in embedded
 mode callback should be preferred.

regards, toby


Re: Make Whiteboard accessible through ContentRepository

2014-02-12 Thread Jukka Zitting
Hi,

On Wed, Feb 12, 2014 at 1:37 AM, Tobias Bocanegra tri...@apache.org wrote:
 On Tue, Feb 11, 2014 at 4:38 PM, Tobias Bocanegra tri...@apache.org wrote:
 but then, why does the Whiteboard interface has a register() method?
 This indicates to me, that there is a global service registry behind
 that can be used by all other users of the whiteboard.

The whiteboard pattern requires mechanisms for registering services
and tracking them. Note that the Whiteboard interface explicitly does
not have a getService() method, only track() method used by event
sources in the whiteboard pattern.

 Also, using the whiteboard in the tests make them very easy
 configurable and simulates a bit better how OSGi will work. for
 example in the ExternalLoginModuleTest, I can just do:

This seems too complicated. Why not just pass the dependencies
directly to the LoginModule component, using the pattern I suggested
earlier?

 addendum: If I want to achieve the same without the whiteboard, I would need 
 to:

This also seems too complicated.

 The additional work is that I need to re-invent some sort of service
 registry for the LoginModuleServiceProviderConfigurationImpl and
 extend the SecurityProvider with another configuration. Also, I limit
 the interfaces to be used in the LoginModules to the ones implementing
 the LoginModuleService interface. you might say, this is more robust -
 I say, this is just more complicated and has tighter coupling.

Not more robust, just way too complicated. :-)

I don't see why stuff like LoginModuleServiceProviderConfigurationImpl
or even SecurityProvider would need to be involved here.  Just pass
the required dependencies directly to the LoginModule implementation
and forget the rest of the stack. There should be no need to route
those dependencies through multiple layers of provider/configuration
objects. The way I see it, the perceived need for a service registry
is just a side-effect of trying to force things to such a pattern.

This is all the wiring that we should need for Java-only environments:

LoginBackend backend =
new LoginBackend(dependency1, dependency2, ...);
MapString, ? options = singletonMap(
LoginBackend.class.getName(), backend);
Configuration.setConfiguration(new ConfigurationExtender(
Configuration.getConfiguration(), options));

Or in the OSGi case, make LoginBackend a service and use something
like the LoginModuleFactory Chetan mentioned.

BR,

Jukka Zitting


Re: Make Whiteboard accessible through ContentRepository

2014-02-12 Thread Tobias Bocanegra
Hi,

On Wed, Feb 12, 2014 at 2:00 AM, Jukka Zitting jukka.zitt...@gmail.com wrote:
 On Wed, Feb 12, 2014 at 1:37 AM, Tobias Bocanegra tri...@apache.org wrote:
 On Tue, Feb 11, 2014 at 4:38 PM, Tobias Bocanegra tri...@apache.org wrote:
 but then, why does the Whiteboard interface has a register() method?
 This indicates to me, that there is a global service registry behind
 that can be used by all other users of the whiteboard.

 The whiteboard pattern requires mechanisms for registering services
 and tracking them. Note that the Whiteboard interface explicitly does
 not have a getService() method, only track() method used by event
 sources in the whiteboard pattern.

 Also, using the whiteboard in the tests make them very easy
 configurable and simulates a bit better how OSGi will work. for
 example in the ExternalLoginModuleTest, I can just do:

 This seems too complicated. Why not just pass the dependencies
 directly to the LoginModule component, using the pattern I suggested
 earlier?

 addendum: If I want to achieve the same without the whiteboard, I would need 
 to:

 This also seems too complicated.

 The additional work is that I need to re-invent some sort of service
 registry for the LoginModuleServiceProviderConfigurationImpl and
 extend the SecurityProvider with another configuration. Also, I limit
 the interfaces to be used in the LoginModules to the ones implementing
 the LoginModuleService interface. you might say, this is more robust -
 I say, this is just more complicated and has tighter coupling.

 Not more robust, just way too complicated. :-)

 I don't see why stuff like LoginModuleServiceProviderConfigurationImpl
 or even SecurityProvider would need to be involved here.  Just pass
 the required dependencies directly to the LoginModule implementation
 and forget the rest of the stack. There should be no need to route
 those dependencies through multiple layers of provider/configuration
 objects. The way I see it, the perceived need for a service registry
 is just a side-effect of trying to force things to such a pattern.

 This is all the wiring that we should need for Java-only environments:

 LoginBackend backend =
 new LoginBackend(dependency1, dependency2, ...);
 MapString, ? options = singletonMap(
 LoginBackend.class.getName(), backend);
 Configuration.setConfiguration(new ConfigurationExtender(
 Configuration.getConfiguration(), options));

 Or in the OSGi case, make LoginBackend a service and use something
 like the LoginModuleFactory Chetan mentioned.

But this LoginBackend is in the end something similar like a
specialized ServiceRegistry. So why not use the whiteboard instead?

However, I give it a try refactoring it with a LoginBackend - even if
only to avoid the callbacks.
regards, toby


Re: Make Whiteboard accessible through ContentRepository

2014-02-12 Thread Tobias Bocanegra
Hi,

On Tue, Feb 11, 2014 at 11:56 PM, Chetan Mehrotra
chetan.mehro...@gmail.com wrote:
 To address the same problem with Felix Jaas support one can make use
 of LoginModuleFactory [1]. Its job is to create LoginModule instances.

 One example of this is JdbcLoginModuleFactory [2]. It creates
 JdbcLoginModule and passes on the DataSource to the LoginModule
 instances. So instead of LoginModule _looking up_ the DataSource
 service it is provided with the DataSource instance. The factory
 itself was _provided_ with DataSource reference via DI (via
 Declarative Services)

 To implement a similar approach in non OSGi world following approach can be 
 used

 1. Have a ProxyLoginModule like [3]. The JAAS Config would refer to
 this class and would be able to create it
 2. Have a LoginModuleFactory LMF (custom one) which is referred to in
 the JAAS Config.
 3. One can register a custom LMF implementation with Oak and they
 would be passed on to SecurityProvider
 3. ProxyLoginModule determines the type of LoginModuleFactory and
 obtains them via Callback
 4. The LMF obtained is used to create the LoginModule instance

 Now same LoginModule (where most of the logic reside) can be shared
 between OSGi and non OSGi world. Further you can even share the
 LoginModuleFactory (if using non OSGi stuff only).

 For OSGi case the LMF would be managed via DS and its dependencies
 provided via DS
 For non OSGi case host application would wire up the LMF with its
 dependencies (via setters) and then register them with the Oak

Interesting idea, but I think we should continue support the LM to be
configured via the application container (eg. via jaas.conf).
Regards, Toby


 Chetan Mehrotra
 [1] 
 http://svn.apache.org/repos/asf/felix/trunk/jaas/src/main/java/org/apache/felix/jaas/LoginModuleFactory.java
 [2] 
 http://svn.apache.org/repos/asf/felix/trunk/examples/jaas/lm-jdbc/src/main/java/org/apache/felix/example/jaas/jdbc/JdbcLoginModuleFactory.java
 [3] 
 http://svn.apache.org/repos/asf/felix/trunk/jaas/src/main/java/org/apache/felix/jaas/boot/ProxyLoginModule.java


 On Wed, Feb 12, 2014 at 12:07 PM, Tobias Bocanegra tri...@apache.org wrote:
 Hi,


 On Tue, Feb 11, 2014 at 4:38 PM, Tobias Bocanegra tri...@apache.org wrote:
 On Tue, Feb 11, 2014 at 1:59 PM, Jukka Zitting jukka.zitt...@gmail.com 
 wrote:
 On Mon, Feb 10, 2014 at 2:25 AM, Felix Meschberger fmesc...@adobe.com 
 wrote:
 This thread indeed raises the question, why Oak has to come up with 
 something (the Whiteboard)
 that is almost but not quite like OSGi instead of going all the way 
 through ?

 This is a misunderstanding; we're not trying to reinvent OSGi.

 The Whiteboard interface is *only* an abstraction of the whiteboard
 pattern described in
 http://www.osgi.org/wiki/uploads/Links/whiteboard.pdf, and is used
 only for those cases in Oak where that pattern is useful. When running
 in an OSGi environment, the Whiteboard simply leverages the existing
 OSGi functionality.

 The Whiteboard in Oak is not a generic service registry, and is not
 supposed to become one.
 but then, why does the Whiteboard interface has a register() method?
 This indicates to me, that there is a global service registry behind
 that can be used by all other users of the whiteboard.

 Also, using the whiteboard in the tests make them very easy
 configurable and simulates a bit better how OSGi will work. for
 example in the ExternalLoginModuleTest, I can just do:

 whiteboard = oak.getWhiteboard();
 whiteboard.register(SyncManager.class, new
 SyncManagerImpl(whiteboard), Collections.emptyMap());
 whiteboard.register(ExternalIdentityProviderManager.class, new
 ExternalIDPManagerImpl(whiteboard), Collections.emptyMap());

 If I need to register them with the login module, this would not work
 today, without hard wiring all possible services to the
 SecurityProvider.

 addendum: If I want to achieve the same without the whiteboard, I would need 
 to:

 * Invent a new interface that allows to pass services/helpers to the
 login modules. eg a LoginModuleService interface
 * Create some sort of LoginModuleServiceProviderConfiguration
 * Create an implementation of the above that deals with OSGi but also
 can be used statically
 * Add the LoginModuleServiceProviderConfiguration to
 ServiceProvider.getConfiguration()
 * Add the interface to my ExternalIDPManagerImpl and SyncManagerImpl
 * in the login module, retrieve the
 LoginModuleServiceProviderConfiguration from the SecurityProvider,
 then find a service for SyncManager and
 ExternalIdentityProviderManager

 * in the non-osgi case, I would need to initialize the
 LoginModuleServiceProviderConfigurationImpl myself and add the 2
 services and add the config to the securityprovider.

 The additional work is that I need to re-invent some sort of service
 registry for the LoginModuleServiceProviderConfigurationImpl and
 extend the SecurityProvider with another configuration. Also, I limit
 the interfaces to be used in 

Re: Make Whiteboard accessible through ContentRepository

2014-02-12 Thread Angela Schreiber
hi

Interesting idea, but I think we should continue support the LM to be
configured via the application container (eg. via jaas.conf).

definitely!

regards
angela



Re: Make Whiteboard accessible through ContentRepository

2014-02-12 Thread Angela Schreiber
hi all

i tend to agree with tobi that this might end up with something
that is really complicated without too much benefit.

so, we may give it a try but i wouldn't not invest too much time.

just my humble opinion...
angela


On 12/02/14 07:37, Tobias Bocanegra tri...@apache.org wrote:

Hi,


On Tue, Feb 11, 2014 at 4:38 PM, Tobias Bocanegra tri...@apache.org
wrote:
 On Tue, Feb 11, 2014 at 1:59 PM, Jukka Zitting
jukka.zitt...@gmail.com wrote:
 On Mon, Feb 10, 2014 at 2:25 AM, Felix Meschberger
fmesc...@adobe.com wrote:
 This thread indeed raises the question, why Oak has to come up with
something (the Whiteboard)
 that is almost but not quite like OSGi instead of going all the way
through ?

 This is a misunderstanding; we're not trying to reinvent OSGi.

 The Whiteboard interface is *only* an abstraction of the whiteboard
 pattern described in
 http://www.osgi.org/wiki/uploads/Links/whiteboard.pdf, and is used
 only for those cases in Oak where that pattern is useful. When running
 in an OSGi environment, the Whiteboard simply leverages the existing
 OSGi functionality.

 The Whiteboard in Oak is not a generic service registry, and is not
 supposed to become one.
 but then, why does the Whiteboard interface has a register() method?
 This indicates to me, that there is a global service registry behind
 that can be used by all other users of the whiteboard.

 Also, using the whiteboard in the tests make them very easy
 configurable and simulates a bit better how OSGi will work. for
 example in the ExternalLoginModuleTest, I can just do:

 whiteboard = oak.getWhiteboard();
 whiteboard.register(SyncManager.class, new
 SyncManagerImpl(whiteboard), Collections.emptyMap());
 whiteboard.register(ExternalIdentityProviderManager.class, new
 ExternalIDPManagerImpl(whiteboard), Collections.emptyMap());

 If I need to register them with the login module, this would not work
 today, without hard wiring all possible services to the
 SecurityProvider.

addendum: If I want to achieve the same without the whiteboard, I would
need to:

* Invent a new interface that allows to pass services/helpers to the
login modules. eg a LoginModuleService interface
* Create some sort of LoginModuleServiceProviderConfiguration
* Create an implementation of the above that deals with OSGi but also
can be used statically
* Add the LoginModuleServiceProviderConfiguration to
ServiceProvider.getConfiguration()
* Add the interface to my ExternalIDPManagerImpl and SyncManagerImpl
* in the login module, retrieve the
LoginModuleServiceProviderConfiguration from the SecurityProvider,
then find a service for SyncManager and
ExternalIdentityProviderManager

* in the non-osgi case, I would need to initialize the
LoginModuleServiceProviderConfigurationImpl myself and add the 2
services and add the config to the securityprovider.

The additional work is that I need to re-invent some sort of service
registry for the LoginModuleServiceProviderConfigurationImpl and
extend the SecurityProvider with another configuration. Also, I limit
the interfaces to be used in the LoginModules to the ones implementing
the LoginModuleService interface. you might say, this is more robust -
I say, this is just more complicated and has tighter coupling.

regards, toby



Re: Make Whiteboard accessible through ContentRepository

2014-02-12 Thread Tobias Bocanegra
Hi,

On Wed, Feb 12, 2014 at 11:00 PM, Chetan Mehrotra
chetan.mehro...@gmail.com wrote:
 The LM would be configured in normal way only just that instead of
 using actual LM it would be passed to ProxyLoginModule which in turn
 would pass it to actual LoginModule.

I don't quite follow. can you give an example of what would be in the
jaas.conf and where you instantiate the ProxyLoginModule ?

 The reason I prefer a factory approach is that any real life
 LoginModule implementation would probably be exposing some extension
 points say mapping LDAP name to User name, extracting extra properties
 etc. Supporting such extension points is quite easy within OSGi env
 without hard coupling.
yes.


 If a LM _pull_ its dependencies then

 1. It becomes hard to expose extension points which can be easily
 swapped/extended at runtime.
I agree.

 2. Further looking up services from OSGi Service Registry frequently
 is not performant. So a frequent operation like Login which triggers
 frequent lookups would cause issues and something which can be avoided
good point.

regards, Toby

 On Wed, Feb 12, 2014 at 9:01 PM, Tobias Bocanegra tri...@apache.org wrote:
 Hi,

 On Tue, Feb 11, 2014 at 11:56 PM, Chetan Mehrotra
 chetan.mehro...@gmail.com wrote:
 To address the same problem with Felix Jaas support one can make use
 of LoginModuleFactory [1]. Its job is to create LoginModule instances.

 One example of this is JdbcLoginModuleFactory [2]. It creates
 JdbcLoginModule and passes on the DataSource to the LoginModule
 instances. So instead of LoginModule _looking up_ the DataSource
 service it is provided with the DataSource instance. The factory
 itself was _provided_ with DataSource reference via DI (via
 Declarative Services)

 To implement a similar approach in non OSGi world following approach can be 
 used

 1. Have a ProxyLoginModule like [3]. The JAAS Config would refer to
 this class and would be able to create it
 2. Have a LoginModuleFactory LMF (custom one) which is referred to in
 the JAAS Config.
 3. One can register a custom LMF implementation with Oak and they
 would be passed on to SecurityProvider
 3. ProxyLoginModule determines the type of LoginModuleFactory and
 obtains them via Callback
 4. The LMF obtained is used to create the LoginModule instance

 Now same LoginModule (where most of the logic reside) can be shared
 between OSGi and non OSGi world. Further you can even share the
 LoginModuleFactory (if using non OSGi stuff only).

 For OSGi case the LMF would be managed via DS and its dependencies
 provided via DS
 For non OSGi case host application would wire up the LMF with its
 dependencies (via setters) and then register them with the Oak

 Interesting idea, but I think we should continue support the LM to be
 configured via the application container (eg. via jaas.conf).
 Regards, Toby


 Chetan Mehrotra
 [1] 
 http://svn.apache.org/repos/asf/felix/trunk/jaas/src/main/java/org/apache/felix/jaas/LoginModuleFactory.java
 [2] 
 http://svn.apache.org/repos/asf/felix/trunk/examples/jaas/lm-jdbc/src/main/java/org/apache/felix/example/jaas/jdbc/JdbcLoginModuleFactory.java
 [3] 
 http://svn.apache.org/repos/asf/felix/trunk/jaas/src/main/java/org/apache/felix/jaas/boot/ProxyLoginModule.java


 On Wed, Feb 12, 2014 at 12:07 PM, Tobias Bocanegra tri...@apache.org 
 wrote:
 Hi,


 On Tue, Feb 11, 2014 at 4:38 PM, Tobias Bocanegra tri...@apache.org 
 wrote:
 On Tue, Feb 11, 2014 at 1:59 PM, Jukka Zitting jukka.zitt...@gmail.com 
 wrote:
 On Mon, Feb 10, 2014 at 2:25 AM, Felix Meschberger fmesc...@adobe.com 
 wrote:
 This thread indeed raises the question, why Oak has to come up with 
 something (the Whiteboard)
 that is almost but not quite like OSGi instead of going all the way 
 through ?

 This is a misunderstanding; we're not trying to reinvent OSGi.

 The Whiteboard interface is *only* an abstraction of the whiteboard
 pattern described in
 http://www.osgi.org/wiki/uploads/Links/whiteboard.pdf, and is used
 only for those cases in Oak where that pattern is useful. When running
 in an OSGi environment, the Whiteboard simply leverages the existing
 OSGi functionality.

 The Whiteboard in Oak is not a generic service registry, and is not
 supposed to become one.
 but then, why does the Whiteboard interface has a register() method?
 This indicates to me, that there is a global service registry behind
 that can be used by all other users of the whiteboard.

 Also, using the whiteboard in the tests make them very easy
 configurable and simulates a bit better how OSGi will work. for
 example in the ExternalLoginModuleTest, I can just do:

 whiteboard = oak.getWhiteboard();
 whiteboard.register(SyncManager.class, new
 SyncManagerImpl(whiteboard), Collections.emptyMap());
 whiteboard.register(ExternalIdentityProviderManager.class, new
 ExternalIDPManagerImpl(whiteboard), Collections.emptyMap());

 If I need to register them with the login module, this would not work
 today, without hard 

Re: Make Whiteboard accessible through ContentRepository

2014-02-11 Thread Jukka Zitting
Hi,

On Mon, Feb 10, 2014 at 8:35 PM, Tobias Bocanegra tri...@apache.org wrote:
 I'd rather offer it via a Callback.

Callbacks are not really meant for such use. Their purpose is to allow
the authentication component to interact with the application to
retrieve specific authentication data, such as usernames and
passwords, or to display certain information, such as error and
warning messages, not to access the rest of the runtime environment.

What we should do instead is to pass context information via the
options map passed to LoginModule.initialize() method. For example the
Karaf JAAS implementation passes the BundleContext through the options
map. The LoginModule class would then look into the options map for
any dependencies it has. Something like this:

abstract class MyLoginModule implements LoginModule {

private LoginBackend backend;

protected abstract LoginBackend getLoginBackend(MapString, ? options);

@Override
public initialize(...,MapString,? options) {
this.backend = getLoginBackend(options);
}

}

Subclasses can specialize the lookup method to work with different
runtime environments. For example in an OSGi/Karaf environment this
could be (omitting error handling and details like handling of service
reference counts):

class MyOsgiLoginModule extends MyLoginModule {
@Override
protected LoginBackend getLoginBackend(MapString, ? options) {
BundleContext context = (BundleContext)
options.get(BundleContext.class.getName());
return getLoginBackend(context); // OSGi service lookup
}
}

Or in a plain old Java environment:

class MyJavaLoginModule extends MyLoginModule {
@Override
protected LoginBackend getLoginBackend(MapString, ? options) {
return (LoginBackend) options.get(LoginBackend.class.getName());
}
}

... with the following bootstrapping code:

LoginBackend backend = new LoginBackend(...);
MapString, ? options =
singletonMap(LoginBackend.class.getName(), backend);
Configuration.setConfiguration(new
ConfigurationExtender(Configuration.getConfiguration(), options));

(The ConfigurationExtender class would decorate the given default
configuration with the given extra options.)

Note how none of this requires a dependency to the Whiteboard. We of
course *can* depend on the Whiteboard if the login code needs stuff
like dynamic service registration or lookups, but there's no inherent
need for that dependency.

BR,

Jukka Zitting


Re: Make Whiteboard accessible through ContentRepository

2014-02-11 Thread Tobias Bocanegra
Hi,

On Tue, Feb 11, 2014 at 1:14 AM, Jukka Zitting jukka.zitt...@gmail.com wrote:
 On Mon, Feb 10, 2014 at 8:35 PM, Tobias Bocanegra tri...@apache.org wrote:
 I'd rather offer it via a Callback.

 Callbacks are not really meant for such use. Their purpose is to allow
 the authentication component to interact with the application to
 retrieve specific authentication data, such as usernames and
 passwords, or to display certain information, such as error and
 warning messages, not to access the rest of the runtime environment.

 What we should do instead is to pass context information via the
 options map passed to LoginModule.initialize() method.
Right, this might be better :-) I just followed the pattern already
there with all the other callbacks :-)

 For example the
 Karaf JAAS implementation passes the BundleContext through the options
 map. The LoginModule class would then look into the options map for
 any dependencies it has. Something like this:

 abstract class MyLoginModule implements LoginModule {

 private LoginBackend backend;

 protected abstract LoginBackend getLoginBackend(MapString, ? 
 options);

 @Override
 public initialize(...,MapString,? options) {
 this.backend = getLoginBackend(options);
 }

 }

 Subclasses can specialize the lookup method to work with different
 runtime environments. For example in an OSGi/Karaf environment this
 could be (omitting error handling and details like handling of service
 reference counts):

 class MyOsgiLoginModule extends MyLoginModule {
 @Override
 protected LoginBackend getLoginBackend(MapString, ? options) {
 BundleContext context = (BundleContext)
 options.get(BundleContext.class.getName());
 return getLoginBackend(context); // OSGi service lookup
 }
 }

 Or in a plain old Java environment:

 class MyJavaLoginModule extends MyLoginModule {
 @Override
 protected LoginBackend getLoginBackend(MapString, ? options) {
 return (LoginBackend) options.get(LoginBackend.class.getName());
 }
 }

 ... with the following bootstrapping code:

 LoginBackend backend = new LoginBackend(...);
 MapString, ? options =
 singletonMap(LoginBackend.class.getName(), backend);
 Configuration.setConfiguration(new
 ConfigurationExtender(Configuration.getConfiguration(), options));

 (The ConfigurationExtender class would decorate the given default
 configuration with the given extra options.)

 Note how none of this requires a dependency to the Whiteboard. We of
 course *can* depend on the Whiteboard if the login code needs stuff
 like dynamic service registration or lookups, but there's no inherent
 need for that dependency.

True, but if we want to write LoginModules what work in both worlds,
then we need to offer a common interface to access to services - and
that's currently the whiteboard.

Regards, Toby


Re: Make Whiteboard accessible through ContentRepository

2014-02-11 Thread Jukka Zitting
Hi,

On Tue, Feb 11, 2014 at 11:59 AM, Tobias Bocanegra tri...@apache.org wrote:
 True, but if we want to write LoginModules what work in both worlds,
 then we need to offer a common interface to access to services - and
 that's currently the whiteboard.

But it isn't. When running in plain old Java, the DefaultWhiteboard
only contains a small subset of services that need the dynamic
registration/lookup functionality of the whiteboard pattern. Normal
components whose wiring can be achieved with direct object references
are not kept in the Whiteboard, and can't be looked up through it.

This is by design. We don't want to reinvent OSGi.

BR,

Jukka Zitting


Re: Make Whiteboard accessible through ContentRepository

2014-02-11 Thread Jukka Zitting
Hi,

On Mon, Feb 10, 2014 at 2:25 AM, Felix Meschberger fmesc...@adobe.com wrote:
 This thread indeed raises the question, why Oak has to come up with something 
 (the Whiteboard)
 that is almost but not quite like OSGi instead of going all the way through ?

This is a misunderstanding; we're not trying to reinvent OSGi.

The Whiteboard interface is *only* an abstraction of the whiteboard
pattern described in
http://www.osgi.org/wiki/uploads/Links/whiteboard.pdf, and is used
only for those cases in Oak where that pattern is useful. When running
in an OSGi environment, the Whiteboard simply leverages the existing
OSGi functionality.

The Whiteboard in Oak is not a generic service registry, and is not
supposed to become one.

BR,

Jukka Zitting


Re: Make Whiteboard accessible through ContentRepository

2014-02-11 Thread Tobias Bocanegra
Hi,

On Tue, Feb 11, 2014 at 1:48 PM, Jukka Zitting jukka.zitt...@gmail.com wrote:
 On Tue, Feb 11, 2014 at 11:59 AM, Tobias Bocanegra tri...@apache.org wrote:
 True, but if we want to write LoginModules what work in both worlds,
 then we need to offer a common interface to access to services - and
 that's currently the whiteboard.

 But it isn't. When running in plain old Java, the DefaultWhiteboard
 only contains a small subset of services that need the dynamic
 registration/lookup functionality of the whiteboard pattern. Normal
 components whose wiring can be achieved with direct object references
 are not kept in the Whiteboard, and can't be looked up through it.

I think that this is a problem. In case of the LoginModule, it would
be very difficult and clumsy to hard wire the respective providers for
them to work. Unless we invent a specific LoginModuleServiceRegistry
or similar, that is provided by the SecurityManager as configuration
and can be used to statically add the services you wantbut we get
this for free with OSGi and we should have a pendant for the non-osgi
case.


 This is by design. We don't want to reinvent OSGi.
sure. we should use OSGi.

regards, toby


Re: Make Whiteboard accessible through ContentRepository

2014-02-11 Thread Tobias Bocanegra
Hi,

On Tue, Feb 11, 2014 at 1:59 PM, Jukka Zitting jukka.zitt...@gmail.com wrote:
 On Mon, Feb 10, 2014 at 2:25 AM, Felix Meschberger fmesc...@adobe.com wrote:
 This thread indeed raises the question, why Oak has to come up with 
 something (the Whiteboard)
 that is almost but not quite like OSGi instead of going all the way through ?

 This is a misunderstanding; we're not trying to reinvent OSGi.

 The Whiteboard interface is *only* an abstraction of the whiteboard
 pattern described in
 http://www.osgi.org/wiki/uploads/Links/whiteboard.pdf, and is used
 only for those cases in Oak where that pattern is useful. When running
 in an OSGi environment, the Whiteboard simply leverages the existing
 OSGi functionality.

 The Whiteboard in Oak is not a generic service registry, and is not
 supposed to become one.
but then, why does the Whiteboard interface has a register() method?
This indicates to me, that there is a global service registry behind
that can be used by all other users of the whiteboard.

Also, using the whiteboard in the tests make them very easy
configurable and simulates a bit better how OSGi will work. for
example in the ExternalLoginModuleTest, I can just do:

whiteboard = oak.getWhiteboard();
whiteboard.register(SyncManager.class, new
SyncManagerImpl(whiteboard), Collections.emptyMap());
whiteboard.register(ExternalIdentityProviderManager.class, new
ExternalIDPManagerImpl(whiteboard), Collections.emptyMap());

If I need to register them with the login module, this would not work
today, without hard wiring all possible services to the
SecurityProvider.
Regards, Toby


Re: Make Whiteboard accessible through ContentRepository

2014-02-11 Thread Chetan Mehrotra
To address the same problem with Felix Jaas support one can make use
of LoginModuleFactory [1]. Its job is to create LoginModule instances.

One example of this is JdbcLoginModuleFactory [2]. It creates
JdbcLoginModule and passes on the DataSource to the LoginModule
instances. So instead of LoginModule _looking up_ the DataSource
service it is provided with the DataSource instance. The factory
itself was _provided_ with DataSource reference via DI (via
Declarative Services)

To implement a similar approach in non OSGi world following approach can be used

1. Have a ProxyLoginModule like [3]. The JAAS Config would refer to
this class and would be able to create it
2. Have a LoginModuleFactory LMF (custom one) which is referred to in
the JAAS Config.
3. One can register a custom LMF implementation with Oak and they
would be passed on to SecurityProvider
3. ProxyLoginModule determines the type of LoginModuleFactory and
obtains them via Callback
4. The LMF obtained is used to create the LoginModule instance

Now same LoginModule (where most of the logic reside) can be shared
between OSGi and non OSGi world. Further you can even share the
LoginModuleFactory (if using non OSGi stuff only).

For OSGi case the LMF would be managed via DS and its dependencies
provided via DS
For non OSGi case host application would wire up the LMF with its
dependencies (via setters) and then register them with the Oak

Chetan Mehrotra
[1] 
http://svn.apache.org/repos/asf/felix/trunk/jaas/src/main/java/org/apache/felix/jaas/LoginModuleFactory.java
[2] 
http://svn.apache.org/repos/asf/felix/trunk/examples/jaas/lm-jdbc/src/main/java/org/apache/felix/example/jaas/jdbc/JdbcLoginModuleFactory.java
[3] 
http://svn.apache.org/repos/asf/felix/trunk/jaas/src/main/java/org/apache/felix/jaas/boot/ProxyLoginModule.java


On Wed, Feb 12, 2014 at 12:07 PM, Tobias Bocanegra tri...@apache.org wrote:
 Hi,


 On Tue, Feb 11, 2014 at 4:38 PM, Tobias Bocanegra tri...@apache.org wrote:
 On Tue, Feb 11, 2014 at 1:59 PM, Jukka Zitting jukka.zitt...@gmail.com 
 wrote:
 On Mon, Feb 10, 2014 at 2:25 AM, Felix Meschberger fmesc...@adobe.com 
 wrote:
 This thread indeed raises the question, why Oak has to come up with 
 something (the Whiteboard)
 that is almost but not quite like OSGi instead of going all the way 
 through ?

 This is a misunderstanding; we're not trying to reinvent OSGi.

 The Whiteboard interface is *only* an abstraction of the whiteboard
 pattern described in
 http://www.osgi.org/wiki/uploads/Links/whiteboard.pdf, and is used
 only for those cases in Oak where that pattern is useful. When running
 in an OSGi environment, the Whiteboard simply leverages the existing
 OSGi functionality.

 The Whiteboard in Oak is not a generic service registry, and is not
 supposed to become one.
 but then, why does the Whiteboard interface has a register() method?
 This indicates to me, that there is a global service registry behind
 that can be used by all other users of the whiteboard.

 Also, using the whiteboard in the tests make them very easy
 configurable and simulates a bit better how OSGi will work. for
 example in the ExternalLoginModuleTest, I can just do:

 whiteboard = oak.getWhiteboard();
 whiteboard.register(SyncManager.class, new
 SyncManagerImpl(whiteboard), Collections.emptyMap());
 whiteboard.register(ExternalIdentityProviderManager.class, new
 ExternalIDPManagerImpl(whiteboard), Collections.emptyMap());

 If I need to register them with the login module, this would not work
 today, without hard wiring all possible services to the
 SecurityProvider.

 addendum: If I want to achieve the same without the whiteboard, I would need 
 to:

 * Invent a new interface that allows to pass services/helpers to the
 login modules. eg a LoginModuleService interface
 * Create some sort of LoginModuleServiceProviderConfiguration
 * Create an implementation of the above that deals with OSGi but also
 can be used statically
 * Add the LoginModuleServiceProviderConfiguration to
 ServiceProvider.getConfiguration()
 * Add the interface to my ExternalIDPManagerImpl and SyncManagerImpl
 * in the login module, retrieve the
 LoginModuleServiceProviderConfiguration from the SecurityProvider,
 then find a service for SyncManager and
 ExternalIdentityProviderManager

 * in the non-osgi case, I would need to initialize the
 LoginModuleServiceProviderConfigurationImpl myself and add the 2
 services and add the config to the securityprovider.

 The additional work is that I need to re-invent some sort of service
 registry for the LoginModuleServiceProviderConfigurationImpl and
 extend the SecurityProvider with another configuration. Also, I limit
 the interfaces to be used in the LoginModules to the ones implementing
 the LoginModuleService interface. you might say, this is more robust -
 I say, this is just more complicated and has tighter coupling.

 regards, toby


Re: Make Whiteboard accessible through ContentRepository

2014-02-10 Thread Michael Dürig



On 9.2.14 6:49 , Jukka Zitting wrote:

Hi,

On Sun, Feb 9, 2014 at 4:05 AM, Davide Giannella
giannella.dav...@gmail.com wrote:

It would make for example a lot easier to inject a CommitHook like a
custom index. So far the only way to achieve so is to recompile the
oak-run adding .with(new MyIndexProvider()) while I'd rather add a
Service implementation the OSGi whiteboard.


Some of us prefer to recompile the jar. :-)


Because this usually works, while starting up an OSGi container and 
deploying bundles usually results in getting tied up in manual 
dependency analysis and class loader debugging, which is quite 
distracting if you just want to run a quick benchmark. Well that, my 
experience anyway.


OTHO I agree that we should probably make an OSGi option available since 
this is our primary deployment scenario.


Michael



Of course that doesn't mean we couldn't do both. If someone's up to
it, an OSGi-based runnable Oak jar would be a nice contribution.

BR,

Jukka Zitting



Re: Make Whiteboard accessible through ContentRepository

2014-02-10 Thread Jukka Zitting
Hi,

On Mon, Feb 10, 2014 at 1:01 AM, Tobias Bocanegra tri...@apache.org wrote:
 ok...using Sling/Felix quite a lot, I'm used to the possibility to
 create a Service that can have references to any other exported
 Service via its ComponentContext, i.e. BundleContext, i.e underlying
 OSGi service registry.

The same thing works also without OSGi, you just add a new component
constructor argument or a setter and adjust the code that does the
wiring to provide that dependency to a component. I admit that doing
it this way does require changing code in two places, but it also
achieves better decoupling of the service from the way it's wired up,
i.e. the component itself doesn't have to worry about the mechanics of
the service lookup. This simplifies also things like unit test
fixtures as you can just mock the direct dependencies of a component
instead of setting up a full runtime environment.

Declarative Services in OSGi works similarly in decoupling the wiring
of services from the services themselves. A DS-based component doesn't
necessarily need to access the Component/BundleContext at all, as it
can just declare direct dependencies to all the services it needs.
Most Oak components should work the same way instead of requiring
direct access to the Whiteboard. By making the DS bind methods
explicit, you could even write a normal DS-based component that you
can also wire up statically in places like oak-run.

 sure, in the end it is a specific service. but we don't want to limit
 the set of services a login module can use. IMO, it should have access
 to all the ones registered. So a login module (also in the non osgi
 world) should be able to retrieve the Whiteboard to get a service.

See above; instead of going through the Whiteboard, I'd rather see a
component declaring direct dependencies to the services it needs. The
wiring should happen elsewhere.

 I think my problem is, that there are (were) several instances of the
 'DefautlWhiteboard created, one in Oak.java, one by the
 SecurityProviderImpl.

Hmm, I only see a DefaultWhiteboard instance being created in
Oak.java. SecurityProviderImpl uses OsgiWhiteboard. Did this change in
OAK-1377?

 And only allow to create Oak() with or without whiteboard, and remove
 the Oak.with(Whiteboard) method. So it's clear that either we use the
 external provided whiteboard, or the implicit internal one.

We can do that, though one of the driving ideas behind Oak has been to
keep things like new Oak().with(new
SomeComponent()).createContentSession() as simple as possible.

 the problem is, that each plugin, that needs a whiteboard, should be
 able to get the default one. without some helper classes, the
 construction gets a bit awkward:

 Oak oak = new Oak();
 SecurityProvider sp = new SecurityProvider(oak.getWhiteboard());
 oak.with(sp);

 IMO it's better that Oak.with() pushes its whiteboard to the plugin.

If this becomes a common need, i.e. there are many components that
need access to the whiteboard (instead of just a more specific set of
services, as suggested above), then I'd rather pull the whiteboard
entirely out of the Oak class, like this:

Whiteboard whiteboard = ...;
new Oak(...)
.with(new SecurityProvider(whiteboard))
.createContentRepository(whiteboard);

But as said, I think only a small subset of our components should
really need direct access to the whiteboard.

For example the authorizable action and restriction providers in
SecurityProviderImpl are composite services, that in an OSGi
deployment can/should be dynamic through the whiteboard mechanism, but
in a static deployment shouldn't need the whiteboard as we could just
provide a static list of all the available component providers.

BR,

Jukka Zitting


Re: Make Whiteboard accessible through ContentRepository

2014-02-10 Thread Tobias Bocanegra
Hi,


On Mon, Feb 10, 2014 at 4:31 AM, Jukka Zitting jukka.zitt...@gmail.com wrote:
 On Mon, Feb 10, 2014 at 1:01 AM, Tobias Bocanegra tri...@apache.org wrote:
  ok...using Sling/Felix quite a lot, I'm used to the possibility to
  create a Service that can have references to any other exported
  Service via its ComponentContext, i.e. BundleContext, i.e underlying
  OSGi service registry.

 The same thing works also without OSGi, you just add a new component
 constructor argument or a setter and adjust the code that does the
 wiring to provide that dependency to a component. I admit that doing
 it this way does require changing code in two places, but it also
 achieves better decoupling of the service from the way it's wired up,
 i.e. the component itself doesn't have to worry about the mechanics of
 the service lookup. This simplifies also things like unit test
 fixtures as you can just mock the direct dependencies of a component
 instead of setting up a full runtime environment.

in case of the LoginModules, that's not possible. They need to
retrieve their services from somewhere.

 Declarative Services in OSGi works similarly in decoupling the wiring
 of services from the services themselves. A DS-based component doesn't
 necessarily need to access the Component/BundleContext at all, as it
 can just declare direct dependencies to all the services it needs.
 Most Oak components should work the same way instead of requiring
 direct access to the Whiteboard. By making the DS bind methods
 explicit, you could even write a normal DS-based component that you
 can also wire up statically in places like oak-run.

This is ok for unit tests etc, but there is currently no way of
configuring Oak. So there is no ootb run.sh that will start your
oak server. If we ever want to go there, we need to define how to get
there. We can shift this problem to Sling and let them provide such a
server, or we can start your own launchpad. currently, you need to
compile classes in order to configure your server. if this is ok, we
can stay with the current setup and hard-wire all dependencies.


  sure, in the end it is a specific service. but we don't want to limit
  the set of services a login module can use. IMO, it should have access
  to all the ones registered. So a login module (also in the non osgi
  world) should be able to retrieve the Whiteboard to get a service.

 See above; instead of going through the Whiteboard, I'd rather see a
 component declaring direct dependencies to the services it needs. The
 wiring should happen elsewhere.

If you want to make this work generally w/o OSGi, then you also need
to invent a DS management for oak...which is clearly not a goal.

  I think my problem is, that there are (were) several instances of the
  'DefautlWhiteboard created, one in Oak.java, one by the
  SecurityProviderImpl.

 Hmm, I only see a DefaultWhiteboard instance being created in
 Oak.java. SecurityProviderImpl uses OsgiWhiteboard. Did this change in
 OAK-1377?

got me :-) I overlooked that.

  And only allow to create Oak() with or without whiteboard, and remove
  the Oak.with(Whiteboard) method. So it's clear that either we use the
  external provided whiteboard, or the implicit internal one.

 We can do that, though one of the driving ideas behind Oak has been to
 keep things like new Oak().with(new
 SomeComponent()).createContentSession() as simple as possible.

  the problem is, that each plugin, that needs a whiteboard, should be
  able to get the default one. without some helper classes, the
  construction gets a bit awkward:
 
  Oak oak = new Oak();
  SecurityProvider sp = new SecurityProvider(oak.getWhiteboard());
  oak.with(sp);
 
  IMO it's better that Oak.with() pushes its whiteboard to the plugin.

 If this becomes a common need, i.e. there are many components that
 need access to the whiteboard (instead of just a more specific set of
 services, as suggested above), then I'd rather pull the whiteboard
 entirely out of the Oak class, like this:

 Whiteboard whiteboard = ...;
 new Oak(...)
 .with(new SecurityProvider(whiteboard))
 .createContentRepository(whiteboard);

 But as said, I think only a small subset of our components should
 really need direct access to the whiteboard.

The problem is, that the whiteboard that is initially initialized in
Oak() already has some anonymous overrides for delaying stuff. So when
passing a non-osgi one externally, this logic is lost, although it
might be needed.

 For example the authorizable action and restriction providers in
 SecurityProviderImpl are composite services, that in an OSGi
 deployment can/should be dynamic through the whiteboard mechanism, but
 in a static deployment shouldn't need the whiteboard as we could just
 provide a static list of all the available component providers.

well :-)

regards, toby


Re: Make Whiteboard accessible through ContentRepository

2014-02-10 Thread Jukka Zitting
Hi,

On Mon, Feb 10, 2014 at 2:50 PM, Tobias Bocanegra tri...@apache.org wrote:
 in case of the LoginModules, that's not possible.

But accessing the whiteboard is? I don't see what's special about the
whiteboard, it's just a service dependency like any other.

 This is ok for unit tests etc, but there is currently no way of
 configuring Oak. So there is no ootb run.sh that will start your
 oak server. If we ever want to go there, we need to define how to get
 there. We can shift this problem to Sling and let them provide such a
 server, or we can start your own launchpad. currently, you need to
 compile classes in order to configure your server. if this is ok, we
 can stay with the current setup and hard-wire all dependencies.

That is OK, at least that's been the plan so far. It doesn't make
sense for Oak to reinvent a component framework like OSGi or Spring.
Instead Oak components should be usable within any such framework, or
even in plain old Java.

 The problem is, that the whiteboard that is initially initialized in
 Oak() already has some anonymous overrides for delaying stuff.
 So when passing a non-osgi one externally, this logic is lost,
 although it might be needed.

Right. I guess we should refactor that part of the code to avoid the overrides.

BR,

Jukka Zitting


Re: Make Whiteboard accessible through ContentRepository

2014-02-10 Thread Tobias Bocanegra
Hi,

On Mon, Feb 10, 2014 at 1:30 PM, Jukka Zitting jukka.zitt...@gmail.com wrote:
 On Mon, Feb 10, 2014 at 2:50 PM, Tobias Bocanegra tri...@apache.org wrote:
 in case of the LoginModules, that's not possible.

 But accessing the whiteboard is? I don't see what's special about the
 whiteboard, it's just a service dependency like any other.

No, it's a piece of infrastructure, and part of the Oak SPI. I think
that components should be able to rely on a system wide Whiteboard if
they want.
Also, the LoginModules are not 'services' in that sense. they get
instantiated by JAAS and can only communicate via Callbacks with the
login context.

 This is ok for unit tests etc, but there is currently no way of
 configuring Oak. So there is no ootb run.sh that will start your
 oak server. If we ever want to go there, we need to define how to get
 there. We can shift this problem to Sling and let them provide such a
 server, or we can start your own launchpad. currently, you need to
 compile classes in order to configure your server. if this is ok, we
 can stay with the current setup and hard-wire all dependencies.

 That is OK, at least that's been the plan so far. It doesn't make
 sense for Oak to reinvent a component framework like OSGi or Spring.
 Instead Oak components should be usable within any such framework, or
 even in plain old Java.

 The problem is, that the whiteboard that is initially initialized in
 Oak() already has some anonymous overrides for delaying stuff.
 So when passing a non-osgi one externally, this logic is lost,
 although it might be needed.

 Right. I guess we should refactor that part of the code to avoid the 
 overrides.

ok: https://issues.apache.org/jira/browse/OAK-1411

regards, toby


Re: Make Whiteboard accessible through ContentRepository

2014-02-09 Thread Davide Giannella
On Sat, Feb 8, 2014 at 6:58 PM, Tobias Bocanegra tri...@apache.org wrote:
 ...
 ps: I still think we should turn the problem around, and make
 everything OSGi services and start a small OSGi container for the
 runtime :-)

I was thinking the same tonight. I was going to ask why (any
historical decisions) Oak in the oak-run doesn't use a simple
bundled-up OSGi container and runs the related jar, that are already
OSGi bundles, in it.

It would make for example a lot easier to inject a CommitHook like a
custom index. So far the only way to achieve so is to recompile the
oak-run adding .with(new MyIndexProvider()) while I'd rather add a
Service implementation the OSGi whiteboard.

D.


Re: Make Whiteboard accessible through ContentRepository

2014-02-09 Thread Jukka Zitting
Hi,

On Sat, Feb 8, 2014 at 1:58 PM, Tobias Bocanegra tri...@apache.org wrote:
 ok, then what we need it the pendant to the OSGi service registry, [...]

s/the pendant/a dependency/? I'm not sure I understood this correctly.

 I.e. a mechanism where I can lookup any service.

This sounds like an XY problem, i.e. you're proposing a solution
without describing the problem you're trying to solve.

You mentioned a LoginModule implementation. Why would it need to look
up any service? Wouldn't a dependency to a specific service be
enough/better?

 thats what I mean, add the whiteboard from 'Oak.class' to the
 constructor to ContentRepositoryImpl.

You mean new ContentRepositoryImpl(..., whiteboard, ...);? Yes, we
can do that. Though as mentioned above I'd like to understand why we
need to do that instead of passing the whiteboard (or better, a more
specific dependency) directly to whatever component that needs it.

 The problem at hand is, that users can provide a service that is used
 in one of the login modules. so eventually we need to pass the osgi
 whiteboard into the login module. which is easy. but otoh, in the
 non-osgi case, a unique whiteboard instance should be passed. which is
 not so easy.

I don't see the problem:

Whiteboard whiteboard = ...;
new Oak(...)
.with(whiteboard)
.with(new SomeComponent(whiteboard))
;

Or perhaps I'm missing something here?

 one workaround idea I tested in [0] by introducing WhiteboardAware
 interface (better name welcome). when such a instance is added to the
 Oak instance via a with() method, it oak will push the whiteboard to
 it.

Right, we can of course do that, but IMHO the above constructor
argument pattern seems much simpler.

BR,

Jukka Zitting


Re: Make Whiteboard accessible through ContentRepository

2014-02-09 Thread Jukka Zitting
Hi,

On Sun, Feb 9, 2014 at 4:05 AM, Davide Giannella
giannella.dav...@gmail.com wrote:
 It would make for example a lot easier to inject a CommitHook like a
 custom index. So far the only way to achieve so is to recompile the
 oak-run adding .with(new MyIndexProvider()) while I'd rather add a
 Service implementation the OSGi whiteboard.

Some of us prefer to recompile the jar. :-)

Of course that doesn't mean we couldn't do both. If someone's up to
it, an OSGi-based runnable Oak jar would be a nice contribution.

BR,

Jukka Zitting


Re: Make Whiteboard accessible through ContentRepository

2014-02-09 Thread Tobias Bocanegra
Hi,

On Sun, Feb 9, 2014 at 9:40 AM, Jukka Zitting jukka.zitt...@gmail.com wrote:
 Hi,

 On Sat, Feb 8, 2014 at 1:58 PM, Tobias Bocanegra tri...@apache.org wrote:
 ok, then what we need it the pendant to the OSGi service registry, [...]

 s/the pendant/a dependency/? I'm not sure I understood this correctly.

 I.e. a mechanism where I can lookup any service.

 This sounds like an XY problem, i.e. you're proposing a solution
 without describing the problem you're trying to solve.

ok...using Sling/Felix quite a lot, I'm used to the possibility to
create a Service that can have references to any other exported
Service via its ComponentContext, i.e. BundleContext, i.e underlying
OSGi service registry.

 You mentioned a LoginModule implementation. Why would it need to look
 up any service? Wouldn't a dependency to a specific service be
 enough/better?

sure, in the end it is a specific service. but we don't want to limit
the set of services a login module can use. IMO, it should have access
to all the ones registered. So a login module (also in the non osgi
world) should be able to retrieve the Whiteboard to get a service.
Either directly via a callback (probably the correct solution) or via
one of the classes it already can access (ContentRepository or
SecurityProvider).

 thats what I mean, add the whiteboard from 'Oak.class' to the
 constructor to ContentRepositoryImpl.

 You mean new ContentRepositoryImpl(..., whiteboard, ...);? Yes, we
 can do that. Though as mentioned above I'd like to understand why we
 need to do that instead of passing the whiteboard (or better, a more
 specific dependency) directly to whatever component that needs it.

you might be right, it doesn't need it, if the services that needs it
is created the correct way.

 The problem at hand is, that users can provide a service that is used
 in one of the login modules. so eventually we need to pass the osgi
 whiteboard into the login module. which is easy. but otoh, in the
 non-osgi case, a unique whiteboard instance should be passed. which is
 not so easy.

 I don't see the problem:

 Whiteboard whiteboard = ...;
 new Oak(...)
 .with(whiteboard)
 .with(new SomeComponent(whiteboard))
 ;

 Or perhaps I'm missing something here?

I think my problem is, that there are (were) several instances of the
'DefautlWhiteboard created, one in Oak.java, one by the
SecurityProviderImpl.
We should make the DefaultWhiteboard implementation private to Oak.

And only allow to create Oak() with or without whiteboard, and remove
the Oak.with(Whiteboard) method. So it's clear that either we use the
external provided whiteboard, or the implicit internal one.

 one workaround idea I tested in [0] by introducing WhiteboardAware
 interface (better name welcome). when such a instance is added to the
 Oak instance via a with() method, it oak will push the whiteboard to
 it.

 Right, we can of course do that, but IMHO the above constructor
 argument pattern seems much simpler.

the problem is, that each plugin, that needs a whiteboard, should be
able to get the default one. without some helper classes, the
construction gets a bit awkward:

Oak oak = new Oak();
SecurityProvider sp = new SecurityProvider(oak.getWhiteboard());
oak.with(sp);

IMO it's better that Oak.with() pushes its whiteboard to the plugin.


 BR,

 Jukka Zitting


Re: Make Whiteboard accessible through ContentRepository

2014-02-09 Thread Tobias Bocanegra
On Sun, Feb 9, 2014 at 9:49 AM, Jukka Zitting jukka.zitt...@gmail.com wrote:
 Hi,

 On Sun, Feb 9, 2014 at 4:05 AM, Davide Giannella
 giannella.dav...@gmail.com wrote:
 It would make for example a lot easier to inject a CommitHook like a
 custom index. So far the only way to achieve so is to recompile the
 oak-run adding .with(new MyIndexProvider()) while I'd rather add a
 Service implementation the OSGi whiteboard.

 Some of us prefer to recompile the jar. :-)

 Of course that doesn't mean we couldn't do both. If someone's up to
 it, an OSGi-based runnable Oak jar would be a nice contribution.

I played around with the felix runtime and gogo shell in [1] but
didn't pursue this further. the problem is, that without a launchpad
(eg [2]) the bootstrapping is tedious.

regards, toby


[1] https://github.com/tripodsan/jackrabbit-oak/tree/OAK-17/oak-felix
[2] 
http://sling.apache.org/documentation/the-sling-engine/the-sling-launchpad.html


On Sun, Feb 9, 2014 at 9:49 AM, Jukka Zitting jukka.zitt...@gmail.com wrote:
 Hi,

 On Sun, Feb 9, 2014 at 4:05 AM, Davide Giannella
 giannella.dav...@gmail.com wrote:
 It would make for example a lot easier to inject a CommitHook like a
 custom index. So far the only way to achieve so is to recompile the
 oak-run adding .with(new MyIndexProvider()) while I'd rather add a
 Service implementation the OSGi whiteboard.

 Some of us prefer to recompile the jar. :-)

 Of course that doesn't mean we couldn't do both. If someone's up to
 it, an OSGi-based runnable Oak jar would be a nice contribution.

 BR,

 Jukka Zitting


Re: Make Whiteboard accessible through ContentRepository

2014-02-09 Thread Felix Meschberger
Hi

This thread indeed raises the question, why Oak has to come up with something 
(the Whiteboard) that is almost but not quite like OSGi instead of going all 
the way through ?

As a stop-gap measure, instead of going full-OSGi you could also just leverage 
the feature, that you really need: The service registry and base on something 
like Karl Pauls' µServices [2] and PojoSR [3]

Interestingly, when I started with what became Apache Sling I worked on a thing 
called the Extension Frameworkg for JCR Repositories [1] until it turned out 
that it basically would be reinventing OSGi … and so Sling became an OSGi 
application.

Regards
Felix

[1] 
http://svn.apache.org/repos/asf/jackrabbit/sandbox/inactive/extension-framework/
[2] 
http://www.pro-vision.de/content/medialib/pro-vision/production/adaptto/2013/adaptto2013-osgi--services-karl-pauls-pdf/_jcr_content/renditions/rendition.download_attachment.file/adaptto2013-osgi--services-karl-pauls.pdf
[3] http://code.google.com/p/pojosr/

Am 09.02.2014 um 10:05 schrieb Davide Giannella giannella.dav...@gmail.com:

 On Sat, Feb 8, 2014 at 6:58 PM, Tobias Bocanegra tri...@apache.org wrote:
 ...
 ps: I still think we should turn the problem around, and make
 everything OSGi services and start a small OSGi container for the
 runtime :-)
 
 I was thinking the same tonight. I was going to ask why (any
 historical decisions) Oak in the oak-run doesn't use a simple
 bundled-up OSGi container and runs the related jar, that are already
 OSGi bundles, in it.
 
 It would make for example a lot easier to inject a CommitHook like a
 custom index. So far the only way to achieve so is to recompile the
 oak-run adding .with(new MyIndexProvider()) while I'd rather add a
 Service implementation the OSGi whiteboard.
 
 D.



Re: Make Whiteboard accessible through ContentRepository

2014-02-08 Thread Tommaso Teofili
+1 I think it makes sense, see also [1].

Regards,
Tommaso

[1] : http://markmail.org/message/4youjqpyjvajcttr


2014-02-08 Tobias Bocanegra tri...@apache.org:

 Hi,

 currently there is not way to access the whiteboard from within the
 content repository - only if it's added from the outside to the
 plugins.

 For example, I would need access to it from within a LoginModule.
 Right now, I got a private whiteboard just for the security provider,
 but this is not optimal. IMO there should only be 1 whiteboard for 1
 Oak.class instance. Also note, that in case of OSGi, all the OSGi
 whiteboards would base on the same service registry anyways.

 WDYT?

 regards, toby



Re: Make Whiteboard accessible through ContentRepository

2014-02-08 Thread Jukka Zitting
Hi,

On Sat, Feb 8, 2014 at 2:42 AM, Tobias Bocanegra tri...@apache.org wrote:
 currently there is not way to access the whiteboard from within the
 content repository - only if it's added from the outside to the
 plugins.

That's the intended design. The whiteboard mechanism is an abstraction
of the OSGi BundleContext and works similarly; i.e. the code that
instantiates/manages a component is expected to pass the
whiteboard/context to that component if/when needed.

 For example, I would need access to it from within a LoginModule.

If you already have access to a ContentRepository, then why not use
the same mechanism to pass the Whiteboard instead of using a
ContentRepository method for that?

BR,

Jukka Zitting


Re: Make Whiteboard accessible through ContentRepository

2014-02-08 Thread Tobias Bocanegra
Hi,

On Sat, Feb 8, 2014 at 7:26 AM, Jukka Zitting jukka.zitt...@gmail.com wrote:
 Hi,

 On Sat, Feb 8, 2014 at 2:42 AM, Tobias Bocanegra tri...@apache.org wrote:
 currently there is not way to access the whiteboard from within the
 content repository - only if it's added from the outside to the
 plugins.

 That's the intended design. The whiteboard mechanism is an abstraction
 of the OSGi BundleContext and works similarly; i.e. the code that
 instantiates/manages a component is expected to pass the
 whiteboard/context to that component if/when needed.

ok, then what we need it the pendant to the OSGi service registry, or
to the SlingHelper stuff. I.e. a mechanism where I can lookup any
service.


 For example, I would need access to it from within a LoginModule.

 If you already have access to a ContentRepository, then why not use
 the same mechanism to pass the Whiteboard instead of using a
 ContentRepository method for that?

thats what I mean, add the whiteboard from 'Oak.class' to the
constructor to ContentRepositoryImpl.

The problem at hand is, that users can provide a service that is used
in one of the login modules. so eventually we need to pass the osgi
whiteboard into the login module. which is easy. but otoh, in the
non-osgi case, a unique whiteboard instance should be passed. which is
not so easy. IMO there should only be 1 whiteboard instance per
system (or it should base on a global service registry). for OSGi
this is not a problem, because they all rely on the same service
registry. but for the non-osgi usecase.

one workaround idea I tested in [0] by introducing WhiteboardAware
interface (better name welcome). when such a instance is added to the
Oak instance via a with() method, it oak will push the whiteboard to
it.

regards, toby

ps: I still think we should turn the problem around, and make
everything OSGi services and start a small OSGi container for the
runtime :-)

[0] 
https://github.com/tripodsan/jackrabbit-oak/commit/8026bd44cf47879c67f7875bc08247a4eb7e501f


 BR,

 Jukka Zitting


Make Whiteboard accessible through ContentRepository

2014-02-07 Thread Tobias Bocanegra
Hi,

currently there is not way to access the whiteboard from within the
content repository - only if it's added from the outside to the
plugins.

For example, I would need access to it from within a LoginModule.
Right now, I got a private whiteboard just for the security provider,
but this is not optimal. IMO there should only be 1 whiteboard for 1
Oak.class instance. Also note, that in case of OSGi, all the OSGi
whiteboards would base on the same service registry anyways.

WDYT?

regards, toby