aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/traccar/BasePipelineFactory.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/traccar/BasePipelineFactory.java')
-rw-r--r--src/main/java/org/traccar/BasePipelineFactory.java169
1 files changed, 169 insertions, 0 deletions
diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java
new file mode 100644
index 000000000..b3d37f689
--- /dev/null
+++ b/src/main/java/org/traccar/BasePipelineFactory.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2012 - 2019 Anton Tananaev (anton@traccar.org)
+ *
+ * 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.traccar;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelInboundHandler;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOutboundHandler;
+import io.netty.channel.ChannelPipeline;
+import io.netty.handler.timeout.IdleStateHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.traccar.config.Keys;
+import org.traccar.handler.DefaultDataHandler;
+import org.traccar.handler.events.AlertEventHandler;
+import org.traccar.handler.events.CommandResultEventHandler;
+import org.traccar.handler.events.DriverEventHandler;
+import org.traccar.handler.events.FuelDropEventHandler;
+import org.traccar.handler.events.GeofenceEventHandler;
+import org.traccar.handler.events.IgnitionEventHandler;
+import org.traccar.handler.events.MaintenanceEventHandler;
+import org.traccar.handler.events.MotionEventHandler;
+import org.traccar.handler.events.OverspeedEventHandler;
+import org.traccar.handler.ComputedAttributesHandler;
+import org.traccar.handler.CopyAttributesHandler;
+import org.traccar.handler.DistanceHandler;
+import org.traccar.handler.EngineHoursHandler;
+import org.traccar.handler.FilterHandler;
+import org.traccar.handler.GeocoderHandler;
+import org.traccar.handler.GeolocationHandler;
+import org.traccar.handler.HemisphereHandler;
+import org.traccar.handler.MotionHandler;
+import org.traccar.handler.NetworkMessageHandler;
+import org.traccar.handler.OpenChannelHandler;
+import org.traccar.handler.RemoteAddressHandler;
+import org.traccar.handler.StandardLoggingHandler;
+
+import java.util.Map;
+
+public abstract class BasePipelineFactory extends ChannelInitializer<Channel> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(BasePipelineFactory.class);
+
+ private final TrackerServer server;
+ private boolean eventsEnabled;
+ private int timeout;
+
+ public BasePipelineFactory(TrackerServer server, String protocol) {
+ this.server = server;
+ eventsEnabled = Context.getConfig().getBoolean(Keys.EVENT_ENABLE);
+ timeout = Context.getConfig().getInteger(Keys.PROTOCOL_TIMEOUT.withPrefix(protocol));
+ if (timeout == 0) {
+ timeout = Context.getConfig().getInteger(Keys.SERVER_TIMEOUT);
+ }
+ }
+
+ protected abstract void addProtocolHandlers(PipelineBuilder pipeline);
+
+ @SafeVarargs
+ private final void addHandlers(ChannelPipeline pipeline, Class<? extends ChannelHandler>... handlerClasses) {
+ for (Class<? extends ChannelHandler> handlerClass : handlerClasses) {
+ if (handlerClass != null) {
+ pipeline.addLast(Main.getInjector().getInstance(handlerClass));
+ }
+ }
+ }
+
+ public static <T extends ChannelHandler> T getHandler(ChannelPipeline pipeline, Class<T> clazz) {
+ for (Map.Entry<String, ChannelHandler> handlerEntry : pipeline) {
+ ChannelHandler handler = handlerEntry.getValue();
+ if (handler instanceof WrapperInboundHandler) {
+ handler = ((WrapperInboundHandler) handler).getWrappedHandler();
+ } else if (handler instanceof WrapperOutboundHandler) {
+ handler = ((WrapperOutboundHandler) handler).getWrappedHandler();
+ }
+ if (clazz.isAssignableFrom(handler.getClass())) {
+ return (T) handler;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void initChannel(Channel channel) {
+ final ChannelPipeline pipeline = channel.pipeline();
+
+ if (timeout > 0 && !server.isDatagram()) {
+ pipeline.addLast(new IdleStateHandler(timeout, 0, 0));
+ }
+ pipeline.addLast(new OpenChannelHandler(server));
+ pipeline.addLast(new NetworkMessageHandler());
+ pipeline.addLast(new StandardLoggingHandler());
+
+ addProtocolHandlers(handler -> {
+ if (!(handler instanceof BaseProtocolDecoder || handler instanceof BaseProtocolEncoder)) {
+ if (handler instanceof ChannelInboundHandler) {
+ handler = new WrapperInboundHandler((ChannelInboundHandler) handler);
+ } else {
+ handler = new WrapperOutboundHandler((ChannelOutboundHandler) handler);
+ }
+ }
+ pipeline.addLast(handler);
+ });
+
+ addHandlers(
+ pipeline,
+ GeolocationHandler.class,
+ HemisphereHandler.class,
+ DistanceHandler.class,
+ RemoteAddressHandler.class);
+
+ addDynamicHandlers(pipeline);
+
+ addHandlers(
+ pipeline,
+ FilterHandler.class,
+ GeocoderHandler.class,
+ MotionHandler.class,
+ EngineHoursHandler.class,
+ CopyAttributesHandler.class,
+ ComputedAttributesHandler.class,
+ WebDataHandler.class,
+ DefaultDataHandler.class);
+
+ if (eventsEnabled) {
+ addHandlers(
+ pipeline,
+ CommandResultEventHandler.class,
+ OverspeedEventHandler.class,
+ FuelDropEventHandler.class,
+ MotionEventHandler.class,
+ GeofenceEventHandler.class,
+ AlertEventHandler.class,
+ IgnitionEventHandler.class,
+ MaintenanceEventHandler.class,
+ DriverEventHandler.class);
+ }
+
+ pipeline.addLast(new MainEventHandler());
+ }
+
+ private void addDynamicHandlers(ChannelPipeline pipeline) {
+ String handlers = Context.getConfig().getString(Keys.EXTRA_HANDLERS);
+ if (handlers != null) {
+ for (String handler : handlers.split(",")) {
+ try {
+ pipeline.addLast((ChannelHandler) Class.forName(handler).getDeclaredConstructor().newInstance());
+ } catch (ReflectiveOperationException error) {
+ LOGGER.warn("Dynamic handler error", error);
+ }
+ }
+ }
+ }
+
+}