Apache Synapse Enterprise Service Bus (ESB) - 1.1.2 Release Notes - February 2008

1. Overview
    The Apache Synapse ESB is a robust, lightweight and highly scalable and distributed
    Enterprise Service Bus (ESB). It supports SOAP Web services as well as Legacy services over
    transports such as JMS, Apache VFS File systems, Mail etc, and SOAP, REST/POX, plain text
    and binary message payloads.

    Apache Synapse graduated from the Apache Incubator on the 2nd of January 2007, and the first
    Synapse 1.0 was released on the 11th of June 2007. On the 20th of December 2007, Synapse was
    accepted as a top level project (TLP) under the Apache Software Foundation.

2. Installation Prerequisites 

    Apache Synapse requires a J2SE runtime of version 1.5.x or later and Apache Ant to run the samples.
    Synapse requires JDK 1.5.x at runtime as it uses a NIO based https implementation, that is only
    possible with a JDK 1.5.x or later. To build Synapse from source, you will need JDK 1.5.x, and
    Apache Maven 2.0.6 or later

3. Quick start
    Please see the docs/Synapse_Quickstart.html guide

4. Building the Samples
    Please see the documents docs/Synapse_Samples.html and docs/Synapse_Samples_Setup.html

5. Synapse configuration language
    Please see the document docs/Synapse_Configuration_Language.html

6. Extending Synapse
    Please see the document docs/Synapse_Extending.html
    
7. Known Issues and limitations

  * SYNAPSE-180 Does not support the ability to throttle by concurrency within a cluster
  * SYNAPSE-174 The non-blocking http/s transports cannot handle WS-RM requests
  * SYNAPSE-186 Does not support PUT/DELETE rest operations
  * SYNAPSE-215 XSLTMediator doesn't handle text output correctly
  * SYNAPSE-212 XSLTMediator doesn't close/delete temporary files properly

  * The Synapse JMS implementation supports JMS 1.0.2b, however due to licensing issues we include
    the JMS 1.1 spec JAR from Apache Geronimo (geronimo-jms_1.1_spec-1.1.jar) instead. If you have
    any issues with JMS 1.0.x, please download the Sun JMS 1.0.2b JAR and replace supplied JAR from
    Geronimo.

8. Frequently asked questions

  * How can I change the default logging level of Synapse?
    Edit the lib/log4j.properties and set the line "log4j.category.org.apache.synapse=INFO" to
    "log4j.category.org.apache.synapse=DEBUG" and restart Synapse.

  * If you get an error related to WS-Security or when using it, check to ensure that your JDK
    uses the "Unlimited Strength Jurisdiction Policy Files". These could be downloaded from
    http://java.sun.com/javase/downloads/index_jdk5.jsp Refer to the associated documentation
    for instructions on how to install it to your JDK.

  * If you encounter issues with your JDK related to XML processing, try placing the Xerces jar
    files xercesImpl-2.8.0.jar and xml-apis-1.3.03.jar in your <JDK>/jre/lib/endorsed/ directory.

9. Reporting Problems

    Please use Apache's JIRA system (http://issues.apache.org/jira/) to report issues you find.
    You may also join the:
        synapse-dev mailing  list by sending email to synapse-dev-subscribe@ws.apache.org
        synapse-user mailing list by sending email to synapse-user-subscribe@ws.apache.org

10. New features
    The 1.1.2 release
        * This release is only to correct the artifacts uploaded to the Maven central repository

    The 1.1.1 release
        * Clustering support for the Cache/Throttle Mediators
        * Maintainance mode support for the HTTP transport
        * New Mail transport that supports POP3/IMAP/SMTP
        * JMX Monitoring support
        * Callout Mediator
        * Improved JMS/VFS transports
        * Improved REST/POX support
        * Annotations support for POJOCommand mediator
        * Ability to pin a proxy or a task to server instances

    
    The 1.1 release
        * Apache VFS based file transport
        * Scheduled Task support
        * XQuery mediator
        * POJO Command mediator
        * DB Report and DB Lookup mediators
        * Cache and Throttle mediators/enhancements
        * Split/Clone/Aggregate mediators
        * Improved logging and tracing support

    The 1.0 release
        * Non blocking HTTP and HTTPS transport based on Apache HttpCore/NIO
        * Enhanced Proxy services with in/out/fault sequences and endpoints, inline sequence and WSDL
          support
        * WSDL endpoints
        * Load balancing and Failover endpoints
        * Throttling mediator

    The 0.91 release adds support for:
        * WS-Reliable Messaging Sequence management

    The 0.90 release adds support for:
        * WS-Security termination and initiation
        * WS-ReliableMessaging termination and initiation
        * Support for dynamic reloading and remote reigstries
        * Scripting mediators based on Apache BSF
        * Refactored and cleaner synapse configuration xml
