Developing Server Object Extensions


Summary This document is intended to familiarize the developer with the relevant objects and concepts related to Server Object Extensions. We will first introduce concepts required to gain an understanding of the objects you work with when developing SOE's then create a Hello World SOE using the Eclipse plug-in SOE template. Further documentation will discuss administrative tasks as well as developing client applications to consume Server Objects extended with SOE's.

Working with SOE Objects

You can define your own SOE by implementing com.esri.arcgis.server.IServerObjectExtension
This mandatory interface must be supported by all SOE’s, and includes two methods: init() and shutdown(). This interface is used by the Server Object to manage the lifetime of the SOE.  The Server Object creates the SOE and calls the init() method handing it back a reference to the Server Object via the Server Object helper argument. The Server Object helper implements a weak reference, one that is not protected from collection of the garbage collector, on the Server Object.  The extension can keep a strong reference on the Server Object helper (for example, in a member variable) but should not keep a strong reference on the Server Object as this can cause unnecessary objects to remain in memory and hinder performance.  Extensions should get the Server Object from the Server Object helper in order to make any method calls on the Server Object and release the reference after making the method calls.  The init() method is called once, when the instance of the SOE is created.
The shutdown() method is called once and informs the SOE that the Server Object's context is being shut down and is about to go away.  In response the SOE should release its reference on the Server Object helper.  Any log entries are merely informative and completely optional.

SOE Pattern

A common pattern for developing SOE’s is to create a SOE class which implements the mandatory IServerObjectExtension interface and a custom ArcGIS Extension Interface which provides your SOE’s custom features.  Your SOE implements specific ArcObject Interfaces to provide specialized functionality and a custom ArcGIS Extension Interface for the business logic.  This pattern will allow clients to access the methods exposed by your SOE remotely.  Below is a basic diagram of the pattern using a mock SOE class and ISoeInterface interface. 

SOE Annotations

At ArcGIS 10, SOE’s support two types of annotations to supply metadata to ArcGIS Server:
  1. @ArcGIS Extension
 
An @ArcGISExtension annotation indicates that the annotated interface or class is automatically exposed to the ArcGIS platform as an extension of ArcObjects.  The @ArcGISExtension annotation is used by the ArcGIS platform as way to associate your interface and classes as extensions without the need for any configuration or programmatic API calls embedded in some external source.  The following is an example of an annotated interface and class for a SOE: 
[Java]
// Custom Interface
@ArcGISExtension public interface ISoeInterface{
    public void mySoeFoo();
}

// SOE class
@ArcGISExtension public class SOE implements IServerObjectExtension, IMySoeInterface{
    // IServerObjectExtension 
    public void init(IServerObjectHelper arg0)throws IOException,
        AutomationException{
        // Called once when the instance of the SOE is created
    }
    public void shutdown()throws IOException, AutomationException{
        // Called once when the SOE’s context is shut down
    }
    public void mySoeFoo(){
        // Instantiate custom interface
    }
}
  1. @ServerObjectExtProperties
An @ServerObjectExtProperties annotation is required by SOE classes to pass compile time element-value pairs to ArcGIS server when you add your SOE to a Map Server Object using SOEManager.  Setting these element-value pairs at design time eliminates the need to have an external properties file in ArcGIS Manager and simplifies the SOEManager tool usage. 
The following element-pairs are supported:
  1. displayName – This is the display name your SOE will have when users enable it as a capability in an ArcGIS Server Admin client. 
  2. description – This is  used to describe your SOE and will show up in an ArcGIS Server Admin client to help administrators understand the usage intended by your SOE.
  3. properties – This is where you can define properties on your SOE.
  4. defaultSOAPCapabilites– When exposing your SOE as a SOAP based Web Service, you can create Web Capabilities.  This parameter lists the default Web Capability.   
  5. allSOAPCapabilities - When exposing your SOE as a SOAP based Web Service, you can create Web Capabilities.  This parameter lists all Web Capabilites. 
[Java]
// SOE class
@ArcGISExtension 

@ServerObjectExtProperties(displayName = "My SOE", description = "My first SOE",
    properties = {}
, defaultSOAPCapabilities = {
    "mySoeFoo1"
}

, allSOAPCapabilities = {
    "mySoeFoo1", "mySoeFoo2"
}

)

public class SOE implements IServerObjectExtension, IMySoeInterface{
    // IServerObjectExtension 
    public void init(IServerObjectHelper arg0)throws IOException,
        AutomationException{
        // Called once when the instance of the SOE is created
    }
    public void shutdown()throws IOException, AutomationException{
        // Called once when the SOE’s context is shut down
    }
    public void mySoeFoo(){
        // Instantiate custom interface
    }
}

Optional Interfaces and Classes

 
Optional interfaces your Java SOE can implement include com.esri.arcgis.system.IObjectConstruct, com.esri.arcgis.system.IObjectActivate, and com.esri.arcgis.systemIRequestHandler which we detail below. 
IObjectConstruct

