Using Identity Store

All

Intro

Was searching here on a small application for deploying in JBoss using ​​Ldap, which is a protocol for managing with services directories.

So, the basic requirement is: An application that has a Ldap custom module for log in.

The ldapwiki helps a lot actually

Application

The process is partially described here, ie, we want to have inMemoryDirectoryServer this basically starts, stop, and manipulate in general the Ldap configuration. To set all the information on the Server, we use a InMemoryDirectoryServerConfig

InMemoryDirectoryServer: start, stop, manipulate

InMemoryListenerConfig: loads  the configuration file

Core

Web.xml

 

Application Config

InMemoryDirectoryServerConfig config =
new InMemoryDirectoryServerConfig(“dc=example,dc=com”);
config.addAdditionalBindCredentials(“cn=Directory Manager”, “password”);

// Create the directory server instance, populate it with data from the
// “test-data.ldif” file, and start listening for client connections.
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
ds.importFromLDIF(true, “app.ldif”);
ds.startListening();

And to start/stop we can do:

// Disconnect from the server and cause the server to shut down.
conn.close();
ds.shutDown(true);

When you login, you will see:

<h:outputText value=”Hello World”/>
<!– added sonic the hedgehog –>
<img src=”img/sonic.jpg” alt=”Sonic”></img>

So this:

sonic

user.ldif  ~ LDAP Data Interchange Format

We use a ldif file so we can set the users that will access the application, as explained on the link, this file is a bit tricky and has its own.

dn: ou=People,dc=example,dc=com
objectClass: organizationalUnit
ou: People

Compilation with Maven

 

Deployment

INFO [stdout] (ServerService Thread Pool — 82) —Starting App

Accessing

The access is done throw http://localhost:8080/app-test/user

References

https://www.digitalocean.com/community/tutorials/how-to-use-ldif-files-to-make-changes-to-an-openldap-system

https://docs.wildfly.org/12/WildFly_Elytron_Security.html

https://docs.ldap.com/ldap-sdk/docs/in-memory-directory-server.html

 

Adding users in EJB

All

Intro

I did in another post about a simple Remote Sum EJB  and client. The scheme is pretty straight forward and I will do the opposite of what usually someone do (tutorial then set the user) let’s do the opposite:

Adding the users/roles

Both two steps below can be done with:

$JBOSS_HOME/bin/add-user.sh -a -u 'testUserOne' -p 'testPasswordOne' -g 'guest'
  1. Add the user you will test in the application-users.properties:

testUserOne=cf8f98f5b90ccc568e1ffc7767ac9d8b

2. Add the roles (either guest and/or admin) in the application-roles.properties:

testUserOne=guest

#testUserOne=guest, admin

3. Add Application in the security domain:

<application-security-domains>
<application-security-domain name=”other” security-domain=”ApplicationDomain”/>
</application-security-domains>

4. And add the connector:

<http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm" sasl-authentication-factory="application-sasl-authentication"/>

Maven is a friend

Maven is always a friend an helps organize the project in the pom.xml. On this case though, I will go step by step ~ thoroughly ~ so won’t use mvn.

So just do jar -cvf EjbSecure.jar SecureSum.class SecureSumRemote.class resources/

Code

1. Besides what was already there, we just need to add the annotation for the RolesAllowed and the SecurityDomain allowed, as follows:

@Stateless
@RolesAllowed({ “guest” }) //Added
@SecurityDomain(“other“) //Added
public class SecureSum implements SecureSumRemote
{
public int add(int a, int b){
return a+b;
}
}

2. Add the wildfly-config.xml (Jakarta 8 specially) for the security validation, setting up the actually user you want

<set-user-name name=”testUserOne”/>
<credentials>
<clear-password password=”testPasswordOne”/>

Testing

  1. Create a Client passing the password that you added on wildfly-config.xml:

if(username != null && password != null) {
props.put(Context.SECURITY_PRINCIPAL, username);
props.put(Context.SECURITY_CREDENTIALS, password);
}

2. Compile it with jboss-annotations-ejb3-4.2.2.GA.jar, run it:

