[wildfly-dev] IMPORTANT: First overview of changes to jboss-ejb-client 3.0 for WildFly 10 (probably)

David M. Lloyd david.lloyd at redhat.com
Fri Nov 28 11:00:07 EST 2014


Thanks for responding; answers inline.

On 11/28/2014 08:59 AM, Wolf-Dieter Fink wrote:
> Hi David,
>
> I'm looking more from the functional side not from the implementation.
> So in general simplifying the code will make it better to understand.
>  From my perspective we need to cover the requirements from our users
> and make it easy to handle.
>
> I don't care whether we have different possibilities to configure the
> client. But the most important is to create a InitialContext programatic
> with properties and use it for all server actions.
> This should be done with a minimum of properties, i.e. default SSL=off
> as there is a need to configure it correct at server side.
>
> So I would assume that we deprecate the scoped-context and remote-naming
> complete and use the new approach.

I think remote-naming will continue to exist however it faces some 
similar refactoring (though likely smaller in scale), probably over the 
next month if all goes well.  But the user-facing changes to that 
project will be far less dramatic (probably completely unnoticeable in 
fact).

> I'll create a client project to show typical use-cases with the new API
> and check whether we cover the current issues.
> For this I appreciate if you have some examples if the creation and
> handling for the client has changed.

I'll put a few directly into this reply.

> BTW, is it possible to use the ejb-client 3.0 with current EAP/WildFly?
> Is there any restriction or dependency?
> At the moment I'm not able to compile the project (branch
> uri_invocation), there is a missing dependency.
>    org.wildfly.common:wildfly-common:jar:1.0.0.Beta1-SNAPSHOT

The API coding is done but there are some things still missing - in 
particular, all the protocol code needs to be rebuilt (probably from 
scratch), so that's going to be at least one person-week of work yet 
(with a few holidays thrown in that time) before the 3.x code will even 
*attempt* to connect to anything.  In addition, it needs an i18n 
work-over and a bunch more documentation.

Also, the wildfly-common project has not yet achieved full existence. 
If you clone and build it from my repository at 
https://github.com/dmlloyd/wildfly-common though, you should be able to 
build with all tests passing.

> please find my other comments inline.

More responses following inline comments.

> On 26/11/14 19:54, David M. Lloyd wrote:
>> I don't want to commit this to a specific WildFly release but I guess
>> and hope it'll come in around WildFly 10 or so (definitely not 9).
>>
>> As previously discussed, the EJB client architecture is undergoing the
>> following substantial changes:
>>
>> • Introduction of URIAffinity, and URI-based invocation
>> • Expansion of the 'ejb' JNDI initial context to auto-associate the
>> PROVIDER_URL as the URI affinity for looked-up proxies
> What does that mean?
> Is it possible to use an InitialContext without any jboss-ejb-client
> configuration to be able to invoke ejb's and lookup other JNDI stuff
> like JMS with one IC and no redundant server properties?

Yes, however any EJB proxies created with an unconfigured IC will have 
Affinity.NONE, meaning the client will have to rely on discovery to 
locate these EJBs (similar to how it works today, though hopefully 
somewhat more robust).

So to give an example:

    Context ctx = new InitialContext();
    MyEJBRemote r = (MyEJBRemote) ctx.lookup("ejb:/myapp/mymodule/MyEJB");

is the same as:

    MyEJBRemote r = EJBClient.createProxy(
        new StatelessEJBLocator(
            MyEJBRemote.class,
            "myapp",
            "mymodule",
            "MyEJB",
            Affinity.NONE));

Any attempt to invoke on "r" relies on the discovery implementation's 
ability to look up a concrete destination URI.

However, if I do this:

    Properties props = new Properties();
    props.put(Context.PROVIDER_URL, "remote://myhost.foo.com:12345");
    Context ctx = new InitialContext(props);
    MyEJBRemote r = (MyEJBRemote) ctx.lookup("ejb:/myapp/mymodule/MyEJB");

This is the same as:

    MyEJBRemote r = EJBClient.createProxy(
        new StatelessEJBLocator(
            MyEJBRemote.class,
            "myapp",
            "mymodule",
            "MyEJB",
            Affinity.forURI(new URI("remote://myhost.foo.com:12345"))));

So any attempt to invoke on "r" will directly create or reuse a 
(possibly preconfigured) connection to "remote://myhost.foo.com:12345" 
with no discovery latency or round-trips of any kind (also, as before, 
no server connection establishment is required to instantiate this 
stateless proxy).

>> • Elimination of all "nested" EJB client context functionality
>> • Integration with Elytron for client identity management
> Does that mean the credentials for the connection and ejb invocation are
> decoupled?

Yes, but only if you've configured it thus.

You can switch identity with the current Elytron API by doing one of the 
following.  First, there's the completely programmatic option:

    AuthenticationContext ctx =
        AuthenticationContext.captureCurrent().with(
 
MatchRule.empty().matchHost("myhost.foo.com").matchProtocol("remote"),
 
AuthenticationConfiguration.EMPTY.setUserName("jane").setPassword("xyz")
        );

    ctx.run(new PrivilegedAction<Void>() {
        public Void run() {
            // This method will run as "jane"
            r.invokeSomeMethod();
        }
    });

