How to run JobScheduler with Jetty

From JobScheduler
Jump to: navigation, search


JobScheduler currently comes with a proprietary built-in web server. However, it is possible to configure JobScheduler to work with Jetty by using the JobScheduler plugin feature. This document describes what you have to do to run JobScheduler with an underlying Jetty web server.

Contents

Installation

Since release 1.3.12.2163 the JobScheduler installer contains a plugin for Jetty. Note that this plugin is still under development and is provided "as is".

The installer tries to generate some symlinks to simulate virtual directories for JOC (JobScheduler Operations Center). The symlink generation is not supported for Windows older than Vista.

The installer configures the ./config/factory.ini, the ./config/jetty.xml and the ./config/web.xml files as described below.

The installer does not configure the ./config/scheduler.xml file. If you want to use Jetty then you must configure ./config/scheduler.xml itself as described below.

The installer contains a keystore file for testing https. This keystore is not trusted and has a wrong hostname inside, but can still be used for testing.

Please make your own keystore file jetty.jks.

After the installation you can open JOC with Jetty via

  • http://localhost:40444
  • https://localhost:48444

You can change these ports in the ./config/jetty.xml.

If you have multiple JobScheduler installations at the same machine then you have to change the ports of jetty so that they will not be used twice.

Configure factory.ini (Put the necessary libraries in the classpath)

To run JobScheduler with Jetty instead the built-in web-server you have to use the Jetty plugin. It is a part of the library com.sos.scheduler.engine.plugins.jetty-xxx.jar. Beside the com.sos.scheduler.engine.plugins.jetty-xxx.jar it is necessary to put the dependent libraries for the Jetty plugin into the classpath of the JobScheduler. The installer puts them into the ./lib/jetty_ext folder and adds them to the classpath in the ./config/factory.ini.

Unix

