You are viewing a plain text version of this content. The canonical link for it is here.
Posted to olio-commits@incubator.apache.org by sh...@apache.org on 2009/09/16 17:43:58 UTC

svn commit: r815906 - in /incubator/olio/workload/rails/trunk: deploy/ src/org/apache/olio/services/

Author: shanti
Date: Wed Sep 16 17:43:58 2009
New Revision: 815906

URL: http://svn.apache.org/viewvc?rev=815906&view=rev
Log:
Fix for OLIO-35. Added new services for thin and nginx. The RailsService now captures the
application's environment.rb and production log. It also clears the rails cache at the start of the
run. The Nginx and Thin services support startup/shutdown etc. 
The deployment configuration files have been modified to allow the user to set various parameters
for these services.

Added:
    incubator/olio/workload/rails/trunk/src/org/apache/olio/services/
    incubator/olio/workload/rails/trunk/src/org/apache/olio/services/NginxService.java
    incubator/olio/workload/rails/trunk/src/org/apache/olio/services/RailsService.java
    incubator/olio/workload/rails/trunk/src/org/apache/olio/services/Thin.java
Modified:
    incubator/olio/workload/rails/trunk/deploy/   (props changed)
    incubator/olio/workload/rails/trunk/deploy/config.xhtml
    incubator/olio/workload/rails/trunk/deploy/run.xml

Propchange: incubator/olio/workload/rails/trunk/deploy/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Sep 16 17:43:58 2009
@@ -0,0 +1 @@
+.config.xhtml.swp

Modified: incubator/olio/workload/rails/trunk/deploy/config.xhtml
URL: http://svn.apache.org/viewvc/incubator/olio/workload/rails/trunk/deploy/config.xhtml?rev=815906&r1=815905&r2=815906&view=diff
==============================================================================
--- incubator/olio/workload/rails/trunk/deploy/config.xhtml (original)
+++ incubator/olio/workload/rails/trunk/deploy/config.xhtml Wed Sep 16 17:43:58 2009
@@ -53,7 +53,7 @@
                         <xforms:bind id="bind-simultaneous" xforms:nodeset="fd:simultaneous"/>
                         <xforms:bind id="bind-parallel" xforms:nodeset="fd:parallel"/>
                     </xforms:bind>
-                    <xforms:bind id="bind-webServer" xforms:nodeset="fd:driverConfig[@name='UIDriver']">
+                    <xforms:bind id="bind-driverConfig" xforms:nodeset="fd:driverConfig[@name='UIDriver']">
                         <xforms:bind id="bind-driver-agents" xforms:nodeset="fd:agents" xforms:type="positiveInteger"/>
                         <xforms:bind id="bind-driver-statsInterval" xforms:nodeset="fd:stats/fd:interval" xforms:type="positiveInteger"/>
                         <xforms:bind id="bind-driver-properties" xforms:nodeset="fd:properties">
@@ -62,21 +62,43 @@
                     </xforms:bind>
                 </xforms:bind>
 
-                <xforms:bind id="bind-webServer" xforms:nodeset="webServer">
-                    <xforms:bind id="bind-webServer-hostConfig" xforms:nodeset="fa:hostConfig">
-                        <xforms:bind id="bind-webServer-hostPorts" xforms:nodeset="fa:hostPorts"/>
-                        <xforms:bind id="bind-webServer-tools" xforms:nodeset="fh:tools"/>
-                        <xforms:bind id="bind-webServer-userCommands" xforms:nodeset="fh:userCommands"/>
+                <xforms:bind id="bind-proxyserver" xforms:nodeset="proxyServer">
+                    <xforms:bind id="bind-proxyserver-hostConfig" xforms:nodeset="fa:hostConfig">
+                        <xforms:bind id="bind-proxyserver-hostPorts" xforms:nodeset="fa:hostPorts"/>
+                        <xforms:bind id="bind-proxyserver-tools" xforms:nodeset="fh:tools"/>
+                        <xforms:bind id="bind-proxyserver-userCommands" xforms:nodeset="fh:userCommands"/>
+                    </xforms:bind>
+                    <xforms:bind id="bind-proxyserver-type" xforms:nodeset="type"/>
+                    <xforms:bind id='bind-proxyserver-service' xforms:nodeset='fh:service'>
+                        <xforms:bind id='bind-proxyserver-service-config' xforms:nodeset='fh:config'>
+                            <xforms:bind id="bind-proxyserver-cmdPath" xforms:nodeset="cmdPath"/>
+                            <xforms:bind id="bind-proxyserver-logsDir" xforms:nodeset="logsDir"/>
+                            <xforms:bind id="bind-proxyserver-pidDir" xforms:nodeset="pidDir"/>
+                            <xforms:bind id="bind-proxyserver-confPath" xforms:nodeset="confPath"/>
+                            <xforms:bind id="bind-proxyserver-getAccLog" xforms:nodeset="getAccLog"/>
+                        </xforms:bind>
+                    </xforms:bind>
+                </xforms:bind>
+
+                <xforms:bind id="bind-appserver" xforms:nodeset="webServer">
+                    <xforms:bind id="bind-appserver-hostConfig" xforms:nodeset="fa:hostConfig">
+                        <xforms:bind id="bind-appserver-hostPorts" xforms:nodeset="fa:hostPorts"/>
+                        <xforms:bind id="bind-appserver-tools" xforms:nodeset="fh:tools"/>
+                        <xforms:bind id="bind-appserver-userCommands" xforms:nodeset="fh:userCommands"/>
+                    </xforms:bind>
+                    <xforms:bind id='bind-appserver-service' xforms:nodeset='fh:service'>
+                        <xforms:bind id='bind-appserver-service-config' xforms:nodeset='fh:config'>
+                            <xforms:bind id="bind-appserver-type" xforms:nodeset="type"/>
+                            <xforms:bind id="bind-appserver-appDir" xforms:nodeset="appDir"/>
+                            <xforms:bind id="bind-appserver-numInstances" xforms:nodeset="numInstances"/>
+                            <xforms:bind id="bind-appserver-cmdPath" xforms:nodeset="cmdPath"/>
+                            <xforms:bind id="bind-appserver-logsDir" xforms:nodeset="logsDir"/>
+                            <xforms:bind id="bind-appserver-pidsDir" xforms:nodeset="pidsDir"/>
+                            <xforms:bind id="bind-appserver-rakePath" xforms:nodeset="rakePath"/>
+                        </xforms:bind>
                     </xforms:bind>
-                    <!-- addition here -->
-                    <xforms:bind id="bind-webServer-type" xforms:nodeset="type"/>
-                    <xforms:bind id="bind-webServer-binPath" xforms:nodeset="hostBinPath"/>
-                    <xforms:bind id="bind-webServer-logPath" xforms:nodeset="hostLogPath"/>
-                    <xforms:bind id="bind-webServer-confPath" xforms:nodeset="hostConfPath"/>                    
-                    <xforms:bind id="bind-webServer-phpIniPath" xforms:nodeset="phpIniPath"/>
                 </xforms:bind>
                  
-                                  
                 <xforms:bind id="bind-dbServer" xforms:nodeset="dbServer">
                     <xforms:bind id="bind-dbServer-hostConfig" xforms:nodeset="fa:hostConfig">
                         <xforms:bind id="bind-dbServer-host" xforms:nodeset="fa:host"/>
@@ -88,8 +110,12 @@
                     <xforms:bind id="bind-reloadDB" xforms:nodeset="reloadDB" xforms:type="boolean"/>
                     <xforms:bind id="bind-load-scale" xforms:nodeset="scale" xforms:type="positiveInteger"/>
                     <!-- addition here -->