If your SOE includes configuration properties or requires any additional initialization logic, you need to implement IObjectConstructIObjectConstruct is an optional interface for SOE’s. The interface includes a single method called construct().  The construct() method is called only once, when the SOE is created, after IServerObjectExtension.init() is called.  You should include any expensive initialization logic within your implementation of the construct() method.
Construct hands back the configuration properties for the SOE as a property set. The configuration properties are stored in the Server Object configuration file.  Configuration files are named <service name>.<server object type>.cfg and stored on the SOM machine in the '<ARCGISHOME>\server\user\cfg directory'. For example, a map service named Yellowstone has a configuration file named Yellowstone.MapServer.cfg.  Properties of SOE’s configured for use with a Server Object are also stored in the *.cfg file.  In this example, a set of properties are being read from the service configuration file.  The property values, a feature layer name and field name, are validated to confirm they exist in the default map frame associated with the map Server Object.  If an error occurs, the appropriate log entries are added.

 
IObjectActivate

While IServerObjectExtension.init() and IObjectConstruct.construct() are called once when the instance of the SOE is created, if your SOE requires logic to run each time its server context is acquired and released (each time a client calls IServerObjectManager.createServerContext() and IServerContext.releaseContext()), you need to implement IObjectActivate.   IObjectActivate is an optional interface for SOE’s that includes two methods, activate() and deactivate().  The activate() method is called each time a client calls CreateServerContext() on the SOE’s Server Objects’s context, and deactivate() is called each time a client releases the context.  Considering activate() and deactivate() are called each time a client gets and releases the Server Object's context, any logic you implement in these methods should not be expensive. In this scenario, we merely add some instructive information to the log file to indicate the method was called.
SOAPRequestHandler

If you plan on exposing your SOE as a Web Service you must extend the SOAPRequestHandler base class in your SOE class.  The SOAPRequstHandler has a handleStringRequest() method implementation of the IRequestHandler interface which takes SOAP requests and invokes the method from the base class.  This is discussed in more detail in the Developing SOE SOAP Web Services document. 
IRESTRequestHandler
If you plan on exposing your SOE as RESTful Web Service you must implement the IRESTRequestHandler interface.  The interface provides two methods:
  1. handleRESTRequest()
  2. getSchema()
This is discussed in more detail in the 'Developing SOE REST Web Services' document. 

Logging

The ArcGIS Server logs events that occur in the server, and any errors associated with those events, to log files. Events such as when services are started, when services go into use (also called server context creation), and when machines are added to the server are some of the examples of events logged by the server.
The server object manager (SOM) is the centralized logging mechanism for ArcGIS server. Through the SOM, all events that occur within the SOM, events that occur in server object containers (SOCs), and their contained services are logged by the SOM.
The logs are actually a pair of files: an XML file and a .dat file. The XML file contains the <log> tags, and the .dat file contains the messages that are constantly being appended. You can open the XML file in any XML aware tool to view the messages in the .dat file.
By default, these log files are written to '%AGSSERVERJAVA%\server\user\log' on the SOM machine. Each time the SOM service starts, a new log file is created, and the server will continue to write messages to that log until it reaches the maximum log size. Once the log file exceeds the maximum size, it is retired and a new log file is created. By default, the maximum log size is 10 megabytes.
All SOE’s have the option to log messages to ArcGIS Server’s log file.  In Java, this is accomplished through the ServerUtilities class.  ServerUtilities is an optional class for SOE’s that has a single getServerLogger() method which returns a handle to ArcGIS Server’s log file via the ILog2 interface.  If you want your SOE to log messages to ArcGIS Server's log file, your SOE must write to the Server’s log file through the ILog2 interface returned from this method. 

Once you have a reference to the server log, you will often call a single method, AddMessage(), to add information to the log.  The AddMessage() method signature and explanation is offered below:
The msgType paramater is the level of detail of the message in relation to other messages.  Levels are classified from 1 to 5 and termed, in order, Error, Warning, Normal, Detailed, and Debug.  ArcGIS Server log file settings determine which messages are included in the server log.
The msgcode parameter is the result code associated with the message. The code is an arbitrary integer value to uniquely define the source of the message. Codes 0 - 5999 are utilized by the SOM. Codes 6000 and above can be generated by any serviced component (e.g. MapServer, GeocodeServer, custom component, etc.).
The msg parameter is the custom string inserted into the GIS server log file.
Log messages can vary in their level of severity from "error", which indicates a problem that requires immediate attention, to "detailed", which is a common message generated through regular use of the server. The messages that are logged are defined by the log level that is set in the server. The following are the ArcGIS Server's logging levels:
0 (None): No logging
1 (Error): Serious problems that require immediate attention are logged.
2 (Warning): Problems that require attention and errors are logged.
3 (Normal): Common administrative messages of the server, warnings, and errors are logged.
4 (Detailed): Common messages from user use of the server, including server services, normal messages, warnings, and errors are logged.
5 (Debug): Verbose messages to aid in troubleshooting; detailed messages, normal messages, warnings, and errors are logged.
By default, the log level of the server is set to level 3 (Normal), meaning messages whose severity is Error, Warning, or Normal will be logged. All messages whose level is Detailed or Debug are not logged.