N1 Grid Service Provisioning System 5.0 Plug-in Development Guide

Chapter 3 Using the Application Programming Interface

The N1 Grid Service Provisioning System includes a Java-based application programming interface (API) that you can use to further extend the functionality of the system. This chapter explains how you can use the classes and methods of the API. Detailed syntax for each class and method is provided in the JavadocTM information included with the provisioning system. The API provides several types of additional functionality:

Component APIs

The Java-based component APIs enable you to provide export and browse functionality for your plug-ins. You can enable users to be able to browse through directory structures and export files from within the N1 Grid Service Provisioning System browser interface.

com.sun.n1.sps.componentdb

This package provides two interfaces for working with the component database:

  • InstallMode – A strongly typed enumeration of component install modes

  • InstallMode.Factory – A factory interface for InstallMode enums

com.sun.n1.sps.plugin

This package contains one interface and three classes to support general plug-in related functionality:

  • AgentContext – This interface publishes services available to the plug-in code on a remote agent.

  • Logger – Use this high level wrapper class for logging in service provisioning projects.

  • PluginMessage – Instances of this class are used to internationalize messages within the plug-in implementations.

  • PluginException – Class representing any exception that uses a PluginMessage for its message resolution.

com.sun.n1.sps.plugin.browse

This package contains five interfaces and four classes that specify browse functionality:

  • Browser – This interface defines the set of functionality that any resource handler that wants to support browsing must export.

  • BrowserDisplay – This interface is used by the UI Browsing portion of the hierarchy manager to make the display more informative and correct.

  • BrowserFactory – This interface provides the interface for the loader to use to obtain an actual instance of the appropriate browser.

  • BrowserFilter – This interface describes how nodes can be filtered according to certain criteria.

  • BrowserNode – This interface defines the functionality for a browsable hierarchy node.

  • BrowserContext – This class provides a container for the client to set initial parameters for a browsing session.

  • BrowserInfo – This class describes the browser that is appropriate for display in the user interface and retrieval of actual instance from within the system.

  • BrowserNodeBase – This class provides a default implementation for the BrowserNode interface.

  • BrowserException – This class identifies typed exceptions to be thrown from within browsing sessions.

More information and examples for the browsing functionality are provided in Browsing Function.

com.sun.n1.sps.plugin.export

This package contains seven interfaces and one exception class for specifying component definition and creation functionality:

  • ComponentExporter – All plug-ins must implement this base interface to construct a component from a browse process.

  • ComponentMonitor – Monitor created by the system that manages the component creation process for a given component.

  • ComponentToken – The token to represent a component for purposes of adding a contained component to a CompositeComponentMonitor.

  • CompositeComponentMonitor – The monitor for a component that contains other components.

  • ResourceProcessor – Allows for introspection of a resource.

  • SimpleComponentMonitor – Component monitor for components that contain a resource.

  • SystemData – Gives access to variables defined by various persistent system objects related to the current export and browse operations.

  • ComponentExportException – Strongly typed exception for use with errors related to component export.

More information and examples for the export functionality are provided in Exporting Function.

com.sun.n1.sps.resource

This package contains seven interfaces and one exception class for managing resources:

  • CheckInMode – A strongly typed enumeration for representing check in modes

  • CheckInMode.Factory – A factory interface for CheckInMode enumerations

  • ResourceEntry – Represents an entry within a resource

  • ResourceEntryIterator – An iterator for ResourceEntry objects

  • ResourceManifest – A manifest that describes the resource

  • ResourceType – A strongly typed enumeration for representing resource types

  • ResourceType.Factory – A factory interface for ResourceType enumerations

  • ResourceException – Typed exceptions thrown from error conditions related to resources

com.sun.n1.util