#java StandaloneSecure
Getting the Remote
…More several
Got the remote InterfaceProxy for remote EJB StatelessEJBLocator for “/EjbSecure/SecureSum”, view is interface SecureSumRemote, affinity is None
20

Interesting

1. Not using password (or using a wrong password) there will be a Not Allowed:

02:19:47,143 ERROR [org.jboss.as.ejb3.invocation] (default task-1) WFLYEJB0034: EJB Invocation failed on component SecureSum for method public abstract int SecureSumRemote.add(int,int): javax.ejb.EJBAccessException: WFLYEJB0364: Invocation on method: public abstract int SecureSumRemote.add(int,int) of bean: SecureSum is not allowed

2. To add the admin feature specific, just add:

@RolesAllowed(admin) some function, like in [dont forget to add admin role for the user in application-roles.properties]:

@RolesAllowed(“admin”)
public int minus(int a, int b){ return a – b; }

Result:

Got the remote InterfaceProxy for remote EJB StatelessEJBLocator for “/EjbSecure/SecureSum”, view is interface SecureSumRemote, affinity is None
Sum:20
Minus:0

Otherwise, you get an exception: WFLYEJB0364: Invocation on method: public abstract int SecureSumRemote.minus(int,int) of bean: SecureSum is not allowed

3. The lookup get’s the remote, so cast to Remote. And to add another method, the method must be on the remote.

Reference

Of course the quickstart security. Very well done, it is a bit of an overkill at first but later understanding the basics you can add more on top of it no problem.

EJB Context

All

Intro

Reviewing some EJBs I started to play with some attributes of the Context.

//this returns java.naming.factory.initial:
System.out.println(Context.INITIAL_CONTEXT_FACTORY.toString());
//this returns java.naming.provider.url:
System.out.println(Context.PROVIDER_URL.toString());

 

EJB Port

The default http port is 8080, given in .

So if you use an offset <port-offset=”${jboss.socket.binding.port-offset:100}”> change Context.PROVIDER_URL,”remote+http://localhost:8180″);  the otherwise, you will get a connection refused:

javax.naming.CommunicationException: WFNAM00018: Failed to connect to remote host [Root exception is java.net.ConnectException: Connection refused]
at (…)

org.wildfly.naming.client.WildFlyRootContext.listBindings(WildFlyRootContext.java:300)
at javax.naming.InitialContext.listBindings(InitialContext.java:472)
at StandaloneJNDI.main(StandaloneJNDI.java:27)
Caused by: java.net.ConnectException: Connection refused

EJB context

Listing

GettingProperties

Unbinding

context.unbiding will return:

21:26:16,717 INFO [org.wildfly.naming] (default task-1) WildFly Naming version 1.0.11.Final-redhat-00001
21:26:16,746 WARN [org.wildfly.naming] (default task-2) WFNAM00036: Unexpected internal error: java.lang.UnsupportedOperationException:  : Naming context is read-only
at org.jboss.as.naming.WritableServiceBasedNamingStore.requireOwner(WritableServiceBasedNamingStore.java:160)
at org.jboss.as.naming.WritableServiceBasedNamingStore.unbind(WritableServiceBasedNamingStore.java:131)
at org.jboss.as.naming.NamingContext.unbind(NamingContext.java:318)

The code is on Github

 

Tag distributable/

All

Intro

HTTP Session Replication, during a session in case a node fails a way to avoid a client to close it is through replication to the other nodes. This is explained on the tutorial Distributable and that’s pretty much how mod_cluster makes its way.

JBoss EAP

In JBoss, this can be modified/tuned with the usage of the jboss-web.xml that contains several attributes. Although very very outdated, this reference can be used to get some idea of the attributes.

One example of what can be used for is to set the context-root of the project:

   <module>
        <web>
            <web-uri>web-client.war</web-uri>
            <context-root>bank</context-root>
        </web>
    </module>

Demo

[standalone@embedded /] /subsystem=distributable-web/infinispan-session-management=default:read-resource

 

Listing all names in JNDI in EJB

All

Intro

Based on here and here created a program that lists all Bindings (using context.Bindings) and JDNI names from the context.list:

Code