-                    <xforms:bind id="bind-db-homePath" xforms:nodeset="dbHomePath" />
-                    <xforms:bind id="bind-db-confPath" xforms:nodeset="dbConfPath" />
+                    <xforms:bind id='bind-dbserver-service' xforms:nodeset='fh:service'>
+                      <xforms:bind id='bind-dbserver-service-config' xforms:nodeset='fh:config'>
+                        <xforms:bind id="bind-db-homePath" xforms:nodeset="serverHome" />
+                        <xforms:bind id="bind-db-confPath" xforms:nodeset="confPath" />
+					  </xforms:bind>
+                    </xforms:bind>
                 </xforms:bind>
                 <xforms:bind id="bind-dataStorage" xforms:nodeset="dataStorage">
                     <xforms:bind id="bind-dataStorage-hostConfig" xforms:nodeset="fa:hostConfig">
@@ -100,23 +126,22 @@
                     <xforms:bind id="bind-reloadMedia" xforms:nodeset="reloadMedia" xforms:type="boolean"/>
                     <xforms:bind id="bind-mediaDir" xforms:nodeset="mediaDir"/>
                 </xforms:bind>
-<!-- change here -->
+
                 <xforms:bind id="bind-cacheServers" xforms:nodeset="cacheServers">
                     <xforms:bind id="bind-cacheServers-hostConfig" xforms:nodeset="fa:hostConfig">
+                        <xforms:bind id="bind-cacheServers-enabled" xforms:nodeset='fh:enabled'/>
                         <xforms:bind id="bind-cacheServers-hostPorts" xforms:nodeset="fa:hostPorts"/>
                         <xforms:bind id="bind-cacheServers-tools" xforms:nodeset="fh:tools"/>
                         <xforms:bind id="bind-cacheServers-userCommands" xforms:nodeset="fh:userCommands"/>
                     </xforms:bind>
-                    <xforms:bind id="bind-cache-binPath" xforms:nodeset="cacheBinPath"/>
-                </xforms:bind>
-                <!-- Shanti - comenting for now, as not used
-                <xforms:bind id="bind-otherServers" xforms:nodeset="otherServers">
-                    <xforms:bind id="bind-otherServers-hostConfig" xforms:nodeset="fa:hostConfig">
-                        <xforms:bind id="bind-otherServers-host" xforms:nodeset="fa:host"/>
-                        <xforms:bind id="bind-otherServers-tools" xforms:nodeset="fh:tools"/>
+                    <xforms:bind id='bind-cacheServers-service' xforms:nodeset='fh:service'  >
+			            <xforms:bind id='bind-cacheServers-service-tools' xforms:nodeset='fh:tools'/>
+			            <xforms:bind id='bind-cacheServers-service-config' xforms:nodeset='fh:config'  >
+				            <xforms:bind id='bind-cacheServers-service-config-cmdPath' xforms:nodeset='cmdPath'/>
+				            <xforms:bind id='bind-cacheMemSize' xforms:nodeset='serverMemSize'/>
+			            </xforms:bind>
                     </xforms:bind>
                 </xforms:bind>
-                -->
             </xforms:bind>
         </xforms:model>
         <xforms:model id="benchmark-labels">
@@ -143,7 +168,10 @@
                     <delay>Time between starts (ms)</delay>
                     <simultaneous>Start simultaneously</simultaneous>
                     <parallel>Start agents in parallel</parallel>
-                    <webServer>Web&#160;Server</webServer>
+                    <proxyServer>Proxy Server</proxyServer>
+                    <railsServer>Rails Server</railsServer>
+                    <numInstances>Number of Instances</numInstances>
+                    <webServer>Web Server</webServer>
                     <dbServer>Database Server</dbServer>
                     <dataStorage>Data Storage Server</dataStorage>
                     <cacheServers>Memcached Servers</cacheServers>
@@ -154,17 +182,20 @@
                     <reloadDB>Reload Database</reloadDB>
                     <reloadMedia>Reload Images</reloadMedia>
                     <dbHomePath>Path for Database Home</dbHomePath>
-                    <webserverType>Web Server</webserverType>
-                    <webserverBinPath>Webserver bin Directory</webserverBinPath>
-                    <webserverLogPath>Webserver logs Directory</webserverLogPath>
-                    <webserverConfPath>Webserver config files Directory</webserverConfPath>
+                    <serverType>Server Type</serverType>
+                    <serverCmdPath>Server command</serverCmdPath>
+                    <serverConfPath>Server config file</serverConfPath>
+                    <serverLogsDir>Server logs directory</serverLogsDir>
+                    <serverPidsDir>Server pids directory</serverPidsDir>
+					<rakePath>Path to rake</rakePath>
+					<getAccLog>Get Access Log ? </getAccLog>
+					<appDir>Application home directory</appDir>
                     <mediaDir>Media Directory</mediaDir>
-                    <phpIniPath>php.ini Directory</phpIniPath>
-                    <dbConfPath>DB config file Directory</dbConfPath>
-                    <otherServers>Cache, Storage, or Other Servers</otherServers>
+                    <dbConfPath>DB config file</dbConfPath>
                     <agents>Agents</agents>
                     <statsInterval>Stats Collection Interval</statsInterval>
-                    <serverConfig>Server Information</serverConfig>
+                    <appserverConfig>App Server Information</appserverConfig>
+                    <proxyserverConfig>Proxy Server Information</proxyserverConfig>
                     <connectURL>Database Connection URL</connectURL>
                     <host>Host</host>
                     <hosts>Hosts</hosts>
@@ -172,6 +203,7 @@
                     <port>Port</port>
                     <cacheHostPorts>Memcached Hosts:Ports</cacheHostPorts>
                     <cacheBinPath>Memcached bin Directory</cacheBinPath>
+                    <serverMemSize>Memcached Max Memory(MB)</serverMemSize>
                     <pathConfig>URL Path Configurations</pathConfig>
                     <java>Java</java>
                     <php>PHP</php>
@@ -179,6 +211,8 @@
                     <apache>Apache</apache>
                     <lighttpd>lighttpd</lighttpd>
                     <glassfish>GlassFish</glassfish>
+                    <nginx>Nginx</nginx>
+                    <thin>Thin</thin>
                     <tools>Tools</tools>
                     <userCommands>User Commands</userCommands>
                     <ok>Ok</ok>
@@ -203,13 +237,15 @@
                     <xforms:toggle id="toggle-runConfig" xforms:case="case-runConfig"/>
                 </xforms:action>
             </xforms:trigger>
-            <xforms:trigger id="trigger-webServer">
+            
+            <xforms:trigger id="trigger-appserver">
                 <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/webServer"/>
-                <xforms:action id="action-webServer">
-                    <xforms:revalidate xforms:model="benchmark-model" id="revalidate-webServer"/>
-                    <xforms:toggle id="toggle-webServer" xforms:case="case-webServer"/>
+                <xforms:action id="action-appserver">
+                    <xforms:revalidate xforms:model="benchmark-model" id="revalidate-appserver"/>
+                    <xforms:toggle id="toggle-appserver" xforms:case="case-appserver"/>
                 </xforms:action>
             </xforms:trigger>
+            
             <xforms:trigger id="trigger-servers">
                 <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/servers"/>
                 <xforms:action id="action-servers">
@@ -247,8 +283,8 @@
                         </xforms:input>
                         <xforms:input id="input-agent-tools" xforms:bind="bind-agent-tools">
                             <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/tools"/>
-                            <xforms:hint>Enter tool commands to collect statistics, separated by semi-colon</xforms:hint>
-                            <xforms:help>Enter tool commands to collect statistics, separated by semi-colon</xforms:help>
+                            <xforms:hint>Enter commands to collect statistics on these hosts, separated by semi-colon</xforms:hint>
+                            <xforms:help>Enter commands to collect statistics on these hosts, separated by semi-colon</xforms:help>
                         </xforms:input>
                         <xforms:input id="input-agent-userCommands" xforms:bind="bind-agent-userCommands">
                             <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/userCommands"/>
