001/* 002 * Copyright (c) 2012 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2015-11-23 20:26:17 +0000 (Mon, 23 Nov 2015) $' 007 * '$Revision: 34244 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.kepler.ddp; 031 032import java.io.File; 033import java.lang.management.ManagementFactory; 034import java.util.ArrayList; 035import java.util.Arrays; 036import java.util.LinkedList; 037import java.util.List; 038import java.util.ResourceBundle; 039 040import org.apache.commons.logging.Log; 041import org.apache.commons.logging.LogFactory; 042import org.kepler.configuration.ConfigurationManager; 043import org.kepler.configuration.ConfigurationProperty; 044import org.kepler.ddp.actor.pattern.stub.StubBaseActor; 045import org.kepler.ddp.director.DDPEngine; 046import org.kepler.provenance.ProvenanceRecorder; 047import org.kepler.reporting.ReportingListener; 048 049import au.edu.jcu.kepler.hydrant.DisplayRedirectFilter; 050import ptolemy.actor.CompositeActor; 051import ptolemy.actor.Director; 052import ptolemy.actor.ExecutionListener; 053import ptolemy.actor.IORelation; 054import ptolemy.actor.Manager; 055import ptolemy.actor.TypedIOPort; 056import ptolemy.actor.injection.ActorModuleInitializer; 057import ptolemy.actor.injection.ActorModuleInitializer.Initializer; 058import ptolemy.actor.injection.PtolemyInjector; 059import ptolemy.actor.injection.PtolemyModule; 060import ptolemy.data.DoubleToken; 061import ptolemy.data.IntToken; 062import ptolemy.data.LongToken; 063import ptolemy.data.RecordToken; 064import ptolemy.data.StringToken; 065import ptolemy.data.Token; 066import ptolemy.data.type.BaseType; 067import ptolemy.data.type.RecordType; 068import ptolemy.data.type.Type; 069import ptolemy.domains.ddf.kernel.DDFDirector; 070import ptolemy.domains.sdf.kernel.SDFDirector; 071import ptolemy.kernel.util.Attribute; 072import ptolemy.kernel.util.IllegalActionException; 073import ptolemy.kernel.util.Nameable; 074import ptolemy.kernel.util.Workspace; 075import ptolemy.moml.MoMLParser; 076import ptolemy.moml.filter.BackwardCompatibility; 077import ptolemy.moml.filter.RemoveGraphicalClasses; 078 079/** A collection of utilities for DDP classes. The methods and fields in this 080 * class are not specific to a DDP engine. 081 * 082 * @author Daniel Crawl and Jianwu Wang 083 * @version $Id: Utilities.java 34244 2015-11-23 20:26:17Z crawl $ 084 * 085 */ 086 087public class Utilities { 088 089 /** Check the director and its iterations with the runWorkflowLifecyclePerInput value. 090 * If the director is SDF, this method changes the iterations based on the 091 * value in runWorkflowLifecyclePerInput. If the director is DDF, then 092 * runWorkflowLifecyclePerInput is changed to true. 093 * @param model the model to execute in the stub. 094 * @param runWorkflowLifecyclePerInput if true, the full lifecycle of the 095 * model will be executed for each input. If false, only one iteration of the 096 * model will be execute for each input. 097 * @return the (possibly changed) runWorkflowLifecyclePerInput value. 098 */ 099 public static boolean checkDirectorIterations(CompositeActor model, boolean runWorkflowLifecyclePerInput) { 100 101 Director director = model.getDirector(); 102 if(director instanceof SDFDirector) { 103 Token iterations; 104 // change the iterations based on runWorkflowLifecyclePerInput 105 if(runWorkflowLifecyclePerInput) { 106 iterations = IntToken.ONE; 107 } else { 108 iterations = SDFDirector.UNBOUNDED_INTTOKEN; 109 } 110 try { 111 ((SDFDirector)director).iterations.setToken(iterations); 112 } catch (IllegalActionException e) { 113 throw new RuntimeException("Error changing iterations for SDF director: " + 114 e.getMessage()); 115 } 116 } else if((director instanceof DDFDirector) && !runWorkflowLifecyclePerInput) { 117 runWorkflowLifecyclePerInput = true; 118 String message = "Sub-workflow " + model.getName() + 119 " uses DDF director, but runWorkflowLifecyclePerInput is false;" + 120 " this is not supported so changing runWorkflowLifecyclePerInput to true."; 121 System.out.println("WARNING: " + message); 122 LOG.warn(message); 123 } else { 124 String message = "Unexpected director in sub-workflow " + 125 model.getName() + ": " + director.getClass().getName() + 126 ". The sub-workflow may not execute correctly."; 127 System.out.println("WARNING: " + message); 128 LOG.warn(message); 129 } 130 131 return runWorkflowLifecyclePerInput; 132 } 133 134 /** Create a Manager for a model and optionally start execution. 135 * @param model the workflow 136 * @param listener an ExecutionListener to register with the Manager to 137 * receive error messages. 138 * @param stubSource the source actor in the model 139 * @param stubSink the sink actor in the model 140 * @param runWorkflowLifecyclePerInput if true, execute the full lifecycle of the 141 * model for each input and the stub must tell the manager to execute the 142 * model. If false, this method starts execution. 143 * @param enablePrintTimeAndMemory if true, print an execution summary each time 144 * the model executes. 145 */ 146 public static Manager createManagerForModel(CompositeActor model, ExecutionListener listener, 147 StubBaseActor stubSource, StubBaseActor stubSink, boolean runWorkflowLifecyclePerInput, 148 boolean enablePrintTimeAndMemory) { 149 150 Manager manager = null; 151 152 // create manager and add model 153 try { 154 manager = new Manager(model.workspace(), "Manager"); 155 } catch(IllegalActionException e) { 156 throw new RuntimeException("Error creating Manager: " + e.getMessage()); 157 } 158 159 try { 160 model.setManager(manager); 161 } catch(IllegalActionException e) { 162 throw new RuntimeException("Error setting Manager for sub-workflow: " + e.getMessage()); 163 } 164 165 manager.enablePrintTimeAndMemory(enablePrintTimeAndMemory); 166 manager.addExecutionListener(listener); 167 168 if(runWorkflowLifecyclePerInput) { 169 stubSource.setRunWorkflowLifecyclePerInput(runWorkflowLifecyclePerInput); 170 stubSink.setRunWorkflowLifecyclePerInput(runWorkflowLifecyclePerInput); 171 } else { 172 try { 173 manager.startRun(); 174 } catch (Exception e) { 175 throw new RuntimeException("Error starting sub-workflow.", e); 176 } 177 } 178 179 return manager; 180 } 181 182 /** Load the model for a stub from a Nephele Configuration. The 183 * top-level ports and connected relations are removed. 184 */ 185 public static synchronized CompositeActor getModel(String modelName, 186 String modelString, String modelFile, boolean sameJVM, String redirectDir) { 187 188 CompositeActor model = null; 189 190 if(modelName == null) { 191 throw new RuntimeException("Subworkflow name was not set in configuration."); 192 } 193 194 if(sameJVM) { 195 196 CompositeActor originalModel = DDPEngine.getModel(modelName); 197 try { 198 model = (CompositeActor) originalModel.clone(new Workspace()); 199 } catch (CloneNotSupportedException e) { 200 throw new RuntimeException("Error cloning subworkflow: " + e.getMessage()); 201 } 202 203 Utilities.removeModelPorts(model); 204 205 // create an effigy for the model so that gui actors can open windows. 206 DDPEngine.createEffigy(model); 207 208 } else { 209 210 List<?> filters = MoMLParser.getMoMLFilters(); 211 212 Workspace workspace = new Workspace(); 213 final MoMLParser parser = new MoMLParser(workspace); 214 215 //parser.resetAll(); 216 217 MoMLParser.setMoMLFilters(null); 218 MoMLParser.setMoMLFilters(BackwardCompatibility.allFilters(), workspace); 219 220 if (redirectDir.isEmpty()) { 221 MoMLParser.addMoMLFilter(new RemoveGraphicalClasses(), workspace); 222 } else { 223 //redirect display-related actors 224 final String pid = ManagementFactory.getRuntimeMXBean().getName(); 225 final String threadId = String.valueOf(Thread.currentThread().getId()); 226 final String displayPath = redirectDir + File.separator + pid + "_" + threadId; 227 MoMLParser.addMoMLFilter(new DisplayRedirectFilter(displayPath), workspace); 228 final ArrayList<PtolemyModule> actorModules = new ArrayList<PtolemyModule>(); 229 actorModules.add(new PtolemyModule(ResourceBundle 230 .getBundle("org/kepler/ActorModuleBatch"))); 231 Initializer _defaultInitializer = new Initializer() { 232 @Override 233 public void initialize() { 234 PtolemyInjector.createInjector(actorModules); 235 } 236 }; 237 ActorModuleInitializer.setInitializer(_defaultInitializer); 238 } 239 240 // get the model from the configuration 241 242 // see if model is in the configuration. 243 if(modelString != null) { 244 245 try { 246 model = (CompositeActor)parser.parse(modelString); 247 } catch (Exception e) { 248 throw new RuntimeException("Error parsing model " + modelName + 249 ": " + e.getMessage()); 250 } 251 252 //LOG.info("parsed model from " + modelString); 253 254 } else { 255 256 // the model was saved as a file. 257 258 if(modelFile == null) { 259 throw new RuntimeException("No model for " + modelName + 260 " in configuration."); 261 } 262 263 // load the model 264 try { 265 model = (CompositeActor)parser.parseFile(modelFile); 266 } catch (Exception e) { 267 e.printStackTrace(); 268 throw new RuntimeException("Error parsing model " + modelName + 269 " in file " + modelFile + ": " + e.getMessage()); 270 } 271 272 LOG.info("parsed model from " + modelFile); 273 } 274 275 // restore the moml filters 276 MoMLParser.setMoMLFilters(null); 277 MoMLParser.setMoMLFilters(filters); 278 279 // remove provenance recorder and reporting listener 280 final List<Attribute> toRemove = new LinkedList<Attribute>( 281 model.attributeList(ProvenanceRecorder.class)); 282 toRemove.addAll(model.attributeList(ReportingListener.class)); 283 for(Attribute attribute : toRemove) { 284 try { 285 attribute.setContainer(null); 286 } catch (Exception e) { 287 throw new RuntimeException("Error removing " + attribute.getName() + 288 ": " + e.getMessage()); 289 } 290 } 291 292 } 293 294 return model; 295 } 296 /** Remove top-level ports and relations from a composite actor. */ 297 public static void removeModelPorts(CompositeActor model) { 298 299 // get a copy of the list since we modify the original when ports 300 // are removed. 301 final List<?> ports = new LinkedList<Object>(model.portList()); 302 for(Object object : ports) { 303 final TypedIOPort port = (TypedIOPort)object; 304 //final String name = port.getName(); 305 306 //LOG.info("going to replace port " + name + " in model."); 307 308 // NOTE: do not remove ports connected to the top-level ports, since 309 // their types are used to the the input/output types of the stub. 310 /* 311 final List<?> connectedPorts = new LinkedList<Object>(port.insidePortList()); 312 for(Object obj : connectedPorts) { 313 try { 314 ((IOPort)obj).setContainer(null); 315 } catch (Exception e) { 316 throw new RuntimeException("Error removing port " + 317 ((IOPort)obj).getFullName() + " from model: " + 318 e.getMessage()); 319 } 320 } 321 */ 322 323 /* 324 // print types of connected ports 325 final List<?> connectedPorts = new LinkedList<Object>(port.insidePortList()); 326 for(Object obj : connectedPorts) { 327 LOG.info("type for " + obj + " is " + ((TypedIOPort)obj).getType()); 328 } 329 */ 330 331 // remove relations 332 final List<?> connectedRelations = new LinkedList<Object>(port.insideRelationList()); 333 for(Object obj : connectedRelations) { 334 try { 335 ((IORelation)obj).setContainer(null); 336 } catch (Exception e) { 337 throw new RuntimeException("Error removing relation " + 338 "from model: " + e.getMessage()); 339 } 340 } 341 342 // remove the top-level port 343 try { 344 port.setContainer(null); 345 } catch (Exception e) { 346 throw new RuntimeException("Error removing port " + 347 port.getFullName() + " from model: " + e.getMessage()); 348 } 349 } 350 351 } 352 353 /** Create a Token from a string based on the Ptolemy Type. */ 354 public static Token createTokenFromString(String tokenStr, Type type) { 355 try { 356 if(type == BaseType.STRING) { 357 return new StringToken(tokenStr); 358 } else if(type == BaseType.INT) { 359 return new IntToken(tokenStr); 360 } else if(type == BaseType.DOUBLE) { 361 return new DoubleToken(tokenStr); 362 } else if(type == BaseType.LONG) { 363 return new LongToken(tokenStr); 364 } else if(type == BaseType.NIL) { 365 return Token.NIL; 366 } else if(type instanceof RecordType) { 367 return new RecordToken(tokenStr); 368 } else { 369 throw new RuntimeException("Unknown type of token: " + type); 370 } 371 } catch(IllegalActionException e) { 372 throw new RuntimeException("Error creating token.", e); 373 } 374 } 375 376 /** Create a Token from a string based on the TokenType enum. */ 377 public static Token createTokenFromString(String tokenStr, TokenType type) { 378 379 try { 380 switch(type) { 381 case String: 382 return new StringToken(tokenStr); 383 case Int: 384 return new IntToken(tokenStr); 385 case Double: 386 return new DoubleToken(tokenStr); 387 case Long: 388 return new LongToken(tokenStr); 389 case Nil: 390 return Token.NIL; 391 case Record: 392 return new RecordToken(tokenStr); 393 default: 394 throw new RuntimeException("Unknown type of token: " + type); 395 } 396 } catch(IllegalActionException e) { 397 throw new RuntimeException("Error creating token.", e); 398 } 399 } 400 401 /** Get the TokenType for a token. */ 402 public static TokenType getTokenTypeForSerialization(Token token) { 403 404 Type type = token.getType(); 405 406 if(type == BaseType.STRING) { 407 return TokenType.String; 408 } else if(type == BaseType.INT) { 409 return TokenType.Int; 410 } else if(type == BaseType.DOUBLE) { 411 return TokenType.Double; 412 } else if(type == BaseType.LONG) { 413 return TokenType.Long; 414 } else if(type == BaseType.NIL) { 415 return TokenType.Nil; 416 } else if(type instanceof RecordType) { 417 return TokenType.Record; 418 } else { 419 throw new RuntimeException("Serialization of Ptolemy type " + 420 type.toString() + " is unsupported."); 421 } 422 423 } 424 425 /** Get the ConfigurationProperty for an Engine on the configuration file. 426 * @param engineName The name of the ddp engine 427 * @param source The source object calling this method 428 * @return If found, returns the ConfigurationProperty. If not found, 429 * throws an exception. 430 */ 431 public static ConfigurationProperty getEngineProperty(String engineName, 432 Nameable source) throws IllegalActionException { 433 434 List<ConfigurationProperty> engineProperties = ConfigurationManager 435 .getInstance() 436 .getProperty(ConfigurationManager.getModule("ddp-common")) 437 .getProperties("Engines.Engine"); 438 439 if(engineProperties == null || engineProperties.isEmpty()) { 440 throw new IllegalActionException(source, "No DDP engines found."); 441 } 442 443 for(ConfigurationProperty engineProperty : engineProperties) { 444 ConfigurationProperty nameProperty = engineProperty.getProperty("Name"); 445 if(nameProperty == null) { 446 throw new IllegalActionException(source, "DDP Engine does not have a name. Try deleting\n" + 447 "$HOME/KeplerData/modules/ddp-common/configuration/configuration.xml\n" + 448 "and restarting Kepler."); 449 } 450 451 if (nameProperty.getValue().equalsIgnoreCase(engineName)) { 452 return engineProperty; 453 } 454 } 455 456 // not found 457 throw new IllegalActionException(source, 458 "No " + engineName + " Engine on configuration file."); 459 } 460 461 /** Get a list of available execution language names. */ 462 public static String[] getExecutionLanguageNames() throws IllegalActionException { 463 464 List<String> names = new ArrayList<String>(); 465 466 final List<ConfigurationProperty> languageList = ConfigurationManager 467 .getInstance() 468 .getProperty(ConfigurationManager.getModule("ddp-common")) 469 .getProperties("ExecutionLanguages.Language"); 470 471 for(ConfigurationProperty property : languageList) { 472 ConfigurationProperty nameProperty = property.getProperty("Name"); 473 if(nameProperty == null) { 474 throw new IllegalActionException( 475 "Missing name for execution language in configuration file."); 476 } 477 names.add(nameProperty.getValue()); 478 } 479 480 String[] array = names.toArray(new String[names.size()]); 481 Arrays.sort(array); 482 return array; 483 } 484 485 /** Get the jars for a language. Returns an empty list if there are non jars. */ 486 public static List<String> getJarsForLanguage(String languageName) throws IllegalActionException { 487 488 final List<ConfigurationProperty> languageList = ConfigurationManager 489 .getInstance() 490 .getProperty(ConfigurationManager.getModule("ddp-common")) 491 .getProperties("ExecutionLanguages.Language"); 492 493 for(ConfigurationProperty property : languageList) { 494 ConfigurationProperty nameProperty = property.getProperty("Name"); 495 if(nameProperty == null) { 496 throw new IllegalActionException( 497 "Missing name for execution language in configuration file."); 498 } 499 if(nameProperty.getValue().equals(languageName)) { 500 ConfigurationProperty jarsProperty = property.getProperty("Jars"); 501 if(jarsProperty != null) { 502 String jarsStr = jarsProperty.getValue(); 503 if(jarsStr != null) { 504 String[] jars = jarsStr.split(","); 505 return Arrays.asList(jars); 506 } 507 } 508 } 509 } 510 511 return new LinkedList<String>(); 512 513 } 514 515 /** Get the script engine name for a language. Returns null if the language 516 * is not found in the configuration, or is not supported by a script engine. 517 */ 518 public static String getScriptEngineName(String languageName) throws IllegalActionException { 519 520 final List<ConfigurationProperty> languageList = ConfigurationManager 521 .getInstance() 522 .getProperty(ConfigurationManager.getModule("ddp-common")) 523 .getProperties("ExecutionLanguages.Language"); 524 525 for(ConfigurationProperty property : languageList) { 526 ConfigurationProperty nameProperty = property.getProperty("Name"); 527 if(nameProperty == null) { 528 throw new IllegalActionException( 529 "Missing name for execution language in configuration file."); 530 } 531 if(nameProperty.getValue().equals(languageName)) { 532 ConfigurationProperty typeProperty = property.getProperty("Type"); 533 if(typeProperty == null) { 534 throw new IllegalActionException( 535 "Missing type for execution language " + 536 languageName + " in configuration file."); 537 } 538 if(typeProperty.getValue().equals("ScriptEngine")) { 539 ConfigurationProperty scriptEngineNameProperty = property.getProperty("ScriptEngineName"); 540 if(scriptEngineNameProperty == null) { 541 throw new IllegalActionException( 542 "Missing script engine name for execution language " + 543 languageName + " in configuration file."); 544 } 545 return scriptEngineNameProperty.getValue(); 546 } 547 } 548 } 549 // not found 550 return null; 551 } 552 553 /** Get the script engine factory name for a language. Returns null if the language 554 * is not found in the configuration, or is not supported by a script engine. 555 */ 556 public static String getScriptEngineFactoryName(String languageName) throws IllegalActionException { 557 558 final List<ConfigurationProperty> languageList = ConfigurationManager 559 .getInstance() 560 .getProperty(ConfigurationManager.getModule("ddp-common")) 561 .getProperties("ExecutionLanguages.Language"); 562 563 for(ConfigurationProperty property : languageList) { 564 ConfigurationProperty nameProperty = property.getProperty("Name"); 565 if(nameProperty == null) { 566 throw new IllegalActionException( 567 "Missing name for execution language in configuration file."); 568 } 569 if(nameProperty.getValue().equals(languageName)) { 570 ConfigurationProperty typeProperty = property.getProperty("Type"); 571 if(typeProperty == null) { 572 throw new IllegalActionException( 573 "Missing type for execution language " + 574 languageName + " in configuration file."); 575 } 576 if(typeProperty.getValue().equals("ScriptEngine")) { 577 ConfigurationProperty scriptEngineFactoryNameProperty = 578 property.getProperty("ScriptEngineFactoryName"); 579 if(scriptEngineFactoryNameProperty == null) { 580 throw new IllegalActionException( 581 "Missing script engine factory name for execution language " + 582 languageName + " in configuration file."); 583 } 584 return scriptEngineFactoryNameProperty.getValue(); 585 } 586 } 587 } 588 // not found 589 return null; 590 } 591 592 /** Returns true if an environment variable is set when 593 * executing under a resource manager such as PBS or SLURM. 594 */ 595 public static boolean isExecutingUnderResourceManager() { 596 // check PBS 597 return System.getenv("PBS_JOBID") != null || 598 // check SGE 599 System.getenv("PE_NODEFILE") != null || 600 // check SLURM 601 System.getenv("SLURM_JOBID") != null; 602 } 603 604 public static final String CONFIGURATION_KEPLER_PARA_PREFIX = "KEPLER::parameter"; 605 606 public static final String CONFIGURATION_KEPLER_PRINT_EXE_INFO = CONFIGURATION_KEPLER_PARA_PREFIX + "::printExeSummary"; 607 608 public static final String CONFIGURATION_KEPLER_TAG = "KEPLER::tagging"; 609 610 public static final String CONFIGURATION_KEPLER_PARA_PARALLEL = "KEPLER::parameter::ParallelNumber"; 611 612 public static final String CONFIGURATION_KEPLER_DISTRIBUTED_CACHE_PATH = "KEPLER::distributedcache::path"; 613 614 public static final String CONFIGURATION_KEPLER_JOB_KEY_CLASS = "KEPLER::job::key::class"; 615 616 public static final String CONFIGURATION_KEPLER_JOB_VALUE_CLASS = "KEPLER::job::value::class"; 617 618 /** The name of the configuration parameter for the MoML of the sub-workflow. */ 619 public static final String CONFIGURATION_KEPLER_MODEL = "KEPLER::model"; 620 621 /** The name of the configuration parameter for the name of the sub-workflow. */ 622 public static final String CONFIGURATION_KEPLER_MODEL_NAME = "KEPLER::modelName"; 623 624 /** The name of the configuration parameter for the path of the sub-worflow MoML. */ 625 public static final String CONFIGURATION_KEPLER_MODEL_PATH = "KEPLER::modelPath"; 626 627 /** The name of the configuration parameter for the path of the Kepler installation. */ 628 public static final String CONFIGURATION_KEPLER_MODULES_DIR = "KEPLER::modulesDir"; 629 630 /** The name of the configuration parameter for the path to redirect display actors. */ 631 public static final String CONFIGURATION_KEPLER_REDIRECT_DIR = "KEPLER::redirectDir"; 632 633 /** The name of the configuration parameter to specify running in the same JVM as Kepler. */ 634 public static final String CONFIGURATION_KEPLER_SAME_JVM = "KEPLER::sameJVM"; 635 636 /** The name of the configuration parameter specifying the name of a DDPDataSource actor. */ 637 public static final String CONFIGURATION_KEPLER_SOURCE_ACTOR_NAME = "KEPLER::sourceActorName"; 638 639 /** The name of the configuration parameter specifying the name of a DDPDataSink actor. */ 640 public static final String CONFIGURATION_KEPLER_SINK_ACTOR_NAME = "KEPLER::sinkActorName"; 641 642 /** The name of the configuration parameter specifying the name of the input token. */ 643 public static final String CONFIGURATION_KEPLER_INPUT_TOKEN = "Kepler::inputToken"; 644 645 /** The name of the configuration parameter specifying if the full lifecycle of the 646 * sub-workflow should be executed for each input. 647 */ 648 public static final String CONFIGURATION_KEPLER_RUN_WORKFLOW_LIFECYCLE_PER_INPUT = "Kepler::runWorkflowLifeCyclePerInput"; 649 650 /** The name of the configuration parameter specifying the code to execute in the stub. */ 651 public static final String CONFIGURATION_KEPLER_STUB_CODE = "Kepler::code"; 652 653 /** The name of the configuration parameter specifying the input key type of the stub. */ 654 public static final String CONFIGURATION_KEPLER_INPUT_KEY_TYPE = "Kepler::inputKeyType"; 655 656 /** The name of the configuration parameter specifying the input value type of the stub. */ 657 public static final String CONFIGURATION_KEPLER_INPUT_VALUE_TYPE = "Kepler::inputValueType"; 658 659 /** The name of the configuration parameter specifying the name of the script engine factory. */ 660 public static final String CONFIGURATION_KEPLER_SCRIPT_ENGINE_FACTORY_NAME = "Kepler::scriptEngineFactoryName"; 661 662 /** Enumeration of types of token that can be serialized to/from strings. */ 663 public enum TokenType { 664 String, 665 Int, 666 Double, 667 Long, 668 Nil, 669 Record; 670 671 public static TokenType getInstance(int value) { 672 // FIXME add error checking 673 return values()[value]; 674 } 675 676 public int getValue() { 677 return ordinal(); 678 } 679 } 680 681 /////////////////////////////////////////////////////////////////// 682 //// private fields //// 683 684 /** Logging. */ 685 private static final Log LOG = LogFactory.getLog(Utilities.class); 686 687}