Author: veithen
Date: Tue May  6 13:10:59 2008
New Revision: 653900

URL: http://svn.apache.org/viewvc?rev=653900&view=rev
Log:
SYNAPSE-282: Added a message builder for syslog messages.

Added:
    
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/
    
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/InputStreamConsumer.java
    
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/ProtocolException.java
    
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/SyslogConstants.java
    
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/SyslogMessageBuilder.java
    
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/package-info.java
    synapse/trunk/java/modules/extensions/src/main/resources/org/
    synapse/trunk/java/modules/extensions/src/main/resources/org/apache/
    synapse/trunk/java/modules/extensions/src/main/resources/org/apache/synapse/
    
synapse/trunk/java/modules/extensions/src/main/resources/org/apache/synapse/format/
    
synapse/trunk/java/modules/extensions/src/main/resources/org/apache/synapse/format/syslog/
    
synapse/trunk/java/modules/extensions/src/main/resources/org/apache/synapse/format/syslog/schema.xsd
    
synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/format/
    
synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/format/syslog/
    
synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/format/syslog/SyslogMessageBuilderTest.java

Added: 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/InputStreamConsumer.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/InputStreamConsumer.java?rev=653900&view=auto
==============================================================================
--- 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/InputStreamConsumer.java
 (added)
+++ 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/InputStreamConsumer.java
 Tue May  6 13:10:59 2008
@@ -0,0 +1,163 @@
+/*
+ *  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.synapse.format.syslog;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Input stream consumer.
+ * This is a helper class used by [EMAIL PROTECTED] SyslogMessageBuilder} to 
parse data
+ * from an input stream. In particular it supports look ahead and allows to
+ * buffer and reread data from the stream.
+ */
+public class InputStreamConsumer {
+    private final InputStream in;
+    private byte[] buffer = new byte[64];
+    private int position;
+    private int bufferPosition;
+    private boolean endOfStream;
+    
+    /**
+     * Constructor.
+     * 
+     * @param in the input stream to consume data from
+     */
+    public InputStreamConsumer(InputStream in) {
+        this.in = in;
+    }
+    
+    /**
+     * Get the next byte from the stream without consuming it.
+     * If the byte is not consumed between invocations, two successive
+     * calls to this method will return the same result.
+     * 
+     * @return the next byte as an integer value in the range 0..255 or
+     *         -1 if the end of the stream has been reached
+     * @throws IOException if an I/O error occurred while reading from
+     *         the stream
+     */
+    public int next() throws IOException {
+        if (position < bufferPosition) {
+            return buffer[position];
+        } else if (endOfStream) {
+            return -1;
+        } else {
+            if (bufferPosition == buffer.length) {
+                byte[] newBuffer = new byte[buffer.length*2];
+                System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
+                buffer = newBuffer;
+            }
+            int c = in.read(buffer, bufferPosition, 
buffer.length-bufferPosition);
+            if (c == -1) {
+                endOfStream = true;
+                return -1;
+            } else {
+                bufferPosition += c;
+            }
+            return buffer[position];
+        }
+    }
+    
+    /**
+     * Consume the last byte read from the stream and advance to the next byte.
+     */
+    public void consume() {
+        position++;
+    }
+    
+    /**
+     * Get the current position in the stream.
+     * 
+     * @return the position in the stream
+     */
+    public int getPosition() {
+        return position;
+    }
+    
+    /**
+     * Reset the stream position to a previous value.
+     * 
+     * @param position the new position
+     */
+    public void setPosition(int position) {
+        this.position = position;
+    }
+    
+    /**
+     * Check the value of the next byte in the stream.
+     * 
+     * @param expected the expected value
+     * @throws IOException if an I/O error occurred while reading from
+     *         the stream
+     * @throws ProtocolException if the next byte doesn't have the expected 
value
+     */
+    public void expect(int expected) throws IOException, ProtocolException {
+        int next = next();
+        if (next != expected) {
+            throw new ProtocolException("Unexpected byte: expected " + 
expected + " ('" + (char)expected + "') , got " + next + " ('" + (char)next + 
"')");
+        }
+    }
+    
+    /**
+     * Check the value of the next byte in the stream and consume it. This is
+     * a convenience method that combines a call to [EMAIL PROTECTED] #expect} 
with a
+     * call to [EMAIL PROTECTED] #consume}.
+     * 
+     * @param expected the expected value
+     * @throws IOException if an I/O error occurred while reading from
+     *         the stream
+     * @throws ProtocolException if the next byte doesn't have the expected 
value
+     */
+    public void consume(int expected) throws IOException, ProtocolException {
+        expect(expected);
+        consume();
+    }
+    
+    /**
+     * Read a decimal representation of an integer from the stream.
+     * 
+     * @param maxDigits the maximum number of expected digits
+     * @return the integer value
+     * @throws IOException if an I/O error occurred while reading from
+     *         the stream
+     * @throws ProtocolException if no integer value was found or if it
+     *         was too long
+     */
+    public int getInteger(int maxDigits) throws IOException, ProtocolException 
{
+        int digits = 0;
+        int result = 0;
+        while (true) {
+            int next = next();
+            if ('0' <= next && next <= '9') {
+                if (++digits > maxDigits) {
+                    throw new ProtocolException("Numeric value too long");
+                }
+                consume();
+                result = result*10 + (next - '0');
+            } else {
+                break;
+            }
+        }
+        if (digits == 0) {
+            throw new ProtocolException("Expected numeric value");
+        }
+        return result;
+    }
+}

