Package de.uniluebeck.itm.ncoap.endpoints

Source Code of de.uniluebeck.itm.ncoap.endpoints.DummyEndpoint$TransmissionTask

/**
* Copyright (c) 2012, Oliver Kleine, Institute of Telematics, University of Luebeck
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
*  - Redistributions of source messageCode must retain the above copyright notice, this list of conditions and the following
*    disclaimer.
*
*  - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
*    following disclaimer in the documentation and/or other materials provided with the distribution.
*
*  - Neither the name of the University of Luebeck nor the names of its contributors may be used to endorse or promote
*    products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package de.uniluebeck.itm.ncoap.endpoints;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import de.uniluebeck.itm.ncoap.communication.codec.CoapMessageDecoder;
import de.uniluebeck.itm.ncoap.communication.codec.CoapMessageEncoder;
import de.uniluebeck.itm.ncoap.message.CoapMessage;
import org.jboss.netty.bootstrap.ConnectionlessBootstrap;
import org.jboss.netty.channel.*;
import org.jboss.netty.channel.socket.DatagramChannel;
import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory;
import org.jboss.netty.util.ThreadNameDeterminer;
import org.jboss.netty.util.ThreadRenamingRunnable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.Iterator;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.*;


/**
* Receives and sends CoAP Messages for testing purposes. A {@link DummyEndpoint} has no automatic functionality
* besides encoding of inbound and decoding of outgoing messages.
*
* @author Oliver Kleine, Stefan Hüske
*/
public class DummyEndpoint extends SimpleChannelHandler {

    private DatagramChannel channel;

    private Logger log = LoggerFactory.getLogger(this.getClass().getName());

    //Received messages are ignored when set to false
    private boolean receptionEnabled = true;

    //map to save received messages
    private SortedMap<Long, CoapMessage> receivedCoapMessages =
            Collections.synchronizedSortedMap(new TreeMap<Long, CoapMessage>());

    private ScheduledExecutorService executor;

    public DummyEndpoint() {
        //Create thread pool factory (for thread-naming)
        ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("Dummy Endpoint Thread#%d").build();

        //This is to suppress renaming of the threads by the netty framework
        ThreadRenamingRunnable.setThreadNameDeterminer(new ThreadNameDeterminer() {
            @Override
            public String determineThreadName(String currentThreadName, String proposedThreadName) throws Exception {
                return null;
            }
        });

        //Create the thread-pool using the previously defined factory
        this.executor = new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 2 + 1,
                threadFactory, new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                log.error("Execution rejected!");
            }
        });

        //Create datagram datagramChannel to receive and send messages
        ChannelFactory channelFactory = new NioDatagramChannelFactory(executor);

        ConnectionlessBootstrap bootstrap = new ConnectionlessBootstrap(channelFactory);
        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {

            @Override
            public ChannelPipeline getPipeline() throws Exception {
                ChannelPipeline pipeline = Channels.pipeline();
                pipeline.addLast("Encoder", new CoapMessageEncoder());
                pipeline.addLast("Decoder", new CoapMessageDecoder());
                pipeline.addLast("CoAP Endpoint", DummyEndpoint.this );
                return pipeline;
            }
        });


        this.channel = (DatagramChannel) bootstrap.bind(new InetSocketAddress(0));
        log.info("New message receiver channel created for port " + channel.getLocalAddress().getPort());
    }


    public int getPort(){
        return channel.getLocalAddress().getPort();
    }


    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
        if(!receptionEnabled){
            return;
        }

        if((e.getMessage() instanceof CoapMessage)) {
            receivedCoapMessages.put(System.currentTimeMillis(), (CoapMessage) e.getMessage());
            log.info("Received #{} (from {}): {}.",
                    new Object[]{getReceivedCoapMessages().size(), e.getRemoteAddress(), e.getMessage()});
        }
    }


    public SortedMap<Long, CoapMessage> getReceivedCoapMessages() {
        return receivedCoapMessages;
    }


    public CoapMessage getReceivedMessage(int index) throws IndexOutOfBoundsException{
        Iterator<Long> receptionTimes = this.receivedCoapMessages.keySet().iterator();

        for(int i = 0; i < index; i++){
            receptionTimes.next();
        }

        return receivedCoapMessages.get(receptionTimes.next());
    }

    public synchronized void setReceptionEnabled(boolean receptionEnabled) {
        this.receptionEnabled = receptionEnabled;
    }


    public void writeMessage(final CoapMessage coapMessage, final InetSocketAddress remoteAddress) {
        try{
            this.executor.schedule(new TransmissionTask(coapMessage, remoteAddress), 0, TimeUnit.MILLISECONDS);
        }
        catch(Exception ex){
            log.error("EXCEPTION!", ex);
        }
    }

    private class TransmissionTask implements Runnable{

        private CoapMessage coapMessage;
        private InetSocketAddress remoteEndpoint;


        private TransmissionTask(CoapMessage coapMessage, InetSocketAddress remoteEndpoint) {
            this.coapMessage = coapMessage;
            this.remoteEndpoint = remoteEndpoint;
        }


        @Override
        public void run() {
            log.info("Send CoAP message: {}", coapMessage);
            Channels.write(channel, coapMessage, remoteEndpoint);
        }
    }

    /**
     * Shuts the client down by closing the datagramChannel which includes to unbind the datagramChannel from a listening port and
     * by this means free the port. All blocked or bound external resources are released.
     */
    public void shutdown(){
        //Close the datagram datagramChannel (includes unbind)
        ChannelFuture future = channel.close();

        //Await the closure and let the factory release its external resource to finalize the shutdown
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                channel.getFactory().releaseExternalResources();
                log.info("External resources released, shutdown completed");
            }
        });

        future.awaitUninterruptibly();
    }
}
TOP

Related Classes of de.uniluebeck.itm.ncoap.endpoints.DummyEndpoint$TransmissionTask

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.