New application controllers are implemented as plugins in the ORCA architecture. Controllers are plugins to the "Service Manager" actor. To implement a new controller,

1. Create a new project under orca/controllers with a new pom file. Look at the example pom files in orca/controllers/sge/pom.xml

mkdir orca/controllers/newcontroller

2. Under orca/controllers/newcontroller/src/main/java/orca/controllers/newcontroller/ start developing your controller code.

3. First, write code for a controller factory (for eg. ProtogeniControllerFactory?.java) that implements ControllerFactory? (which is extends the PluginFactory? interface). When the service manager actor stars up, it calls the create() method in the controller factory to actually stand up the controller. Here is an example:

public class ProtogeniControllerFactory implements ControllerFactory
{

    public static final String PropertySliceName = "sliceName";
    protected IActor actor;
    protected Manager manager;
    protected ProtogeniController cont;
    protected ProtogeniControllerManagerObject protogeniManagerObject;
    protected PortalPluginDescriptor desc;
    protected String sliceName = "protogeni";

    public void create(IExtensionsContainerManager manager) throws Exception
    {
        this.manager = (Manager) manager;

        if (!(actor instanceof IServiceManager)) {
            throw new Exception("Invalid actor type");
        }

        if (sliceName == null) {
            throw new Exception("Missing slice name");
        }

        ICodSlice slice = (ICodSlice) CodClientSliceFactory.getInstance().create(sliceName);
        actor.registerSlice(slice);

        cont = new ProtogeniController();
        cont.setActor(actor);
        cont.setSlice(slice);
        cont.initialize();
        // attach the controller to the slice
        slice.setController(cont);

        protogeniManagerObject = new ProtogeniControllerManagerObject(cont, actor);
        protogeniManagerObject.initialize(manager);

        ....

    }

    ....
}

4. Now, write code for a simple controller manager (a service manager manager) which extends ControllerManager?. This is the management interface to the the controller. This is also used in the factory code above where the controller gets initialized through this management interface. For eg. ProtogeniControllerManagerObject?.java looks like

public class ProtogeniControllerManagerObject extends ControllerManagerObject
{
    public ProtogeniControllerManagerObject(ProtogeniController controller, IActor actor)
    {
        super(controller, actor);
    }

    public void disableController(AuthToken auth)
    {
        ((ProtogeniController) controller).disableController();
    }

    public void enableController(AuthToken auth)
    {
        ((ProtogeniController) controller).enableController();
    }

    ...

}

5. Write code for controller (for eg. ProtogeniController?.java) that implements the IController interface. The initialize() method in this class is called when the controller starts up using the controller factory. The other important methods are tick() and bid(), which are called on clock ticks to serve the various requests. Implement specific controller features in this file or in separate handlers registered in this controller code. Event handling code (which extend EventHandler?) can also be included as a class in this piece of code. Here is an example:

public class ProtogeniController implements IController
{

    ....

    protected IServiceManager sm;
    protected LoggingTool logger = null;
    protected ISlice slice;
    protected String root;
    private boolean initialized = false;
    protected WebServer webserver;

    ....

    public synchronized void initialize() throws Exception
    {
        if (!initialized) {
            if (sm == null) {
                throw new Exception("Missing actor");
            }

            if (slice == null) {
                throw new Exception("Missing slice");
            }

            pendingReservations = new ArrayList<ICodClientReservation>();
            logger = sm.getLogger();
            root = ((Manager) ContainerManager.getInstance()).getPackageRootFolder(
                ProtogeniConstants.PackageId);
            ((ServiceManagerCalendarPolicy) sm.getPolicy()).register(new ProtogeniEventHandler());
            handler = new ProtogeniHandler(sm, this, slice, logger);
            webserver.addHandler(ServiceName, handler);
            webserver.start();

            initialized = true;
        }
    }

    ....

    public void tick(long cycle)
    {
        
        if (needAdvanceTime) {
            advanceTime = getAdvanceTime();
            needAdvanceTime = false;
        }

        bid(cycle);
        
    }


    protected void bid(long cycle)
    {
        int flag = 0;

        for(Iterator i = pendingReservations.iterator(); i.hasNext();){
            ICodClientReservation res = (ICodClientReservation) i.next();
            sm.demand(res);
            flag = 1;
        }

        if(flag==1){
            pendingReservations.clear();
        }
        
    }

    ....

}

6. To test the controller, create new test class in orca/controllers/newcontroller/src/test/java/orca/controllers/newcontroller/. This test class should extend ControllerTest?. The important method is runTest(). Here is an example, ProtogeniTest?.java

public class ProtogeniTest extends ControllerTest 
{

    ....

    public ProtogeniTest(String[] args)
    {
        super(args);
    }

    ....

    protected void runTest()
    {
        System.out.println("Inside runTest()");
        try {
            prepare();
            ProtogeniController cont = (ProtogeniController)getController();
            assert cont != null;
            System.out.println("Protogeni Controller started successfully");
            ....

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Test failed");
            System.exit(-1);
        }
    }

    ....

    public static void main(String[] args) throws Exception
    {
        if (args.length > 0) {
            ProtogeniTest test = new ProtogeniTest(args);
            test.run();
        } else {
            System.out.println("Insufficient arguments");
        }
    }

}