System.out.println(“Listing all names”);
NamingEnumeration namingenumeration = context.listBindings(“”);
while (namingenumeration.hasMore()) {
Binding binding = (Binding)namingenumeration.next();
System.out.println(binding.getName() + ” XXX ” + binding.getObject()
);
}

The core part is the NameClassPair

Result on Client

INFO: JBoss Remoting version 5.0.16.Final-redhat-00001
EjbRemote XXX org.wildfly.naming.client.store.RelativeFederatingContext@32eebfca
javax.naming.Context: true:EjbRemote

org.wildfly.naming.client.store.RelativeFederatingContext@7dc222ae

This is the binding name for JBoss EAP 7.1: org.wildfly.naming.client.WildFlyInitialContextFactory

javax.naming.Context: true:EjbSum

This is the EjbSum from the EJB pt1 – post.

Result on Server side

03:01:46,984 INFO [org.wildfly.naming] (default task-1) WildFly Naming version 1.0.11.Final-redhat-00001

 

EJB pt-2

All

Comparing JBoss EAP for EJB in several versions

JBoss  EAP 4x/5x:

  1. For JBoss EAP  you will need dist/lib/jbossall-client-4.2.2.GA.jar

2. This initial context factory when trying to call a different JVM

public class EJBTester {

jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY,”org.jnp.interfaces.NamingContextFactory”);
jndiProperties.put(Context.URL_PKG_PREFIXES, “org.jboss.ejb.client.naming”);
ctx = new InitialContext(jndiProperties);

3. JBoss EAP 4 /5  – the initial context is like:

public static Context getInitialContext( String host ) throws Exception {
if ( host == null ) host = “localhost”;
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, “org.jnp.interfaces.NamingContextFactory”);
properties.put(Context.URL_PKG_PREFIXES, “org.jboss.naming:org.jnp.interfaces”);
properties.put(“jnp.socket.Factory”, “org.jnp.interfaces.TimedSocketFactory”);
properties.setProperty(“java.naming.provider.url”, “jnp://”+ host +”:1099″);
return new InitialContext(properties);
}
    4. The EJB lookup would be :

LibrarySessionBeanRemote remoteEJB = (LibrarySessionBeanRemote) getInitialContext(“localhost”).lookup(“LibrarySessionBean/remote”);

18:21:35,100 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

LibrarySessionBean/remote – EJB3.x Default Remote Business Interface
LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote – EJB3.x Remote Business Interface

   5. Deployment

18:21:35,100 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

LibrarySessionBean/remote – EJB3.x Default Remote Business Interface
LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote – EJB3.x Remote Business Interface

For JBoss EAP 6x

properties.put(Context.URL_PKG_PREFIXES, “org.jboss.naming:org.jnp.interfaces”);

For JBoss 7x

The process is described with more details on the post <EJB pt1>

  1. Add $JBOSS_HOME/modules/system/layers/base/javax/ejb/api/main/jboss-ejb-api_3.2_spec-1.0.1.Final-redhat-1.jar to the classpath.

2. For the Client, the initial context changed for:

props.put(Context.INITIAL_CONTEXT_FACTORY, “org.wildfly.naming.client.WildFlyInitialContextFactory”);
props.put(Context.PROVIDER_URL,”remote+http://localhost:8080″);

3. Compile with $JBOSS_HOME/bin/client/jboss-client.jar

4. Lookup – when the client app is in the same JVM as the EJB

LibrarySessionBeanRemote libraryBean =
(LibrarySessionBeanRemote)this.ctx.lookup(“java:global/EjbComponent/LibrarySessionBean!com.tutorialspoint.stateless.LibrarySessionBeanRemote”);

    AdderImplRemote remote = (AdderImplRemote) getInitialContext().lookup(“ejb:/EjbRemote/AdderImpl!AdderImplRemote”);

   org.wildfly.naming.client.WildFlyInitialContextFactory

 

Reduce in Ruby

All
For numbers
array = [1,2,3,4,5,6,7,8,9,10]
puts array.reduce(:+) #very simplified
puts array.reduce(0,:+)
puts array.reduce(1,:+)
puts array.reduce(10,:+)
puts array.reduce(100,:+)
puts array.reduce(-1,:+)

 

For strings

array = [“say”, “my”,”name”,”say”,”my”,”name”]
puts array.reduce(:+)
puts array.reduce(“mario”,:+)
Output:
55
55
56
65
155
54
saymynamesaymyname
mariosaymynamesaymyname

EJB – pt1

All

EJB

EJB is deployed in Jar, War, Ear format. In WAR, if the EJB is packaged in jar format, it can be placed in WEB-INF/lib. If EJB classes are to be directly packaged in WAR, they can placed in WEB-INF/classes.

I will create a minimal project here to show a client accessing a Stateless bean (basically a simplified version from quickstart) and code on Github.

1. Create the project:

For this you need a home interface/remote interface and the implementation, as explained here:

1.a Create an interface

import javax.ejb.Remote;
@Remote
public interface SumRemote
{ int add(int a, int b); }

1.b Implement this interface

import javax.ejb.Stateless;

@Stateless
public class Sum implements SumRemote
{ public int add(int a, int b){ return a+b; } }

1.c Create a client (eap 7.1:)

Get the InitialContext:

public static Context getInitialContext() throws NamingException{
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, “org.wildfly.naming.client.WildFlyInitialContextFactory”);
props.put(Context.PROVIDER_URL,”remote+http://localhost:8080“);
final Context context = new InitialContext(props);
return context;

(The port here comes from <socket-binding name=”http” port=”${jboss.http.port:8080}”/>)

And then get the remote – attention that is stateless so the JNDI will be:

The class name we know, is SumRemote, so we can add it diretly, or use the .class.getName(0;

SumRemote remote = (SumRemote) getInitialContext().lookup(“ejb:/EjbSum/Sum!” + SumRemote.class.getName());

OR

AdderImplRemote remote = (AdderImplRemote) getInitialContext().lookup(“ejb:/EjbRemote/Sum!SumRemote”);

2. Export

JBOSS_HOME/modules/system/layers/base/javax/ejb/api/main/jboss-ejb-api_3.2_spec-1.0.1.Final-redhat-1.jar

3. Compile and package:

[fdemeloj@fdemeloj Bean]$ javac Sum*

[fdemeloj@fdemeloj Bean]$ jar -cvf EjbSum.jar .
added manifest
adding: SumRemote.class(in = 194) (out= 163)(deflated 15%)
adding: Sum.class(in = 335) (out= 253)(deflated 24%)

Compile the Client

#export CLASSPATH=/home/fdemeloj/jboss-eap-7.3/bin/client/jboss-client.jar:$CLASSPATH
#javac StandaloneClient.java

4.Deploy

[fdemeloj@fdemeloj Bean]$ cp EjbSum.jar $JBOSS_HOME/standalone/deployments

This is the JNDI:

23:17:47,545 INFO [org.jboss.as.ejb3.deployment] (MSC service thread 1-1) WFLYEJB0473: JNDI bindings for session bean named ‘Sum’ in deployment unit ‘deployment “EjbSum.jar”‘ are as follows:

java:global/EjbSum/Sum!SumRemote
java:app/EjbSum/Sum!SumRemote
java:module/Sum!SumRemote
java:jboss/exported/EjbSum/Sum!SumRemote
ejb:/EjbSum/Sum!SumRemote
java:global/EjbSum/Sum
java:app/EjbSum/Sum
java:module/Sum

5. Test

# java StandaloneClient
Getting the Remote
Apr 19, 2020 2:05:10 AM org.wildfly.naming.client.Version <clinit>
INFO: WildFly Naming version 1.0.11.Final-redhat-00001
Apr 19, 2020 2:05:10 AM org.wildfly.security.Version <clinit>
INFO: ELY00001: WildFly Elytron version 1.10.4.Final-redhat-00001
Apr 19, 2020 2:05:10 AM org.xnio.Xnio <clinit>
INFO: XNIO version 3.7.7.Final-redhat-00001
Apr 19, 2020 2:05:10 AM org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.7.7.Final-redhat-00001
Apr 19, 2020 2:05:10 AM org.jboss.threads.Version <clinit>
INFO: JBoss Threads version 2.3.3.Final-redhat-00001
Apr 19, 2020 2:05:10 AM org.jboss.remoting3.EndpointImpl <clinit>
INFO: JBoss Remoting version 5.0.16.Final-redhat-00001
Apr 19, 2020 2:05:10 AM org.jboss.ejb.client.EJBClient <clinit>
INFO: JBoss EJB Client version 4.0.27.Final-redhat-00001
Got the remote InterfaceProxy for remote EJB StatelessEJBLocator for “/EjbSum/Sum”, view is interface SumRemote, affinity is None
20

The 20 is the answer.

5. Comparing Remote vs Local

When Same deploying in the same JVM use local and when using another JVM use remote:

@Local ~

Call by Reference, the overhead is minimal, since it is the same JVM so the parameters is the same, so the references are the same. As results, no overhead.

@Remote ~

Call by Value, processing overhead, since are different JVM, the location is remote, the parameters will be value. Remote method invocation: marshed parameters then.
There is a overhead, because of the marsheling. So no references, but a copy of the value.

@Local annotated beans can only be accessed if they are in the same application.

@Remote annotated beans can be accessed across different applications, residing in different jvms or across application servers.

As pointed here

6. JNDI Reference

ejb:<app>/<moduleName>/<distinctName>/<beanName>!<viewClassName>?stateful
<app>EAR name
<moduleName> name of EJB jar
<distinctName> Optional Name
<beanName> Bean’s class
<ViewClassName> fully qualified class name of the remote interface

7. To extract content from jar file:

jar xf jar-file [archived-file(s)]

8. Get the Environment from the context, it will return what is passed:

System.out.println(context.getEnvironment());

Returns:

{java.naming.factory.initial=org.wildfly.naming.client.WildFlyInitialContextFactory, java.naming.provider.url=remote+http://localhost:8080}

8. References:

For JBoss EAP 7.1:

Coding EJB clients for JBoss EAP 7.1

Infinispan/JDG Quickstarts Pt4 – HotRod

All

Intro

This tutorial I have been a long time thinking about doing. This will come in handy: Rod Hot Client Guide

Before start

Download and install the client and install it:

npm install /path/to/jboss-datagrid-7.0.0-nodejs-client/infinispan-0.2.0.Final-redhat-1.tgz

It will also require vorpal js lib =|===>

Deploying

[fdemeloj@fdemeloj hotrod-endpoint-js]$ node football-manager.js
football-manager >

Core

As the guide mentions, the main part is done after the connection, then the functions are added after, but they use vorpal – bsically all in football-manager.js:

   var infinispan = require(‘infinispan’);
var vorpal = require(‘vorpal’)();

infinispan.client({port: 11222, host: ‘127.0.0.1’}).then(function(client)

Commands in Vorpal:

vorpal
.command(‘at [teamName]’, ‘Add a team.’)
.action(addTeam(client));

addPlayer:

function addPlayer(client) {
return function(args, callback) {
var teamName = args.teamName;
var playerName = args.playerName;

var getTeam = client.get(teamName);
var putPlayer = getTeam.then(function(t) {
return client.put(teamName, appendPlayer(t, playerName));
});

return putPlayer.then(callback);

Printing value with `​p`

football-manager > at “Holand”
Add Team
true

football-manager > p
Add Team
=== Team: Holand ===

Interesting facts

  1. If you do ​`tree command` the list of files is huge, cause all the js scripts from the libs are there, apparently.
  2. Deploying in version JDG 7.2 gives an exception, but version JDG 7.3 works perfectly.
    1. ERROR [org.infinispan.server.hotrod.CacheDecodeContext]ISPN005003: Exception reported: org.infinispan.server.hotrod.InvalidMagicIdException: Error reading magic byte or message id: 13 at org.infinispan.server.hotrod.HotRodDecoder.readHeader(HotRodDecoder.java:184)
  3. Using vorpal makes the example pretty easy, with help and everything – tutorial here
  4. The package.json` has the dependencies and others info about the project
  5. `hotrod-client.properties` is not used.