@@ -320,75 +356,137 @@
                         </xforms:input>
                     </xforms:group>
                 </xforms:case>
-                <xforms:case id="case-webServer"> 
-                    <xforms:group id="group-serverConfig">
-                        <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/serverConfig"/>
-                        <xforms:input id="input-webServer-hostPorts" xforms:bind="bind-webServer-hostPorts">
+                <xforms:case id="case-appserver">
+                    <xforms:group id="group-appserverConfig">
+                        <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/appserverConfig"/>
+                        <xforms:input id="input-appserver-hostPorts" xforms:bind="bind-appserver-hostPorts">
                             <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/hostPorts"/>
                             <xforms:hint>The server host names or IP addresses and ports in the form host:port, space separated</xforms:hint>
                             <xforms:help>Enter the server host names or IP addresses and ports in the form host:port, space separated</xforms:help>
                         </xforms:input>
-                        <xforms:select1 id="select1-webServer-type" xforms:bind="bind-webServer-type">
-                             <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/webserverType"/>
+                        <xforms:select1 id="select1-appserver-type" xforms:bind="bind-appserver-type">
+                             <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/serverType"/>
                              <xforms:choices>
                                  <xforms:item>
-                                     <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/apache"/>
-                                     <xforms:value>apache</xforms:value>
+                                     <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/thin"/>
+                                     <xforms:value>thin</xforms:value>
+                                 </xforms:item>
+                                 <!--
+                                 <xforms:item>
+                                     <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/mongrel"/>
+                                     <xforms:value>mongrel</xforms:value>
                                  </xforms:item>
+                                 -->
+                                 <xforms:hint>Choose the app server type.</xforms:hint>
+                                 <xforms:help>Choose the app server type.</xforms:help>
+                             </xforms:choices>
+                         </xforms:select1>
+                        <xforms:input id="input-appserver-numInstances" xforms:bind="bind-appserver-numInstances" xforms:type="Integer">
+                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/numInstances"/>
+                            <xforms:hint>Enter the number of appserver instances</xforms:hint>
+                            <xforms:help>Enter the number of appserver instances</xforms:help>
+                        </xforms:input>
+                        <xforms:input id="input-appserver-cmdPath" xforms:bind="bind-appserver-cmdPath">
+                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/serverCmdPath"/>
+                            <xforms:hint>Enter the appserver command path</xforms:hint>
+                            <xforms:help>Enter the appserver command path to use for start/stop</xforms:help>
+                        </xforms:input>
+                        <xforms:input id="input-appserver-logsDir" xforms:bind="bind-appserver-logsDir">
+                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/serverLogsDir"/>
+                            <xforms:hint>Enter the path to the appserver logs directory</xforms:hint>
+                            <xforms:help>Enter the path to the appserver logs directory</xforms:help>
+                        </xforms:input>
+                        <xforms:input id="input-appserver-pidsDir" xforms:bind="bind-appserver-pidsDir">
+                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/serverPidsDir"/>
+                            <xforms:hint>Enter the path to the appserver pid files directory</xforms:hint>
+                            <xforms:help>Enter the path to the appserver pid files directory</xforms:help>
+                        </xforms:input>
+                        <xforms:input id="input-appserver-rakePath" xforms:bind="bind-appserver-rakePath">
+                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/rakePath"/>
+                            <xforms:hint>Enter the path to rake</xforms:hint>
+                            <xforms:help>Enter the path to rake</xforms:help>
+                        </xforms:input>
+                        <xforms:input id="input-appserver-appDir" xforms:bind="bind-appserver-appDir">
+                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/appDir"/>
+                            <xforms:hint>Enter the home directory of the rails application</xforms:hint>
+                            <xforms:help>Enter the home directory of the rails application</xforms:help>
+                        </xforms:input>
+                   
+                       <xforms:input id="input-appserver-tools" xforms:bind="bind-appserver-tools">
+                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/tools"/>
+                            <xforms:hint>Enter commands to collect statistics on these hosts, separated by semi-colon</xforms:hint>
+                            <xforms:help>Enter commands to collect statistics on these hosts, separated by semi-colon</xforms:help>
+                        </xforms:input>
+                        <xforms:input id="input-appserver-userCommands" xforms:bind="bind-appserver-userCommands">
+                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/userCommands"/>
+                            <xforms:hint>Enter any extra command or script to execute</xforms:hint>
+                            <xforms:help>Enter any extra command or script to execute</xforms:help>
+                        </xforms:input>
+                    </xforms:group>
+                    <xforms:group id="group-proxyserverConfig">
+                        <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/proxyserverConfig"/>
+                        <xforms:input id="input-proxyserver-hostPorts" xforms:bind="bind-proxyserver-hostPorts">
+                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/hostPorts"/>
+                            <xforms:hint>The server host names or IP addresses and ports in the form host:port, space separated</xforms:hint>
+                            <xforms:help>Enter the server host names or IP addresses and ports in the form host:port, space separated</xforms:help>
+                        </xforms:input>
+                        <xforms:select1 id="select1-proxyserver-type" xforms:bind="bind-proxyserver-type">
+                             <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/serverType"/>
+                             <xforms:choices>
                                  <xforms:item>
-                                     <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/lighttpd"/>
-                                     <xforms:value>lighttpd</xforms:value>
+                                     <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/nginx"/>
+                                     <xforms:value>nginx</xforms:value>
                                  </xforms:item>
                                  <xforms:item>
-                                     <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/glassfish"/>
-                                     <xforms:value>glassfish</xforms:value>
+                                     <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/apache"/>
+                                     <xforms:value>apache</xforms:value>
                                  </xforms:item>
-                                 <xforms:hint>Choose the web server type.</xforms:hint>
-                                 <xforms:help>Choose the web server type.</xforms:help>
+                                 <xforms:hint>Choose the proxy server type.</xforms:hint>
+                                 <xforms:help>Choose the proxy server type.</xforms:help>
                              </xforms:choices>
                          </xforms:select1>
-                        <xforms:input id="input-webServer-binPath" xforms:bind="bind-webServer-binPath">
-                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/webserverBinPath"/>
-                            <xforms:hint>Enter the path to the webserver bin directory</xforms:hint>
-                            <xforms:help>Enter the path to the webserver bin directory</xforms:help>
-                        </xforms:input>
-                        <xforms:input id="input-webServer-logPath" xforms:bind="bind-webServer-logPath">
-                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/webserverLogPath"/>
-                            <xforms:hint>Enter the path to the webserver logs directory</xforms:hint>
-                            <xforms:help>Enter the path to the webserver logs directory</xforms:help>
-                        </xforms:input>
-                        <xforms:input id="input-webServer-confPath" xforms:bind="bind-webServer-confPath">
-                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/webserverConfPath"/>
-                            <xforms:hint>Enter the path to the webserver config files directory</xforms:hint>
-                            <xforms:help>Enter the path to the webserver config files directory</xforms:help>
-                        </xforms:input>
-                        <xforms:input id="input-webServer-phpIniPath" xforms:bind="bind-webServer-phpIniPath">
-                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/phpIniPath"/>
-                            <xforms:hint>Enter the path to the directory containing php.ini</xforms:hint>
-                            <xforms:help>Enter the path to the directory containing php.ini</xforms:help>
+                        <xforms:input id="input-proxyserver-cmdPath" xforms:bind="bind-proxyserver-cmdPath">
+                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/serverCmdPath"/>
+                            <xforms:hint>Enter the proxyserver command path</xforms:hint>
+                            <xforms:help>Enter the proxyserver command path to use for start/stop</xforms:help>
+                        </xforms:input>
+                        <xforms:input id="input-proxyserver-confPath" xforms:bind="bind-proxyserver-confPath">
+                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/serverConfPath"/>
+                            <xforms:hint>Enter the path to the config file. Edit it for the correct number of upstream rails servers</xforms:hint>
+                            <xforms:help>Enter the path to the configuration file</xforms:help>
+                        </xforms:input>
+                        <xforms:input id="input-proxyserver-logsPath" xforms:bind="bind-proxyserver-logsDir">
+                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/serverLogsDir"/>
+                            <xforms:hint>Enter the path to the proxyserver logs directory</xforms:hint>
+                            <xforms:help>Enter the path to the proxyserver logs directory</xforms:help>
+                        </xforms:input>
+                        <xforms:input id="input-proxyserver-pidPath" xforms:bind="bind-proxyserver-pidDir">
+                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/serverPidsDir"/>
+                            <xforms:hint>Enter the path to the proxyserver pid file directory</xforms:hint>
+                            <xforms:help>Enter the path to the proxyserver pid file directory</xforms:help>
                         </xforms:input>