Added: 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/ProtocolException.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/ProtocolException.java?rev=653900&view=auto
==============================================================================
--- 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/ProtocolException.java
 (added)
+++ 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/ProtocolException.java
 Tue May  6 13:10:59 2008
@@ -0,0 +1,30 @@
+/*
+ *  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.synapse.format.syslog;
+
+/**
+ * Exception used by [EMAIL PROTECTED] InputStreamConsumer}.
+ */
+public class ProtocolException extends Exception {
+    private static final long serialVersionUID = 8130321223000903222L;
+
+    public ProtocolException(String message) {
+        super(message);
+    }
+}

Added: 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/SyslogConstants.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/SyslogConstants.java?rev=653900&view=auto
==============================================================================
--- 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/SyslogConstants.java
 (added)
+++ 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/SyslogConstants.java
 Tue May  6 13:10:59 2008
@@ -0,0 +1,58 @@
+/*
+ *  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.synapse.format.syslog;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Class defining constants for the syslog protocol.
+ */
+public class SyslogConstants {
+    private SyslogConstants() {}
+    
+    /**
+     * The namespace used in the XML representation of a syslog event.
+     */
+    public static final String NAMESPACE_URI = 
"http://synapse.apache.org/ns/syslog";;
+    
+    /**
+     * Qualified name of the root element of the XML representation of a 
syslog event.
+     */
+    public static final QName MESSAGE = new QName(NAMESPACE_URI, "message");
+    
+    /**
+     * Name of the attribute storing the facility of a syslog event.
+     */
+    public static final String FACILITY = "facility";
+    
+    /**
+     * Name of the attribute storing the severity of a syslog event.
+     */
+    public static final String SEVERITY = "severity";
+    
+    /**
+     * Name of the attribute storing the tag of a syslog event.
+     */
+    public static final String TAG = "tag";
+    
+    /**
+     * Name of the attribute storing the process ID of a syslog event;
+     */
+    public static final String PID = "pid";
+}

Added: 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/SyslogMessageBuilder.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/SyslogMessageBuilder.java?rev=653900&view=auto
==============================================================================
--- 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/SyslogMessageBuilder.java
 (added)
+++ 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/SyslogMessageBuilder.java
 Tue May  6 13:10:59 2008
