From b16a1776373976078b4e9889f1518e81915c2626 Mon Sep 17 00:00:00 2001 From: Ardika Rommy Sanjaya Date: Fri, 30 Nov 2018 14:54:52 +0700 Subject: [PATCH] Add reactor, netty, and nio packet handler --- gradle/configure.gradle | 3 +- jxnet-spring-boot-autoconfigure/build.gradle | 3 + .../autoconfigure/JxnetAutoConfiguration.java | 14 +++ .../JxnetConfigurationProperties.java | 13 +++ .../autoconfigure/NettyBufferHandler.java | 44 +++++++++ .../boot/autoconfigure/NioBufferHandler.java | 44 +++++++++ .../autoconfigure/ReactorPacketHandler.java | 43 +++++++++ .../annotation/EnablePacket.java | 45 +++++++++ .../constant/PacketHandlerType.java | 30 ++++++ .../jxpacket/JxpacketAutoconfiguration.java | 17 ---- .../JxpacketConfigurationProperties.java | 13 --- ...java => JxpacketHandlerConfiguration.java} | 14 ++- .../NettyBufferHandlerConfiguration.java | 79 +++++++++++++++ .../nio/NioBufferHandlerConfiguration.java | 75 +++++++++++++++ .../ReactorPacketHandlerConfiguration.java | 95 +++++++++++++++++++ .../JxpacketConfigurationSelector.java | 53 +++++++++++ .../main/resources/META-INF/spring.factories | 3 +- .../build.gradle | 2 + .../configuration/DefaultPacketHandler.java | 7 +- .../src/main/resources/application.properties | 2 +- 20 files changed, 556 insertions(+), 43 deletions(-) create mode 100644 jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/NettyBufferHandler.java create mode 100644 jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/NioBufferHandler.java create mode 100644 jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/ReactorPacketHandler.java create mode 100644 jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/annotation/EnablePacket.java create mode 100644 jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/constant/PacketHandlerType.java rename jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/jxpacket/{JxpacketHandler.java => JxpacketHandlerConfiguration.java} (86%) create mode 100644 jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/netty/NettyBufferHandlerConfiguration.java create mode 100644 jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/nio/NioBufferHandlerConfiguration.java create mode 100644 jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/reactor/ReactorPacketHandlerConfiguration.java create mode 100644 jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/selector/JxpacketConfigurationSelector.java diff --git a/gradle/configure.gradle b/gradle/configure.gradle index 272a4870..5fa6257b 100644 --- a/gradle/configure.gradle +++ b/gradle/configure.gradle @@ -7,7 +7,7 @@ ext { NAME = 'Jxnet' GROUP = 'com.ardikars.jxnet' - VERSION = '1.4.8.Final' + VERSION = '1.4.9.RC1' DESCRIPTION = 'Jxnet is a java library for capturing and sending network packet.' NDK_HOME = "${System.env.NDK_HOME}" @@ -34,6 +34,7 @@ ext { COMMON_VERSION = '1.2.2.Final' JXPACKET_VERSION = '1.2.0.Final' NETTY_VERSION = '4.1.31.Final' + REACTOR_VERSION = 'Californium-RELEASE' JNR_VERSION = '2.1.9' SPRING_BOOT_VERSION = '2.0.4.RELEASE' diff --git a/jxnet-spring-boot-autoconfigure/build.gradle b/jxnet-spring-boot-autoconfigure/build.gradle index b5afbd03..08952a37 100644 --- a/jxnet-spring-boot-autoconfigure/build.gradle +++ b/jxnet-spring-boot-autoconfigure/build.gradle @@ -9,6 +9,8 @@ dependencyManagement { imports { mavenBom("org.springframework.boot:spring-boot-dependencies:${SPRING_BOOT_VERSION}") mavenBom("com.ardikars.jxpacket:jxpacket:${JXPACKET_VERSION}") + mavenBom("io.netty:netty-bom:${NETTY_VERSION}") + mavenBom("io.projectreactor:reactor-bom:${REACTOR_VERSION}") } } @@ -21,6 +23,7 @@ dependencies { implementation ("com.ardikars.common:common-util") implementation ("com.ardikars.jxpacket:jxpacket-common") implementation ("com.ardikars.jxpacket:jxpacket-core") + implementation ("io.projectreactor:reactor-core") implementation ("org.slf4j:slf4j-api:${SLF4J_VERSION}") testImplementation ("junit:junit:${JUNIT_VERSION}") testImplementation ("org.mockito:mockito-core:${MOCKITO_VERSION}") diff --git a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/JxnetAutoConfiguration.java b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/JxnetAutoConfiguration.java index 2cbcc93e..37112bff 100644 --- a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/JxnetAutoConfiguration.java +++ b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/JxnetAutoConfiguration.java @@ -38,6 +38,8 @@ import java.net.SocketException; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -206,4 +208,16 @@ public StringBuilder errbuf() { return new StringBuilder(PCAP_ERRBUF_SIZE); } + /** + * Thread pool. + * @return returns {@link ExecutorService} object. + */ + @Bean("com.ardikars.jxnet.spring.boot.autoconfigure.executorService") + public ExecutorService executorService() { + if (this.properties.getNumberOfThread() == 0) { + return Executors.newCachedThreadPool(); + } + return Executors.newFixedThreadPool(this.properties.getNumberOfThread()); + } + } diff --git a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/JxnetConfigurationProperties.java b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/JxnetConfigurationProperties.java index 8981ff82..60af0b5f 100644 --- a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/JxnetConfigurationProperties.java +++ b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/JxnetConfigurationProperties.java @@ -67,6 +67,8 @@ public class JxnetConfigurationProperties { private Pcap.PcapType pcapType; + private Integer numberOfThread; + /** * Initialize field. */ @@ -108,6 +110,9 @@ public void initialize() { if (file == null) { file = null; } + if (numberOfThread == null) { + numberOfThread = 0; + } } public String getSource() { @@ -214,4 +219,12 @@ public void setPcapType(Pcap.PcapType pcapType) { this.pcapType = pcapType; } + public Integer getNumberOfThread() { + return numberOfThread; + } + + public void setNumberOfThread(Integer numberOfThread) { + this.numberOfThread = numberOfThread; + } + } diff --git a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/NettyBufferHandler.java b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/NettyBufferHandler.java new file mode 100644 index 00000000..bc59dbe1 --- /dev/null +++ b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/NettyBufferHandler.java @@ -0,0 +1,44 @@ +/** + * Copyright (C) 2015-2018 Jxnet + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.ardikars.jxnet.spring.boot.autoconfigure; + +import com.ardikars.jxnet.PcapPktHdr; +import com.ardikars.jxpacket.common.Packet; +import io.netty.buffer.ByteBuf; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +/** + * Callback function used for capturing packets. + * + * @author Ardika Rommy Sanjaya + * @since 1.4.9 + */ +public interface NettyBufferHandler { + + /** + * Next available packet. + * @param argument user argument. + * @param header pcap header. + * @param packet {@link Packet} object. + * @throws ExecutionException execution exception. + * @throws InterruptedException interrupted exception. + */ + void next(T argument, PcapPktHdr header, Future packet) throws ExecutionException, InterruptedException; + +} diff --git a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/NioBufferHandler.java b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/NioBufferHandler.java new file mode 100644 index 00000000..e839c2d8 --- /dev/null +++ b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/NioBufferHandler.java @@ -0,0 +1,44 @@ +/** + * Copyright (C) 2015-2018 Jxnet + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.ardikars.jxnet.spring.boot.autoconfigure; + +import com.ardikars.jxnet.PcapPktHdr; +import com.ardikars.jxpacket.common.Packet; +import java.nio.ByteBuffer; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +/** + * Callback function used for capturing packets. + * + * @author Ardika Rommy Sanjaya + * @since 1.4.9 + */ +public interface NioBufferHandler { + + /** + * Next available packet. + * @param argument user argument. + * @param header pcap header. + * @param packet {@link Packet} object. + * @throws ExecutionException execution exception. + * @throws InterruptedException interrupted exception. + */ + void next(T argument, PcapPktHdr header, Future packet) throws ExecutionException, InterruptedException; + +} diff --git a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/ReactorPacketHandler.java b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/ReactorPacketHandler.java new file mode 100644 index 00000000..0061bd9d --- /dev/null +++ b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/ReactorPacketHandler.java @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2015-2018 Jxnet + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.ardikars.jxnet.spring.boot.autoconfigure; + +import com.ardikars.jxnet.PcapPktHdr; +import com.ardikars.jxpacket.common.Packet; +import java.util.concurrent.ExecutionException; +import reactor.core.publisher.Mono; + +/** + * Callback function used for capturing packets. + * + * @author Ardika Rommy Sanjaya + * @since 1.4.9 + */ +public interface ReactorPacketHandler { + + /** + * Next available packet. + * @param argument user argument. + * @param header pcap header. + * @param packet {@link Packet} object. + * @throws ExecutionException execution exception. + * @throws InterruptedException interrupted exception. + */ + void next(T argument, PcapPktHdr header, Mono packet) throws ExecutionException, InterruptedException; + +} diff --git a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/annotation/EnablePacket.java b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/annotation/EnablePacket.java new file mode 100644 index 00000000..caa0bcf3 --- /dev/null +++ b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/annotation/EnablePacket.java @@ -0,0 +1,45 @@ +/** + * Copyright (C) 2015-2018 Jxnet + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.ardikars.jxnet.spring.boot.autoconfigure.annotation; + +import com.ardikars.jxnet.spring.boot.autoconfigure.constant.PacketHandlerType; +import com.ardikars.jxnet.spring.boot.autoconfigure.selector.JxpacketConfigurationSelector; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.springframework.context.annotation.Import; + +/** + * Enable packet handler configuration. + * + * @author Ardika Rommy Sanjaya + * @since 1.4.9 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Import(JxpacketConfigurationSelector.class) +public @interface EnablePacket { + + /** + * Packet handler type. + * @return a {@link PacketHandlerType} object. + */ + PacketHandlerType packetHandlerType() default PacketHandlerType.JXPACKET; + +} diff --git a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/constant/PacketHandlerType.java b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/constant/PacketHandlerType.java new file mode 100644 index 00000000..6c761227 --- /dev/null +++ b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/constant/PacketHandlerType.java @@ -0,0 +1,30 @@ +/** + * Copyright (C) 2015-2018 Jxnet + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.ardikars.jxnet.spring.boot.autoconfigure.constant; + +/** + * Packet handler type. + * + * @author Ardika Rommy Sanjaya + * @since 1.4.9 + */ +public enum PacketHandlerType { + + JXPACKET, NETTY_BUFFER, NIO_BUFFER, REACTOR, RXJAVA + +} diff --git a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/jxpacket/JxpacketAutoconfiguration.java b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/jxpacket/JxpacketAutoconfiguration.java index 7ea639a6..f5ffe547 100644 --- a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/jxpacket/JxpacketAutoconfiguration.java +++ b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/jxpacket/JxpacketAutoconfiguration.java @@ -35,12 +35,9 @@ import com.ardikars.jxpacket.core.ip.ip6.Routing; import com.ardikars.jxpacket.core.tcp.Tcp; import com.ardikars.jxpacket.core.udp.Udp; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** @@ -56,7 +53,6 @@ public class JxpacketAutoconfiguration { private final Boolean autoRegister; - private final Integer numberOfThread; /** * @@ -64,22 +60,9 @@ public class JxpacketAutoconfiguration { */ public JxpacketAutoconfiguration(JxpacketConfigurationProperties properties) { this.autoRegister = properties.getAutoRegister(); - this.numberOfThread = properties.getNumberOfThread(); register(); } - /** - * Thread pool. - * @return returns {@link ExecutorService} object. - */ - @Bean("com.ardikars.jxnet.spring.boot.autoconfigure.jxpacket.executorService") - public ExecutorService executorService() { - if (this.numberOfThread == 0) { - return Executors.newCachedThreadPool(); - } - return Executors.newFixedThreadPool(this.numberOfThread); - } - private void register() { if (this.autoRegister) { DataLinkLayer.register(DataLinkLayer.EN10MB, new Ethernet.Builder()); diff --git a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/jxpacket/JxpacketConfigurationProperties.java b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/jxpacket/JxpacketConfigurationProperties.java index 4f381d3f..942ea96b 100644 --- a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/jxpacket/JxpacketConfigurationProperties.java +++ b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/jxpacket/JxpacketConfigurationProperties.java @@ -32,8 +32,6 @@ public class JxpacketConfigurationProperties { private Boolean autoRegister; - private Integer numberOfThread; - /** * Initialize properties. */ @@ -42,9 +40,6 @@ public void initialize() { if (autoRegister == null) { this.autoRegister = false; } - if (numberOfThread == null) { - numberOfThread = 0; - } } public Boolean getAutoRegister() { @@ -55,12 +50,4 @@ public void setAutoRegister(Boolean autoRegister) { this.autoRegister = autoRegister; } - public Integer getNumberOfThread() { - return numberOfThread; - } - - public void setNumberOfThread(Integer numberOfThread) { - this.numberOfThread = numberOfThread; - } - } diff --git a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/jxpacket/JxpacketHandler.java b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/jxpacket/JxpacketHandlerConfiguration.java similarity index 86% rename from jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/jxpacket/JxpacketHandler.java rename to jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/jxpacket/JxpacketHandlerConfiguration.java index 51d3f1b9..edba7934 100644 --- a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/jxpacket/JxpacketHandler.java +++ b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/jxpacket/JxpacketHandlerConfiguration.java @@ -35,7 +35,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Configuration; @@ -45,12 +44,11 @@ * @author Ardika Rommy Sanjaya * @since 1.4.8 */ -@ConditionalOnClass(Packet.class) -@ConditionalOnBean(PacketHandler.class) +@ConditionalOnClass({Packet.class, ByteBuf.class}) @Configuration("com.ardikars.jxnet.spring.boot.autoconfigure.jxpacket.jxpacketHandler") -public class JxpacketHandler implements PcapHandler { +public class JxpacketHandlerConfiguration implements PcapHandler { - private static final Log LOG = LogFactory.getLog(JxpacketHandler.class.getName()); + private static final Log LOG = LogFactory.getLog(JxpacketHandlerConfiguration.class.getName()); private final int rawDataLinkType; private final PacketHandler packetHandler; @@ -62,9 +60,9 @@ public class JxpacketHandler implements PcapHandler { * @param dataLinkType datalink type. * @param packetHandler callback function. */ - public JxpacketHandler(@Qualifier("com.ardikars.jxnet.spring.boot.autoconfigure.jxpacket.executorService") ExecutorService executorService, - DataLinkType dataLinkType, - PacketHandler packetHandler) { + public JxpacketHandlerConfiguration(@Qualifier("com.ardikars.jxnet.spring.boot.autoconfigure.executorService") ExecutorService executorService, + DataLinkType dataLinkType, + PacketHandler packetHandler) { this.rawDataLinkType = dataLinkType != null ? dataLinkType.getValue() : 1; this.packetHandler = packetHandler; this.executorService = executorService; diff --git a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/netty/NettyBufferHandlerConfiguration.java b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/netty/NettyBufferHandlerConfiguration.java new file mode 100644 index 00000000..8c7afca0 --- /dev/null +++ b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/netty/NettyBufferHandlerConfiguration.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2015-2018 Jxnet + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.ardikars.jxnet.spring.boot.autoconfigure.netty; + +import com.ardikars.jxnet.PcapHandler; +import com.ardikars.jxnet.PcapPktHdr; +import com.ardikars.jxnet.spring.boot.autoconfigure.NettyBufferHandler; +import com.ardikars.jxpacket.common.Packet; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import java.nio.ByteBuffer; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.annotation.Configuration; + +/** + * Netty buffer handler. + * + * @author Ardika Rommy Sanjaya + * @since 1.4.9 + */ +@ConditionalOnClass({Packet.class, ByteBuf.class}) +@Configuration("com.ardikars.jxnet.spring.boot.autoconfigure.jxpacket.nettyBufferHandler") +public class NettyBufferHandlerConfiguration implements PcapHandler { + + private static final Log LOG = LogFactory.getLog(NettyBufferHandlerConfiguration.class.getName()); + + private final NettyBufferHandler packetHandler; + private final ExecutorService executorService; + + /** + * + * @param executorService thread pool. + * @param packetHandler callback function. + */ + public NettyBufferHandlerConfiguration(@Qualifier("com.ardikars.jxnet.spring.boot.autoconfigure.executorService") ExecutorService executorService, + NettyBufferHandler packetHandler) { + this.packetHandler = packetHandler; + this.executorService = executorService; + } + + @Override + public void nextPacket(final T user, final PcapPktHdr h, final ByteBuffer bytes) { + Future packet = executorService.submit(new Callable() { + @Override + public ByteBuf call() throws Exception { + ByteBuf buffer = ByteBufAllocator.DEFAULT.directBuffer(bytes.capacity()); + buffer.setBytes(0, bytes); + return buffer; + } + }); + try { + packetHandler.next(user, h, packet); + } catch (Exception e) { + LOG.warn(e.getMessage()); + } + } + +} diff --git a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/nio/NioBufferHandlerConfiguration.java b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/nio/NioBufferHandlerConfiguration.java new file mode 100644 index 00000000..04f590ec --- /dev/null +++ b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/nio/NioBufferHandlerConfiguration.java @@ -0,0 +1,75 @@ +/** + * Copyright (C) 2015-2018 Jxnet + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.ardikars.jxnet.spring.boot.autoconfigure.nio; + +import com.ardikars.jxnet.PcapHandler; +import com.ardikars.jxnet.PcapPktHdr; +import com.ardikars.jxnet.spring.boot.autoconfigure.NioBufferHandler; +import com.ardikars.jxpacket.common.Packet; +import java.nio.ByteBuffer; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.annotation.Configuration; + +/** + * NIO buffer handler. + * + * @author Ardika Rommy Sanjaya + * @since 1.4.9 + */ +@ConditionalOnClass(Packet.class) +@Configuration("com.ardikars.jxnet.spring.boot.autoconfigure.jxpacket.nioBufferHandler") +public class NioBufferHandlerConfiguration implements PcapHandler { + + private static final Log LOG = LogFactory.getLog(NioBufferHandlerConfiguration.class.getName()); + + private final NioBufferHandler packetHandler; + private final ExecutorService executorService; + + /** + * + * @param executorService thread pool. + * @param packetHandler callback function. + */ + public NioBufferHandlerConfiguration(@Qualifier("com.ardikars.jxnet.spring.boot.autoconfigure.executorService") ExecutorService executorService, + NioBufferHandler packetHandler) { + this.packetHandler = packetHandler; + this.executorService = executorService; + } + + @Override + public void nextPacket(final T user, final PcapPktHdr h, final ByteBuffer bytes) { + Future packet = executorService.submit(new Callable() { + @Override + public ByteBuffer call() throws Exception { + return bytes; + } + }); + try { + packetHandler.next(user, h, packet); + } catch (Exception e) { + LOG.warn(e.getMessage()); + } + } + +} diff --git a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/reactor/ReactorPacketHandlerConfiguration.java b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/reactor/ReactorPacketHandlerConfiguration.java new file mode 100644 index 00000000..f3ed307e --- /dev/null +++ b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/reactor/ReactorPacketHandlerConfiguration.java @@ -0,0 +1,95 @@ +/** + * Copyright (C) 2015-2018 Jxnet + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.ardikars.jxnet.spring.boot.autoconfigure.reactor; + +import com.ardikars.jxnet.DataLinkType; +import com.ardikars.jxnet.PcapHandler; +import com.ardikars.jxnet.PcapPktHdr; +import com.ardikars.jxnet.spring.boot.autoconfigure.ReactorPacketHandler; +import com.ardikars.jxpacket.common.Packet; +import com.ardikars.jxpacket.common.UnknownPacket; +import com.ardikars.jxpacket.core.ethernet.Ethernet; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import java.nio.ByteBuffer; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.context.annotation.Configuration; +import reactor.core.publisher.Mono; + +/** + * Reactor packet handler. + * + * @author Ardika Rommy Sanjaya + * @since 1.4.9 + */ +@ConditionalOnClass({Packet.class, ByteBuf.class, Mono.class}) +@Configuration("com.ardikars.jxnet.spring.boot.autoconfigure.jxpacket.reactorPacketHandler") +public class ReactorPacketHandlerConfiguration implements PcapHandler { + + private static final Log LOG = LogFactory.getLog(ReactorPacketHandlerConfiguration.class.getName()); + + private final int rawDataLinkType; + private final ReactorPacketHandler packetHandler; + private final ExecutorService executorService; + + /** + * + * @param executorService thread pool. + * @param dataLinkType datalink type. + * @param packetHandler callback function. + */ + public ReactorPacketHandlerConfiguration(@Qualifier("com.ardikars.jxnet.spring.boot.autoconfigure.executorService") + ExecutorService executorService, + DataLinkType dataLinkType, + ReactorPacketHandler packetHandler) { + this.rawDataLinkType = dataLinkType != null ? dataLinkType.getValue() : 1; + this.packetHandler = packetHandler; + this.executorService = executorService; + } + + @Override + public void nextPacket(final T user, final PcapPktHdr h, final ByteBuffer bytes) { + Future> packet = executorService.submit(new Callable>() { + @Override + public Mono call() throws Exception { + ByteBuf buffer = ByteBufAllocator.DEFAULT.directBuffer(bytes.capacity()); + buffer.setBytes(0, bytes); + Packet packet; + if (rawDataLinkType == 1) { + packet = Ethernet.newPacket(buffer); + } else { + packet = UnknownPacket.newPacket(buffer); + } + return Mono.justOrEmpty(packet); + } + }); + try { + packetHandler.next(user, h, packet.get()); + } catch (ExecutionException | InterruptedException e) { + LOG.warn(e.getMessage()); + } + } + +} diff --git a/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/selector/JxpacketConfigurationSelector.java b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/selector/JxpacketConfigurationSelector.java new file mode 100644 index 00000000..4cd7a7b4 --- /dev/null +++ b/jxnet-spring-boot-autoconfigure/src/main/java/com/ardikars/jxnet/spring/boot/autoconfigure/selector/JxpacketConfigurationSelector.java @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2015-2018 Jxnet + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.ardikars.jxnet.spring.boot.autoconfigure.selector; + +import com.ardikars.jxnet.spring.boot.autoconfigure.annotation.EnablePacket; +import com.ardikars.jxnet.spring.boot.autoconfigure.constant.PacketHandlerType; +import org.springframework.context.annotation.ImportSelector; +import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.core.type.AnnotationMetadata; + +/** + * @author jxnet 2018/11/30 + * @author Langkuy + */ +public class JxpacketConfigurationSelector implements ImportSelector { + + @Override + public String[] selectImports(AnnotationMetadata importingClassMetadata) { + AnnotationAttributes attributes = AnnotationAttributes + .fromMap(importingClassMetadata + .getAnnotationAttributes(EnablePacket.class.getName(), false)); + if (attributes == null) { + throw new IllegalStateException(); + } + PacketHandlerType type = attributes.getEnum("packetHandlerType"); + switch (type) { + case REACTOR: + return new String[] {"com.ardikars.jxnet.spring.boot.autoconfigure.reactor.ReactorPacketHandlerConfiguration"}; + case NETTY_BUFFER: + return new String[] {"com.ardikars.jxnet.spring.boot.autoconfigure.netty.NettyBufferHandlerConfiguration"}; + case NIO_BUFFER: + return new String[] {"com.ardikars.jxnet.spring.boot.autoconfigure.nio.NioBufferHandlerConfiguration"}; + default: + return new String[] {"com.ardikars.jxnet.spring.boot.autoconfigure.jxpacket.JxpacketHandlerConfiguration"}; + } + } + +} diff --git a/jxnet-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/jxnet-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index b9a5808f..36888f8e 100644 --- a/jxnet-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/jxnet-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -1,4 +1,3 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.ardikars.jxnet.spring.boot.autoconfigure.JxnetAutoConfiguration,\ - com.ardikars.jxnet.spring.boot.autoconfigure.jxpacket.JxpacketAutoconfiguration,\ - com.ardikars.jxnet.spring.boot.autoconfigure.jxpacket.JxpacketHandler \ No newline at end of file + com.ardikars.jxnet.spring.boot.autoconfigure.jxpacket.JxpacketAutoconfiguration \ No newline at end of file diff --git a/jxnet-spring-boot-starter-example/build.gradle b/jxnet-spring-boot-starter-example/build.gradle index 807ac20a..ce7eecb1 100644 --- a/jxnet-spring-boot-starter-example/build.gradle +++ b/jxnet-spring-boot-starter-example/build.gradle @@ -11,6 +11,7 @@ dependencyManagement { imports { mavenBom("org.springframework.boot:spring-boot-dependencies:${SPRING_BOOT_VERSION}") mavenBom("com.ardikars.jxpacket:jxpacket:${JXPACKET_VERSION}") + mavenBom("io.projectreactor:reactor-bom:${REACTOR_VERSION}") } } @@ -25,6 +26,7 @@ dependencies { implementation ("com.ardikars.common:common-util") implementation ("com.ardikars.jxpacket:jxpacket-common") implementation ("com.ardikars.jxpacket:jxpacket-core") + implementation ("io.projectreactor:reactor-core") } bootJar { diff --git a/jxnet-spring-boot-starter-example/src/main/java/com/ardikars/jxnet/spring/boot/starter/example/configuration/DefaultPacketHandler.java b/jxnet-spring-boot-starter-example/src/main/java/com/ardikars/jxnet/spring/boot/starter/example/configuration/DefaultPacketHandler.java index 5931346c..18f74e5c 100644 --- a/jxnet-spring-boot-starter-example/src/main/java/com/ardikars/jxnet/spring/boot/starter/example/configuration/DefaultPacketHandler.java +++ b/jxnet-spring-boot-starter-example/src/main/java/com/ardikars/jxnet/spring/boot/starter/example/configuration/DefaultPacketHandler.java @@ -19,6 +19,7 @@ import com.ardikars.jxnet.PcapPktHdr; import com.ardikars.jxnet.spring.boot.autoconfigure.PacketHandler; +import com.ardikars.jxnet.spring.boot.autoconfigure.annotation.EnablePacket; import com.ardikars.jxpacket.common.Packet; import java.util.Iterator; import java.util.concurrent.ExecutionException; @@ -31,6 +32,7 @@ * @author jxnet 2018/11/29 * @author Langkuy */ +@EnablePacket @Configuration public class DefaultPacketHandler implements PacketHandler { @@ -41,7 +43,10 @@ public class DefaultPacketHandler implements PacketHandler { @Override public void next(String argument, PcapPktHdr header, Future packet) throws ExecutionException, InterruptedException { - Iterator iterator = packet.get().iterator(); + print(packet.get().iterator()); + } + + private void print(Iterator iterator) { while (iterator.hasNext()) { LOGGER.info(iterator.next().toString()); } diff --git a/jxnet-spring-boot-starter-example/src/main/resources/application.properties b/jxnet-spring-boot-starter-example/src/main/resources/application.properties index f5db88e8..622388f4 100644 --- a/jxnet-spring-boot-starter-example/src/main/resources/application.properties +++ b/jxnet-spring-boot-starter-example/src/main/resources/application.properties @@ -1,5 +1,5 @@ spring.banner.location=classpath:/banner.txt jxnet.jxpacket.autoRegister=true -jxnet. +jxnet.numberOfThread=10 logging.pattern.console=%clr(%m){faint}%n