-
-                       <xforms:select1 id="select1-serverType" xforms:bind="bind-driver-serverType">
-                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/serverType"/>
+                        <xforms:select1 id="input-proxyserver-getAccLog" xforms:bind="bind-proxyserver-getAccLog">
+                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/getAccLog"/>
                             <xforms:choices>
                                 <xforms:item>
-                                    <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/java"/>
-                                    <xforms:value>jsp</xforms:value>
-                                </xforms:item>
+                                    <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/no"/>
+                                     <xforms:value>false</xforms:value>
+                                 </xforms:item>
                                 <xforms:item>
-                                    <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/php"/>
-                                    <xforms:value>php</xforms:value>
-                                </xforms:item>
-                                <xforms:hint>Choose the server architecture type.</xforms:hint>
-                                <xforms:help>Choose the server architecture type.</xforms:help>
+                                    <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/yes"/>
+                                     <xforms:value>true</xforms:value>
+                                 </xforms:item>
+                                <xforms:hint>Do you want to save the access log in the run output dir ?</xforms:hint>
+                                <xforms:help>Do you want to save the access log in the run output directory ?</xforms:help>
                             </xforms:choices>
-                        </xforms:select1>
-                       <xforms:input id="input-webServer-tools" xforms:bind="bind-webServer-tools">
+                          </xforms:select1>
+                   
+                       <xforms:input id="input-proxyserver-tools" xforms:bind="bind-proxyserver-tools">
                             <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/tools"/>
-                            <xforms:hint>Enter tool commands to collect statistics, separated by semi-colon</xforms:hint>
-                            <xforms:help>Enter tool commands to collect statistics, separated by semi-colon</xforms:help>
+                            <xforms:hint>Enter commands to collect statistics on these hosts, separated by semi-colon</xforms:hint>
+                            <xforms:help>Enter commands to collect statistics on these hosts, separated by semi-colon</xforms:help>
                         </xforms:input>
-                        <xforms:input id="input-webServer-userCommands" xforms:bind="bind-webServer-userCommands">
+                        <xforms:input id="input-proxyserver-userCommands" xforms:bind="bind-proxyserver-userCommands">
                             <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/userCommands"/>
                             <xforms:hint>Enter any extra command or script to execute</xforms:hint>
                             <xforms:help>Enter any extra command or script to execute</xforms:help>
@@ -435,8 +533,8 @@
                         </xforms:input>
                         <xforms:input id="input-dbServer-tools" xforms:bind="bind-dbServer-tools">
                             <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/tools"/>
-                            <xforms:hint>Enter tool commands to collect statistics, separated by semi-colon</xforms:hint>
-                            <xforms:help>Enter tool commands to collect statistics, separated by semi-colon</xforms:help>
+                            <xforms:hint>Enter commands to collect statistics on these hosts, separated by semi-colon</xforms:hint>
+                            <xforms:help>Enter commands to collect statistics on these hosts, separated by semi-colon</xforms:help>
                         </xforms:input>
                         <xforms:input id="input-dbServer-userCommands" xforms:bind="bind-dbServer-userCommands">
                             <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/userCommands"/>
@@ -483,8 +581,8 @@
                         </xforms:input>
                         <xforms:input id="input-dataStorage-tools" xforms:bind="bind-dataStorage-tools">
                             <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/tools"/>
-                            <xforms:hint>Enter tool commands to collect statistics, separated by semi-colon</xforms:hint>
-                            <xforms:help>Enter tool commands to collect statistics, separated by semi-colon</xforms:help>
+                            <xforms:hint>Enter commands to collect statistics on these hosts, separated by semi-colon</xforms:hint>
+                            <xforms:help>Enter commands to collect statistics on these hosts, separated by semi-colon</xforms:help>
                         </xforms:input>
                         <xforms:input id="input-dataStorage-userCommands" xforms:bind="bind-dataStorage-userCommands">
                             <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/userCommands"/>
@@ -501,35 +599,25 @@
                         </xforms:input>
                         <xforms:input id="input-cacheServers-tools" xforms:bind="bind-cacheServers-tools">
                             <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/tools"/>
-                            <xforms:hint>Enter tool commands to collect statistics, separated by semi-colon</xforms:hint>
-                            <xforms:help>Enter tool commands to collect statistics, separated by semi-colon</xforms:help>
+                            <xforms:hint>Enter commands to collect statistics on these hosts, separated by semi-colon</xforms:hint>
+                            <xforms:help>Enter commands to collect statistics on these hosts, separated by semi-colon</xforms:help>
                         </xforms:input>
                         <xforms:input id="input-cacheServers-userCommands" xforms:bind="bind-cacheServers-userCommands">
                             <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/userCommands"/>
                             <xforms:hint>Enter any extra command or script to execute</xforms:hint>
                             <xforms:help>Enter any extra command or script to execute</xforms:help>
                         </xforms:input>
-                        <xforms:input id="input-cacheServers-binPath" xforms:bind="bind-cache-binPath">
+                        <xforms:input id="input-cacheServers-binPath" xforms:bind="bind-cacheServers-service-config-cmdPath">
                             <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/cacheBinPath"/>
                             <xforms:hint>Enter the path to the cache server bin directory</xforms:hint>
                             <xforms:help>Enter the path to the cache server bin directory</xforms:help>
                         </xforms:input>
-                    </xforms:group>
-                    <!-- Shanti - commenting for now, as not used
-                    <xforms:group id="group-otherServers">
-                        <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/otherServers"/>
-                        <xforms:input id="input-otherServers-host" xforms:bind="bind-otherServers-host">
-                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/hosts"/>
-                            <xforms:hint>The servers' host names or IP addresses, space separated</xforms:hint>
-                            <xforms:help>Enter the servers' host names or IP addresses, space separated</xforms:help>
-                        </xforms:input>
-                        <xforms:input id="input-otherServers-tools" xforms:bind="bind-otherServers-tools">
-                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/tools"/>
-                            <xforms:hint>Enter tool commands to collect statistics, separated by semi-colon</xforms:hint>
-                            <xforms:help>Enter tool commands to collect statistics, separated by semi-colon</xforms:help>
+                        <xforms:input id="input-cache-memSize" xforms:bind="bind-cacheMemSize" xforms:type="positiveInteger">
+                            <xforms:label xforms:model="benchmark-labels" xforms:ref="/labels/serverMemSize"/>
+                            <xforms:hint>Enter the max. size in MB of the cache</xforms:hint>
+                            <xforms:help>Enter the max. size in MB of the cache</xforms:help>
                         </xforms:input>
                     </xforms:group>
