/* * Copyright 2014-2016 CyberVision, Inc. * * 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.kaaproject.kaa.server.transports.tcp.transport; import io.netty.channel.ChannelInitializer; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.socket.SocketChannel; import org.kaaproject.kaa.server.common.server.AbstractNettyServer; import org.kaaproject.kaa.server.transport.AbstractKaaTransport; import org.kaaproject.kaa.server.transport.RangeExpressionParser; import org.kaaproject.kaa.server.transport.SpecificTransportContext; import org.kaaproject.kaa.server.transport.TransportLifecycleException; import org.kaaproject.kaa.server.transport.tcp.config.gen.AvroTcpConfig; import org.kaaproject.kaa.server.transports.tcp.transport.commands.KaaTcpCommandFactory; import org.kaaproject.kaa.server.transports.tcp.transport.netty.AbstractKaaTcpCommandProcessor; import org.kaaproject.kaa.server.transports.tcp.transport.netty.AbstractKaaTcpServerInitializer; import org.kaaproject.kaa.server.transports.tcp.transport.netty.KaaTcpDecoder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import java.util.UUID; /** * Implementation of Kaa TCP transport. * * @author Andrew Shvayka */ public class TcpTransport extends AbstractKaaTransport<AvroTcpConfig> { private static final Logger LOG = LoggerFactory.getLogger(TcpTransport.class); private static final int SUPPORTED_VERSION = 1; private AbstractNettyServer netty; @Override protected void init(SpecificTransportContext<AvroTcpConfig> context) throws TransportLifecycleException { AvroTcpConfig configuration = context.getConfiguration(); configuration.setBindInterface(replaceProperty(configuration.getBindInterface(), BIND_INTERFACE_PROP_NAME, context.getCommonProperties().getProperty(BIND_INTERFACE_PROP_NAME, LOCALHOST))); configuration.setPublicInterface(replaceProperty(configuration.getPublicInterface(), PUBLIC_INTERFACE_PROP_NAME, context.getCommonProperties().getProperty(PUBLIC_INTERFACE_PROP_NAME, LOCALHOST))); final KaaTcpCommandFactory factory = new KaaTcpCommandFactory(); this.netty = new AbstractNettyServer(configuration.getBindInterface(), configuration.getBindPort()) { @Override protected ChannelInitializer<SocketChannel> configureInitializer() throws Exception { return new AbstractKaaTcpServerInitializer() { @Override protected SimpleChannelInboundHandler<AbstractKaaTcpCommandProcessor> getMainHandler( UUID uuid) { return new TcpHandler(uuid, TcpTransport.this.handler); } @Override protected KaaTcpDecoder getDecoder() { return new KaaTcpDecoder(factory); } }; } }; } @Override public void start() { LOG.info("Initializing netty"); netty.init(); LOG.info("Starting netty"); netty.start(); } @Override public void stop() { LOG.info("Stopping netty"); netty.shutdown(); } @Override public Class<AvroTcpConfig> getConfigurationClass() { return AvroTcpConfig.class; } @Override protected List<byte[]> getSerializedConnectionInfoList() { List<byte[]> connectionInfoList = new ArrayList<>(); RangeExpressionParser rangeExpressionParser = new RangeExpressionParser(); List<Integer> publicPorts = rangeExpressionParser .getNumbersFromRanges(context.getConfiguration().getPublicPorts()); for (int publicPort : publicPorts) { byte[] interfaceData = toUtf8Bytes(context.getConfiguration().getPublicInterface()); byte[] publicKeyData = context.getServerKey().getEncoded(); ByteBuffer buf = ByteBuffer.wrap( new byte[SIZE_OF_INT * 3 + interfaceData.length + publicKeyData.length]); buf.putInt(publicKeyData.length); buf.put(publicKeyData); buf.putInt(interfaceData.length); buf.put(interfaceData); buf.putInt(publicPort); connectionInfoList.add(buf.array()); } return connectionInfoList; } @Override protected int getMinSupportedVersion() { return SUPPORTED_VERSION; } @Override protected int getMaxSupportedVersion() { return SUPPORTED_VERSION; } }