This package provides one interface and three additional packages for managing utilities:

  • RPCSerializable – This interface marks objects that can be serialized by RPC.

  • com.sun.n1.util.enum – This package contains two interfaces and one exception class:

    • Enum – An interface for strongly typed enumerations

    • Enum.Factory – Enables a client to look up all values defined for a particular Enum subclass, and also to look up a particular value by its integer or string value

    • NoSuchEnumException – Exception class indicating that an enumeration lookup failed

  • com.sun.n1.util.message – This package contains two interfaces:

    • Severity – A strongly typed enumeration for representing severities associated with messages

    • Severity.Factory – A factory interface for Severity enumerations

  • com.sun.n1.util.vars – This package contains three interfaces and three classes:

    • DisplayMode – A strongly-typed enumeration of display modes

    • DisplayMode.Factory – A factory interface for DisplayMode enumerations

    • VariableSettingsSource – Defines the interface for objects that can be used as a source of variable settings

    • PromptParam – A parameter that includes information about the structure of a prompt, including a textual prompt and a display mode

    • PromptParamList – A list of PromptParam objects

    • VariableSettingsHolder – An implementation of the VariableSettingsSource interface that can be used to specify variable name-value pairs

Browsing Function

The com.sun.n1.sps.plugin.browse package contains five interfaces and four classes that specify browse functionality:

Browser API Implementation

The Browser implementation includes the following key API segments:

BrowserFilter[] getAvailableFilters()

Returns the different filters this browser supports. Use the BrowserFilter interface to filter BrowserNodes based on particular criteria, for example, filter all files to show just *.tmp files.

BrowserDisplay getDisplay()

Gets the display properties object to be used with this browser.

BrowserNode getNode(java.lang.String location)

Returns a node in the hierarchy this browser represents.

void setFilterName(java.lang.String name)

Specifies the filter to be used while browsing.

BrowserNode Class

The BrowserNode class implements the entire hierarchy tree functionality. This functionality is segmented into four key areas:

BrowserFactory Interface

The BrowserFactory interface provides the interface for the HierarchyBrowserLoader to obtain an actual instance of the appropriate HierarchyBrowser.

To define a class which implements the BrowserFactory interface, use an API call similar to the following example:

Browser getBrowser(BrowserContext bContext,AgentContext aContext)

where:

The BrowserFactory implementation defines a getBrowser method with the system-supplied BrowserContext object and AgentContext objects as parameters.

In the backing component of the component type, declare the fully qualified class name of the browser factory in the browserClass variable. The following code fragment defines two browser factories for a backing component:

<var 
 access="PRIVATE" 
 name="EJBFileSystemBrowser" 
 default="com.raplix.rolloutexpress.plugins.weblogic.hierarchies.ejb.EJBFileBrowserFactory"
/> 
<var 
 access="PRIVATE" 
 name="EJBDomainBrowser" 
 default="com.raplix.rolloutexpress.plugins.weblogic.hierarchies.ejb.EJBDomainBrowserFactory"
/>

Sample Code for Browsing Function


Example 3–1 Browser Filter

The following example filters all files of the name *.tmp:

public class TmpFilter implements BrowserFilter, ExampleFilter {

    public String getName() {
        return "tmpFilter";
    }
    public String getDescription() {
        return "show only *.tmp files";
    }
    public boolean filter(ExampleBrowserNode node) {
        return node.getLocalName().endsWith(".tmp");
    }

}

Exporting Function

The com.sun.n1.sps.plugin.export package contains seven interfaces and one exception class for specifying component definition and creation functionality:

ComponentExporter Process

