org.commoncrawl.service.dns.DNSServiceTester.java Source code

Java tutorial

Introduction

Here is the source code for org.commoncrawl.service.dns.DNSServiceTester.java

Source

/**
 * Copyright 2008 - CommonCrawl Foundation
 * 
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU 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 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 <http://www.gnu.org/licenses/>.
 *
 **/

package org.commoncrawl.service.dns;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.HashSet;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.commoncrawl.async.EventLoop;
import org.commoncrawl.async.Timer;
import org.commoncrawl.crawl.common.internal.CrawlEnvironment;
import org.commoncrawl.io.NIODNSCache;
import org.commoncrawl.io.NIODNSLocalResolver;
import org.commoncrawl.rpc.base.internal.AsyncClientChannel;
import org.commoncrawl.rpc.base.internal.AsyncRequest;
import org.commoncrawl.rpc.base.internal.Server;
import org.commoncrawl.rpc.base.internal.AsyncRequest.Callback;
import org.commoncrawl.rpc.base.shared.RPCException;
import org.commoncrawl.util.CCStringUtils;
import org.commoncrawl.util.IPAddressUtils;
import org.commoncrawl.util.JVMStats;

/**
 * 
 * @author rana
 *
 */
public class DNSServiceTester extends Server implements AsyncClientChannel.ConnectionCallback {

    private static final Log LOG = LogFactory.getLog(DNSServiceTester.class);
    EventLoop _eventLoop = null;
    InetSocketAddress _address = null;
    AsyncClientChannel _channel;
    DNSService.AsyncStub _serviceStub;
    long _connectionCookie = 0;
    Semaphore _blockingSempahore = new Semaphore(0);
    long _testItemCount = 0;
    // long _itemsComplete = 0;
    AtomicLong _itemsComplete = new AtomicLong();
    File _testFile = null;
    String _testName = "";

    public static void main(String[] args) {

        InetSocketAddress socketAddress = new InetSocketAddress(args[0], CrawlEnvironment.DNS_SERVICE_RPC_PORT);
        // File testFileLocation = new File(args[1]);

        if (socketAddress != null && args[1].length() != 0) {
            DNSServiceTester tester = new DNSServiceTester(socketAddress, args[1]);
            LOG.info("Waiting for Event Loop to Terminate");
            try {
                tester._eventLoop.getEventThread().join();
            } catch (InterruptedException e) {
            }
            LOG.info("Event Loop Terminated");
        } else {
            LOG.error("Invalid Local Address Specified!");
        }
    }

    public DNSServiceTester(InetSocketAddress address, String queryName) {

        _eventLoop = new EventLoop();
        _address = address;
        _testFile = null;
        ;
        _testName = queryName;

        _eventLoop.start();

        try {
            start();
        } catch (IOException e) {
            LOG.error(CCStringUtils.stringifyException(e));
            _eventLoop.stop();
            return;
        }

        _eventLoop.setTimer(new Timer(0, false, new Timer.Callback() {

            @Override
            public void timerFired(Timer timer) {
                connect();
            }

        }));
    }

