org.apache.axis2.transport.p2p.registry.RegistryApp.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.axis2.transport.p2p.registry.RegistryApp.java

Source

/*
 * * Licensed to the Apache Software Foundation (ASF) under one
 *  * or more contributor license agreements. See the NOTICE file
 *  * distributed with this work for additional information
 *  * regarding copyright ownership. The ASF 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 org.apache.axis2.transport.p2p.registry;

import org.apache.axis2.transport.p2p.pastry.PastryNodeUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import rice.Continuation;
import rice.environment.Environment;
import rice.p2p.commonapi.Id;
import rice.p2p.past.PastContent;
import rice.p2p.past.PastImpl;
import rice.pastry.NodeIdFactory;
import rice.pastry.PastryNode;
import rice.pastry.PastryNodeFactory;
import rice.pastry.commonapi.PastryIdFactory;
import rice.pastry.socket.SocketPastryNodeFactory;
import rice.pastry.standard.RandomNodeIdFactory;
import rice.persistence.*;

import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;

public class RegistryApp {

    private PastImpl pastApp;

    private PastryIdFactory idf;

    private boolean initialized;

    private Environment env;

    private String baseDir = "pastry";

    private File storageFile = null;

    private static final Log log = LogFactory.getLog(RegistryApp.class);

    public RegistryApp(String bootIp, String bootPort, String bindPort) throws IOException, InterruptedException {

        this.initialize(bootIp, bootPort, bindPort);
    }

    private void initialize(String bootIp, String bootPort, String bindPort)
            throws IOException, InterruptedException {

        PastryNodeUtils nodeUtils = new PastryNodeUtils();

        int bindport;

        if (bindPort == null) {

            bindport = nodeUtils.createRandomPort();

        } else {
            bindport = Integer.parseInt(bindPort);
        }

        log.debug("generated random port no for the Registry application :" + bindport);

        InetSocketAddress bootaddress = nodeUtils.getBootAddress(bootIp, Integer.parseInt(bootPort));

        this.env = new Environment();

        // Generate the NodeIds Randomly
        NodeIdFactory nidFactory = new RandomNodeIdFactory(env);

        PastryNodeFactory factory = null;

        if (bootaddress.getAddress().isLoopbackAddress()) {
            factory = new SocketPastryNodeFactory(nidFactory, bootaddress.getAddress(), bindport, env);
        } else {
            // construct the PastryNodeFactory, this is how we use rice.pastry.socket
            factory = new SocketPastryNodeFactory(nidFactory, bindport, env);
        }
        // construct a node, passing the null boothandle on the first loop will
        // cause the node to start its own ring
        PastryNode node = factory.newNode();

        // used for generating PastContent object Ids.
        // this implements the "hash function" for our DHT
        this.idf = new rice.pastry.commonapi.PastryIdFactory(env);

        // create a different storage root for each node
        String storageDirectory = "./" + baseDir + "/storage" + node.getId().hashCode();

        this.storageFile = new File(storageDirectory);

        // create the persistent part
        Storage store = new PersistentStorage(idf, storageDirectory, 4 * 1024 * 1024, node.getEnvironment());
        //Storage store = new MemoryStorage(idf);
        PastImpl app = new PastImpl(node, new StorageManagerImpl(idf, store,
                new LRUCache(new MemoryStorage(idf), 512 * 1024, node.getEnvironment())), 3, "");

        this.pastApp = app;

        node.boot(bootaddress);

        // the node may require sending several messages to fully boot into the ring
        synchronized (node) {
            while (!node.isReady() && !node.joinFailed()) {
                // delay so we don't busy-wait
                node.wait(500);

                // abort if can't join
                if (node.joinFailed()) {
                    throw new IOException("Could not join the FreePastry ring.  Reason:" + node.joinFailedReason());
                }
            }
        }

        this.setInitialized(true);

        log.info("Finished creating new node for Registry " + node);

    }

    //TODO need to handle duplicate inserts
    public void insertIntoRegistry(String operation, Id serverId) throws InterruptedException {

        final RegistryContent myContent = new RegistryContent(idf.buildId(operation), serverId);

        Id result = this.lookupRegistry(operation);

        // we insert only if there is no entry for the key
        if (result == null) {

            log.debug(" storing key for" + operation + "  :" + myContent.getId());

            pastApp.insert(myContent, new Continuation<Boolean[], Exception>() {
                // the result is an Array of Booleans for each insert
                public void receiveResult(Boolean[] results) {
                    int numSuccessfulStores = 0;
                    for (int ctr = 0; ctr < results.length; ctr++) {
                        if (results[ctr].booleanValue())
                            numSuccessfulStores++;
                    }
                    log.debug(myContent + " successfully stored at " + +numSuccessfulStores + " locations.");
                }

                public void receiveException(Exception result) {
                    log.debug("Error storing " + myContent);
                    //result.printStackTrace();
                }
            });

        }
    }

    public Id lookupRegistry(String operation) throws InterruptedException {

        final Id lookupKey = idf.buildId(operation);

        //TODO is this a good approch to assignt the result to final variable ?
        final PastContent[] resultContent = new PastContent[1];

        final BlockFlag blockFlag = new BlockFlag(true);

        if (pastApp != null) {
            pastApp.lookup(lookupKey, new Continuation<PastContent, Exception>() {

                public void receiveResult(PastContent result) {
                    log.debug("Successfully looked up Successfully looked up" + result + " for key " + lookupKey
                            + ".");

                    resultContent[0] = result;

                    blockFlag.unblock();
                }

                public void receiveException(Exception result) {
                    log.error("Error looking up " + lookupKey);
                    result.printStackTrace();

                    blockFlag.unblock();

                }

            });

            while (blockFlag.isBlocked()) {

                env.getTimeSource().sleep(200);
            }

        }
        if (resultContent != null && resultContent[0] != null) {
            return ((RegistryContent) resultContent[0]).getFirstServerId();
        } else {
            return null;
        }

    }

    public boolean isInitialized() {
        return initialized;
    }

    public void setInitialized(boolean initialized) {
        this.initialized = initialized;
    }

    private class BlockFlag {
        boolean block;
        int maxBlockCount = 10;
        int count = 0;

        BlockFlag(boolean blockstaus) {
            this.block = blockstaus;

        }

        void block() {
            block = true;
        }

        void unblock() {
            block = false;
        }

        boolean isBlocked() {
            count++;
            if (maxBlockCount == count) {
                return false;
            }
            return block;
        }
    }

    public void cleanupRegistry() {

        if (env != null) {
            env.destroy();
        }

        if (storageFile != null) {

            if (deleteDirectory(new File(baseDir))) {

                log.debug("cleaned up registry file :" + storageFile);
            }
        }

    }

    static public boolean deleteDirectory(File path) {
        if (path.exists()) {
            File[] files = path.listFiles();
            for (int i = 0; i < files.length; i++) {
                if (files[i].isDirectory()) {
                    deleteDirectory(files[i]);
                } else {
                    files[i].delete();
                }
            }
        }
        return (path.delete());
    }

}