Friday, September 11, 2015

Register RMI Service on RmiServer and how to consume it (ATG Oracle Commerce)

ATG does have an RMI server running when the application starts, that can be seen at the logs with a line similar to this:

INFO  [nucleusNamespace.atg.dynamo.server.RmiServer] (ServerService Thread Pool -- 55) Service /atg/dynamo/server/RmiServer listening at rmi://localhost:8860/

And this rmi server is used for BCC on the agents.


Let's see how we can create our on RMI Service and register this on ATG RmiServer, this example Service will invalidate cache on a given Repository.

Create base Interface for our RmiService.
First of All you will need a Interface that that extends java.rmi.Remote
This will have the methods you want to expose to be executed Remote.

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface RepositoryCacheInvalidation extends Remote {
    
    /** 
     * Method signature for invalidateCache that will receive repositoryPath to invalidate.
     * @param repositoryPath to invalidate.
     * @throws RemoteException if happens.
     */
    void invalidateCache(String repositoryPath) throws RemoteException;
    
}


Create Class that Will be our RmiService
Once this is done, lets implement the Interface, our class will Implement our interface, and will extend atg.nucleus.GenericRMIService

import java.rmi.RemoteException;

import atg.adapter.gsa.GSARepository;
import atg.core.util.StringUtils;
import atg.nucleus.GenericRMIService;
import atg.nucleus.spring.NucleusResolverUtil;
import atg.repository.ItemDescriptorImpl;
import atg.repository.Repository;
import atg.repository.RepositoryException;

public class RepositoryCacheInvalidationImpl extends GenericRMIService implements RepositoryCacheInvalidation {

    /** Constant to hold serialVersionUID. */
    private static final long serialVersionUID = 3719003929540922692L;

    /**
     * Default constructor that throws RemoteException.
     * 
     * @throws RemoteException if happens.
     */
    public RepositoryCacheInvalidationImpl() throws RemoteException {
        super();
    }

    /** 
     * Method signature for invalidateCache that will receive repositoryPath to invalidate.
     * @param repositoryPath to invalidate.
     * @throws RemoteException if happens.
     */
    @Override
    public void invalidateCache(final String repositoryPath) throws RemoteException {
        vlogDebug("Start RepositoryCacheInvalidationImpl.invalidateCache({0})", repositoryPath);
        if (!StringUtils.isBlank(repositoryPath)) {
            Object obj = NucleusResolverUtil.resolveName(repositoryPath);
            if (obj != null && obj instanceof Repository) {
                ((GSARepository) obj).invalidateCaches();
            }
        }
        vlogDebug("End RepositoryCacheInvalidationImpl.invalidateCache({0})", repositoryPath);
    }
    
}


Register the RmiSerivce as Dynamo Component 
Since this class will be a component we need to create the .properties for it, to be registered on dynamo server.

##
# /com/example/repository/rmi/RepositoryCacheInvalidation/
# RMIService component that will be used to invalidate cache.
##
$class=com.example.repository.rmi.RepositoryCacheInvalidationImpl


Register RepositoryCacheInvalidation on RmiServer
Now we need to make sure our Server register this Service, this needs to be done at /atg/dynamo/server/RmiServer
Just add the new RmiService at exportedServices as Follows:

exportedServices+=/com/example/repository/rmi/RepositoryCacheInvalidation as


This will make your RmiSerivce be available on the RmiServer, if everything is done correctly you will see it as follows:



Create a client for the RmiService
The new RmiService is created and registered, let's call it, you can create a GeniercService class to call this, here is how the method should look like to call our new RmiService

    /**
     * Method that will invalidate the cache for the repository that is sent as parameter.
     * @param repositoryPath to invalidate.
     * @throws MalformedURLException if wrong rmi servers are sent.
     * @throws RemoteException if there is an error connecting to rmi server.
     * @throws NotBoundException if Naming.lookup method fails fails.
     */
    public void invalidateCaches(final String repositoryPath)
            throws MalformedURLException, RemoteException, NotBoundException {
        if (!StringUtils.isBlank(repositoryPath)) {
            String url = "rmi://localhost:8860/com/example/repository/rmi/RepositoryCacheInvalidation";
                if (null != Naming.lookup(url)) {
                    vlogDebug("calling RMI service for cache invalidation {0}", url);
                    RepositoryCacheInvalidation repositoryCacheInvalidation = 
                            (RepositoryCacheInvalidation) Naming.lookup(url);
                    repositoryCacheInvalidation.invalidateCache(repositoryPath);
                }
        }
    }


And that's it, everything is documented at http://docs.oracle.com/cd/E24152_01/Platform.10-1/ATGPlatformProgGuide/html/s1003writinganrmiservice01.html
Post a Comment