<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>eric @ flux</title>
	<atom:link href="http://fluxstuff.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://fluxstuff.com</link>
	<description></description>
	<lastBuildDate>Fri, 22 Feb 2013 21:35:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='fluxstuff.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>eric @ flux</title>
		<link>http://fluxstuff.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://fluxstuff.com/osd.xml" title="eric @ flux" />
	<atom:link rel='hub' href='http://fluxstuff.com/?pushpress=hub'/>
		<item>
		<title>An Exit Strategy for Custom Flux Components</title>
		<link>http://fluxstuff.com/2013/02/20/an-exit-strategy/</link>
		<comments>http://fluxstuff.com/2013/02/20/an-exit-strategy/#comments</comments>
		<pubDate>Wed, 20 Feb 2013 15:56:47 +0000</pubDate>
		<dc:creator>fluxeric</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://fluxstuff.com/?p=59</guid>
		<description><![CDATA[A powerful component of Flux is the ability to customize workflows to meet business requirements. While many business processes seem to be cookie cutter templates at first blush, once in the trenches and faced with solving real world business problems, the cookie cutter business process will likely need to be tweaked. Flux provides built-in components [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=59&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>A powerful component of Flux is the ability to customize workflows to meet business requirements. While many business processes seem to be cookie cutter templates at first blush, once in the trenches and faced with solving real world business problems, the cookie cutter business process will likely need to be tweaked. Flux provides built-in components for transferring files, invoking web services, running system commands, time-based scheduling, etc. <a title="Built-in Flux triggers and actions" href="https://fluxdoc.atlassian.net/wiki/display/flux80/Triggers+and+Actions" target="_blank">We&#8217;ve got the bases covered</a>. Flux does not limit you to the built-in components though. You&#8217;re free to go crazy <a title="Developing custom Flux triggers and actions" href="https://fluxdoc.atlassian.net/wiki/display/flux80/Custom+Triggers+and+Actions" target="_blank">developing custom components</a> to drop into Flux workflows. Turn a Java developer loose with Flux and you&#8217;d be surprised what they can come up with, very quickly. For example, Flux allows you to plug-in custom Java code via Java Action&#8217;s in your workflows. Simply add a Java Action and set the Java class to invoke. Bang the Java code out, and now you have a custom component that you can reuse throughout your workflows. To make things a bit tighter, you can take it a step further and develop a custom Flux trigger or action. This allows you to create triggers and actions, like those that ship with Flux, which have icons and allow users to easily input custom properties for your custom component.</p>
<p>This sounds great! But, I know you&#8217;re thinking that I&#8217;m hiding some gory implementation details from you. I must confess. I am. But these are good details and are fundamental concepts that you&#8217;ll need to have a firm grasp on when customizing Flux.</p>
<h2>Happy Path</h2>
<p>Let&#8217;s get a picture of what things look like when adding custom components to a Flux workflow. Let&#8217;s say I have a workflow that begins witha Timer Trigger (waits for a calendar event), then flows into a Java Action which invokes the rock solid Java code, then it flows back to the Timer Trigger. Sounds simply, eh? So we have a workflow that runs some Java code based on a time schedule. This is all we need to illustrate the concept presented here. When all is well, your rock solid Java code runs happily and exits. All is well.</p>
<h2>Rudely Interrupted</h2>
<p>You&#8217;ve come to appreciate the ability to plug-in custom Java code into a Flux workflow. Good. But what sort of control does Flux have over your Java code you ask? What if you shutdown Flux while your Java code is executing from a workflow? What if someone rudely interrupts a workflow via the Flux Operations Console while your Java code is running in a workflow? This is starting to sound scary! What happens?! Well, it&#8217;s actually quite simple and not scary at all. Nothing happens. That&#8217;s right. If someone interrupts the workflow or shuts down Flux while your Java code is happily executing, nothing will happen. This is because Flux does not have the authority to rudely interrupt your rock solid Java code. This is a good thing. But, it&#8217;s also nice to exit gracefully too.</p>
<h2>An Exit Strategy</h2>
<p>To exit gracefully, you&#8217;ll need to come up with an exit strategy for your custom component. There are three conditions that you should code for in your custom Java code:</p>
<ol>
<li><span style="line-height:13px;">Interrupted.</span></li>
<li>Signal raised.</li>
<li>Timeout.</li>
</ol>
<p>Three conditions. That&#8217;s manageable. You&#8217;ll need to write a bit of Java code to properly handle the situation where someone interrupts a workflow running your custom Java code,  a signal is raised, or a timeout occurs.  The <a title="flux.FlowContext Javadoc" href="http://support.flux.ly/80/javadoc/flux/FlowContext.html" target="_blank">flux.FlowContext </a>API will be your friend here. You&#8217;ll be able to easily access this from your Java code as Flux will pass the flow context is into your Java code. So you can check to see if the workflow is interrupted by calling: flowContext.isInterrupted(), or to see if a signal is raised: flowContext.isSignalRaised(), or if the timeout (as the user defines in the Timeout Expression property) was exceeded: flowContext.isTimedOut().</p>
<p>You&#8217;ll want to check for these conditions frequently in your Java code. If your Java code waits for a resource, like a host to become available, then you&#8217;ll want to frequently check the flow context to see if the workflow was interrupted. If the flow context is interrupted, then you&#8217;re Java code will need to exit appropriately and Flux will then be able to shutdown cleanly and the Java JVM will exit. If you do not account for these flow context conditions in your custom Java code, then the Java JVM will not be able to exit cleanly and you&#8217;ll need to kill the Java JVM via operating system commands to forcibly terminate your Java code.</p>
<h2>Identifying the Problem</h2>
<p>Do you have some custom Java code deployed and invoked via Flux workflows? Are you wondering how to confirm that an improper exit strategy is in place? Be sure your systems are in a state that will cause your custom Java code to wait or take an excessively long time to execute. Then, launch the workflow that invokes your custom Java code. Your code should be waiting for a resource or something that will basically cause it to block for a long period of time. Now interrupt the workflow via the Flux Operations Console, then attempt to shutdown the Flux engine. You&#8217;ll see something like this, if you&#8217;re running Flux from the console:</p>
<p>Flux engine has been disposed.</p>
<p>You are trying to dispose the connection pool, but there is at least one database connection still open. Did you call Engine.get(), Engine.getByState(), or Engine.getByType() and forget to call close() on the returned FlowChartIterator object? Or did you create a J2seSession object and forget to call commit() or rollback() on it? The following thread IDs hold open database connections: Thread[Flux Executor Thread [pool-1-thread-13]].</p>
<h2>Examining the Problem</h2>
<p>When attempting to shutdown Flux, we can see that there is a Java thread &#8220;pool-1-thread-13&#8243; that is blocking. Good. Let&#8217;s confirm that this is your custom Java code. We should see the thread mentioned above in a Java thread dump of the JVM where the Flux engine is running:</p>
<p>&#8220;Flux Executor Thread [pool-1-thread-13]&#8221; prio=10 tid=0xcddcb400 nid=0&#215;4695 waiting on condition [0xcccbf000]<br />
java.lang.Thread.State: TIMED_WAITING (sleeping)<br />
at java.lang.Thread.sleep(Native Method)<br />
at com.company.CustomJavaClass.actionFired(CustomJavaClass.java:43)<br />
at fluximpl.core.FlowChartExecutor.a(dld:938)<br />
at fluximpl.core.FlowChartExecutor.A(dld:533)<br />
at fluximpl.core.FlowChartExecutor.a(dld:196)<br />
at fluximpl.core.Runner.internalRun(wkd:31)<br />
at fluximpl.threadpool.FluxThread.run(zqb:215)<br />
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)<br />
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)<br />
at java.util.concurrent.FutureTask.run(FutureTask.java:138)<br />
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)<br />
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)<br />
at java.lang.Thread.run(Thread.java:619)</p>
<p>Sure enough! We can see that Flux has executed the custom Java code and is waiting for the Java code to return. The same test can be repeated after implementing a proper exit strategy for your custom Java code.</p>
<h2>Always Interrupt to Shutdown</h2>
<p>It&#8217;s often the case when development a workflow that you&#8217;ll be restarting your environments quite a bit. This is good. Flux really shines here. But, you&#8217;ll want to remember that if you are invoking Java code that executes for a long period of time, that the Java JVM (where Flux launched your Java code) will not exit cleanly until your Java code exits. For this to occur, you&#8217;ll likely need to interrupt your workflows before shutting down the Flux engine. This can be done easily via the Flux Java API:</p>
<pre>engine.pause("/");
engine.interrupt("/");
engine.dispose();</pre>
<p>This will properly interrupt the running workflows and shutdown the Flux engine. Just be sure to resume the workflows when restarting the environment.</p>
<h2>Further Help</h2>
<p>Would you like some help customizing an exit strategy for your custom Flux components? <a title="Mail Flux Support" href="mailto:support@flux.ly">Contact our in-house Flux gurus</a> and they&#8217;ll be glad to help!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fluxeric.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fluxeric.wordpress.com/59/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=59&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fluxstuff.com/2013/02/20/an-exit-strategy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e3f2b44f98d4f31463ccf85d16b2e1b0?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fluxeric</media:title>
		</media:content>
	</item>
		<item>
		<title>Initializing Flux in Java Code to Support Runtime Configuration Properties</title>
		<link>http://fluxstuff.com/2011/09/26/initializing-flux-in-java-code-to-support-runtime-configuration-properties/</link>
		<comments>http://fluxstuff.com/2011/09/26/initializing-flux-in-java-code-to-support-runtime-configuration-properties/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 20:58:26 +0000</pubDate>
		<dc:creator>fluxeric</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://fluxstuff.com/?p=50</guid>
		<description><![CDATA[Introduction Often times when our customers design workflows, the workflows act as templates and read in different values based on the location of the workflow. For example, let&#8217;s say I&#8217;ve created a workflow to automate file transfers for a customer, such as &#8220;ACME Bank&#8221;. The same workflow could likely be used to service all of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=50&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Often times when our customers design workflows, the workflows act as templates and read in different values based on the location of the workflow. For example, let&#8217;s say I&#8217;ve created a workflow to automate file transfers for a customer, such as &#8220;ACME Bank&#8221;. The same workflow could likely be used to service all of my customers but with variables whose values are different based on which customer the workflow template is servicing. So, if I run the workflow template for ACME Bank, it may pull files from acmebank.com but if I run the workflow template for Wile Bank, it would put files from wilebank.com. We&#8217;ll look at how to setup a Flux environment to support this sort of flexible configuration to reduce overhead in maintaining workflows for many customers. You can easily reduce 200+ workflows down to one workflow using this technique as I&#8217;ve witnessed which drastically simplifies your Flux setup.</p>
<h2>Initializing Flux</h2>
<p>First, let&#8217;s create a Java class that will be responsible for initializing the Flux environment.</p>
<p><strong><em>FluxController.java</em></strong></p>
<pre>import flux.Configuration;
import flux.Engine;
import flux.Factory;
import flux.runtimeconfiguration.RuntimeConfigurationNode;

public class FluxController {
  private static Factory factory = Factory.makeInstance();
  private static Engine engine;

  private String enginePropertiesFilename = "engine.properties";
  private String runtimePropertiesFilename = "runtime.properties";

  public FluxController() throws Exception {
    initializeEngine();
  }

  public Engine initializeEngine() throws Exception {
    System.out.println("Flux version:  " + flux.Factory.getVersion());
    System.out.println("Copyright 2000-2011 Flux Corporation. All rights reserved.\n");

    System.out.println("Creating Flux engine using properties file: " + enginePropertiesFilename + "...");
    Configuration engineConfiguration = factory.makeConfigurationFromProperties(enginePropertiesFilename);
    System.out.println("Flux engine created!");

    engineConfiguration.setRuntimeConfiguration(loadRuntimeConfiguration());
    engine = factory.makeEngine(engineConfiguration);
    engine.start();

    return engine;
  }

  private RuntimeConfigurationNode loadRuntimeConfiguration() throws Exception {
    return new RuntimeConfigurationLoader(runtimePropertiesFilename).getRuntimeConfigurationRootNode();
  }

  public static Engine getEngine() {
    return engine;
  }

  public static void disposeEngine() throws Exception {
    if (engine != null) {
      System.out.println("Disposing Flux engine...");
      engine.dispose();
      System.out.println("Flux engine is disposed!");
    }
  }

  public static void main(String[] args) throws Exception {
    new FluxController();
  }
}</pre>
<h2>Loading Runtime Configuration Properties</h2>
<p>The <em>FluxController</em> class above relies on <em>RuntimeConfigurationLoader</em> to read in the custom runtime configuration properties, or variables, that we&#8217;ll use in our workflow templates. Here&#8217;s what it looks like.</p>
<p><em><strong>RuntimeConfigurationLoader</strong></em></p>
<pre>import flux.Factory;
import flux.runtimeconfiguration.RuntimeConfigurationNode;
import flux.xml.XmlFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;

public class RuntimeConfigurationLoader {
  private RuntimeConfigurationNode runtimeConfigurationRootNode = null;

  public RuntimeConfigurationLoader(String filename) throws Exception {
    Properties runtimeProperties = new Properties();
    runtimeProperties.load(new FileReader(filename));

    runtimeConfigurationRootNode = Factory.makeInstance().makeRuntimeConfigurationFactory().makeRuntimeConfiguration();

    Enumeration names = runtimeProperties.propertyNames();
    while (names.hasMoreElements()) {
      String branch = (String) names.nextElement();

      StringTokenizer st = new StringTokenizer(branch, "/");

      int count = st.countTokens();

      RuntimeConfigurationNode currentNode = runtimeConfigurationRootNode;
      while (st.hasMoreElements()) {
        String name = (String) st.nextElement();
        if (count &gt; 1) {
          RuntimeConfigurationNode node = currentNode.getChild(name);
          if (node == null) {
            currentNode = currentNode.makeChild(name);
          } else {
            currentNode = node;
          }
        } else {
          Object obj = null;
          String value = runtimeProperties.getProperty(branch, "");
          if (name.equalsIgnoreCase(RuntimeConfigurationNode.DEFAULT_FLOW_CHART_ERROR_HANDLER)) {
            obj = loadFlowChart(value);
            //} else if (name.equalsIgnoreCase(RuntimeConfigurationNode.CONCURRENCY_THROTTLE)) {
            // Handle standard Flux runtime configuration properties here
          } else {
            obj = value;
          }

          if (obj != null) {
            currentNode.put(name, obj);
          } else {
            System.out.println("Failed to load runtime configuration property: " + name);
          }
        }
        count--;
      }
    }
  }

  public RuntimeConfigurationNode getRuntimeConfigurationRootNode() {
    return runtimeConfigurationRootNode;
  }

  private Object loadFlowChart(String urlPath) throws Exception {
    List flowCharts;
    InputStream fileStream = new FileInputStream(new File(urlPath));
    // Or load resource from class path
    // InputStream fileStream = ClassLoader.getSystemResourceAsStream(resourceName);

    try {
      flowCharts = XmlFactory.makeInstance().makeXmlEngineHelper().makeFlowChartsFromXml(fileStream, false);
    } finally {
      fileStream.close();
    }

    if (flowCharts.size() &gt; 0) {
      return flowCharts.get(0);
    } // if

    return null;
  }
}<span style="font-family:Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;"><span class="Apple-style-span" style="font-size:20px;line-height:19px;white-space:normal;"><strong>
</strong></span></span></pre>
<h2>Runtime Configuration Properties</h2>
<p>Workflows can have variables defined that are only accessible within the workflow itself (flow chart variables). We can also define runtime configuration properties that all workflows can access or isolate the runtime configuration properties so they can be easily accessed within the context of a workflow. In the example mentioned in the introduction, we may want to define some custom properties like: /ACME Bank/username=acmeuser and /Wile Bank/username=wileuser. When we run the same workflow template for these different customers, the correct value will be used. Let&#8217;s see what the configuration file format would look like to achieve something like this.</p>
<p><strong><em>runtime.properties</em></strong></p>
<pre>/businessUnit1/customConfigProperty=testValue1
/businessUnit2/customConfigProperty=testValue2</pre>
<h2>Test it!</h2>
<p>No Java code would be complete without a test that we can automate! Let&#8217;s make sure we can initialize Flux, access our custom configuration properties, and shutdown Flux.</p>
<pre>import flux.Engine;
import flux.runtimeconfiguration.RuntimeConfigurationNode;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

public class RuntimeConfigurationLoaderTest {
  @Test
  public void testLoad() throws Exception {
    new FluxController();
    Engine engine = FluxController.getEngine();

    assertTrue(engine.isRunning());
    RuntimeConfigurationNode businessUnitConfigNode1 = engine.getRuntimeConfiguration().getChild("businessUnit1");
    assertNotNull(businessUnitConfigNode1);

    Object customConfigProperty1 = businessUnitConfigNode1.getProperty("customConfigProperty");
    assertNotNull(customConfigProperty1);
    assertEquals("testValue1", customConfigProperty1.toString());

    RuntimeConfigurationNode businessUnitConfigNode2 = engine.getRuntimeConfiguration().getChild("businessUnit2");
    assertNotNull(businessUnitConfigNode2);

    Object customConfigProperty2 = businessUnitConfigNode2.getProperty("customConfigProperty");
    assertNotNull(customConfigProperty2);
    assertEquals("testValue2", customConfigProperty2.toString());

    FluxController.disposeEngine();

    assertTrue(engine.isDisposed());
  }
}</pre>
<h2>Conclusion</h2>
<p>Now we can simply edit one of our workflows and change static values to: <em>${runtime customConfigProperty}</em>. If the workflow runs under &#8220;/businessUnit1&#8243;, the value &#8220;testValue1&#8243; would be used but when the same workflow runs under &#8220;/businessUnit2&#8243;, the value &#8220;testValue2&#8243; would be used. Pretty handy, eh?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fluxeric.wordpress.com/50/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fluxeric.wordpress.com/50/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=50&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fluxstuff.com/2011/09/26/initializing-flux-in-java-code-to-support-runtime-configuration-properties/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e3f2b44f98d4f31463ccf85d16b2e1b0?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fluxeric</media:title>
		</media:content>
	</item>
		<item>
		<title>Flux Unit (functional, integration: make sure it works) Testing</title>
		<link>http://fluxstuff.com/2011/09/19/flux-unit-testing/</link>
		<comments>http://fluxstuff.com/2011/09/19/flux-unit-testing/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 17:22:58 +0000</pubDate>
		<dc:creator>fluxeric</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://fluxstuff.com/?p=42</guid>
		<description><![CDATA[Introduction We take testing very seriously here @ Flux. Testing complex enterprise systems is not for the faint of heart as it can become very complicated in short order. Designing unit tests, functional tests, integration tests, user interface tests, and in-container tests (inside of enterprise application containers or a simple servlet container) are enough to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=42&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>We take testing very seriously here @ Flux. Testing complex enterprise systems is not for the faint of heart as it can become very complicated in short order. Designing unit tests, functional tests, integration tests, user interface tests, and in-container tests (inside of enterprise application containers or a simple servlet container) are enough to make your head spin; much less keeping the systems up and running (not many QA teams have dedicated System and Database Administrators).</p>
<p>You may have landed on this blog post because you are considering building some automated tests to ensure that your enterprise software which uses Flux is up-to-snuff and enterprise-ready. No worries. Let&#8217;s keep it simple. We&#8217;ll start out by looking out some Java code which can be used as a starting point for your Flux related tests.  The test code that we&#8217;ll consider today will cover unit, functional, and integration tests (as I like to call them: make sure it works tests). We&#8217;ll save in-container testing and user interface testing for another day.</p>
<h2>Testing Environment</h2>
<p>What&#8217;s required in a Flux testing environment? We&#8217;ll use JUnit (<a title="JUnit" href="http://www.junit.org/">http://www.junit.org/</a>), Apache log4j (<a title="log4j" href="http://logging.apache.org/log4j/">http://logging.apache.org/log4j/</a>), and of course Flux (<a title="Flux" href="http://fluxcorp.com/">http://fluxcorp.com/</a>). You can use Flux with a lightweight in-memory database (H2: <a title="H2" href="http://www.h2database.com/">http://www.h2database.com/</a>) or you can configure Flux with the database that you&#8217;ll use in production (or to test with multiple databases if you are an OEM embedding Flux in an application that supports multiple databases such as Oracle, SQL Server, DB2, MySQL, or PostgreSQL).</p>
<h2>Abstract Flux Test</h2>
<p>Let&#8217;s start by creating an abstract test which can be extended to create a Flux test for your application. Let&#8217;s call this <em>AbstractFluxTest.java</em> (a very sensible name). This abstract test will take care of initializing Flux, setting up the test, cleaning up after the test, and provide some convenience methods for things like loading flow charts from XML files (.FFC) and verifying that Flux flow charts and actions executed as expected.</p>
<p><em><strong>AbstractFluxTest.java</strong></em></p>
<pre>import flux.*;
import flux.xml.XmlEngineHelper;
import flux.xml.XmlFactory;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;

import java.io.FileInputStream;
import java.util.Date;
import java.util.List;

public abstract class AbstractFluxTest {
  protected Factory factory = Factory.makeInstance();
  protected EngineHelper engineHelper = factory.makeEngineHelper();
  protected Engine engine;
  protected String enginePropertiesFile = "engine.properties";
  protected boolean clearEngine = false;
  protected Date startTime;
  public static boolean fired = false;

  public static final Logger log = Logger.getLogger("flux-test");

  @Before
  public void setUpTest() throws Exception {
    log.info("[START] AbstractFluxTest.setUpTest");

    startTime = new Date();
    engine = factory.makeEngine(enginePropertiesFile);

    if (clearEngine) {
      engine.clear();
    }

    engine.start();

    log.info("[END] AbstractFluxTest.setUpTest");
  }

  @After
  public void tearDownTest() throws Exception {
    log.info("[START] AbstractFluxTest.tearDownTest");

    fired = false;
    engine.dispose();

    log.info("[END] AbstractFluxTest.tearDownTest");
  }

  @SuppressWarnings("unchecked")
  protected FlowChart readFlowChartFFC(String fileName) throws Exception {
    XmlEngineHelper xmlHelper = XmlFactory.makeInstance().makeXmlEngineHelper();
    FileInputStream fileInputStream = new FileInputStream(fileName);
    try {
      List&lt;FlowChart&gt; flowCharts = xmlHelper.makeFlowChartsFromXml(fileInputStream, false);

      return flowCharts.get(0);
    } finally {
      fileInputStream.close();
    }
  }

  protected FlowChart readFlowChartFFCOnClassPath(String filename) throws Exception {
    return readFlowChartFFC(this.getClass().getClassLoader().getResource(filename).getPath());
  }

  protected boolean didActionExecute(String namespace, String actionName) throws Exception {
    log.info("didActionExecute namespace: " + namespace + " actionName: " + actionName);
    ActionHistoryIterator it = engine.getActionHistory(namespace, actionName, startTime, new Date());

    try {
      return it.next() != null;
    } catch (Exception e) {
      return false;
    } finally {
      it.close();
    }
  }

  public long waitForRuns(String namespace, int minimumExpectedRunCount, int delayInSeconds, int timeoutInSeconds) throws Exception {
    long runCount = 0;
    long totalTime = 0;
    int delayInMillis = delayInSeconds * 1000;

    String initialMsg = "waitForRuns namespace:" + namespace + " minimumExpectedRunCount: " + minimumExpectedRunCount + " delayInSeconds: " + delayInSeconds +
      " timeoutInSeconds: " + timeoutInSeconds;
    log.info(initialMsg);

    while (runCount &lt; minimumExpectedRunCount &amp;&amp; totalTime &lt; timeoutInSeconds) {
      runCount = engine.getRunCount(namespace);

      log.info(initialMsg + " runCount: " + runCount + " totalTime: " + totalTime);
      if (runCount &lt; minimumExpectedRunCount) {
        Thread.sleep(delayInMillis);
        totalTime += delayInSeconds;
      }
    }

    return runCount;
  }
}</pre>
<h2>Flux Engine Configuration</h2>
<p>AbstractFluxTest loads the Flux engine configuration from the file: engine.properties. You can add more configuration properties to match your production environment. Here&#8217;s the recommended minimum configuration for a testing environment:</p>
<p><strong><em>engine.properties</em></strong></p>
<pre>database_type=H2
logger_type=log4j</pre>
<h2>Apache log4j Configuration</h2>
<p>I&#8217;ve decided to use Apache log4j for logging in these tests. I&#8217;ve chosen log4j for two reasons: it&#8217;s popular and Flux can tie into log4j (you can configure Flux and your test code to log to the same or different files and some other crazy things). Here&#8217;s a simple log4j configuration that will log the test messages (logged via <em>log.info()</em> in the test code) to both the console and the <em>flux-test.log</em> file (where the Flux engine is configured to log to as well via the <em>engine.properties</em> file:<em> logger_type=log4j</em>).</p>
<pre>log4j.rootLogger=INFO,FileAppender

log4j.logger.flux-test=INFO,ConsoleAppender

log4j.appender.ConsoleAppender.Threshold=INFO
log4j.appender.ConsoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.ConsoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.ConsoleAppender.layout.ConversionPattern=%d %-4r %-5p [%t] %10c %3x - %m%n\

log4j.appender.FileAppender=org.apache.log4j.RollingFileAppender
log4j.appender.FileAppender.MaxFileSize=50MB
log4j.appender.FileAppender.MaxBackupIndex=10
log4j.appender.FileAppender.File=flux-test.log
log4j.appender.FileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.FileAppender.layout.ConversionPattern=%d %-4r %-5p [%t] %15c %3x - %m%n\</pre>
<h2>Sample Flux Test</h2>
<p>Now that we have the test framework in place, let&#8217;s take a look at a simple Flux test.</p>
<p><em><strong>FluxTest.java</strong></em></p>
<pre>import flux.FlowChart;
import flux.JavaAction;
import flux.TimerTrigger;
import org.junit.Test;

import static org.junit.Assert.assertTrue;

public class FluxTest extends AbstractFluxTest {
  @Test
  public void testFFCFile() throws Exception {

    String namespace = "/FluxFlowChart";    log.info("[START] FluxTest.testFFCFile");

    FlowChart flowChart = readFlowChartFFC("flowCharts/FluxFlowChart.ffc");
    flowChart.setName(namespace);
    engine.put(flowChart);

    waitForRuns(namespace, 1, 10, 120);

    didActionExecute("/FluxFlowChart", "Timer Trigger");
    didActionExecute("/FluxFlowChart", "Java Action");
    assertTrue(fired);
    log.info("[END] FluxTest.testFFCFile");
  }

  @Test
  public void testJavaAPI() throws Exception {
    log.info("[START] FluxTest.testJavaAPI");
    String namespace = "/FluxFlowChart";

    FlowChart flowChart = engineHelper.makeFlowChart(namespace);
    TimerTrigger timerTrigger = flowChart.makeTimerTrigger("Timer Trigger");
    timerTrigger.setTimeExpression("+1m");

    JavaAction javaAction = flowChart.makeJavaAction("Java Action");
    javaAction.setListener(FluxTestListener.class);

    timerTrigger.addFlow(javaAction);

    engine.put(flowChart);

    waitForRuns(namespace, 1, 10, 120);

    didActionExecute("/FluxFlowChart", "Timer Trigger");
    didActionExecute("/FluxFlowChart", "Java Action");
    assertTrue(fired);

    log.info("[END] FluxTest.testJavaAPI");
  }
}</pre>
<p><em>FluxTest.java</em> provides to tests: one for testing a flow chart which was designed using the visual Flux flow chart designer and another that creates the flow chart to test using the Flux Java API. In <em>testFFCFile()</em>, we load the flow chart from the file <em>FluxFlowChart.ffc</em>, ensure that the name is set correctly, and verify that the actions and Java code executed as expected.</p>
<p>Here&#8217;s what the flow chart looks like that is loaded from <em>FluxFlowChart.ffc</em>:</p>
<p><img class="alignnone" title="FluxFlowChart.ffc" src="http://content.screencast.com/users/ericrich/folders/Jing/media/7c1831b2-fa7d-4f64-91b0-8358c51fa8dc/00000190.png" alt="" width="123" height="225" /></p>
<h2>Flux Test Listener</h2>
<p>Many Flux customers use Java Action&#8217;s in their flow charts. A Java Action allows flow charts (which are often designed visually by connecting various components together with conditions) to execute some Java code. in <em>FluxTest</em> above, we designed a flow chart that executes <em>FluxTestListener</em>. For illustration purposes, this listener code is designed to update a variable in the test case which can be asserted via JUnit after the flow chart completes. This illustrates how we can ensure that the actual Java code executed as anticipated.</p>
<p><em><strong>FluxTestListener.java</strong></em></p>
<pre>import flux.ActionListener;
import flux.KeyFlowContext;

public class FluxTestListener implements ActionListener {
  public Object actionFired(KeyFlowContext flowContext) throws Exception {
    FluxTest.fired = true;
    flowContext.getLogger().info("FluxTestListener.actionFired!");
    return null;
  }
}</pre>
<h2>Conclusion</h2>
<p>Well, that should give you enough to get you started testing with Flux. I&#8217;ll follow-up with some more Flux test related blog posts (maybe detecting errors from the Flux engine via Apache log4j will be next). If you have questions about testing your Flux based software or would like more code examples, just reach out to Flux Support and we&#8217;ll be sure to satisfy your Flux testing appetite. Have fun!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fluxeric.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fluxeric.wordpress.com/42/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=42&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fluxstuff.com/2011/09/19/flux-unit-testing/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e3f2b44f98d4f31463ccf85d16b2e1b0?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fluxeric</media:title>
		</media:content>

		<media:content url="http://content.screencast.com/users/ericrich/folders/Jing/media/7c1831b2-fa7d-4f64-91b0-8358c51fa8dc/00000190.png" medium="image">
			<media:title type="html">FluxFlowChart.ffc</media:title>
		</media:content>
	</item>
		<item>
		<title>Flux Mobile on iPhone, iPad, Android, and Blackberry!</title>
		<link>http://fluxstuff.com/2010/11/24/fluxmobile/</link>
		<comments>http://fluxstuff.com/2010/11/24/fluxmobile/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 20:30:59 +0000</pubDate>
		<dc:creator>fluxeric</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://fluxstuff.com/?p=37</guid>
		<description><![CDATA[Flux operators are responsible for overseeing the automated jobs in their environment. These jobs often run during non-working hours. Having quick access to system and job status from mobile devices can be really beneficial for some operators. Specific applications can be developed quickly to allow these operators to administer their jobs from mobile devices. I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=37&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Flux operators are responsible for overseeing the automated jobs in their environment. These jobs often run during non-working hours. Having quick access to system and job status from mobile devices can be really beneficial for some operators.</p>
<p>Specific applications can be developed quickly to allow these operators to administer their jobs from mobile devices. I developed a mobile application that uses the backend REST API in about 2 hours. The REST API is accessible in Flux 7.10 (since the new Flux Operations Console is based on the REST backend) and will be fully documented with examples in Flux 7.11.</p>
<p>Here&#8217;s a quick video showing &#8220;Flux Mobile&#8221; running on Flux 7.10:</p>
<p><a title="Flux Mobile with Flux 7.10!" href="http://screencast.com/t/Z5fB17hGgcJc">Flux Mobile</a></p>
<p>Are you interested in viewing the status of your Flux jobs from a mobile device? I&#8217;d love to hear from you!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fluxeric.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fluxeric.wordpress.com/37/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=37&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fluxstuff.com/2010/11/24/fluxmobile/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e3f2b44f98d4f31463ccf85d16b2e1b0?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fluxeric</media:title>
		</media:content>
	</item>
		<item>
		<title>Data Warehouse Automation</title>
		<link>http://fluxstuff.com/2010/11/05/data_warehouse_automation/</link>
		<comments>http://fluxstuff.com/2010/11/05/data_warehouse_automation/#comments</comments>
		<pubDate>Fri, 05 Nov 2010 16:41:19 +0000</pubDate>
		<dc:creator>fluxeric</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://fluxstuff.com/?p=26</guid>
		<description><![CDATA[&#8220;We&#8217;re trying to reduce our 2 a.m. calls, like everyone else.&#8221; That&#8217;s what I heard when a CIO came to us looking to solve problems in his data center. He didn&#8217;t sound excited about it. But, he knew that if they could find solutions to common problems they&#8217;ve encountered, that there could be a tremendous [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=26&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>&#8220;We&#8217;re trying to reduce our 2 a.m. calls, like everyone else.&#8221; That&#8217;s what I heard when a CIO came to us looking to solve problems in his data center. He didn&#8217;t sound excited about it. But, he knew that if they could find solutions to common problems they&#8217;ve encountered, that there could be a tremendous positive impact on the organization.</p>
<p>How often are your data center operators called in to rescue you from a bad situation? Can these situations be avoided to reduce these calls? Data warehouse automation is an area where workload automation can truly shine.</p>
<p><a href="http://fluxeric.files.wordpress.com/2010/11/datawarehousediagram.png"><img class="aligncenter size-full wp-image-33" title="Data Warehouse" src="http://fluxeric.files.wordpress.com/2010/11/datawarehousediagram.png?w=604" alt=""   /></a></p>
<ol>
<li>Did the data arrive from the customer as expected? If not, does the customer need to be notified?</li>
<li>Was the data intact and valid?</li>
<li>Is the ETL process started as soon as the data is available?</li>
<li>Could the data be extracted, transformed, and loaded without any errors?</li>
<li>If there are errors, are they resolved automatically with proper logging, auditing, notifications, and reporting?</li>
<li>Does the entire process need to start over when an error occurs, or can parts of the process be restarted to increase throughput?</li>
<li>Is report generation started as soon as the data is available?</li>
<li>Are reporting errors handled automatically?</li>
<li>Is the report sent to recipient as soon as it&#8217;s available?</li>
<li>Are multiple delivery mechanisms supported, such as: FTP, FTPS, SFTP, UNC, JMS, etc?</li>
</ol>
<p>Are you looking to solve some of these problems with your data warehouse automation solution? Great! I&#8217;ve got some news for you! Flux 7.11 will include Cognos integration straight out of the box! We&#8217;re in the preliminary stages of planning support for Informatica as well. With support planned for Informatica and Cognos, Flux should be on your radar.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fluxeric.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fluxeric.wordpress.com/26/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=26&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fluxstuff.com/2010/11/05/data_warehouse_automation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e3f2b44f98d4f31463ccf85d16b2e1b0?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fluxeric</media:title>
		</media:content>

		<media:content url="http://fluxeric.files.wordpress.com/2010/11/datawarehousediagram.png" medium="image">
			<media:title type="html">Data Warehouse</media:title>
		</media:content>
	</item>
		<item>
		<title>This ain&#8217;t your grandpa&#8217;s job scheduler!</title>
		<link>http://fluxstuff.com/2010/09/02/this-aint-your-grandpas-job-scheduler/</link>
		<comments>http://fluxstuff.com/2010/09/02/this-aint-your-grandpas-job-scheduler/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 15:47:02 +0000</pubDate>
		<dc:creator>fluxeric</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://fluxstuff.com/?p=18</guid>
		<description><![CDATA[Still using cron, Autosys, CONTROL-M, Quartz? Does the new Flux Ops Console make you jealous? :-)<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=18&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>We&#8217;ve been working on redesigning and rewriting the Flux Operations Console from the ground up. It&#8217;s designed to be responsive and scale well to provide you with the latest runtime stats on your distributed enterprise jobs in one central webapp.</p>
<p>Here&#8217;s a quick video (1 min 26 secs) that illustrates the performance and scalability of the new Ops Console:</p>
<p><a title="Is your job scheduler this cool?" href="http://screencast.com/t/YzdiZmFmYTY">Flux Operations Console Performance Video</a></p>
<p>This video was taken when around 6,000 flow charts were running in the cluster and a background thread was adding flow charts constantly. Google Chrome on Mac was used for the browser.</p>
<p>Still using cron, Autosys, CONTROL-M, Quartz? Does the new Flux Ops Console make you jealous? <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fluxeric.wordpress.com/18/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fluxeric.wordpress.com/18/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=18&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fluxstuff.com/2010/09/02/this-aint-your-grandpas-job-scheduler/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e3f2b44f98d4f31463ccf85d16b2e1b0?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fluxeric</media:title>
		</media:content>
	</item>
		<item>
		<title>Interactive Flux Architecture Diagram</title>
		<link>http://fluxstuff.com/2010/05/05/interactive-flux-architecture-diagram/</link>
		<comments>http://fluxstuff.com/2010/05/05/interactive-flux-architecture-diagram/#comments</comments>
		<pubDate>Wed, 05 May 2010 22:41:36 +0000</pubDate>
		<dc:creator>fluxeric</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://fluxeric.wordpress.com/?p=11</guid>
		<description><![CDATA[We&#8217;re working on an interactive Flux architecture diagram that will be included in the next version of the Flux Operations Console. This diagram is displayed to first time Flux users to help them understand the Flux components and how they relate to each other. You can take a peek at the diagram here: http://screencast.com/t/YTljNTU5Zj PS [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=11&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>We&#8217;re working on an interactive Flux architecture diagram that will be included in the next version of the Flux Operations Console. This diagram is displayed to first time Flux users to help them understand the Flux components and how they relate to each other.</p>
<p>You can take a peek at the diagram here:</p>
<p><a href="http://screencast.com/t/YTljNTU5Zj">http://screencast.com/t/YTljNTU5Zj</a></p>
<p>PS &#8211; Have no fear iPad users! Flash was not used for the interactive diagram. <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fluxeric.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fluxeric.wordpress.com/11/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=11&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fluxstuff.com/2010/05/05/interactive-flux-architecture-diagram/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e3f2b44f98d4f31463ccf85d16b2e1b0?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fluxeric</media:title>
		</media:content>
	</item>
		<item>
		<title>Automation in the cloud: debunking marketing hype</title>
		<link>http://fluxstuff.com/2009/12/17/automation-in-the-cloud/</link>
		<comments>http://fluxstuff.com/2009/12/17/automation-in-the-cloud/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 17:39:17 +0000</pubDate>
		<dc:creator>fluxeric</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://fluxeric.wordpress.com/?p=6</guid>
		<description><![CDATA[The latest craze in the enterprise job scheduling industry seems to be cloud computing. It can be difficult to determine what a job scheduling product offers to address cloud computing by listening to presentations given by the executives.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=6&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>The latest craze in the enterprise job scheduling industry seems to be cloud computing. It can be difficult to determine what a job scheduling product offers to address cloud computing by listening to presentations given by the executives.</p>
<ul>
<li>&#8220;Support for events is necessary&#8221;</li>
<li>&#8220;Linking tasks together&#8221;</li>
<li>&#8220;Security&#8221;</li>
</ul>
<p>What is different about job scheduling in the cloud and a traditional enterprise production environment? If you move your data center to Amazon EC2 or another cloud provider, how does the move impact your enterprise jobs?</p>
<p>I was on a conference call with a new Flux customer yesterday discussing how they can leverage Flux more in their cloud environment. It seems pretty simple to me. Servers are static in a traditional data center. Your data center should scale dynamically when moved to the cloud. Today you&#8217;re running 5 servers to handle your load. Next month you may need to add 2 additional servers to handle the load. Scaling to meet demand should be automated. Configure the cloud server images with the necessary software and then start/stop instances from APIs or a user interface.</p>
<p>How should job scheduling software support cloud environments? Supporting the ability to add and remove servers dynamically is key.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fluxeric.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fluxeric.wordpress.com/6/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fluxstuff.com&#038;blog=11000789&#038;post=6&#038;subd=fluxeric&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fluxstuff.com/2009/12/17/automation-in-the-cloud/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/e3f2b44f98d4f31463ccf85d16b2e1b0?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fluxeric</media:title>
		</media:content>
	</item>
	</channel>
</rss>