-                    -->
                 </xforms:case>
             </xforms:switch>
         </xforms:group>

Modified: incubator/olio/workload/rails/trunk/deploy/run.xml
URL: http://svn.apache.org/viewvc/incubator/olio/workload/rails/trunk/deploy/run.xml?rev=815906&r1=815905&r2=815906&view=diff
==============================================================================
--- incubator/olio/workload/rails/trunk/deploy/run.xml (original)
+++ incubator/olio/workload/rails/trunk/deploy/run.xml Wed Sep 16 17:43:58 2009
@@ -71,25 +71,56 @@
             <runtimeStats target="9988"/>
 	    
             <properties>
-                <property name="serverType">html</property>
+                <property name="serverType">rails</property>
             </properties>            
         </driverConfig>
     </fa:runConfig>
+    <proxyServer>
+        <fa:hostConfig xmlns="http://faban.sunsource.net/ns/fabanharness" xmlns:fa="http://faban.sunsource.net/ns/faban">
+            <fa:hostPorts>proxyHost:80</fa:hostPorts>
+            <enabled>true</enabled>
+            <cpus>0</cpus>
+            <tools>vmstat 10; mpstat 10; nicstat 10</tools>
+            <userCommands/>
+        </fa:hostConfig>
+        <type>nginx</type>
+        <fh:service xmlns:fh="http://faban.sunsource.net/ns/fabanharness">
+            <fh:name>NginxService</fh:name>
+            <fh:tools>NONE</fh:tools>
+            <fh:restart>true</fh:restart>
+            <fh:config>
+                <cmdPath>/usr/nginx/sbin/nginx</cmdPath>
+                <logsDir>/var/nginx/logs</logsDir>
+                <pidDir>/var/nginx/logs</pidDir>
+                <confPath>/etc/nginx/nginx.conf</confPath>
+				<getAccLog>false</getAccLog>
+             </fh:config>
+        </fh:service>
+     </proxyServer>
     
     <webServer>
         <fa:hostConfig xmlns="http://faban.sunsource.net/ns/fabanharness" xmlns:fa="http://faban.sunsource.net/ns/faban">
-            <fa:hostPorts>webserverHost:8080</fa:hostPorts>
+            <fa:hostPorts>serverHost:3000</fa:hostPorts>
             <enabled>true</enabled>
             <cpus>0</cpus>
-            <tools>vmstat 10; mpstat 10; iostat -xn 10; nicstat 10</tools>           
+            <tools>vmstat 10; mpstat 10; nicstat 10</tools>           
             <userCommands/>            
         </fa:hostConfig>
-        <type></type>
-        <hostBinPath></hostBinPath>
-        <hostLogPath></hostLogPath>
-        <hostConfPath></hostConfPath>
-        <phpIniPath></phpIniPath>
-    </webServer>
+        <fh:service xmlns:fh="http://faban.sunsource.net/ns/fabanharness">
+            <fh:name>RailsService</fh:name>
+            <fh:tools>NONE</fh:tools>
+            <fh:restart>true</fh:restart>
+            <fh:config>
+                <type>thin</type>
+			    <appDir>/export/home/olio</appDir>
+                <cmdPath>/var/ruby/1.8/gem_home/bin/thin</cmdPath>
+                <logsDir>/var/log</logsDir>
+                <pidsDir>/var/run</pidsDir>
+                <numInstances>16</numInstances>
+				<rakePath>/var/ruby/1.8/gem_home/bin/rake</rakePath>
+             </fh:config>
+        </fh:service>
+     </webServer>
     <dbServer>
         <fa:hostConfig xmlns="http://faban.sunsource.net/ns/fabanharness" xmlns:fa="http://faban.sunsource.net/ns/faban">
             <fa:host>dbHost</fa:host>
@@ -102,8 +133,17 @@
         <connectURL>jdbc:mysql://dbHost/olio?user=olio&amp;password=olio&amp;relaxAutoCommit=true&amp;sessionVariables=FOREIGN_KEY_CHECKS=0</connectURL>
         <reloadDB>true</reloadDB>
         <scale>50</scale>
-        <dbHomePath>/opt/coolstack/mysql</dbHomePath>
-        <dbConfPath>/etc</dbConfPath>
+        <fh:service xmlns:fh="http://faban.sunsource.net/ns/fabanharness">
+            <fh:name>MySQLService</fh:name>
+            <fh:tools>Mysqlstats</fh:tools>
+            <fh:restart>false</fh:restart>
+            <fh:config>
+                <serverHome>/opt/coolstack/mysql</serverHome>
+                <user>olio</user>
+                <password>olio</password>
+                <confPath>/etc/my.cnf</confPath>
+             </fh:config>
+        </fh:service>
     </dbServer>
     <dataStorage>
         <fa:hostConfig xmlns:fa="http://faban.sunsource.net/ns/faban"
@@ -120,23 +160,19 @@
     <cacheServers>
         <fa:hostConfig xmlns="http://faban.sunsource.net/ns/fabanharness" xmlns:fa="http://faban.sunsource.net/ns/faban">
 		    <fa:hostPorts>cacheHost:11211</fa:hostPorts>
-            <enabled>true</enabled>
+            <enabled>false</enabled>
             <cpus>0</cpus>
             <tools>NONE</tools>
             <userCommands/>
         </fa:hostConfig>
-        <cacheBinPath></cacheBinPath>
+        <fh:service xmlns:fh="http://faban.sunsource.net/ns/fabanharness">
+            <fh:name>MemcachedService</fh:name>
+            <fh:tools>MemcacheStats -i 10</fh:tools>
+            <fh:restart>true</fh:restart>
+            <fh:config>
+                <cmdPath>/usr/lib/memcached</cmdPath>
+                <serverMemSize>256</serverMemSize>
+             </fh:config>
+        </fh:service>
     </cacheServers>
-    <!-- Shanti - commenting as not used
-    <otherServers>
-        <fa:hostConfig xmlns="http://faban.sunsource.net/ns/fabanharness" xmlns:fa="http://faban.sunsource.net/ns/faban">
-            <fa:host></fa:host>
-            <enabled>true</enabled>
-            <cpus>0</cpus>
-            <tools>NONE</tools>
-            <userCommands/>
-        </fa:hostConfig>
-        <serverList></serverList>
-    </otherServers>
-    -->
 </olio>

