INT-4187: Add enable-status-reader for tailer
JIRA: https://jira.spring.io/browse/INT-4187 Add javadoc and test - assertTrue on default adapter - assertFalse check on nativeAdapter - update XSD to add enable-status-reader add `@auther` add example in reference document update adoc * Fix minor typos in docs and allow to configure `enable-status-reader` with property placeholder **Cherry-pick to 4.3.x**
This commit is contained in:
committed by
Artem Bilan
parent
44ad81114c
commit
16c7535577
@@ -35,6 +35,7 @@ import org.springframework.util.StringUtils;
|
|||||||
/**
|
/**
|
||||||
* @author Gary Russell
|
* @author Gary Russell
|
||||||
* @author Artem Bilan
|
* @author Artem Bilan
|
||||||
|
* @author Ali Shahbour
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -43,6 +44,8 @@ public class FileTailInboundChannelAdapterFactoryBean extends AbstractFactoryBea
|
|||||||
|
|
||||||
private volatile String nativeOptions;
|
private volatile String nativeOptions;
|
||||||
|
|
||||||
|
private volatile boolean enableStatusReader = true;
|
||||||
|
|
||||||
private volatile File file;
|
private volatile File file;
|
||||||
|
|
||||||
private volatile TaskExecutor taskExecutor;
|
private volatile TaskExecutor taskExecutor;
|
||||||
@@ -77,6 +80,16 @@ public class FileTailInboundChannelAdapterFactoryBean extends AbstractFactoryBea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If false, thread for capturing stderr will not be started
|
||||||
|
* and stderr output will be ignored
|
||||||
|
* @param enableStatusReader true or false
|
||||||
|
* @since 4.3.6
|
||||||
|
*/
|
||||||
|
public void setEnableStatusReader(boolean enableStatusReader) {
|
||||||
|
this.enableStatusReader = enableStatusReader;
|
||||||
|
}
|
||||||
|
|
||||||
public void setFile(File file) {
|
public void setFile(File file) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
}
|
}
|
||||||
@@ -180,6 +193,7 @@ public class FileTailInboundChannelAdapterFactoryBean extends AbstractFactoryBea
|
|||||||
FileTailingMessageProducerSupport adapter;
|
FileTailingMessageProducerSupport adapter;
|
||||||
if (this.delay == null && this.end == null && this.reopen == null) {
|
if (this.delay == null && this.end == null && this.reopen == null) {
|
||||||
adapter = new OSDelegatingFileTailingMessageProducer();
|
adapter = new OSDelegatingFileTailingMessageProducer();
|
||||||
|
((OSDelegatingFileTailingMessageProducer) adapter).setEnableStatusReader(this.enableStatusReader);
|
||||||
if (this.nativeOptions != null) {
|
if (this.nativeOptions != null) {
|
||||||
((OSDelegatingFileTailingMessageProducer) adapter).setOptions(this.nativeOptions);
|
((OSDelegatingFileTailingMessageProducer) adapter).setOptions(this.nativeOptions);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.springframework.util.StringUtils;
|
|||||||
/**
|
/**
|
||||||
* @author Gary Russell
|
* @author Gary Russell
|
||||||
* @author Artem Bilan
|
* @author Artem Bilan
|
||||||
|
* @author Ali Shahbour
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -41,6 +42,7 @@ public class FileTailInboundChannelAdapterParser extends AbstractChannelAdapterP
|
|||||||
builder.addPropertyReference("outputChannel", channelName);
|
builder.addPropertyReference("outputChannel", channelName);
|
||||||
}
|
}
|
||||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "native-options");
|
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "native-options");
|
||||||
|
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "enable-status-reader");
|
||||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "file");
|
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "file");
|
||||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "task-executor");
|
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "task-executor");
|
||||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "task-scheduler");
|
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "task-scheduler");
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import org.springframework.util.Assert;
|
|||||||
*
|
*
|
||||||
* @author Gary Russell
|
* @author Gary Russell
|
||||||
* @author Gavin Gray
|
* @author Gavin Gray
|
||||||
|
* @author Ali Shahbour
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -46,6 +47,8 @@ public class OSDelegatingFileTailingMessageProducer extends FileTailingMessagePr
|
|||||||
|
|
||||||
private volatile String command = "ADAPTER_NOT_INITIALIZED";
|
private volatile String command = "ADAPTER_NOT_INITIALIZED";
|
||||||
|
|
||||||
|
private volatile boolean enableStatusReader = true;
|
||||||
|
|
||||||
private volatile BufferedReader reader;
|
private volatile BufferedReader reader;
|
||||||
|
|
||||||
private volatile TaskScheduler scheduler;
|
private volatile TaskScheduler scheduler;
|
||||||
@@ -59,6 +62,16 @@ public class OSDelegatingFileTailingMessageProducer extends FileTailingMessagePr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If false, thread for capturing stderr will not be started
|
||||||
|
* and stderr output will be ignored
|
||||||
|
* @param enableStatusReader true or false
|
||||||
|
* @since 4.3.6
|
||||||
|
*/
|
||||||
|
public void setEnableStatusReader(boolean enableStatusReader) {
|
||||||
|
this.enableStatusReader = enableStatusReader;
|
||||||
|
}
|
||||||
|
|
||||||
public String getCommand() {
|
public String getCommand() {
|
||||||
return this.command;
|
return this.command;
|
||||||
}
|
}
|
||||||
@@ -114,7 +127,9 @@ public class OSDelegatingFileTailingMessageProducer extends FileTailingMessagePr
|
|||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||||
this.process = process;
|
this.process = process;
|
||||||
this.startProcessMonitor();
|
this.startProcessMonitor();
|
||||||
this.startStatusReader();
|
if (this.enableStatusReader) {
|
||||||
|
startStatusReader();
|
||||||
|
}
|
||||||
this.reader = reader;
|
this.reader = reader;
|
||||||
this.getTaskExecutor().execute(this);
|
this.getTaskExecutor().execute(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,6 +234,17 @@ Only files matching this regular expression will be picked up by this adapter.
|
|||||||
</xsd:documentation>
|
</xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="enable-status-reader" default="true">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Configure the adapter to either start a thread for capturing stderr or not.
|
||||||
|
Default: True
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:simpleType>
|
||||||
|
<xsd:union memberTypes="xsd:boolean xsd:string"/>
|
||||||
|
</xsd:simpleType>
|
||||||
|
</xsd:attribute>
|
||||||
<xsd:attribute name="file" type="xsd:string">
|
<xsd:attribute name="file" type="xsd:string">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation>
|
<xsd:documentation>
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
native-options="-F -n 6"
|
native-options="-F -n 6"
|
||||||
task-executor="exec"
|
task-executor="exec"
|
||||||
task-scheduler="sched"
|
task-scheduler="sched"
|
||||||
|
enable-status-reader="false"
|
||||||
file-delay="456"
|
file-delay="456"
|
||||||
file="/tmp/foo"
|
file="/tmp/foo"
|
||||||
auto-startup="true"
|
auto-startup="true"
|
||||||
|
|||||||
@@ -38,15 +38,18 @@ import org.springframework.messaging.MessageChannel;
|
|||||||
import org.springframework.scheduling.TaskScheduler;
|
import org.springframework.scheduling.TaskScheduler;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Gary Russell
|
* @author Gary Russell
|
||||||
* @author Artem Bilan
|
* @author Artem Bilan
|
||||||
* @author Gavin Gray
|
* @author Gavin Gray
|
||||||
|
* @author Ali Shahbour
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
@ContextConfiguration
|
@ContextConfiguration
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@DirtiesContext
|
||||||
public class FileTailInboundChannelAdapterParserTests {
|
public class FileTailInboundChannelAdapterParserTests {
|
||||||
|
|
||||||
@Autowired @Qualifier("default")
|
@Autowired @Qualifier("default")
|
||||||
@@ -78,6 +81,7 @@ public class FileTailInboundChannelAdapterParserTests {
|
|||||||
assertEquals("tail -F -n 0 " + fileName, TestUtils.getPropertyValue(defaultAdapter, "command"));
|
assertEquals("tail -F -n 0 " + fileName, TestUtils.getPropertyValue(defaultAdapter, "command"));
|
||||||
assertSame(exec, TestUtils.getPropertyValue(defaultAdapter, "taskExecutor"));
|
assertSame(exec, TestUtils.getPropertyValue(defaultAdapter, "taskExecutor"));
|
||||||
assertTrue(TestUtils.getPropertyValue(defaultAdapter, "autoStartup", Boolean.class));
|
assertTrue(TestUtils.getPropertyValue(defaultAdapter, "autoStartup", Boolean.class));
|
||||||
|
assertTrue(TestUtils.getPropertyValue(defaultAdapter, "enableStatusReader", Boolean.class));
|
||||||
assertEquals(123, TestUtils.getPropertyValue(defaultAdapter, "phase"));
|
assertEquals(123, TestUtils.getPropertyValue(defaultAdapter, "phase"));
|
||||||
assertSame(this.tailErrorChannel, TestUtils.getPropertyValue(defaultAdapter, "errorChannel"));
|
assertSame(this.tailErrorChannel, TestUtils.getPropertyValue(defaultAdapter, "errorChannel"));
|
||||||
this.defaultAdapter.stop();
|
this.defaultAdapter.stop();
|
||||||
@@ -95,6 +99,7 @@ public class FileTailInboundChannelAdapterParserTests {
|
|||||||
assertSame(exec, TestUtils.getPropertyValue(nativeAdapter, "taskExecutor"));
|
assertSame(exec, TestUtils.getPropertyValue(nativeAdapter, "taskExecutor"));
|
||||||
assertSame(sched, TestUtils.getPropertyValue(nativeAdapter, "taskScheduler"));
|
assertSame(sched, TestUtils.getPropertyValue(nativeAdapter, "taskScheduler"));
|
||||||
assertTrue(TestUtils.getPropertyValue(nativeAdapter, "autoStartup", Boolean.class));
|
assertTrue(TestUtils.getPropertyValue(nativeAdapter, "autoStartup", Boolean.class));
|
||||||
|
assertFalse(TestUtils.getPropertyValue(nativeAdapter, "enableStatusReader", Boolean.class));
|
||||||
assertEquals(123, TestUtils.getPropertyValue(nativeAdapter, "phase"));
|
assertEquals(123, TestUtils.getPropertyValue(nativeAdapter, "phase"));
|
||||||
assertEquals(456L, TestUtils.getPropertyValue(nativeAdapter, "tailAttemptsDelay"));
|
assertEquals(456L, TestUtils.getPropertyValue(nativeAdapter, "tailAttemptsDelay"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -446,6 +446,18 @@ This creates a native adapter with default '-F -n 0' options (follow the file na
|
|||||||
This creates a native adapter with '-F -n +0' options (follow the file name, emitting all existing lines).
|
This creates a native adapter with '-F -n +0' options (follow the file name, emitting all existing lines).
|
||||||
If the tail command fails (on some platforms, a missing file causes the `tail` to fail, even with `-F` specified), the command will be retried every 10 seconds.
|
If the tail command fails (on some platforms, a missing file causes the `tail` to fail, even with `-F` specified), the command will be retried every 10 seconds.
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<int-file:tail-inbound-channel-adapter id="native"
|
||||||
|
channel="input"
|
||||||
|
enable-status-reader="false"
|
||||||
|
task-executor="exec"
|
||||||
|
file="/tmp/foo"/>
|
||||||
|
----
|
||||||
|
|
||||||
|
By default native adapter capture from standard output and send them as messages and from standard error to raise events.
|
||||||
|
Starting with _version 4.3.6_, you can discard the standard error events by setting the `enable-status-reader` to `false`.
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
<int-file:tail-inbound-channel-adapter id="apache"
|
<int-file:tail-inbound-channel-adapter id="apache"
|
||||||
|
|||||||
Reference in New Issue
Block a user