To enable an export function, use a process similar to the following sequence:

  1. In the backing component of the component type, declare the fully qualified class name of the componentExporter in the exporterClass variable.

    <varList>
      <var name="exporterClassName" 
        default="com.sun.n1.sps.pluginimpl.sample.export.StaticCompExporter"/>
    </varList>
  2. Define a class which implements the ComponentExporter interface.

    ComponentExporter calls the various methods on the ComponentMonitor input argument to build the component. These methods might include addComponentVar, addSourceInfoParam, setComponentDescription, and setComponentLabel.

    ComponentExporter can also call get routines to obtain information from the ComponentMonitor. These get routines might include getPluginComponentVars, getPluginHostVars, getActiveBrowser, getSourceInfoParam, and getLocation.

    ComponentExporter can also call exportResource to call into control blocks to execute component type-specific functionality for exporting the component.

  3. After constructing the component, the ComponentExporter can call setResource to set a physical resource to be bundled in the component, completing the export process.

ComponentExporter Example


Example 3–2 ComponentExporter

public class  implements ComponentExporter {

    public ExampleExporter() {

    }

    public BrowserContext getBrowserContext() {
        return new BrowserContext();
    }

    public BrowserInfo[] getAvailableBrowsers() {
        return new BrowserInfo[] {
            new BrowserInfo("example",             //relevant comp type
                            "Example Browser",     //browser ui display name
                            "example ss",          //relevant ss
                            null,                  //valid for all platforms
                            null,                  //no host set restriction
                            new PromptParamList()) //no checkin params
        };
    }

    public String getBrowserClassPath(BrowserInfo browser) {
        return null;
    }
public void constructComponent(ComponentMonitor mon) 
        throws ComponentExportException {

        //It's the responsibility of the infrastructure to  identify the type
        //of component and construct the component with the appropriate monitor
        SimpleComponentMonitor sMon = (SimpleComponentMonitor)mon;

      sMon.setComponentDescription("This is an example component");
        sMon.setComponentLabel("What the hell is a label for?");
        
        sMon.setResource(ResourceType.FILE,  //our sample type is a file
                         sMon.getLocation(), //get the location specified
                         false,              //do not use differential checkin
                         false,              //not a config template
                         false,              //file->symlinks meaningless
                         true,               //capture permissions
                         null,               //file->checkinmode meaningless
                         null);              //no special processing of rsrc
    }    
}

execJava API

execJava functionality is provided through the XML schema for plans and components. Through the XML, you can execute a piece of Java code as needed. In addition, execJava also exists as an API.

Both preflight and actual behavior may be specified. The classes are typically deployed using a JAR resource of a component. For more information about the execJava classes, methods, and interfaces, see the JavaDoc software.

<execJava
className= classname of the executor factory class
class Path=...
>

The execJava API is contained in the com.sun.n1.sps.plugin.execJava package. The execJava API consists of five interfaces and two exception classes:

ActualExecJavaContext

This interface publishes the services available to the execJava implementations when they are invoked during the deployment or actual phase of the execution.

ExecJavaContext

This interface provides an execution context to an execJava implementation that is common to both the preflight and actual run levels.

Executor

This interface is implemented by classes that need to execute code on the agent through execJava

ExecutorFactory

This interface is part of the infrastructure to execute arbitrary code on the remote agent using execJava steps.

PreflightExecJavaContext

This interface publishes the services available to the execJava implementations when they are invoked during the preflight phase of the execution.

ExecutionException

Instances of ExecutionException are used to flag failure or warnings from execJava invocations.

ExecutionTimeoutException

Instances of this exception are thrown when execJava execution is timed out.

ExecutorFactory Interface

The ExecutorFactory interface is used to obtain the preflight and actual executor instances for a particular step:

Executor getActualExecutor(AgentContext callContext)
Executor getPreflightExecutor(AgentContext callContext)

The call context passed between preflight and actual execution steps need not be the same.

AgentContext Method

The AgentContext method provides an invocation context on a particular remote agent.

VariableSettingsHolder getVariables()
    // Returns the variables passed to the execJava step using <argList>

PrintStream getStandardOutput()
PrintStream getStandardError()
InputStream getStandardInput()
File getWorkingDir()

Executor Interface

The Executor interface provides an entry point that is used to execute the step body:

void execute() throw ExecutionException

