Monday, December 30, 2013

Detect AJAX Request or PPR Request in ADF Faces

I have a need to detect if the request generated is an AJAX request or Full request. In JSF 2.0 this is easy and you can find many blog posts and forum discussions which have dealt with it. But as I am using ADF 11.1.1.6.0 which uses JSF 1.2 so none of those methods of detecting an AJAX request wouldn't work for me.

So I tried to find a way to detect if the request generated is an AJAX or not and what I found I am sharing with you. You can use any one of the following methods from your Utility class:

public static boolean isPprRequest(FacesContext context) {
 return isPprRequest(context.getExternalContext());
}

public static boolean isPprRequest(ExternalContext ec) {
 return (("true".equals(ec.getRequestHeaderMap().get("Adf-Rich-Message"))) || ("true".equals(ec.getRequestParameterMap().get("Adf-Rich-Message"))));
}

public static boolean isPprRequest(HttpServletRequest req) {
 return (("true".equals(req.getHeader("Adf-Rich-Message"))) || ("true".equals(req.getParameter("Adf-Rich-Message"))));
}

Note this is applicable for ADF 11.1.1.6.0. I haven't tested with other ADF versions.

Happy coding :-)

Saturday, December 28, 2013

WildFly: EJB invocations from a remote client

Currently I am experimenting with Java EE7 and I have chosen WildFly as my application server. So far everything is working fine, the WebService, EJB 3.2 etc until today when I tried to access my EJB from a client application - jUnit Test.
To solve the issue initially I followed the instruction given in WildFly documentation EJB invocations from a remote client using JNDI, but it is not what I needed. After spending almost half a day at last I achieved what I wanted.

Prerequisite:

  • You need to have an Application User. Follow the instruction given in Add User Utility.
  • I am running my server with the parameter -b 0.0.0.0 --server-config standalone-full.xml
  • jboss-client.jar in your classpath, which can be found inside the /bin/client directory of the server.
Following is the piece of code which you need to access the EJB:

import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.jboss.ejb.client.EJBClient;
import org.jboss.ejb.client.EJBClientContext;
import org.jboss.ejb.client.PropertiesBasedEJBClientConfiguration;
import org.jboss.ejb.client.StatelessEJBLocator;
import org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector;

/**
 * Class EJBLocator is the class to connect with EJB
 * 
 * @author Tapas Bose
 * @since 1.0
 */
public class EJBLocator {

 /**
  * Method locateEJB locates an EJB for the given jndi
  * 
  * @author Tapas Bose
  * @since 1.0
  * @param jndi
  *            - the jndi to lookup
  * @return an instance of EJB
  * @throws NamingException
  */
 @SuppressWarnings("unchecked")
 public static <T> T locateEJB(String jndi) throws NamingException {
  Properties clientProperties = new Properties();
  clientProperties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
  clientProperties.put("remote.connections", "default");
  clientProperties.put("remote.connection.default.port", myPort);
  clientProperties.put("remote.connection.default.host", myHost);
  clientProperties.put("remote.connection.default.username", myUser);
  clientProperties.put("remote.connection.default.password", myPassword);
  clientProperties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");

  EJBClientContext.setSelector(new ConfigBasedEJBClientContextSelector(new PropertiesBasedEJBClientConfiguration(clientProperties)));

  Properties properties = new Properties();
  properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
  Context context = new InitialContext(properties);
  return (T) context.lookup(jndi);
 }

 /**
  * Method locateEJBStateless locates an Stateless EJB for the given parameters
  * 
  * @author Tapas Bose
  * @since 1.0
  * @param viewType
  *            - the view type
  * @param appName
  *            - the application name
  * @param moduleName
  *            - the module name
  * @param beanName
  *            - the bean name
  * @param distinctName
  *            - the distinct name
  * @return an instance of EJB
  */
 public static <T> T locateEJBStateless(Class<T> viewType, String appName, String moduleName, String beanName, String distinctName) {
  Properties properties = new Properties();

  properties.put("endpoint.name", "client-endpoint");
  properties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
  properties.put("remote.connections", "default");
  properties.put("remote.connection.default.port", myPort);
  properties.put("remote.connection.default.host", myHost);
  properties.put("remote.connection.default.username", myUser);
  properties.put("remote.connection.default.password", myPassword);
  properties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");

  EJBClientContext.setSelector(new ConfigBasedEJBClientContextSelector(new PropertiesBasedEJBClientConfiguration(properties)));
  StatelessEJBLocator<T> locator = new StatelessEJBLocator<T>(viewType, appName, moduleName, beanName, distinctName);
  T ejb = EJBClient.createProxy(locator);
  return ejb;
 }
}

Use this class as:
YourService service = EJBLocator.locateEJB(jndi);
//where the jndi is of the form ejb:<app-name>/<module-name>/<distinct-name>/<bean-name>!<fully-qualified-classname-of-the-remote-interface>
Or by:
YourServic service = EJBLocator.locateEJBStateless(YourServic.class, "appName", "moduleName", "YourServicImpl", "distinctName");
Hope it will help.