@@ -0,0 +1,141 @@
+/*
+ *  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.synapse.format.syslog;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axiom.om.impl.llom.factory.OMLinkedListImplFactory;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.builder.Builder;
+import org.apache.axis2.context.MessageContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Message builder for syslog events.
+ * <p>
+ * See [EMAIL PROTECTED] org.apache.synapse.format.syslog} for a description 
of how to use
+ * this class.
+ */
+public class SyslogMessageBuilder implements Builder {
+    private static final Log log = 
LogFactory.getLog(SyslogMessageBuilder.class);
+    
+    private static final String[] facilityNames = {
+        "kern", "user", "mail", "daemon", "auth", "syslog", "lpr", "news", 
"uucp", "cron",
+        "authpriv", "ftp", "reserved0", "reserved1", "reserved2", "reserved3",
+        "local0", "local1", "local2", "local3", "local4", "local5", "local6", 
"local7"
+    };
+    
+    private static final String[] severityNames = {
+        "emerg", "alert", "crit", "err", "warning", "notice", "info", "debug"
+    };
+    
+    public OMElement processDocument(InputStream inputStream,
+            String contentType, MessageContext messageContext) throws 
AxisFault {
+        String facility = null;
+        String severity = null;
+        String tag = null;
+        int pid = -1;
+        String content = null;
+        
+        InputStreamConsumer in = new InputStreamConsumer(inputStream);
+        try {
+            StringBuilder buffer = new StringBuilder();
+            
+            in.consume('<');
+            int priority = in.getInteger(3);
+            if (priority > 199) {
+                throw new ProtocolException("Invalid priority value (greater 
than 199)");
+            }
+            in.consume('>');
+            
+            severity = severityNames[priority & 7];
+            facility = facilityNames[priority >> 3];
+            
+            int savedPosition = in.getPosition();
+            try {
+                outer: while (true) {
+                    int next = in.next();
+                    switch (next) {
+                        case '[':
+                            in.consume();
+                            pid = in.getInteger(6);
+                            in.consume(']');
+                            in.expect(':');
+                            // Fall through
+                        case ':':
+                            in.consume();
+                            in.consume(' ');
+                            tag = buffer.toString();
+                            break outer;
+                        case ' ':
+                        case -1:
+                            throw new ProtocolException("Unexpected end of 
tag");
+                        default:
+                            in.consume();
+                            buffer.append((char)next);
+                    }
+                }
+            }
+            catch (ProtocolException ex) {
+                in.setPosition(savedPosition);
+            }
+            
+            buffer.setLength(0);
+            while (true) {
+                int next = in.next();
+                if (next == '\n') {
+                    in.consume();
+                    in.consume(-1);
+                    content = buffer.toString();
+                    break;
+                } else if (next == -1) {
+                    throw new ProtocolException("Unexpected end of content");
+                } else {
+                    in.consume();
+                    buffer.append((char)next);
+                }
+            }
+        }
+        catch (ProtocolException ex) {
+            log.error("Protocol error: " + ex.getMessage() + " [pri=" + 
facility + "." + severity + " tag=" + tag + " pid=" + pid + "]");
+            throw new AxisFault("Protocol error", ex);
+        }
+        catch (IOException ex) {
+            throw new AxisFault("I/O error", ex);
+        }
+        
+        OMFactory factory = new OMLinkedListImplFactory();
+        OMElement message = factory.createOMElement(SyslogConstants.MESSAGE);
+        
message.addAttribute(factory.createOMAttribute(SyslogConstants.FACILITY, null, 
facility));
+        
message.addAttribute(factory.createOMAttribute(SyslogConstants.SEVERITY, null, 
severity));
+        if (tag != null) {
+            
message.addAttribute(factory.createOMAttribute(SyslogConstants.TAG, null, tag));
+        }
+        if (pid != -1) {
+            
message.addAttribute(factory.createOMAttribute(SyslogConstants.PID, null, 
String.valueOf(pid)));
+        }
+        message.setText(content.toString());
+        
+        return message;
+    }
+}

Added: 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/package-info.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/package-info.java?rev=653900&view=auto
==============================================================================
--- 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/package-info.java
 (added)
+++ 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/syslog/package-info.java
 Tue May  6 13:10:59 2008
@@ -0,0 +1,52 @@
+/*
+ *  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.
+ */
+
+/**
+ * Implementation of the BSD syslog protocol described in RFC 3164.
+ * <p>
+ * The protocol is implemented as an Axis2 message builder that takes
+ * a single syslog message as input and that produces an XML
+ * representation of the event in the form of an AXIOM tree. The
+ * XML format is non standard and is defined by the
+ * <tt>org/apache/synapse/format/syslog/schema.xsd</tt> included in
+ * the JAR. 
+ * <p>
+ * A typical message looks as follows:
+ * <pre>
+ * &lt;message xmlns="http://synapse.apache.org/ns/syslog";
+ *          facility="authpriv" severity="info" tag="CRON" pid="6813">
+ *   pam_unix(cron:session): session closed for user root
+ * &lt;/message></pre>
+ * The message builder can be registered in the Axis2 configuration file
+ * (<tt>axis2.xml</tt>) in the following way:
+ * <pre>
+ * &lt;messageBuilders>
+ *   &lt;messageBuilder contentType="application/x-syslog"
+ *                   
class="org.apache.synapse.format.syslog.SyslogMessageBuilder"/>
+ * &lt;/messageBuilders>
+ * </pre>
+ * Again the content type <tt>application/x-syslog</tt> is non standard and is 
only
+ * used to refer to the message builder later.
+ * <h4>Known issues</h4>
+ * <ul>
+ *   <li>The message builder currently doesn't support timestamp and host 
fields.
+ *       Messages containing these fields are not parsed correctly.</li>
+ * </ul>
+ */
+package org.apache.synapse.format.syslog;
\ No newline at end of file

Added: 
synapse/trunk/java/modules/extensions/src/main/resources/org/apache/synapse/format/syslog/schema.xsd
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/extensions/src/main/resources/org/apache/synapse/format/syslog/schema.xsd?rev=653900&view=auto
==============================================================================
--- 
synapse/trunk/java/modules/extensions/src/main/resources/org/apache/synapse/format/syslog/schema.xsd
 (added)
+++ 
synapse/trunk/java/modules/extensions/src/main/resources/org/apache/synapse/format/syslog/schema.xsd
 Tue May  6 13:10:59 2008
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  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.
+  -->
+<schema xmlns="http://www.w3.org/2001/XMLSchema";
+        targetNamespace="http://synapse.apache.org/ns/syslog";
+        xmlns:tns="http://synapse.apache.org/ns/syslog";
+        elementFormDefault="qualified">
+    <simpleType name="facilityType">
+        <restriction base="string">
+            <enumeration value="kern"/>
+            <enumeration value="user"/>
+            <enumeration value="mail"/>
+            <enumeration value="daemon"/>
+            <enumeration value="auth"/>
+            <enumeration value="syslog"/>
+            <enumeration value="lpr"/>
+            <enumeration value="news"/>
+            <enumeration value="uucp"/>
+            <enumeration value="cron"/>
+            <enumeration value="authpriv"/>
+            <enumeration value="ftp"/>
+            <enumeration value="reserved0"/>
+            <enumeration value="reserved1"/>
+            <enumeration value="reserved2"/>
+            <enumeration value="reserved3"/>
+            <enumeration value="local0"/>
+            <enumeration value="local1"/>
+            <enumeration value="local2"/>
+            <enumeration value="local3"/>
+            <enumeration value="local4"/>
+            <enumeration value="local5"/>
+            <enumeration value="local6"/>
+            <enumeration value="local7"/>
+        </restriction>
+    </simpleType>
+    
+    <simpleType name="severityType">
+        <restriction base="string">
+            <enumeration value="emerg"/>
+            <enumeration value="alert"/>
+            <enumeration value="crit"/>
+            <enumeration value="err"/>
+            <enumeration value="warning"/>
+            <enumeration value="notice"/>
+            <enumeration value="info"/>
+            <enumeration value="debug"/>
+        </restriction>
+    </simpleType>
+    
+    <element name="message">
+        <complexType>
+            <simpleContent>
+                <extension base="string">
+                    <attribute name="facility" type="tns:facilityType" 
use="required"/>
+                    <attribute name="severity" type="tns:severityType" 
use="required"/>
+                    <attribute name="tag" type="string" use="optional"/>
+                    <attribute name="pid" type="int" use="optional"/>
+                </extension>
+            </simpleContent>
+        </complexType>
+    </element>
+</schema>

Added: 
synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/format/syslog/SyslogMessageBuilderTest.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/format/syslog/SyslogMessageBuilderTest.java?rev=653900&view=auto
==============================================================================
--- 
synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/format/syslog/SyslogMessageBuilderTest.java
 (added)
+++ 
synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/format/syslog/SyslogMessageBuilderTest.java
 Tue May  6 13:10:59 2008
@@ -0,0 +1,120 @@
+/*
+ *  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.synapse.format.syslog;
+
+import java.io.ByteArrayInputStream;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import junit.framework.TestCase;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.context.MessageContext;
+import org.apache.commons.lang.ObjectUtils;
+import org.springframework.xml.transform.StaxSource;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+public class SyslogMessageBuilderTest extends TestCase {
+    private class SyslogMessage {
+        private final String facility;
+        private final String severity;
+        private final String tag;
+        private final int pid;
+        private final String content;
+        
+        public SyslogMessage(String facility, String severity, String tag,
+                int pid, String content) {
+            this.facility = facility;
+            this.severity = severity;
+            this.tag = tag;
+            this.pid = pid;
+            this.content = content;
+        }
+        
+        @Override
+        public String toString() {
+            return "[pri=" + facility + "." + severity + " tag=" + tag + " 
pid=" + pid + ": " + content + "]";
+        }
+
+        @Override
+        public boolean equals(Object _obj) {
+            if (_obj == null || !(_obj instanceof SyslogMessage)) {
+                return false;
+            } else {
+                SyslogMessage obj = (SyslogMessage)_obj;
+                return ObjectUtils.equals(facility, obj.facility) &&
+                       ObjectUtils.equals(severity, obj.severity) &&
+                       ObjectUtils.equals(tag, obj.tag) &&
+                       pid == obj.pid &&
+                       ObjectUtils.equals(content, obj.content);
+            }
+        }
+    }
+    
+    private SyslogMessage test(String message) throws Exception {
+        MessageContext msgContext = new MessageContext();
+        ByteArrayInputStream in = new 
ByteArrayInputStream(message.getBytes("us-ascii"));
+        OMElement element = new SyslogMessageBuilder().processDocument(in, 
null, msgContext);
+        SchemaFactory factory = 
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+        Schema schema = factory.newSchema(new 
StreamSource(SyslogMessageBuilderTest.class.getResource("schema.xsd").toExternalForm()));
+        Validator validator = schema.newValidator();
+        validator.setErrorHandler(new ErrorHandler() {
+            public void error(SAXParseException exception) throws SAXException 
{
+                throw exception;
+            }
+
+            public void fatalError(SAXParseException exception) throws 
SAXException {
+                throw exception;
+            }
+
+            public void warning(SAXParseException exception) throws 
SAXException {
+                throw exception;
+            }
+        });
+        validator.validate(new StaxSource(element.getXMLStreamReader()));
+        String pidString = element.getAttributeValue(new 
QName(SyslogConstants.PID));
+        return new SyslogMessage(element.getAttributeValue(new 
QName(SyslogConstants.FACILITY)),
+                                 element.getAttributeValue(new 
QName(SyslogConstants.SEVERITY)),
+                                 element.getAttributeValue(new 
QName(SyslogConstants.TAG)),
+                                 pidString == null ? -1 : 
Integer.parseInt(pidString),
+                                 element.getText());
+    }
+    
+    public void testTagPidContent() throws Exception {
+        assertEquals(new SyslogMessage("mail", "info", "fetchmail", 8928, 
"awakened at Sun 04 May 2008 08:04:56 PM CEST"),
+                     test("<22>fetchmail[8928]: awakened at Sun 04 May 2008 
08:04:56 PM CEST\n"));
+    }
+    
+    public void testTagContent() throws Exception {
+        assertEquals(new SyslogMessage("local3", "info", "logger", -1, "test"),
+                     test("<158>logger: test\n"));
+    }
+    
+    public void testContent() throws Exception {
+        assertEquals(new SyslogMessage("syslog", "info", null, -1, "exiting on 
signal 15."),
+                     test("<46>exiting on signal 15.\n"));
+    }
+}


Reply via email to