[Suggestion: Do not cut-paste this directly from a web browser, since some of the code characters may not correctly show up (e.g. the "less-than" operator). Rather, using an editor, grab this section of the html file itself, and save it as JIntPoller.java.]
package OPUS.UTIL; import OPUS.OPUS_API.*; // CORBA OAPI support import OPUS.OPUS_API.BB.*; // CORBA Blackboard import OPUS.OPUS_API.OPUSUSER.*; // CORBA application services import OPUS.UTIL.Msg; // Message reporting ////////////////////////////////////////////////////////////////////////// // // An OPUS Java Internal Poller w/ message reporting & resource value // fetches using an OSF trigger. // // The process resource file for this application is decribed in the // OPUS FAQ under "OPUS Applications" -> "Can I create an internal poller // in a language besides C++ ?" -> "Java" // // Note that, although some C++ internal pollers are able to be run // independently (on the command-line), this example cannot, because // it requires the stringified IOR to be passed to it by an OPUS server. // That is how it gains a PipelineAppContext which gives it access to OPUS // resources, whereas C++ apps simply use an Opus_env object for this. // Therefore this example can only be run via the PMG or the broker. // // Modification History: // // Date PR Who Reason // --------- -------- ----------- ---------------------------------------- // 09/20/02 46438 Sontag First version, based on OAPI doc // 02/12/04 49903 Sontag Add use of Event.eventName // 07/28/04 49860 Sontag Rename member for tao_idl keyword clash // 01/21/05 52462 Sontag Use a 100% Java message class // ////////////////////////////////////////////////////////////////////////// class JIntPoller { // // The dataset processing routine - this is where the OPUS user's work is // actually performed. Put task-specific processing here. // private static void processDataset(final String dataset) throws Exception { Msg msgObj = Msg.getInstance(); msgObj.print("Serious processing being done on: " + dataset + "..."); Thread.sleep(5000); // 5 secs } // // The main routine. // public static void main(String[] args) { // Get the message reporting object. It is a singleton, so the // static method getInstance() is the only way to obtain a // reference (ie., no constructors are public). Msg msgObj = Msg.getInstance(); // Must handle message report level manually (at least for now) msgObj.setReportLevel(Msg.ReportLevel.ALL); // Initialize the CORBA orb (this is always the same) org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null); // Need to grab the -i option from the command line: it has // the object reference for the UserContext CORBA object. String ior = null; for(int i = 0; i < args.length; ++i) { if (args[i].equals("-i")) { ior = args[++i]; break; } } if (ior == null) { msgObj.print(Msg.Severity.E, Msg.Type.MISSING, "IOR not found on command-line"); System.exit(0); } // Convert the stringified object reference to a CORBA object org.omg.CORBA.Object obj = orb.string_to_object(ior); // Narrow the object to its actual type (like a cast) UserContext uc = UserContextHelper.narrow(obj); if (obj == null) { msgObj.print(Msg.Severity.E, Msg.Type.MISSING, "IOR not found on command-line"); System.exit(0); } // Use the UserContext object to "register" this application with OPUS. // Must do for internal pollers; xpoll does this for external pollers. String[] cargs = new String[args.length + 1]; cargs[0] = "JIntPoller"; // note you must create the C-like 0th // argument for registerPipelineApp() System.arraycopy(args, 0, cargs, 1, args.length); PipelineAppContext papp = null; try { msgObj.print("About to register pipeline application..."); papp = uc.registerPipelineApp(cargs); msgObj.print("Registered successfully"); } catch(Exception e) { msgObj.print(Msg.Severity.E, Msg.Type.SEVERE, "Attempt to register application with UserContext failed:\n" + e.toString()); System.exit(0); } // As an example of fetching values from the process resource file, // get all key/val pairs. Just an example, this is not required. KeyValPair[] res = null; try { res = papp.getResourceClass("*.*"); // or, e.g. "OSF_SUCCESS." } catch(Exception e) { msgObj.print(Msg.Severity.E, Msg.Type.FIO, "An error occured while attempting to fetch resource values"); System.exit(0); } // Print out resources msgObj.print("The key/val pairs from the process resource file:\n"); for (int i = 0; i < res.length; ++i) { msgObj.print(res[i].key + " = " + res[i].val); } msgObj.print("\n"); // Event-handling loop for internal pollers only. Unlike C++, there // is no callback scheme for the events. You must determine the event // type and handle it accordingly. Event anEvent = null; while (true) { try { anEvent = papp.poll(); // Can print this diagnostic message: msgObj.print(Msg.Severity.D, Msg.Type.INFO, "Got an event, id: " + anEvent.eid + ", name: " + anEvent.eventName); } catch (Exception ex) { msgObj.print(Msg.Severity.E, Msg.Type.SEVERE, "An error occured during polling:\n" + ex.toString()); System.exit(1); } // // Determine event type and handle appropriately // if (anEvent.theEventType == EVENT_TYPE.HALT) { msgObj.print("Received HALT event. Stopping."); System.exit(0); // exit } // This Java example includes the code to handle both a FILE // trigger and an OSF trigger, though the OSF trigger section // farther below is the focus of this example. else if (anEvent.theEventType == EVENT_TYPE.FILE) { // If file contains "bad", set FILE_ERROR, otherwise, file success // Get special entry that contains fields with the // field names, sizes, id's from blackboard state BBStateInfo bbData = anEvent.bb.getState(); // Locate ROOTNAME field int rootnameID = -999; int dirnameID = -999; for (int i = 0; i < bbData.entryInfo.length; ++i) { if (bbData.entryInfo[i].value.equals("ROOTNAME")) { rootnameID = bbData.entryInfo[i].id; break; } } for (int i = 0; i < bbData.entryInfo.length; ++i) { if (bbData.entryInfo[i].value.equals("DIRECTORY")) { dirnameID = bbData.entryInfo[i].id; break; } } if (rootnameID == -999) // something wrong: not file entry { msgObj.print(Msg.Severity.E, Msg.Type.MISUSE, "File event contains non-file entry!"); System.exit(1); } if (dirnameID == -999) // something wrong: not file entry { msgObj.print(Msg.Severity.E, Msg.Type.MISUSE, "File event contains non-file entry!"); System.exit(1); } // Get dataset name from event trigger String dataset = "unknown"; for (int i = 0; i < anEvent.triggers[0].length; ++i) { Field[] ent = anEvent.triggers[0]; if (ent[i].id == rootnameID) { dataset = ent[i].value.trim(); // rm trailing whitespace pad break; } } // Starting message msgObj.print("--- Processing started for: " + dataset + " ---"); // Check for "bad" in the dataset name, otherwise process it try { if (dataset.indexOf("bad") >= 0) { papp.closeEvent("FILE_ERROR", anEvent.eid); } else { // Normal looking rootname, lets process the data processDataset(dataset); // Close event with success papp.closeEvent("FILE_SUCCESS", anEvent.eid); } } catch(Exception ex) { msgObj.print(Msg.Severity.E, Msg.Type.EXEC, "Error closing file event"); } // Completion message msgObj.print("--- Processing completed for: " + dataset + " ---"); } // Handle an OSF trigger, as in our example usage. else if (anEvent.theEventType == EVENT_TYPE.OSF) { // Get special entry that contains fields with the // field names, sizes, id's from blackboard state BBStateInfo bbData = anEvent.bb.getState(); // Locate DATASET field int datasetID = -999; for (int i = 0; i < bbData.entryInfo.length; ++i) { if (bbData.entryInfo[i].value.equals("DATASET")) { datasetID = bbData.entryInfo[i].id; break; } } if (datasetID == -999) // something wrong: not osf entry { msgObj.print(Msg.Severity.E, Msg.Type.MISUSE, "OSF event contains incorrect entry!"); System.exit(1); } // Get dataset name from event trigger String dataset = "unknown"; for (int i = 0; i < anEvent.triggers[0].length; ++i) { Field[] ent = anEvent.triggers[0]; if (ent[i].id == datasetID) { dataset = ent[i].value; // This value comes with a suffix of underscores // which we remove to get the dataset name. while (dataset.endsWith("_") && dataset.length() > 1) { // this is not the most efficient algorithm, but it // serves the example well enough dataset = dataset.substring(0, dataset.length()-1); } break; } } // Starting message msgObj.print("--- Processing started for: " + dataset + " ---"); // Everything looks good, lets process the data boolean success = true; try { processDataset(dataset); } catch(Exception ex) { msgObj.print(Msg.Severity.E, Msg.Type.EXEC, "Error processing dataset:\n" + ex.toString()); success = false; } // Now close the event try { if (success) papp.closeEvent("OSF_SUCCESS", anEvent.eid); else papp.closeEvent("OSF_ERROR", anEvent.eid); } catch(Exception ex) { msgObj.print(Msg.Severity.E, Msg.Type.EXEC, "Error closing osf event"); } // Completion message msgObj.print("--- Processing completed for: " + dataset + " ---"); } else // all others ignore { msgObj.print(Msg.Severity.W, Msg.Type.BADVAL, "Unhandled event type received; ignoring"); try { papp.closeEvent("IGNEVT", anEvent.eid); } catch(Exception ex) { msgObj.print(Msg.Severity.E, Msg.Type.EXEC, "Error closing unhandled event"); } } // checks on theEventType } // event loop / while loop } // main() }
!-------------------------------------------------------------------- ! ! An OPUS Java Internal Poller example with resource value fetches, ! using an OSF trigger ! !-------------------------------------------------------------------- ! PROCESS_NAME = jpoller TASK = < java -classpath $OPUS_CLASSPATH OPUS.UTIL.JIntPoller -p $PATH_FILE -r jpoller -ssrl INFO > DESCRIPTION = 'Example Java Internal Poller' SYSTEM = SAMPLE CLASS = ALL ! OSF_RANK = 1 ! Sets this to use an OSF trigger OSF_TRIGGER1.KW = w ! when OSF column KW = "w" (waiting) OSF_PROCESSING.KW = p ! then set column KW to "p" when triggered OSF_SUCCESS.KW = c ! then set column KW to "c" on success OSF_SUCCESS.HD = w ! then set column HD to "w", to start it OSF_ERROR.KW = e ! or to "e" if the process has a failure ! POLLING_TIME = 10 ! Wait (seconds) before polling for next MINBLOCKS = 2000 ! blocks required on output disk INPATH = input_data ! make INPATH available to process OUTPATH = success_dir ! check for space in success directory ERRPATH = error_dir ! make ERRPATH available to process ! ! And the path file should contain the following key-value pairs: ! ! STAGE_FILE = OPUS_DEFINITIONS_DIR:g2f_pipeline.stage ! OPUS_OBSERVATIONS_DIR = (set this to your OSF directory) ! input_data = (set this to the location of input files) ! success_dir = (set this to the dir to copy files on success) ! error_dir = (set this to the dir to copy files on error) !
OPUS: +++ opus_run_process.csh started +++ OPUS: OPUS: Pipeline Software Release OPUS xx.x SHARE x.x ********* dd Mon YYYY ********* OPUS: OPUS: Input parameters: OPUS: PROCESS_NAME = jpoller ODCL: PATH_FILE = /home/sontag/opus_test/definitions//quick.path ODCL: PATH_BASENAME = quick.path ODCL: PATH_BASEROOT = quick OPUS: TIME_STAMP = 41f1328f (date: 21-Jan-05 16:49:19) OPUS: PASSWORD? No OPUS: OPUS: Fetching TASK line from process resource file...(odcl_get_resource_command) OPUS: OPUS: OPUS: Task to be run: java (/usr/local/j2sdk1.4.2_03/bin/sparcv9/java) OPUS: OPUS: OPUS: Creating process PSTAT...(odcl_create_psffile) OPUS: OPUS: OPUS: Running the process... OPUS: 2005021164938-I-INFO About to register pipeline application... 2005021164938-I-INFO Registered successfully 2005021164938-I-INFO The key/val pairs from the process resource file: 2005021164938-I-INFO CLASS = ALL 2005021164938-I-INFO DESCRIPTION = Example Java Internal Poller 2005021164938-I-INFO ERRPATH = /home/sontag/opus_test/quick/error/ 2005021164938-I-INFO INPATH = /home/sontag/opus_test/quick/input/ 2005021164938-I-INFO MINBLOCKS = 2000 2005021164938-I-INFO OSF_ERROR.KW = e 2005021164938-I-INFO OSF_PROCESSING.KW = p 2005021164938-I-INFO OSF_RANK = 1 2005021164938-I-INFO OSF_SUCCESS.HD = w 2005021164938-I-INFO OSF_SUCCESS.KW = c 2005021164938-I-INFO OSF_TRIGGER1.KW = w 2005021164938-I-INFO OUTPATH = /home/sontag/opus_test/quick/input/ 2005021164938-I-INFO POLLING_TIME = 10 2005021164938-I-INFO PROCESS_NAME = jpoller 2005021164938-I-INFO SYSTEM = SAMPLE 2005021164938-I-INFO TASK = < java -classpath $OPUS_CLASSPATH OPUS.UTIL.JIntPoller -p $PATH_FILE -r jpoller -ssrl INFO > 2005021164938-I-INFO 2005021183049-D-INFO Got an event, id: 1, name: OSF_TRIGGER1 2005021183049-I-INFO --- Processing started for: my_osf --- 2005021183049-I-INFO Serious processing being done on: my_osf... 2005021183054-I-INFO --- Processing completed for: my_osf --- 2005021183134-D-INFO Got an event, id: 2, name: halt 2005021183134-I-INFO Received HALT event. Stopping. OPUS: OPUS: Process exited. Cleaning up...(odcl_cleanup) OPUS: