/*
* Copyright 2014 The FIX.io Project
*
* The FIX.io Project 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 com.github.kpavlov.jreactive8583.netty.pipeline;
import com.github.kpavlov.jreactive8583.ConnectorConfiguration;
import com.github.kpavlov.jreactive8583.ConnectorConfigurer;
import com.github.kpavlov.jreactive8583.netty.codec.Iso8583Decoder;
import com.github.kpavlov.jreactive8583.netty.codec.Iso8583Encoder;
import com.solab.iso8583.MessageFactory;
import io.netty.bootstrap.AbstractBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.timeout.IdleStateHandler;
public class Iso8583ChannelInitializer<C extends Channel, B extends AbstractBootstrap, G extends ConnectorConfiguration> extends ChannelInitializer<C> {
public static final int DEFAULT_LENGTH_HEADER_LENGTH = 2;
private final G configuration;
private final ConnectorConfigurer<G, B> configurer;
private final EventLoopGroup workerGroup;
private final MessageFactory isoMessageFactory;
private final ChannelHandler[] customChannelHandlers;
private final Iso8583Encoder isoMessageEncoder;
private ChannelHandler loggingHandler;
private int headerLength = DEFAULT_LENGTH_HEADER_LENGTH;
public Iso8583ChannelInitializer(
G configuration,
ConnectorConfigurer<G, B> configurer,
EventLoopGroup workerGroup,
MessageFactory isoMessageFactory,
ChannelHandler... customChannelHandlers) {
this.configuration = configuration;
this.configurer = configurer;
this.workerGroup = workerGroup;
this.isoMessageFactory = isoMessageFactory;
this.customChannelHandlers = customChannelHandlers;
this.isoMessageEncoder = createIso8583Encoder(headerLength);
this.loggingHandler = createLoggingHandler(configuration);
}
@Override
public void initChannel(C ch) throws Exception {
final ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("lengthFieldFameDecoder", new LengthFieldBasedFrameDecoder(
configuration.getMaxFrameLength(), 0, headerLength, 0, headerLength));
pipeline.addLast("iso8583Decoder", createIso8583Decoder(isoMessageFactory));
pipeline.addLast("iso8583Encoder", isoMessageEncoder);
if (configuration.addLoggingHandler()) {
pipeline.addLast(workerGroup, "logging", loggingHandler);
}
if (configuration.replyOnError()) {
pipeline.addLast(workerGroup, "replyOnError", loggingHandler);
}
pipeline.addLast("idleState", new IdleStateHandler(0, 0, configuration.getIdleTimeout()));
pipeline.addLast("idleEventHandler", new IdleEventHandler(isoMessageFactory));
if (customChannelHandlers != null) {
pipeline.addLast(workerGroup, customChannelHandlers);
}
if (configurer != null) {
configurer.configurePipeline(pipeline, configuration);
}
}
protected Iso8583Encoder createIso8583Encoder(int lengthHeaderLength) {
return new Iso8583Encoder(lengthHeaderLength);
}
protected Iso8583Decoder createIso8583Decoder(final MessageFactory messageFactory) {
return new Iso8583Decoder(messageFactory);
}
protected ChannelHandler createLoggingHandler(G configuration) {
return new IsoMessageLoggingHandler(LogLevel.DEBUG,
configuration.logSensitiveData(),
configuration.logFieldDescription(),
configuration.getSensitiveDataFields());
}
}