INT-3450 Support RFC 5424/6587 for SYSLOG
JIRA: https://jira.spring.io/browse/INT-3450 Use LinkedHashMap - natural iteration order INT-3450 Polishing - PR Comments INT-3450: Polishing
This commit is contained in:
committed by
Artem Bilan
parent
1a4f98ac4c
commit
864cabcfe0
@@ -54,9 +54,18 @@
|
||||
connection-factory="cf"
|
||||
auto-startup="false"
|
||||
phase="123"
|
||||
converter="converter"
|
||||
converter="rfc5424"
|
||||
send-timeout="456"
|
||||
error-channel="errors" />
|
||||
|
||||
<int-ip:tcp-connection-factory id="cf" type="server" port="1514" />
|
||||
<int-ip:tcp-connection-factory id="cf"
|
||||
using-nio="true"
|
||||
type="server"
|
||||
port="1514"
|
||||
deserializer="rfc6587" />
|
||||
|
||||
<bean id="rfc5424" class="org.springframework.integration.syslog.RFC5424MessageConverter" />
|
||||
|
||||
<bean id="rfc6587" class="org.springframework.integration.syslog.inbound.RFC6587SyslogDeserializer" />
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,9 +37,9 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.ip.tcp.connection.AbstractConnectionFactory;
|
||||
import org.springframework.integration.ip.tcp.connection.AbstractServerConnectionFactory;
|
||||
import org.springframework.integration.syslog.MessageConverter;
|
||||
import org.springframework.integration.syslog.RFC5424MessageConverter;
|
||||
import org.springframework.integration.syslog.inbound.TcpSyslogReceivingChannelAdapter;
|
||||
import org.springframework.integration.syslog.inbound.UdpSyslogReceivingChannelAdapter;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
@@ -81,6 +81,9 @@ public class SyslogReceivingChannelAdapterParserTests {
|
||||
@Autowired
|
||||
private PassThruConverter converter;
|
||||
|
||||
@Autowired
|
||||
private RFC5424MessageConverter rfc5424;
|
||||
|
||||
@Autowired @Qualifier("bar.adapter")
|
||||
private TcpSyslogReceivingChannelAdapter adapter2;
|
||||
|
||||
@@ -152,7 +155,7 @@ public class SyslogReceivingChannelAdapterParserTests {
|
||||
assertFalse(fullBoatTcp.isAutoStartup());
|
||||
assertEquals(123, fullBoatTcp.getPhase());
|
||||
assertEquals(456L, TestUtils.getPropertyValue(fullBoatUdp, "messagingTemplate.sendTimeout"));
|
||||
assertSame(converter, TestUtils.getPropertyValue(fullBoatTcp, "converter"));
|
||||
assertSame(rfc5424, TestUtils.getPropertyValue(fullBoatTcp, "converter"));
|
||||
assertSame(errors, TestUtils.getPropertyValue(fullBoatTcp, "errorChannel"));
|
||||
assertSame(cf, TestUtils.getPropertyValue(fullBoatTcp, "connectionFactory"));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.integration.syslog.inbound;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.syslog.SyslogHeaders;
|
||||
|
||||
/**
|
||||
* @author Duncan McIntyre
|
||||
* @author Gary Russell
|
||||
* @since 4.1.1
|
||||
*
|
||||
*/
|
||||
public class SyslogDeserializerTests {
|
||||
|
||||
static final String VALID_UNFRAMED_ENTRY =
|
||||
"<14>1 2014-06-20T09:14:07+00:00 loggregator d0602076-b14a-4c55-852a-981e7afeed38 DEA - - Removing instance\n";
|
||||
static final String VALID_FRAMED_ENTRY =
|
||||
"106 <14>1 2014-06-20T09:14:07+00:00 loggregator d0602076-b14a-4c55-852a-981e7afeed38 DEA - - Removing instance";
|
||||
static final String SHORT_FRAMED_ENTRY =
|
||||
"107 <14>1 2014-06-20T09:14:07+00:00 loggregator d0602076-b14a-4c55-852a-981e7afeed38 DEA - - Removing instance";
|
||||
static final String SD_ENTRY_1 =
|
||||
"179 <14>1 2014-06-20T09:14:07+00:00 loggregator d0602076-b14a-4c55-852a-981e7afeed38 DEA - " +
|
||||
"[exampleSDID@32473 iut=\\\"3\\\" eventSource=\\\"Application\\\" eventID=\\\"1011\\\"] Removing instance";
|
||||
static final String SD_ENTRY_2 =
|
||||
"253 <14>1 2014-06-20T09:14:07+00:00 loggregator d0602076-b14a-4c55-852a-981e7afeed38 DEA - " +
|
||||
"[exampleSDID@32473 iut=\\\"3\\\" eventSource=\\\"Application\\\" eventID=\\\"1011\\\"][exampleSDID@32473 " +
|
||||
"iut=\\\"3\\\" eventSource=\\\"Application\\\" eventID=\\\"1011\\\"] Removing instance";
|
||||
static final String SD_ENTRY_3 = "275 <14>1 2014-06-20T09:14:07+00:00 loggregator d0602076-b14a-4c55-852a-981e7afeed38 DEA - " +
|
||||
"[exampleSDID@32473 iut=\\\"3\\\" eventSource=\\\"Application\\\" eventID=\\\"1011\\\"][exampleSDID@32473 " +
|
||||
"iut=\\\"3\\\" eventSource=\\\"Application\\\" escapedBracket=\\\"\\]\\\" eventID=\\\"1011\\\"] Removing instance";
|
||||
|
||||
@Test
|
||||
public void shouldParseAValidFramedEntry() throws Exception {
|
||||
|
||||
RFC6587SyslogDeserializer deserializer = new RFC6587SyslogDeserializer();
|
||||
|
||||
Map<String, ?> map = deserializer.deserialize(new ByteArrayInputStream(VALID_FRAMED_ENTRY.getBytes()));
|
||||
|
||||
assertEquals(1, map.get(SyslogHeaders.FACILITY));
|
||||
assertEquals(6, map.get(SyslogHeaders.SEVERITY));
|
||||
assertEquals(1, map.get(SyslogHeaders.VERSION));
|
||||
assertEquals("2014-06-20T09:14:07+00:00", map.get(SyslogHeaders.TIMESTAMP));
|
||||
assertEquals("loggregator", map.get(SyslogHeaders.HOST));
|
||||
assertEquals("d0602076-b14a-4c55-852a-981e7afeed38", map.get(SyslogHeaders.APP_NAME));
|
||||
assertEquals("DEA", map.get(SyslogHeaders.PROCID));
|
||||
assertEquals("-", map.get(SyslogHeaders.MSGID));
|
||||
assertEquals("Removing instance", map.get(SyslogHeaders.MESSAGE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldParseAValidUnframedEntry() throws Exception {
|
||||
|
||||
RFC6587SyslogDeserializer deserializer = new RFC6587SyslogDeserializer();
|
||||
|
||||
Map<String, ?> map = deserializer.deserialize(new ByteArrayInputStream(VALID_UNFRAMED_ENTRY.getBytes()));
|
||||
|
||||
assertEquals(1, map.get(SyslogHeaders.FACILITY));
|
||||
assertEquals(6, map.get(SyslogHeaders.SEVERITY));
|
||||
assertEquals(1, map.get(SyslogHeaders.VERSION));
|
||||
assertEquals("2014-06-20T09:14:07+00:00", map.get(SyslogHeaders.TIMESTAMP));
|
||||
assertEquals("loggregator", map.get(SyslogHeaders.HOST));
|
||||
assertEquals("d0602076-b14a-4c55-852a-981e7afeed38", map.get(SyslogHeaders.APP_NAME));
|
||||
assertEquals("DEA", map.get(SyslogHeaders.PROCID));
|
||||
assertEquals("-", map.get(SyslogHeaders.MSGID));
|
||||
assertEquals("Removing instance", map.get(SyslogHeaders.MESSAGE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetStructuredData() throws Exception {
|
||||
|
||||
RFC6587SyslogDeserializer deserializer = new RFC6587SyslogDeserializer();
|
||||
|
||||
Map<String, ?> map = deserializer.deserialize(new ByteArrayInputStream(SD_ENTRY_1.getBytes()));
|
||||
|
||||
assertEquals(1, map.get(SyslogHeaders.FACILITY));
|
||||
assertEquals(6, map.get(SyslogHeaders.SEVERITY));
|
||||
assertEquals(1, map.get(SyslogHeaders.VERSION));
|
||||
assertEquals("2014-06-20T09:14:07+00:00", map.get(SyslogHeaders.TIMESTAMP));
|
||||
assertEquals("loggregator", map.get(SyslogHeaders.HOST));
|
||||
assertEquals("d0602076-b14a-4c55-852a-981e7afeed38", map.get(SyslogHeaders.APP_NAME));
|
||||
assertEquals("DEA", map.get(SyslogHeaders.PROCID));
|
||||
assertEquals("-", map.get(SyslogHeaders.MSGID));
|
||||
assertEquals("Removing instance", map.get(SyslogHeaders.MESSAGE));
|
||||
assertEquals(1, ((List<?>) map.get(SyslogHeaders.STRUCTURED_DATA)).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetMultipleStructuredData() throws Exception {
|
||||
|
||||
RFC6587SyslogDeserializer deserializer = new RFC6587SyslogDeserializer();
|
||||
|
||||
Map<String, ?> map = deserializer.deserialize(new ByteArrayInputStream(SD_ENTRY_2.getBytes()));
|
||||
|
||||
assertEquals("false", map.get(SyslogHeaders.DECODE_ERRORS));
|
||||
assertEquals("Removing instance", map.get(SyslogHeaders.MESSAGE));
|
||||
assertEquals(2, ((List<?>) map.get(SyslogHeaders.STRUCTURED_DATA)).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetMultipleStructuredDataWithEscapedBracket() throws Exception {
|
||||
|
||||
RFC6587SyslogDeserializer deserializer = new RFC6587SyslogDeserializer();
|
||||
|
||||
Map<String, ?> map = deserializer.deserialize(new ByteArrayInputStream(SD_ENTRY_3.getBytes()));
|
||||
|
||||
assertEquals("false", map.get(SyslogHeaders.DECODE_ERRORS));
|
||||
assertEquals("Removing instance", map.get(SyslogHeaders.MESSAGE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldErrorOnShortFramedData() throws Exception {
|
||||
|
||||
RFC6587SyslogDeserializer deserializer = new RFC6587SyslogDeserializer();
|
||||
|
||||
Map<String, ?> map = deserializer.deserialize(new ByteArrayInputStream(SHORT_FRAMED_ENTRY.getBytes()));
|
||||
|
||||
assertEquals("true", map.get(SyslogHeaders.DECODE_ERRORS));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -44,7 +45,10 @@ import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.ip.tcp.connection.AbstractServerConnectionFactory;
|
||||
import org.springframework.integration.ip.tcp.connection.TcpNioServerConnectionFactory;
|
||||
import org.springframework.integration.syslog.DefaultMessageConverter;
|
||||
import org.springframework.integration.syslog.RFC5424MessageConverter;
|
||||
import org.springframework.integration.syslog.config.SyslogReceivingChannelAdapterFactoryBean;
|
||||
import org.springframework.integration.test.util.SocketUtils;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
@@ -109,7 +113,7 @@ public class SyslogReceivingChannelAdapterTests {
|
||||
Log logger = spy(TestUtils.getPropertyValue(adapter, "logger", Log.class));
|
||||
doReturn(true).when(logger).isDebugEnabled();
|
||||
final CountDownLatch sawLog = new CountDownLatch(1);
|
||||
doAnswer(new Answer<Void>(){
|
||||
doAnswer(new Answer<Void>() {
|
||||
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -163,4 +167,91 @@ public class SyslogReceivingChannelAdapterTests {
|
||||
adapter.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTcpRFC5424() throws Exception {
|
||||
SyslogReceivingChannelAdapterFactoryBean factory = new SyslogReceivingChannelAdapterFactoryBean(
|
||||
SyslogReceivingChannelAdapterFactoryBean.Protocol.tcp);
|
||||
int port = SocketUtils.findAvailableServerSocket(1514);
|
||||
PollableChannel outputChannel = new QueueChannel();
|
||||
factory.setOutputChannel(outputChannel);
|
||||
ApplicationEventPublisher publisher = mock(ApplicationEventPublisher.class);
|
||||
final CountDownLatch latch = new CountDownLatch(2);
|
||||
doAnswer(new Answer<Object>() {
|
||||
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
latch.countDown();
|
||||
return null;
|
||||
}
|
||||
}).when(publisher).publishEvent(any(ApplicationEvent.class));
|
||||
factory.setBeanFactory(mock(BeanFactory.class));
|
||||
AbstractServerConnectionFactory connectionFactory = new TcpNioServerConnectionFactory(port);
|
||||
connectionFactory.setDeserializer(new RFC6587SyslogDeserializer());
|
||||
connectionFactory.setApplicationEventPublisher(publisher);
|
||||
factory.setConnectionFactory(connectionFactory);
|
||||
factory.setConverter(new RFC5424MessageConverter());
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
TcpSyslogReceivingChannelAdapter adapter = (TcpSyslogReceivingChannelAdapter) factory.getObject();
|
||||
Log logger = spy(TestUtils.getPropertyValue(adapter, "logger", Log.class));
|
||||
doReturn(true).when(logger).isDebugEnabled();
|
||||
final CountDownLatch sawLog = new CountDownLatch(1);
|
||||
doAnswer(new Answer<Void>(){
|
||||
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
if (((String) invocation.getArguments()[0]).contains("Error on syslog socket")) {
|
||||
sawLog.countDown();
|
||||
}
|
||||
invocation.callRealMethod();
|
||||
return null;
|
||||
}
|
||||
}).when(logger).debug(anyString());
|
||||
new DirectFieldAccessor(adapter).setPropertyValue("logger", logger);
|
||||
Thread.sleep(1000);
|
||||
byte[] buf = ("253 <14>1 2014-06-20T09:14:07+00:00 loggregator d0602076-b14a-4c55-852a-981e7afeed38 DEA - " +
|
||||
"[exampleSDID@32473 iut=\\\"3\\\" eventSource=\\\"Application\\\" eventID=\\\"1011\\\"]" +
|
||||
"[exampleSDID@32473 iut=\\\"3\\\" eventSource=\\\"Application\\\" eventID=\\\"1011\\\"] Removing instance")
|
||||
.getBytes("UTF-8");
|
||||
Socket socket = SocketFactory.getDefault().createSocket("localhost", port);
|
||||
socket.getOutputStream().write(buf);
|
||||
socket.close();
|
||||
assertTrue(sawLog.await(10, TimeUnit.SECONDS));
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<Map<String, ?>> message = (Message<Map<String, ?>>) outputChannel.receive(10000);
|
||||
assertNotNull(message);
|
||||
assertEquals("loggregator", message.getPayload().get("syslog_HOST"));
|
||||
adapter.stop();
|
||||
assertTrue(latch.await(10, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUdpRFC5424() throws Exception {
|
||||
SyslogReceivingChannelAdapterFactoryBean factory = new SyslogReceivingChannelAdapterFactoryBean(
|
||||
SyslogReceivingChannelAdapterFactoryBean.Protocol.udp);
|
||||
int port = SocketUtils.findAvailableUdpSocket(1514);
|
||||
factory.setPort(port);
|
||||
PollableChannel outputChannel = new QueueChannel();
|
||||
factory.setOutputChannel(outputChannel);
|
||||
factory.setBeanFactory(mock(BeanFactory.class));
|
||||
factory.setConverter(new RFC5424MessageConverter());
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
UdpSyslogReceivingChannelAdapter adapter = (UdpSyslogReceivingChannelAdapter) factory.getObject();
|
||||
Thread.sleep(1000);
|
||||
byte[] buf = ("<14>1 2014-06-20T09:14:07+00:00 loggregator d0602076-b14a-4c55-852a-981e7afeed38 DEA - " +
|
||||
"[exampleSDID@32473 iut=\\\"3\\\" eventSource=\\\"Application\\\" eventID=\\\"1011\\\"]" +
|
||||
"[exampleSDID@32473 iut=\\\"3\\\" eventSource=\\\"Application\\\" eventID=\\\"1011\\\"] Removing instance")
|
||||
.getBytes("UTF-8");
|
||||
DatagramPacket packet = new DatagramPacket(buf, buf.length, new InetSocketAddress("localhost", port));
|
||||
DatagramSocket socket = new DatagramSocket();
|
||||
socket.send(packet);
|
||||
socket.close();
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<Map<String, ?>> message = (Message<Map<String, ?>>) outputChannel.receive(10000);
|
||||
assertNotNull(message);
|
||||
assertEquals("loggregator", message.getPayload().get("syslog_HOST"));
|
||||
adapter.stop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user