    void connect() {
        try {
            _channel = new AsyncClientChannel(_eventLoop, new InetSocketAddress(0), _address, this);
            _channel.open();
            _serviceStub = new DNSService.AsyncStub(_channel);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    void doSimpleQuery(String dnsName) {
        LOG.info("Doing Simple Query for Name:" + dnsName);
        DNSQueryInfo queryInfo = new DNSQueryInfo();
        queryInfo.setHostName(dnsName);

        //TODO: PASS TIMEOUT VALUE TO THE DNS SERVER SERVICE 

        try {
            _serviceStub.doQuery(queryInfo, new Callback<DNSQueryInfo, DNSQueryResponse>() {

                @Override
                public void requestComplete(AsyncRequest<DNSQueryInfo, DNSQueryResponse> request) {

                    if (request.getStatus() == AsyncRequest.Status.Success) {
                        if (request.getOutput().getStatus() == DNSQueryResponse.Status.SUCCESS) {
                            String strIPAddress = null;
                            String strCName = "";
                            String strTTL = "";

                            strIPAddress = IPAddressUtils
                                    .IntegerToIPAddressString(request.getOutput().getAddress());
                            if (request.getOutput().isFieldDirty(DNSQueryResponse.Field_CNAME)) {
                                strCName = request.getOutput().getCname();
                            }
                            strTTL = Long.toString(request.getOutput().getTtl());

                            LOG.info("DNS Query Succeeded. IP:" + strIPAddress + " CName:" + strCName + " TTL:"
                                    + strTTL);
                        } else {
                            String strError = "UNKNOWN ERROR";
                            switch (request.getOutput().getStatus()) {
                            case DNSQueryResponse.Status.RESOLVER_FAILURE: {
                                strError = "RESOLVER FAILURE (";
                                strError += request.getOutput().getErrorDesc();
                                strError += ")";
                            }
                            default: {
                                strError = "SERVER FAILURE (";
                                strError += request.getOutput().getErrorDesc();
                                strError += ")";
                            }
                            }
                            LOG.info("DNS Query Failed with Error:" + strError);
                        }
                    } else {
                        LOG.info("DNS Query Failed with RPC ERROR");
                    }

                    _eventLoop.stop();
                }

            });
        } catch (RPCException e) {
            LOG.error("RPC Exception:" + CCStringUtils.stringifyException(e));
            _eventLoop.stop();
        }
    }

    void startTest(File testFileLocation) {
        LOG.info("Starting Test...");

        LOG.info("Loading DNS Test File:" + testFileLocation);
        JVMStats.dumpMemoryStats();

        FileReader reader = null;

        NIODNSCache cache = NIODNSLocalResolver.getDNSCache();

        try {

            reader = new FileReader(testFileLocation);

            BufferedReader lineReader = new BufferedReader(reader);

            String line = null;

            HashSet<String> hostSet = new HashSet<String>();

            while ((line = lineReader.readLine()) != null) {

                int firstDelimiterIdx = line.indexOf(",/");
                int secondDelimiterIdx = -1;
                int thirdDelimiterIdx = -1;
                if (firstDelimiterIdx != -1) {
                    secondDelimiterIdx = line.indexOf(',', firstDelimiterIdx + 2);
                    thirdDelimiterIdx = line.indexOf(',', secondDelimiterIdx + 1);
                }

                if (firstDelimiterIdx != -1 && secondDelimiterIdx != -1) {
                    final String hostName = line.substring(0, firstDelimiterIdx);
                    final String ipAddress = line.substring(firstDelimiterIdx + 2, secondDelimiterIdx);
                    int ipAddressInteger = IPAddressUtils.IPV4AddressStrToInteger(ipAddress);

                    LOG.info("Querying Service for Address for Host:" + hostName);
                    DNSQueryInfo queryInfo = new DNSQueryInfo();

                    queryInfo.setHostName(hostName);

                    // increase item count 
                    _testItemCount++;

                    _serviceStub.doQuery(queryInfo, new Callback<DNSQueryInfo, DNSQueryResponse>() {

                        @Override
                        public void requestComplete(AsyncRequest<DNSQueryInfo, DNSQueryResponse> request) {

                            if (request.getOutput().getStatus() == DNSQueryResponse.Status.SUCCESS) {
                                LOG.info("Request Succeeded for Host:" + hostName + " IPAddress:"
                                        + IPAddressUtils.IntegerToIPAddressString(request.getOutput().getAddress())
                                        + " TTL:" + request.getOutput().getTtl() + "("
                                        + (request.getOutput().getTtl() - System.currentTimeMillis()) + ")Source:"
                                        + request.getOutput().getSourceServer());
                            } else {
                                LOG.info("Request Failed for Host:" + hostName + " Reason:"
                                        + request.getOutput().getErrorDesc() + " Source:"
                                        + request.getOutput().getSourceServer());
                            }

                            LOG.info("Total:" + _testItemCount + " Complete:" + _itemsComplete.get());
                            _itemsComplete.incrementAndGet();

                            // release the semaphore 
                            _blockingSempahore.release();
                        }

                    });

                }

                if (_testItemCount - _itemsComplete.get() > 5000) {
                    LOG.info("Queued Count:" + (_testItemCount - _itemsComplete.get())
                            + ". Waiting for Queued Count to drop to 1000");
                    while (_testItemCount - _itemsComplete.get() > 1000) {
                        LOG.info("Waiting for Count to Go Below 1000 (" + (_testItemCount - _itemsComplete.get())
                                + ")");
                        try {
                            _blockingSempahore.acquire();
                        } catch (InterruptedException e) {
                        }
                    }
                }
            }

            LOG.info("Done Processing Test File. Entry Count:" + _testItemCount);
            JVMStats.dumpMemoryStats();

        } catch (IOException e) {
            LOG.error(CCStringUtils.stringifyException(e));
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                LOG.error(CCStringUtils.stringifyException(e));
            }
        }

        LOG.info("Waiting on all items to complete...");

        while (_itemsComplete.get() != _testItemCount) {
            try {
                _blockingSempahore.acquire();
            } catch (InterruptedException e) {
            }
            if (_itemsComplete.get() % 1000 == 0) {
                LOG.info("Completed Another 1000 Items");
            }
        }
        LOG.info("All items to completed...");
    }

    @Override
    public void OutgoingChannelConnected(AsyncClientChannel channel) {
        LOG.info("Connected to Service. Starting Test Thread");
        new Thread(new Runnable() {

            @Override
            public void run() {
                LOG.info("Test Thread Started...");
                doSimpleQuery(_testName);
            }

        }).start();
    }

    @Override
    public boolean OutgoingChannelDisconnected(AsyncClientChannel channel) {
        LOG.error("Connection to DNS Service Severed. Exiting ... ");
        _eventLoop.stop();
        return false;
    }

}