oX Server 0.3 - User Guide

Peter Michalek

V 0.3


Table of Contents

1. Preface
1.1. About oX - oBIX Server Project
1.2. License Information
1.3. Author Information
2. Introduction
2.1. Why oBIX Server?
2.2. What You Need to Build
2.3. Caveat Emptor!
3. Quick Start
4. Architecture of oX Framework
4.1. Overall Design
4.2. Modules
Internal Modules
Push model
Pull model
Supported Internal Modules
External Modules
4.3. Services
Watch Service
Alarm Service
4.4. Configuration Options
5. Security
5.1. Authentication
5.2. Authorization
5.3. Encryption
5.4. Summary of Security Options
6. Creating Your Own Module
6.1. How to Set up Your Module
6.2. Implementing Your Module
Module Creation Walk-Through - Internal Module
Module Creation Walk-Through - External Module
6.3. Configuration Entries
6.4. Testing and Debugging Your Module
6.5. Deploying Your Module
7. Tips
7.1. Deploying With Tomcat
7.2. Using Winstone Lite
8. Acknowledgements

1. Preface

1.1 About oX - oBIX Server Project

What is oX?

According to wikipedia: Ox_(zodiac)

The Ox is the sign of prosperity through fortitude and hard work. This powerful sign is a born leader, being quite dependable and possessing an innate ability to achieve great things. ... The Ox works hard, patiently, and methodically, with original intelligence and reflective thought.

... and that is the essence of this project.

The current implementation of oBIX server provides basic functionality to support the oBIX standard from OASIS. It enables to browse oBIX objects via GET, set their values via PUT. POST support is provided for watch service, alarm service and feed operations. oBIX objects with associated URIs can be loaded from resource files or created in the Java code.

oX can be deployed with any modern servlet container. It has been tested with Winstone which is the default container and also with Tomcat.

Current footprint of a minimal configuration of oX is around 500K and it works with Java 1.4 VM, so it can be deployed on systems with limited resources.

1.2 License Information

Copyright © 2006-2009 Peter Michalek.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that this entire copyright notice is duplicated in all such copies.

This software is provided "as is" and without any expressed or implied warranties, including, without limitation, the implied warranties of merchantability and fitness for any particular purpose.

1.3 Author Information

This framework and documentation was written by Peter Michalek. If you have questions, found a bug or have enhancements, please contact me through this email

2. Introduction

2.1 Why oBIX Server?

Open source oX project was created to provide an infrastructure that developers can use for device integration in projects with "systems which sense" (to quote the oBIX spec). Its authors believe that this implementation will enable, among other things, integration and interoperability of wireless sensor networks that use Zigbee, ZWave and other technologies as well as the integration of robotics systems. oX will enable the seamless integration of these resource constrained system into SOA-enabled enterprise systems.

2.2 What You Need to Build

  • A Java Runtime. All testing has been done using the Sun JSDK 1.6 and 1.4. The code and binary release targets JSDK 1.4 and should work with it.

  • Apache Ant version 1.6 or better. The build scripts use the macrodef task which was introduced in ant 1.6. Any later version should work, too. You can get it from http://ant.apache.org/

  • oBIX toolkit: obix.jar is included in the source tree as well as in the binary package.

Optional servlet containers

  • Winstone 0.9.9 (jars included in the source tree): light-weight servlet container http://sourceforge.net/projects/winstone

  • Tomcat 5.0 or higher - can be downloaded http://tomcat.apache.org

Some modules, such as GPS and Lejos, that are part of the source tree use 3rd party jars and libraries. All needed libraries are included in the source distribution.

2.3 Caveat Emptor!

This framework is in alpha stage and will undergo API and other changes.

Last word and updates may be found in the latest release and on the project web page at http://obix-server.sourceforge.net/

Please refer to README.TXT for detailed information on setup and build documentation. The source for this documentation is in docbook format and is located in doc/docbook sub folder of the source distribution.

3. Quick Start

To quickly try out a running server, download the binary from http://sourceforge.net/projects/obix-server.