Added: incubator/olio/workload/rails/trunk/src/org/apache/olio/services/NginxService.java
URL: http://svn.apache.org/viewvc/incubator/olio/workload/rails/trunk/src/org/apache/olio/services/NginxService.java?rev=815906&view=auto
==============================================================================
--- incubator/olio/workload/rails/trunk/src/org/apache/olio/services/NginxService.java (added)
+++ incubator/olio/workload/rails/trunk/src/org/apache/olio/services/NginxService.java Wed Sep 16 17:43:58 2009
@@ -0,0 +1,314 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.olio.services;
+
+import com.sun.faban.common.Command;
+import com.sun.faban.common.CommandHandle;
+import com.sun.faban.common.Utilities;
+import com.sun.faban.harness.*;
+import com.sun.faban.harness.services.ServiceContext;
+
+import com.sun.faban.harness.RemoteCallable;
+import com.sun.faban.harness.services.GetLogs;
+import com.sun.faban.harness.services.ClearLogs;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class implements the service to start/stop Nginx instances.
+ * It also provides functionality to transfer the portion of the nginx
+ * error_log for a run to the run output directory.
+ * It can be used by any benchmark to manage nginx servers and
+ * perform these operations remotely using this Service.
+ *
+ * @author Shanti Subramanyam
+ * Based on ApacheHttpdService provided in faban sample services.
+ * It is assumed that nginx resides in the same path on all hosts.
+ */
+public class NginxService {
+
+    /** Injected service context. */
+    @Context public ServiceContext ctx;
+    private Logger logger = Logger.getLogger(NginxService.class.getName());
+    private String[] myServers = new String[1];
+    private String nginxCmd, confFile, errlogFile, acclogFile; 
+	private static String pidFile;
+	private boolean getAccLog = false;
+    CommandHandle nginxHandles[];
+	private boolean skipService = false;
+
+    /**
+     * Configures the service.
+     * Assumptions: 
+	 * The log files are named access.log and error.log
+	 * The pid file is named nginx.pid
+	 * It is the user's responsibility to edit the nginx.conf file
+	 * and set all parameters appropriately.
+     */
+    @Configure
+    public void configure() {
+        myServers = ctx.getUniqueHosts();
+		if (myServers == null) {
+			skipService = true;
+			return;
+        }
+
+        nginxCmd = ctx.getProperty("cmdPath");
+        confFile = ctx.getProperty("confPath");
+		nginxCmd = nginxCmd + " -c " + confFile;
+		getAccLog = Boolean.parseBoolean(ctx.getProperty("getAccLog"));
+
+        String logsDir = ctx.getProperty("logsDir");
+        if (!logsDir.endsWith(File.separator)) {
+            logsDir = logsDir + File.separator;
+        }
+        errlogFile = logsDir + "error.log";
+        acclogFile = logsDir + "access.log";
+
+        String pidDir = ctx.getProperty("pidDir");
+        if (!pidDir.endsWith(File.separator)) {
+            pidDir = pidDir + File.separator;
+        }
+        pidFile = pidDir + "nginx.pid";
+        logger.fine("pidFile is " + pidFile);
+
+        nginxHandles = new CommandHandle[myServers.length];
+    }
+
+    /**
+     * Starts up the Nginx web server.
+     */
+    @Start
+    public void startup() {
+		if (skipService) return;
+        Command startCmd = new Command(nginxCmd);
+        // startCmd.setSynchronous(false); // to run in bg
+
+        for (int i = 0; i < myServers.length; i++) {
+            String server = myServers[i];
+            try {
+                // Run the command in the foreground and wait for the start
+                nginxHandles[i] = RunContext.exec(server, startCmd);
+
+                if (checkServerStarted(server)) {
+                    logger.fine("Completed nginx startup successfully on " +
+                            server);
+                } else {
+                    logger.severe("Failed to find " + pidFile + " on " + server);
+                }
+
+            } catch (Exception e) {
+                logger.log(Level.WARNING, "Failed to start nginx server.", e);
+            }
+        }
+    }
+
+    /*
+     * Check if server started by looking for pidfile
+     * @param String hostName
+     * @return boolean
+     */
+    private boolean checkServerStarted(String hostName) 
+		throws Exception {
+
+        boolean val = false;
+        // We will check for the existence of the pid file
+
+        // Just to make sure we don't wait for ever.
+        // We try to read the msg 20 times before we give up
+        // Sleep 1 sec between each try. So wait for 20 secs
+        int attempts = 20;
+        while (attempts > 0) {
+            if (RunContext.isFile(hostName, pidFile)) {
+                val = true;
+                break;
+            } else {
+                // Sleep for some time
+                try {
+                    Thread.sleep(1000);
+                    attempts--;
+                } catch (Exception e) {
+                    break;
+                }
+            }
+        }
+        return (val);
+    }
+
+    /*
+     * Return nginx pid
+     * It reads the pid file from the remote server host and
+     * returns the pid stored in it.
+     * @param String hostName
+     * @return int pid
+     * @throws Exception
+     */
+    private static int getPid(String hostName) throws Exception {
+        int pid;
+		final String pfile = Utilities.convertPath(pidFile);
+
+		if (! RunContext.isFile(hostName, pfile))
+			return -1;
+
+        pid = RunContext.exec(hostName, new RemoteCallable<Integer>() {
+            public Integer call() throws Exception {
+                String pidval;
+
+                // FileInputStream is = new FileInputStream(Utilities.convertPath(pidFile));
+                FileInputStream is = new FileInputStream(pfile);
+                BufferedReader bufR = new BufferedReader(new InputStreamReader(is));
+                pidval = bufR.readLine();
+                bufR.close();
+                return (Integer.parseInt(pidval));
+            }
+        });
+        return (pid);
+    }
+
+    /**
+     * Shuts down the Nginx web server.
+     * @throws IOException Error executing the shutdown
+     * @throws InterruptedException Interrupted waiting for the shutdown
+     */
+    @Stop
+    public void shutdown() throws IOException, InterruptedException {
+		if (skipService) return;
+        int pid = -1;
+        for (String hostName : myServers) {
+            //Retrieve the pid value
+            try {
+                pid = getPid(hostName);
+                logger.fine("Found nginx pidvalue of " + pid +
+                        " on host " + hostName);
+            } catch (Exception ee) {
+                logger.log(Level.WARNING, "Failed to read nginx pidfile on " +
+                        hostName + " with " + ee);
+                logger.log(Level.FINE, "Exception", ee);
+            }
+            if (pid <= 0) {
+                continue;
+            }
+            // Now kill the server
+            Command cmd = new Command("kill " + pid);
+            try {
+                RunContext.exec(hostName, cmd);
+                // Check if the server truly stopped
+                if (!checkServerStopped(hostName))
+                        logger.severe("Cannot kill nginx pid " + pid + " on " + hostName);
+            } catch (Exception re) {
+                logger.log(Level.WARNING, "Failed to stop Nginx server on " + hostName);
+                logger.log(Level.FINE, "Exception", re);
+            }
+        }
+    }
+
+    /*
+     * Check if server stopped by looking for pidfile
+     * @param String hostName
+     * @return boolean
+     */
+    private static boolean checkServerStopped(String hostName) 
+		throws Exception {
+        boolean val = false;
+        // We will check for the existence of the pid file
+
+        // Just to make sure we don't wait for ever.
+        // We try to read the msg 20 times before we give up
+        // Sleep 1 sec between each try. So wait for 20 secs
+        int attempts = 20;
+        while (attempts > 0) {
+            if ( !RunContext.isFile(hostName, pidFile)) {
+                val = true;
+                break;
+            } else {
+                // Sleep for some time
+                try {
+                    Thread.sleep(1000);
+                    attempts--;
+                } catch (Exception e) {
+                    break;
+                }
+            }
+        }
+        return (val);
+    }
+
+    /**
+     * Clears the Nginx web server logs - the access and error logs.
+     */
+    @ClearLogs
+    public void clearLogs() {
+		if (skipService) return;
+        for (int i = 0; i < myServers.length; i++) {
+            if (RunContext.isFile(myServers[i], errlogFile)) {
+                if (!RunContext.deleteFile(myServers[i], errlogFile)) {
+                    logger.log(Level.WARNING, "Delete of " + errlogFile +
+                            " failed on " + myServers[i]);
+                }
+            }
+            if (RunContext.isFile(myServers[i], acclogFile)) {
+                if (!RunContext.deleteFile(myServers[i], acclogFile)) {
+                    logger.log(Level.WARNING, "Delete of " + acclogFile +
+                            " failed on " + myServers[i]);
+                }
+            }
+
+            logger.fine("Logs cleared for " + myServers[i]);
+        }
+    }
+
+    /*
+     * transfer log files
+     * This method copies over the error log to the run output directory
+     * It will optionally copy over the access log if the user has
+     * requested it
+     */
+    @GetLogs
+    public void getLogs() {
+		if (skipService) return;
+        for (int i = 0; i < myServers.length; i++) {
+            String outFile = RunContext.getOutDir() + "nginx_err.log." +
+                    RunContext.getHostName(myServers[i]);
+
+            /*
+             * copy the error_log to the master
+             * TODO: Truncate the error log to contain only entries for
+             * this run. However, since by default we clearLogs before
+             * the run, this is okay
+             */
+            if (!RunContext.getFile(myServers[i], errlogFile, outFile)) {
+                logger.warning("Could not copy " + errlogFile + " to " + outFile);
+            }
+			if (getAccLog) {
+			String accFile = RunContext.getOutDir() + "nginx_acc.log." +
+				RunContext.getHostName(myServers[i]);
+            if (!RunContext.getFile(myServers[i], acclogFile, accFile))
+                logger.warning("Could not copy " + acclogFile + " to " + accFile);
+            }
+            logger.fine("getLogs completed for " + myServers[i]);
+        }
+
+    }
+}