Second, you can preconfigure two (or more) identities in the global 
configuration, and switch by using different URI affinities:

    Properties props = new Properties();
    props.put(Context.PROVIDER_URL, "remote://jane@myhost.foo.com:12345");
    Context janeCtx = new InitialContext(props);
    MyEJBRemote janeRemote = (MyEJBRemote) 
janeCtx.lookup("ejb:/myapp/mymodule/MyEJB");
    props.put(Context.PROVIDER_URL, "remote://joe@myhost.foo.com:12345");
    Context joeCtx = new InitialContext(props);
    MyEJBRemote joeRemote = (MyEJBRemote) 
joeCtx.lookup("ejb:/myapp/mymodule/MyEJB");

The identity used will depend on which proxy is invoked (one connection 
is still shared though).

> Is there a possibility to use the old style CallBackHandler and/or being
> able to change the user for an existing remoting connection?

Yes, you can use the Elytron APIs to do both of these things.  In the 
present design, there is no way to use credentials configured in an 
InitialContext property map though; we haven't found a way to map this 
to Elytron that was both intuitive and also not rife with security and 
implementation problems.  It's not a closed issue though; any input here 
is appreciated.

> Also whether the credentials are used to invoke ejb's in a
> server-to-server communication and the user will be the invocation use
> of the first EJB and not the connection user?

Yes it will be possible to easily connect with one set of credentials 
and invoke EJBs with different credentials, even switching identities on 
a per-invocation basis (as briefly described above).

>> • Deferral to Remoting for automatic connection management
>> • Unification of client configuration, so the Elytron authentication
>> client, Remoting connection management, remote transaction client, and
>> EJB client configurations all can be configured in one file or
>> deployment descriptor
> Great!

:-D

>> • The following classes and interfaces are currently removed in my
>> working copy:
>>      • ClusterContext - replaced with discovery (?)
>>      • ClusterNodeManager - replaced with discovery
>>
>>      • ClusterNodeSelector - replaced with discovery
>>      • DeploymentNodeSelector - replaced with discovery
> As Cluster/Deployment NodeSelector is being removed and replaced by
> discovery this sounds to me that there is no possibility to customize
> the load-balancing process
>
> This might affect some use-cases where such policy was implemented to
> control specific behaviour.

This is an example of an API that can probably be added back.  I want to 
spend some time consulting with Radoslav H. and Paul F. though to make 
sure that the API is "right" before I reintroduce this exact API (or a 
similar one).  Any input regarding use cases will be useful, I expect.

> Does this mean also that the cluster configuration at client side is
> deprecated and not longer necessary?

I'm not sure yet.  Maybe.

> Also the need to configure the cluster-name within the server
> configuration to distinguish between different clusters?

Yeah having a name-based identity for clusters is still the key to the 
EJB clustering design (for better or worse).  Ideally this would be 
something that the user can keep unique within their organizations.

>>      • EJBClientContext
>>         • No longer implements Closeable
> Does this mean there is no longer a need to close a context to avoid
> "too much channel" problems. I suppose the "scoped context" will be removed

Correct.  Remoting will maintain all connections based on configuration 
(including idle timeouts, if any), and all connections will be shareable 
among all Remoting-based services.  Other protocols (like HTTP) will 
similarly be responsible for the configuration and reuse of connections. 
  There will no longer be a need to close *anything*, which I believe 
our experiences have shown will be a good thing overall.

>> Transaction handling will be relegated to a separate
>> wildfly-transaction-client API.  However the getUserTransaction(node)
>> method will continue to be supported as a deprecated delegation to the
>> transaction-client API.  In addition, when talking to a 2.x server, it
>> is expected that a wildfly-transaction-client SPI implementation will
>> piggyback on the existing EJB protocol transaction messages.

> Is there a possibility to use the InitialContext and do a
> lookup("UserTransaction") to get a reference to UserTransaction without
> any knowledge of the server environment?  This was used <AS7 and also from other vendor.

Yes, that's a possibility.  I can imagine a simple JNDI protocol handler 
to accomplish this, e.g. lookup("txn:UserTransaction") or something 
along those lines.  The UserTransaction should be associated with a URI 
in exactly the same way that the EJB proxies would be, and this code 
would work universally on client and server (much like the EJB "ejb:" 
contexts are universal).

> Also is the ejb and other invocations sticky during the Tx is active?

Yes.  And, like today, trying to use an EJB which is located someplace 
that is incompatible with the current transaction will result in an 
error.  In addition, any current or future additional services we 
transport over Remoting (current: JMX, Management, JNDI; future: 
Authentication, maybe others like JDBC) can also reuse the same 
transaction context.  At present this can not include JMS though, 
unfortunately, unless you have a local Narayana transaction manager that 
can manage the transaction using JTA and XA, or unless we (or someone 
else) would create a Remoting-based transport for one or more JMS 
implementations.

-- 
- DML


More information about the wildfly-dev mailing list