Execution output and error output are written into the stdout and stderr streams of the associated agent context. Input is read from the input stream of the associated agent context. Errors are reported by calling an instance of the ExecutionException class.

execJava Examples


Example 3–3 execJava in Java Code

public class StopServerFactory extends WLFactoryBase {
    
    public static final String TARGET = "serverName";
    
    public Executor 
        getActualExecutor(AgentContext inAgentContext, ActualExecJavaContext inContext) 
        {

        VariableSettingsSource variableSettings = inContext.getVariableSettings();
        String target = variableSettings.getVarValue(TARGET);
        return new StopServerExecutor(getConnect(variableSettings), target);
    }
    
    public VariableSettingsSource getParams() {
        VariableSettingsHolder list = getWLParams();
        list.setVarValue(TARGET, null);
        return list;
    }

}
public class StopServerExecutor implements Executor {
    private WLConnect mConnect;
    private String mTarget;

    /**
     *
     **/
    public StopServerExecutor(WLConnect connect, String target) {
           mConnect = connect;
           mTarget = target;
    }

    /**
     *
     **/
    public void execute() throws ExecutionException {

  try {
    WLAdminServer server = new WLAdminServer(mConnect);
    server.stopServer(server.getServer(mTarget));
    } 
catch (Exception e) {
    throw new ExecutionException
    (new PluginMessage(WLPluginHierarchyException.MSG_WEBLOGIC_ERROR), e);
    }
  }
}


Example 3–4 Another execJava Code Sample

public class SampleExecutorFactory implements ExecutorFactory
{
    public Executor getActualExecutor(AgentContext inAgentContext, 
           ActualExecJavaContext inActualExecJavaContext)
    {
        return new EnvParamSettingActualExecutor(inActualExecJavaContext);
    }

    public Executor getPreflightExecutor(AgentContext inAgentContext,
           PreflightExecJavaContext inPreflightExecJavaContext)
    {
        return new EnvParamSettingPreflightExecutor(inPreflightExecJavaContext);
    }

    public VariableSettingsSource getParams()
    {
        VariableSettingsHolder params = new VariableSettingsHolder();
        params.setVarValue(PARAM_NAME, "");
        params.setVarValue(PARAM_VALUE, "");
        return params;
    }

    public static final String PARAM_NAME = "nameParam";
    public static final String PARAM_VALUE = "valueParam";
}
public class EnvParamSettingPreflightExecutor implements Executor
{
    VariableSettingsSource mVars;
    public EnvParamSettingPreflightExecutor
           (PreflightExecJavaContext inPreflightExecJavaContext)
    {
        mVars = inPreflightExecJavaContext.getVariableSettings();
    }

    public void execute() throws ExecutionException
    {
        String propName = mVars.getVarValue(SampleExecutorFactory.PARAM_NAME);
        if("".equals(propName)) {
            throw new ExecutionException(new PluginMessage("sample.noNameParam"));
        }

        String propValue=System.getProperty(propName);
        if(!(propValue == null || "".equals(propValue))) {
            // property already set, error out
            throw new ExecutionException(new PluginMessage("sample.propAlreadySet",
                                        new String[]{propName, propValue}));
        }
    }
}

public class EnvParamSettingActualExecutor implements Executor
{
    VariableSettingsSource mVars;
    public EnvParamSettingActualExecutor(ActualExecJavaContext inCtx)
    {
        mVars  = inCtx.getVariableSettings();
    }

    public void execute() throws ExecutionException
    {
        String propName = mVars.getVarValue(SampleExecutorFactory.PARAM_NAME);
        String propValue = mVars.getVarValue(SampleExecutorFactory.PARAM_VALUE);
        System.setProperty(propName, propValue);
        if(Logger.isDebugEnabled(this)) {
            Logger.debug("Setting prop "+propName + " to " + propValue, this);
        }
        System.out.println("Setting prop "+propName + " to " + propValue);
    }
}