Added: incubator/olio/workload/rails/trunk/src/org/apache/olio/services/RailsService.java
URL: http://svn.apache.org/viewvc/incubator/olio/workload/rails/trunk/src/org/apache/olio/services/RailsService.java?rev=815906&view=auto
==============================================================================
--- incubator/olio/workload/rails/trunk/src/org/apache/olio/services/RailsService.java (added)
+++ incubator/olio/workload/rails/trunk/src/org/apache/olio/services/RailsService.java Wed Sep 16 17:43:58 2009
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.olio.services;
+
+import com.sun.faban.common.Command;
+import com.sun.faban.common.CommandHandle;
+import com.sun.faban.common.NameValuePair;
+import com.sun.faban.harness.*;
+
+
+import com.sun.faban.harness.services.ClearLogs;
+import com.sun.faban.harness.services.GetLogs;
+import com.sun.faban.harness.services.ServiceContext;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.logging.Logger;
+import java.util.List;
+
+/**
+ * This class implements the service to manage Rails servers.
+ * It only manages the rails application specific functionality and
+ * passes the actual server handling to the underlying appserver classes.
+ * It also provides functionality to transfer the portion of the app
+ * production log for a run to the run output directory.
+ * It can be used by any benchmark to manage rails servers and
+ * perform these operations remotely using this Service.
+ *
+ * @author Shanti Subramanyam
+ * 
+ */
+public class RailsService {
+ /** Injected service context. */
+    @Context public ServiceContext ctx;
+    private Logger logger = Logger.getLogger(ThinService.class.getName());
+
+    private String[] myServers;
+	private List<NameValuePair<Integer>> hostPorts;
+    private String serverType, appDir, rakePath;
+    private String appLogFile, appConfFile;
+	private Thin thin;
+
+	private boolean skipService = false;
+
+    @Configure public void configure() {
+		String pidFile, errlogFile;
+
+        myServers = ctx.getUniqueHosts();
+        hostPorts = ctx.getUniqueHostPorts();
+		if (hostPorts == null || hostPorts.get(0) == null) {
+			skipService = true; 
+			return;
+        }
+		serverType = ctx.getProperty("type");
+		if (serverType.equals("thin"))
+			thin = new Thin(ctx);
+		   
+		appDir = ctx.getProperty("appDir");
+		if (appDir == null) {
+			logger.warning("appDir property not set. Assuming /export/home/oliorails");
+			appDir = "/export/home/oliorails";
+        }
+
+        // We need to locate rake
+		rakePath = ctx.getProperty("rakePath");
+		if (rakePath == null) {
+			logger.warning("rakePath not set. Assuming /var/ruby/1.8/gem_home/bin");
+			rakePath = "/var/ruby/1.8/gem_home/bin";
+		}
+		if (!rakePath.endsWith(File.separator))
+			rakePath = rakePath + File.separator;
+		appLogFile = appDir + File.separator + "log" + 
+                File.separator + "production.log";
+        appConfFile = appDir + File.separator + "config" +
+                File.separator + "environment.rb";
+    }
+
+    /**
+     * Starts up the Rails server.
+     */
+    @Start
+    public void startup() {
+		if (skipService) return;
+		if (serverType.equals("thin"))
+			thin.startup();
+    }
+
+    /**
+     * Shuts down the Rails server.
+     * @throws IOException Error executing the shutdown
+     * @throws InterruptedException Interrupted waiting for the shutdown
+     */
+    @Stop
+    public void shutdown() throws IOException, InterruptedException {
+        if (skipService) return;
+		if (serverType.equals("thin"))
+			thin.shutdown();
+    }
+
+    /**
+     * Clears the Thin server logs 
+     */
+    @ClearLogs
+    public void clearLogs() {
+		if (skipService) return;
+		String rake = rakePath + " tmp:clear";
+		Command rakeCmd = new Command(rake);
+		rakeCmd.setWorkingDirectory(appDir);
+        rakeCmd.setStreamHandling(Command.STDOUT, Command.CAPTURE);
+
+        for (String server : myServers) {
+			// Clear app log
+			if (RunContext.isFile(server, appLogFile))
+				RunContext.deleteFile(server, appLogFile);
+            try {
+		        // Clear app cache
+			    logger.fine("Now clearing application cache on " + server);
+			    RunContext.exec(server, rakeCmd);
+           } catch (Exception ee) {
+			   logger.warning("Failed to run 'rake tmp:clear' on " + server);
+           }
+        }
+		if (serverType.equals("thin"))
+			thin.clearLogs();
+    }
+
+    /*
+     * transfer log files
+     * This method copies over the application error log to the run 
+	 * output directory. It also copies the environment.rb file.
+     */
+    @GetLogs
+    public void getLogs() {
+        if (skipService) return;
+		Command rcmd = new Command("rails_env.sh");
+        rcmd.setStreamHandling(Command.STDOUT, Command.CAPTURE);
+		
+        for (int i = 0; i < myServers.length; i++) {
+            String outFile = RunContext.getOutDir() + "rails_err.log." +
+                RunContext.getHostName(myServers[i]);
+
+            // copy the error_log to the master
+            if (!RunContext.getFile(myServers[i], appLogFile, outFile)) {
+                logger.warning("Could not copy " + appLogFile + " to " + outFile);
+                return;
+            }
+            outFile = RunContext.getOutDir() + "rails_env.rb.log." +
+                RunContext.getHostName(myServers[i]);
+            if (!RunContext.getFile(myServers[i], appConfFile, outFile)) {
+                logger.warning("Could not copy " + appConfFile + " to " + outFile);
+                return;
+            }
+            try {
+            // get ruby related config info
+			CommandHandle ch = RunContext.exec(myServers[i], rcmd);
+            outFile = RunContext.getOutDir() + "ruby_config.log." +
+                RunContext.getHostName(myServers[i]);
+			ch.fetchOutput(Command.STDOUT, outFile);
+            } catch (Exception e) {
+                logger.warning("Could not execute/fetch ruby config on " + myServers[i]);
+            }
+            logger.fine("getLogs Completed for " + myServers[i]);
+        }
+    }
+}