Unzip into a directory and click on winstone-0.9.9.jar from the explorer or run from the command line:

java -jar winstone-0.0.9.jar

Then navigate to the obix uri http://localhost:1225/obix/ using your browser.

You can customize the modules loaded by modifying the configuration file obix-server.properties.

4. Architecture of oX Framework

Note: Javadoc documenting all packages and classes can be generated from the source tree by running

 ant javadoc

and is also available on the project web site obix-server.sourceforge.net

oX User Guide can be built by running this build after installing docbook framework and configuring docbook.properties:

ant -f build-docbook.xml

4.1 Overall Design

Figure 4.1. High Level Architecture of oX Server

High Level Architecture of oX Server


At high-level, oX consists of oBIX engine and modules. Horizontal modules provide essential support for oBIX functionality, such as Watch, Alarm, Feed and History.

Vertical modules provide means of integrating with devices or software modules.

Figure 4.2. Overview of oX server class hierarchy

Overview of oX server class hierarchy


ObjBroker is the fundamental manager interface and ObjBrokerImpl a class that implements that interface. It also provides mapping of Objs to REST end points for GET, PUT, POST, Obj to service mapping and routing and related infrastructure. ObjBroker interface as facade for Obj management. The implementation ObjBrokerImpl uses WatchManager to manage watches and feeds and InvocationManager to invoke processing for operations (POST requests).

ObjBroker contains most functionality for loading oBIX object repository, object management and overall interfacing with the obj repository.

ObjCache is used for caching of Obj's and their mapping and lookup based on Obj hrefs (URIs).

ObixEnv holds system properties and is used to load application behavior such as logging.

ObjProxy interface is used for proxying external objects to oBIX Obj's and is used primarily in the Pull model.

At the startup time, ObixServerEngine loads modules according to settings in obix-server.properties.

It also loads services based on the configuration.

4.2 Modules

oX features a modular design where devices can integrate their state into the oBIX tree via pluggable entities called modules. Modules can be:

  • Internal - loaded at oX startup, run within the same process/JVM

  • External - run out of process or on a remote system

Internal Modules

oX internal modules can work in one of two different modes depending on how they add their Obj's to the oBIX tree and internal cached repository and how Obj status is updated: the push mode and the pull mode.

In the push model, Obj's can be added at run-time by the module via ObjBroker's addObj function. At a system-defined interval that can be fine-tuned by the module, watched obj proxies are invoked. ObjBroker will accordingly invoke an 'insert your object' operation on the feed object. The feed object updates its watch with a new list item.

Push model

In the push model, Obj's can be added at run-time by the module via ObjBroker's addObj function. At a system-defined interval that can be fine-tuned by the module, watched obj proxies are invoked. ObjBroker will accordingly invoke an 'insert your object' operation on the feed object. The feed object updates its watch with a new list item.

Pull model

In the pull model, objects already loaded are associated with 'proxy' objects that can be used for dynamic updates and later for integration. Update notifications are generated by the module, therefore updates don't need any extra processing thread like in the push model. If an obj has a feed associated with it and its URI is added to a watch, the feed will be notified about changes in any obj's in its span. Feed will then decide which objs to add to watch.

Supported Internal Modules

oX currently supports the following modules:

  • push-simulator

  • pull-simulator

  • lejos

  • gps

  • noop

Documentation for the modules is in corresponding README files placed in module/{name} directories in the source distribution

The default binary distribution comes only with the simulator modules included.

External Modules

oX provides experimental support for external modules. They can run on a remote system or out of process on the local system.

This is a typical scenario for an external module interaction with the main oX server:

  • At load time, register the area of the tree to which this module will add objects and keep updating their state

  • At execution time, as the Obj's become available, add them to the tree by performing HTTP PUTs

  • At execution time, as the Obj's status changes, update Obj sub-items by performing HTTP PUTs

oX server takes care of accepting PUTs, creating corresponding Obj's on its tree or updating Obj's attributes if the Obj already exists.

The following external modules are provided as samples

  • ext-push-simulator