...
[java]
class_path = ${SCHEDULER_HOME}/lib/*.jar:${SCHEDULER_HOME}/lib/hibernate/*.jar:${SCHEDULER_HOME}/lib/jetty_ext/*.jar
...

Windows

...
[java]
class_path = ${SCHEDULER_HOME}/lib/*.jar;${SCHEDULER_HOME}/lib/hibernate/*.jar;${SCHEDULER_HOME}/lib/jetty_ext/*.jar
...

Configure scheduler.xml

To use the Jetty plugin you have to configure it in the scheduler.xml:

<spooler>
 <config ...>
   ...
   <security ignore_unknown_hosts="yes">
     <allowed_host host="localhost" level="all"/>
     <allowed_host host="192.11.0" level="all"/>
   </security>
   
   <plugins>
     ...
     <plugin java_class="com.sos.scheduler.engine.plugins.jetty.JettyPlugin">
       <plugin.config />
     </plugin>
     ...
   </plugins>
   ...
 </config>
</spooler>

Please note that it is necessary to specify an empty plugin.config element.

Simple user authentication

It is possible to configure a simple user authentication in the plugin configuration, e.g.

<plugins>
  <plugin java_class="com.sos.scheduler.engine.plugins.jetty.JettyPlugin">
    <plugin.config>
      <loginService>
        <logins>
          <login name="testName" password="testPassword" roles="SecurityLevel.all"/>
        </logins>
      </loginService>
    </plugin.config>
  </plugin>
</plugins>

SecurityLevel.info and SecurityLevel.all are predefined roles for JobScheduler.

SecurityLevel.info allows only rights for watching but not for starting jobs, while SecurityLevel.all allows additionally the right for starting jobs.

Add a security constraint to the web.xml:

   <security-constraint>
       <web-resource-collection>
           <url-pattern>/*</url-pattern>
       </web-resource-collection>
       <auth-constraint>
           <role-name>SecurityLevel.info</role-name>
           <role-name>SecurityLevel.all</role-name>
       </auth-constraint>
   </security-constraint>


Configure jetty.xml

To run JobScheduler with Jetty it is also necessary to create two configuration files for the Jetty web server (./config/jetty.xml and ./config/web.xml). The minimal declaration defines a connector for the port to communicate with JobScheduler via http:

<Configure class="org.eclipse.jetty.server.Server">
  <Call name="addConnector">
    <Arg>
      <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
        <Set name="port">40444</Set>
      </New>
    </Arg>
  </Call>
</Configure>

It is important to know that this port (here 40444) is a substitute for the port attribute in the config element of scheduler.xml.
At the moment both ports are required.

With a second connector it is possible to define a communication channel via https (ssl):

<Call name="addConnector">
 <Arg>
   <New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
     <Arg>
       <New class="org.eclipse.jetty.util.ssl.SslContextFactory">
         <Set name="keyStore"><SystemProperty name="jetty.home" default="." />/ssl/jetty.jks</Set>
         <Set name="keyStorePassword">jobscheduler</Set>
         <Set name="keyManagerPassword">jobscheduler</Set>
         <Set name="trustStore"><SystemProperty name="jetty.home" default="." />/ssl/jetty.jks</Set>
         <Set name="trustStorePassword">jobscheduler</Set>
       </New>
     </Arg>
     <Set name="port">48444</Set>
     <Set name="maxIdleTime">30000</Set>
   </New>
 </Arg>
</Call>

The SSL connection expects the jetty keystore file jetty.jks in the subfolder ssl (under the JobScheduler data folder). With the configuration above you can connect JobScheduler via https at port 48444.

keystore

To generate a keystore file use keytool:

keytool -genkey -alias jetty -keyalg RSA -keysize 1024 -dname "CN=[hostname], OU=JobScheduler, O=SOS GmbH, L=Berlin C=DE" -keystore my_jetty.jks -storepass jobscheduler -keypass jobscheduler -validity 1826

whereas [hostname] should be the JobScheduler host. Use also your own values for OU=, O= and L=.

Configure web.xml

To run JobScheduler with jetty it is also necessary to create two configuration files for the Jetty web server ( jetty.xml and web.xml). It has to place in the root of your config folder.

You must configure the JOC servlet with the JobScheduler installation path. Note that you must use the file protocol.

For Example:

  • file:///c:/Program Files (x86)/sos-berlin.com/jobscheduler/[scheduler_id] on Windows
  • file:///opt/sos-berlin.com/jobscheduler/[scheduler_id] on Linux
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" 
         xmlns="http://java.sun.com/xml/ns/j2ee" 
         version="2.4">
   <display-name>JobScheduler test configuration (web.xml)</display-name>
   <servlet>
       <servlet-name>Default</servlet-name>
       <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
       <init-param>
           <param-name>dirAllowed</param-name>
           <param-value>false</param-value>
       </init-param>
   </servlet>
   <servlet-mapping>
       <servlet-name>Default</servlet-name>
       <url-pattern>/</url-pattern>
   </servlet-mapping>
   <servlet>
       <servlet-name>JOC</servlet-name>
       <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
       <init-param>
           <param-name>resourceBase</param-name>
           <param-value>file:///c:/Program Files (x86)/sos-berlin.com/jobscheduler/scheduler</param-value>
       </init-param>
   </servlet>
   <servlet-mapping>
       <servlet-name>JOC</servlet-name>
       <url-pattern>/operations_gui/*</url-pattern>
   </servlet-mapping>
</web-app>

Send commands via HTTP (POST|GET)

If you use jetty and you want to send a command (e.g. <show_state/>) to the JobScheduler then you must use the URL:

 http://localhost:40444/jobscheduler/engine-cpp/

or resp.

 https://localhost:48444/jobscheduler/engine-cpp/

Example for HTTP GET

 http://localhost:40444/jobscheduler/engine-cpp/<show_state/>

Note

The commands that can be sent via HTTP GET have been restricted from JobScheduler version 1.7 onwards. See our news release for further information.

Jetty configuration examples

user authentication with a properties file

Beside the Simple user authentication provided by the jetty plugin you can use a more complex authentification method described by the jetty configuration. The example below shows the use of the HashLoginService, a mechanism whose authentication and authorization information is stored in a properties file.

First make sure, that your plugin declaration in scheduler.xml does not contain any authentification information:

  <plugins>
    <plugin java_class="com.sos.scheduler.engine.plugins.jetty.JettyPlugin">
      <plugin.config />
    </plugin>
    ...
  </plugins>

In the second step you should define the HashLoginService in your jetty configuration (jetty.xml) as a user realm. That means that you have to configure at least the location of the properties file containing the user information (userid, password, roles) and give them a name (here myRealm).

   <Call name="addBean">
       <Arg>
           <New class="org.eclipse.jetty.security.HashLoginService">
               <Set name="name">myRealm</Set>
               <Set name="config"><SystemProperty name="jetty.home" default="." />/config/realm.properties</Set>
               <Set name="refreshInterval">0</Set>
           </New>
       </Arg>
   </Call>

The properties file config/realm.properties contains one or more user definitions, e.g.

  infouser: test, SecurityLevel.info
  alluser: test, SecurityLevel.all

Please note: In realm.properties you can specify the password like

 alluser: MD5:098f6bcd4621d373cade4e832627b4f6, SecurityLevel.all

Hint: You can use the MD5 Key generated by JOE but you have to change it to lowercase.

More informations can be found here.

wiki.eclipse.org/Jetty/Howto/Secure_Passwords 

You can execute the password utility mentioned there. You can find the jetty-utilxxxx.jar in scheduler_home/lib/jetty_ext.

Finally you have to configure a security constraint and assign your user realm myRealm to a login configuration. To do this you have to change your web.xml:

   <security-constraint>
       <web-resource-collection>
           <url-pattern>/*</url-pattern>
       </web-resource-collection>
       <auth-constraint>
           <role-name>SecurityLevel.info</role-name>
           <role-name>SecurityLevel.all</role-name>
       </auth-constraint>
   </security-constraint>
   <login-config>
       <auth-method>BASIC</auth-method>
       <realm-name>myRealm</realm-name>
   </login-config>

SecurityLevel.info and SecurityLevel.all are predefined roles for JobScheduler.

SecurityLevel.info allows only rights for watching but not for starting jobs, while SecurityLevel.all allows additionally the right for starting jobs.


IP authorization

To restrict the access for specific hosts you have to define an IPAccessHandler in your jetty.xml:

   <Get id="oldhandler" name="handler" />
   <Set name="handler">
       <New class="org.eclipse.jetty.server.handler.IPAccessHandler">
           <Set name="handler"><Ref id="oldhandler"/></Set>
           <Set name="white">     
               <Array type="java.lang.String">
                   <Item>127.0.0.1</Item>    
               </Array>
           </Set>
       </New>
   </Set>

It is important to store the given handlers in the local variable oldhandler to set them as the handler for the IPAccessHandler (see Jetty handler concept for more details). You can define a whitelist (as in the example above) or a blacklist. The IPAccessHandler does not allow to use alias names to point to specific IPs.


Wiki-rabbit-left.jpg << back to all FAQs

Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox
Templates