Added: incubator/olio/workload/rails/trunk/src/org/apache/olio/services/Thin.java
URL: http://svn.apache.org/viewvc/incubator/olio/workload/rails/trunk/src/org/apache/olio/services/Thin.java?rev=815906&view=auto
==============================================================================
--- incubator/olio/workload/rails/trunk/src/org/apache/olio/services/Thin.java (added)
+++ incubator/olio/workload/rails/trunk/src/org/apache/olio/services/Thin.java Wed Sep 16 17:43:58 2009
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.olio.services;
+
+import com.sun.faban.common.Command;
+import com.sun.faban.common.CommandHandle;
+import com.sun.faban.common.Utilities;
+import com.sun.faban.common.NameValuePair;
+import com.sun.faban.harness.*;
+
+import com.sun.faban.harness.services.ServiceContext;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.rmi.RemoteException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.List;
+
+/**
+ * This class implements the service to start/stop Thin instances.
+ * It also provides functionality to transfer the portion of the thin
+ * error logs for a run to the run output directory.
+ * The user can specify the number of thins to start. It will use
+ * port numbers starting from the user-specified value for the instances.
+ * Note that the same starting port# must be specified for ALL hosts
+ * We just pick the first host's port (if not specified, defaults to 3000).
+ * It can be used by any benchmark to manage thin servers and
+ * perform these operations remotely using this Service.
+ *
+ * @author Shanti Subramanyam
+ * Based on LighttpdService provided in faban sample services.
+ * 
+ */
+public class Thin {
+    private ServiceContext ctx;
+    private Logger logger = Logger.getLogger(ThinService.class.getName());
+
+    private static final int PORT = 3000;
+    private final String logName = "thin.log";
+    private final String pidName = "thin.pid";
+    private String logFileNames[];
+    private static String pidFileNames[];
+   
+    private String[] myServers;
+	private List<NameValuePair<Integer>> hostPorts;
+    private String thinCmd, appDir, logsDir, pidsDir;
+    private String appLogFile, appConfFile;
+    private static int numInstances, startPort;
+    CommandHandle thinHandles[];
+
+
+    public Thin(ServiceContext ctx) {
+		this.ctx = ctx;
+		String pidFile, errlogFile;
+
+        myServers = ctx.getUniqueHosts();
+        hostPorts = ctx.getUniqueHostPorts();
+		startPort = hostPorts.get(0).value;
+		if (startPort == 0)
+			startPort = PORT;
+        thinCmd = ctx.getProperty("cmdPath");
+        if (!thinCmd.endsWith(" ")) {
+            thinCmd = thinCmd + " ";
+        }
+        numInstances = Integer.parseInt(ctx.getProperty("numInstances"));
+		if (numInstances == 0)
+			numInstances = 1;
+		appDir = ctx.getProperty("appDir");
+		if (appDir == null) {
+			logger.warning("appDir property not set. Assuming /export/home/oliorails");
+			appDir = "/export/home/oliorails";
+        }
+        logsDir = ctx.getProperty("logsDir");
+        if (!logsDir.endsWith(File.separator)) {
+            logsDir = logsDir + File.separator;
+        }
+
+        pidsDir = ctx.getProperty("pidsDir");
+        if (!pidsDir.endsWith(File.separator)) {
+            pidsDir = pidsDir + File.separator;
+        }
+
+        pidFile = pidsDir + pidName;
+		errlogFile = logsDir + logName;
+
+        //Create all the pid and log filenames
+        logFileNames = new String[numInstances];
+        pidFileNames = new String[numInstances];
+        for (int i = 0; i < numInstances; i++) {
+            logFileNames[i] = logsDir + "thin." + (startPort + i) +  ".log";
+            pidFileNames[i] = pidsDir + "thin." + (startPort + i) + ".pid";
+        }
+
+        thinCmd = thinCmd + "-p " + startPort + " -d -e production -s " + numInstances +
+                " --log " + errlogFile + " --pid " + pidFile + " start";
+        thinHandles = new CommandHandle[myServers.length];
+    }
+
+    /**
+     * Starts up the Thin server.
+     */
+    public void startup() {
+        Command startCmd = new Command(thinCmd);
+		startCmd.setWorkingDirectory(appDir);
+        startCmd.setStreamHandling(Command.STDOUT, Command.CAPTURE);
+
+        for (int i = 0; i < myServers.length; i++) {
+            String server = myServers[i];
+            try {
+                // Run the command in the foreground and wait for the start
+                thinHandles[i] = RunContext.exec(server, startCmd);
+
+                if (checkServerStarted(server)) {
+                    logger.fine("Completed thin startup successfully on " +
+                            server);
+                } else {
+                    logger.severe("Failed to find " + pidName + " on " + server);
+                }
+
+            } catch (Exception e) {
+                logger.log(Level.WARNING, "Failed to start thin server.", e);
+            }
+        }
+    }
+
+    /*
+     * Check if server started by looking for pidfiles
+     * @param String hostName
+     * @return boolean
+     */
+    private static boolean checkServerStarted(String hostName) throws Exception {
+        boolean val = false;
+        // We will check pid files for 1st and last instances;
+
+        // Just to make sure we don't wait for ever.
+        // We try to read the msg 20 times before we give up
+        // Sleep 1 sec between each try. So wait for 20 secs
+        int attempts = 20;
+        while (attempts > 0) {
+            if (RunContext.isFile(hostName, pidFileNames[0]) &&
+                    RunContext.isFile(hostName, pidFileNames[numInstances - 1])) {
+                val = true;
+                break;
+            } else {
+                // Sleep for some time
+                try {
+                    Thread.sleep(1000);
+                    attempts--;
+                } catch (Exception e) {
+                    break;
+                }
+            }
+        }
+        return (val);
+    }
+
+    /*
+     * Return thin pids
+     * It reads the pid file from the remote server host for the
+     * specified instance and returns the pid stored in it.
+     * @param String hostName
+	 * @param int num - the instance# of the thin server
+     * @return int pid if pidfile exists, otherwise -1
+     * @throws Exception
+     */
+    private static int getPid(String hostName, int num) throws Exception {
+        final String host = hostName;
+        final String file = Utilities.convertPath(pidFileNames[num]);
+        int pid;
+
+        if ( !RunContext.isFile(host, file)) {
+			return -1;
+        }
+        pid = RunContext.exec(host, new RemoteCallable<Integer>() {
+
+            public Integer call() throws Exception {
+                String pidval;
+
+                FileInputStream is = new FileInputStream(file);
+                BufferedReader bufR = new BufferedReader(new InputStreamReader(is));
+                pidval = bufR.readLine();
+                bufR.close();
+                return (Integer.parseInt(pidval));
+            }
+        });
+        return (pid);
+    }
+
+    /**
+     * Shuts down the Thin web server.
+     * @throws IOException Error executing the shutdown
+     * @throws InterruptedException Interrupted waiting for the shutdown
+     */
+    public void shutdown() throws IOException, InterruptedException {
+        for (String hostName : myServers) {
+            //Retrieve the pid values
+            for (int i = 0; i < numInstances; i++) {
+                int pid = 0;
+                try {
+                    pid = getPid(hostName, i);
+                } catch (Exception ee) {
+                    logger.log(Level.WARNING, "Failed to read thin pidfile on " +
+                            hostName + " with " + ee);
+                    logger.log(Level.FINE, "Exception", ee);
+                }
+                // Now kill the server
+                if (pid <= 0) {
+                    continue;
+                }
+                Command cmd = new Command("kill " + pid);
+				logger.fine("Now killing " + pid + " on " + hostName);
+                try {
+                    RunContext.exec(hostName, cmd);
+                } catch (RemoteException re) {
+                    logger.log(Level.WARNING, "Failed to stop Thin server(s) on " +
+                            hostName);
+                    logger.log(Level.FINE, "Exception: ", re);
+                }
+            }
+        }
+    }
+
+    /**
+     * Clears the Thin server logs 
+     */
+    public void clearLogs() {
+        for (String server : myServers) {
+            // Clear thin logs
+            for (int i = 0; i < logFileNames.length; i++) {
+                if (RunContext.isFile(server, logFileNames[i])) {
+                    if (!RunContext.deleteFile(server, logFileNames[i])) {
+                        logger.log(Level.WARNING, "Delete of " + logFileNames[i] +
+                                " failed on " + server);
+                    }
+                }
+            }
+        }
+    }
+
+    /*
+     * transfer log files
+     */
+    public void getLogs() {
+    }
+}