Documentation for the modules is in corresponding README files placed in module/{name} directories in the source distribution.

4.3 Services

Orthogonal to the notion of modules is the notion of services. Services are system facilities that cooperate in overall operation of the oX system to enable or implement specific system features.

There are several stock (built-in) services and new services can be potentially provided by customizing the oX system.

A service can be configured in the property file and loaded at startup time. The following fragment shows has services can be specified.

Invocation target, represented by the interface InvocationTarget, allows the system the configure a service that can be 'invoked' at run time using obix 'Op' operations, such as 'make' operation of WatchService (represented by the class obixserver.watch.WatchManager in this case), or 'query' operation of a standard oBIX alarm service.

# invocation target definition
obixserver.targets=alarmService,watchService

obixserver.target.alarmService.class=obixserver.core.alarm.AlarmManager
obixserver.target.alarmService.uri=/obix/config/services/alarmservice/
obixserver.target.watchService.class=obixserver.watch.WatchManager
obixserver.target.watchService.uri=/obix/watchService/

Watch Service

Watch service provides standard obix watch creation and management.

Please see testing readme in test/resources/README.TXT and associated scripts for the detailed semantics of watch service implementation.

Alarm Service

Alarm service provides standard obix alarm creation and management.

Alarm creation is enabled by modules. A module can associate a condition with an Obj. When the condition is true, the oX system, using the collaboration of alarm service, objBroker and notifications about changes from the modules, automatically creates an alarm.

There is a set of stock conditions provided by the system, represented by Java classes that implement Condition interface. See javadoc for package obixserver.core.alarm.condition.

To see sample usage and setup of conditions and notifications that result in alarm creation, see PushSimulatorModule. Here is a relevant code fragment that creates two conditions that result in alarms if the value of Int obj 'intModuloMinute' goes above 59000, and if the Real obj 'realSize' is between 0.1 and 0.2.

 objBroker.addCondition(new GreaterThanCondition(intModuloMinute, 59000));
 objBroker.addCondition(new OutofrangeCondition(realSine, 0.1, 0.2));

Please see testing readme in test/resources/README.TXT and associated scripts for the detailed semantics of alarm service implementation.

4.4 Configuration Options

oX can be currently deployed with winstone in minimal (no logging and server administration), regular and secure configuration. The size for minimal configuration is 503K.

Jars required by minimal configuration:

255351 obix.jar
170010 winstone-lite-0.9.9.jar
 52308 obixserver.jar

With a more full-featured version of winstone container, the footprint is about 150K more (655K):

327027 winstone-0.9.9.jar

5. Security

In any given system, security is usually a trade off of multiple factors. To keep oX system simple, security facilities of underlying technology: the HTTP server and servlet container are being used. While this may not be optimal in all situations, it is in line with some of the fundamental goals of the project: simplicity and ability to run on low-power servers.

5.1 Authentication

Authentication (ability to validate user credentials) is provided via standard servlet authentication facility. If you deploy the product in secure configuration, a sample web.xml will be installed that contains authentication for specific resources.

This can be adjusted based on your needs.

If you deployed a secure version of oX, you can test authentication by going to protected areas, such as: http://localhost:1225/obix/config/users/. You can use admin user with the password 'admin' as configured in tomcat-users.xml file of the deployment directory.

5.2 Authorization

Authorization (granting access to resources to a user or principal) is provided in a standard servlet container manner: in the default winstone configuration this is done via the combination of web.xml, winstone.properties and tomcat-users.xml file.

5.3 Encryption

Encryption, which provides data integrity and confidentiality, is implemented via HTTPS protocol that is part of the servlet container. In default configuration, winstone properties are used to enable it.

5.4 Summary of Security Options

To summarize the sections above and how they translate into changes in configuration files, here are portions of relevant configuration files.

Please note that this applies to a particular sample configuration. By changing real specification class, more flexible and dynamic approach to authentication and authorization can be deployed.

tomcat-users.xml contains a list of users and their passwords. Here is a sample file:

<tomcat-users>
  <role rolename="guest"/>
  <role rolename="user"/>
  <role rolename="module"/>
  <role rolename="admin"/>
  <user username="admin" password="admin" roles="admin"/>
  <user username="both" password="both" roles="admin,user"/>
  <user username="frank" password="frank" roles="user"/>
  <user username="x10" password="x10" roles="module"/>
  <user username="chris" password="chris" roles="user"/>
</tomcat-users>

winstone.properties file provides a mechanism to associate a realm in web.xml with user roles and user login credentials. This is the relevant section of winstone.properties:

...
# Authentication
#argumentsRealm.passwd.user=password
#argumentsRealm.roles.user=admin
realmClassName=winstone.realm.FileRealm
fileRealm.configFile=tomcat-users.xml
# enable encryption: this requires keystore in winstone.ks
#httpsPort=1226
...

Note that encryption can be specified as well. It requires that a standard Java keystore file with the name 'winstone.ks' be created.

web.xml provides a declarative mechanism where resources can be associated with roles. It can specify which methods can be applied to a resource, thus allowing read access (GET) to some user roles, and read/write access to others (DELETE/PUT), or method execution ability within the context of oBIX to yet another user role (POST). This is the relevant section of web.xml:

...
   <security-constraint>
     <display-name>Obix Security Constraint - Users</display-name>
     <web-resource-collection>
       <web-resource-name>Protected Area - Users</web-resource-name>
       <url-pattern>/obix/config/users/*</url-pattern>
       <http-method>GET</http-method>
       <http-method>DELETE</http-method>
       <http-method>POST</http-method>
       <http-method>PUT</http-method>
     </web-resource-collection>
     <auth-constraint>
       <role-name>admin</role-name>
       <role-name>user</role-name>
     </auth-constraint>
   </security-constraint>

   <security-constraint>
     <display-name>Obix Security Constraint - Config</display-name>
     <web-resource-collection>
       <web-resource-name>Protected Area - Config</web-resource-name>
       <url-pattern>/obix/config/*</url-pattern>
       <http-method>DELETE</http-method>
       <http-method>POST</http-method>
       <http-method>PUT</http-method>
     </web-resource-collection>
     <auth-constraint>
       <role-name>admin</role-name>
       <role-name>user</role-name>
     </auth-constraint>
   </security-constraint>
...
   <login-config>
     <auth-method>BASIC</auth-method>
     <realm-name>oBIX Server Protected Area</realm-name>
     <transport-guarantee>NONE</transport-guarantee>
   </login-config>

   <security-role>
     <description>Admin role</description>
     <role-name>admin</role-name>
   </security-role>

   <security-role>
     <description>Module role</description>
     <role-name>module</role-name>
   </security-role>

   <security-role>
     <description>User role</description>
     <role-name>user</role-name>
   </security-role>

   <security-role>
     <description>Guest role</description>
     <role-name>guest</role-name>
   </security-role>


6. Creating Your Own Module

[Important]Important

Please take a look at a sample module, such as push-simulator in the modules/push-simulator or NoopModule in modules/core directory to see a sample project.

6.1 How to Set up Your Module

Figure 6.1. Source layout

<root>
  |
  +---- build.xml 1
  +---- ant.properties 2
  |
  +-- module
  |     |
  |     |
  |     +-- core
  |     |     |
  |     |     +-- java 3
  |     |     |
  |     |     +-- resources 4
  |     |     |
  |     |     +-- lib 5
  |     |     |
  |     |     +-- test 6
  |     |
  |     +-- yourmodule
  |     |     |
  |     |     +-- java
  |     |     |
  |     |     +-- resources
  |     |     |
  |     |     +-- lib
  |     |     |
  |     |     +-- test
  |     |
  |     +-- test 7
  +-- standalone-modules
        |
        +-- ext-pushsimulator
        |
        +-- int-pushsimulator
        |
        +-- yourmodule

1

ant build file

2

ant properties file

3

Java source

4

resources directory: such as for XML Obj description files

5

3rd party libraries/jars

6

unit tests

7

tests scripts and resources for all modules

It's recommended that your module follows a similar structure within this project, in particular for modules that may be later integrated into this projects source base.

For your own standalone modules, you can use structure similar to that of ./standalone-modules/int-pushsimulator example or similar examples.

6.2 Implementing Your Module

Please refer to any of the sample module, such as NoopModule or PushSimulator. For a simple module that just loads a tree, you need to do the following:

  • If applicable, create a resource tree and save it in a resource file.

  • Create a class that extends AbstractBaseModule. Include an implementation of start and stop functions. They could be noops if you don't need to start and stop your own processing threads

  • Add configuration information to obix-server.properties file - see below

  • Deploy your class into servlet environment - see below

Note: You may find it useful to view the source code for the minimal module: NoopModule - you may use it as a template to write your own module.

You'll notice that the source tree contains module examples under ./modules directory: those may offer additional ideas if you are interested in seeing solutions to specific problems such as integrating a GPS device into the oX system.

Module Creation Walk-Through - Internal Module

To create a new project for an internal module, follow these steps:

  • Copy a sample project , using it as a template, e.g.

    cp -a standalone-modules/int-pushsimulator/ standalone-modules/mymodule
  • Rename and modify the Java file included in the project: ./java/obixserver/module/PushSimulatorModule.java

    Note: Using an IDE such as Eclipse is recommended.

  • Add directives to load the module to the configuration file obix-server.properties

    Here is an example.

    ...
    obixserver.modules=core,push-simulator
    ...
    obixserver.module.push-simulator=obixserver.module.PushSimulatorModule
    obixserver.module.push-simulator.base=push-simulator
    ...
    
    
    
    
  • Build and deploy

    ant
    # copy jar to your obix-server deployment
    cp ./build/ox-int-pushsimulator/lib/ox-int-pushsimulator.jar $OBIXSERVER_ROOT/WEB-INF/lib
    # where OBIXSERVER_ROOT points to the directory
    # where you installed the obix server.
    
    
  • Restart the server

  • Validate that internal module subtree is present in the obix tree

    You can do this by navigating to the URL as specified in .home property of the configuration file:

    http://localhost:1225/obix/pushsimulator/

    or by running a command line utility, e.g.:

    curl http://localhost:1225/obix/pushsimulator/

    For this particular sample, you should see several values at http://localhost:1225/obix/push-simulator/dynamicValues/ changing when you refresh the URL.

Module Creation Walk-Through - External Module

Note: external module support is experimental at this point.

Known problem: intermittent failure of PUT from ext-pushsimulator client invocation.

To create a new project, follow these steps:

  • Copy a sample project , using it as a template, e.g.

    cp -a standalone-modules/ext-pushsimulator/ standalone-modules/ext-mymodule
  • Rename and modify the Java file included in the project: ./java/obixserver/module/external/ExternalSimModule.java

  • Modify the configuration file for the module: ./conf/obix-modules.properties

    Specify your classname, home and credentials. obixmodule.serverUri is the URL of the main oX server where the tree will be expanded. Here is an example.

    # Obix remote/external module properties
    
    # oX server URL
    obixmodule.serverUri=http://localhost:1225
    
    # ignore errors on init and start of modules. obix server will still start
    obixmodule.ignoreInitErrors=true
    
    # module definition
    obixmodule.modules=sim-external
    
    obixmodule.module.sim-external=obixserver.module.external.ExternalSimModule
    obixmodule.module.sim-external.home=/obix/sim-external/
    obixmodule.module.sim-external.username=admin
    obixmodule.module.sim-external.password=admin
  • Build

    ant
  • Execute

    #first start an instance oX server
    #then run external module
    cd build/ox-ext-pushsimulator/
    ./run.sh
  • Validate that external module results in new item on the tree

    You can do this by navigating to the URL as specified in .home property of the configuration file:

    http://localhost:1225/obix/sim-external/

    or by running a command line utility, e.g.:

    curl http://localhost:1225/obix/sim-external/

    For this particular sample, you should see integer value at http://localhost:1225/obix/sim-external/myRealObj/ being incremented at 5 s interval when you refresh the URLS.

[Note]Note

This sample doesn't address security: a system should ship only with authentication-based area to receive Obj's created by external module. For example, in a secure production system, an external module that attempts to create new Obj's by writing via HTTP PUT to /obix/sim-external/ should be properly authenticated and the communication encrypted.

6.3 Configuration Entries

The obix-server.properties file contains a line to add your module

 obixserver.modules=core,push-simulator,pull-simulator,my-module
      

A separate set of settings specify your module's properties:

 obixserver.module.my-module=obixserver.module.MyModule
 obixserver.module.my-module.base=my-module
      

If you configure your module as described above, you will see it when accessing the running oX server on this URL: http://localhost:1225/obix/my-module/

6.4 Testing and Debugging Your Module

If you are using Eclipse development environment, a .project file and a .classpath file is provided in the source tree: that should help you load the project.

After the project is in eclipse and you've built from the command line as well, you can start Launcher which will start the project in debug mode using winstone. To also set breakpoint in winstone, you'll need to install winstone and modify .classpath to point to it's sources, such as:

<classpathentry kind="lib" path="lib/winstone-lite-0.9.9.jar" sourcepath="c:/sw/winstone-src-0.9.9" />
     

You will also need to install obix toolkit and import into eclipse, or modify your .classpath to point to lib/obix.jar.

You can also use curl-based command-line scripts and procedures outlined in test/resources/README.TXT included in the source distribution.

6.5 Deploying Your Module

For a simple module, just make your classes or jar available on the classpath. That means copying it to build/webroot/WEB-INF/lib (for jar) or to build/webroot/WEB-INF/classes during the build process. At run time, it will be found by the loader.

If your module uses 3rd party libraries or other resources, you should also copy those during the deployment phase, typically to build/webroot/WEB-INF/lib for jars and build/webroot/WEB-INF/classes for resources that need to be on the classpath.

7. Tips

7.1 Deploying With Tomcat

Deploying with Tomcat has been tested but doesn't work out of the box without modifications at this point.

Steps to deploy:

  • Create the war file:

    ant war
  • Modify the files in the war file or after deployment to tomcat like this:

    diff -r ./WEB-INF/classes/obix-server.properties /cygdrive/c/projects/obix-server/build/webroot/WEB-INF/classes/obix-server.properties
    4d3
    < obixserver.rest.serverPort=8080
    6,7c5
    < #obixserver.rest.xslt=/obix/resources/xsl/obix.xsl
    < obixserver.rest.xslt=
    ---
    > obixserver.rest.xslt=/resources/xsl/obix.xsl
    diff -r ./WEB-INF/web.xml /cygdrive/c/projects/obix-server/build/webroot/WEB-INF/web.xml
    37c37
    <     <url-pattern>/*</url-pattern>
    ---
    >     <url-pattern>/obix/*</url-pattern>
  • Deploy in tomcat's webapps

7.2 Using Winstone Lite

To use the minimal configuration, you need to do this modification to the default deployment (comment out logging lines):

< #simpleAccessLogger.format=combined
< #accessLoggerClassName=winstone.accesslog.SimpleAccessLogger
< #simpleAccessLogger.file=logs/access_log.txt
---
> simpleAccessLogger.format=combined
> accessLoggerClassName=winstone.accesslog.SimpleAccessLogger
> simpleAccessLogger.file=logs/access_log.txt

You also need to replace winstone-0.9.9.jar with winstone-lite-0.9.9.jar (both files are in lib subdirectory of the source root).

You can shutdown the server or reload the application it in this manner:

# reload application
java -cp winstone-0.9.9.jar winstone.tools.WinstoneControl  reload
# stop server
java -cp winstone-0.9.9.jar winstone.tools.WinstoneControl  shutdown

8. Acknowledgements

oBIX Server project builds on the clean design and implementation of oBIX core by Brian Frank: see http://obix.sourceforge.net

The default deployment integrates with Winstone, a very efficient and full-featured servlet container from sourceforge: see winstone