Example usage for org.apache.hadoop.hdfs.client HdfsDataInputStream getCurrentDatanode

List of usage examples for org.apache.hadoop.hdfs.client HdfsDataInputStream getCurrentDatanode

Introduction

In this page you can find the example usage for org.apache.hadoop.hdfs.client HdfsDataInputStream getCurrentDatanode.

Prototype

public DatanodeInfo getCurrentDatanode() 

Source Link

Document

Get the datanode from which the stream is currently reading.

Usage

From source file:de.zib.sfs.WrappedFSDataInputStream.java

License:BSD License

/**
 * Gets the datanode that was last read from as a string. Should be called
 * after the first read operation has been performed.
 * //w  ww  .  j av a2s  .c om
 * @return "->" + hostname of the datanode, or empty string if the
 *         information is not available
 */
private String getDatanodeHostNameString() {
    if (this.datanodeHostnameSupplier == null) {
        if (this.in instanceof HdfsDataInputStream) {
            // call Hadoop's method directly
            final HdfsDataInputStream hdfsIn = (HdfsDataInputStream) this.in;
            if (hdfsIn.getCurrentDatanode() != null) {
                this.datanodeHostnameSupplier = () -> hdfsIn.getCurrentDatanode().getHostName();
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Using datanodeHostNameSupplier from Hadoop.");
                }
            } else {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("datanodeHostNameSupplier from Hadoop has no DataNode information.");
                }
                this.datanodeHostnameSupplier = () -> "";
            }
        } else {
            try {
                // Check if there's an appropriately named method available
                // that returns the hostname of the current node that is
                // being read from. Using the lambda factory provides almost
                // direct invocation performance.
                MethodHandles.Lookup methodHandlesLookup = MethodHandles.lookup();

                // try this stream or the one it wraps
                Method getCurrentDatanodeHostNameMethod = null;
                InputStream bindToStream = null;
                try {
                    getCurrentDatanodeHostNameMethod = this.in.getClass()
                            .getDeclaredMethod("getCurrentDatanodeHostName");
                    bindToStream = this.in;
                } catch (NoSuchMethodException e) {
                    getCurrentDatanodeHostNameMethod = this.in.getWrappedStream().getClass()
                            .getDeclaredMethod("getCurrentDatanodeHostName");
                    bindToStream = this.in.getWrappedStream();
                }

                MethodHandle datanodeHostNameSupplierTarget = LambdaMetafactory.metafactory(methodHandlesLookup,
                        "get", MethodType.methodType(Supplier.class, bindToStream.getClass()),
                        MethodType.methodType(Object.class),
                        methodHandlesLookup.unreflect(getCurrentDatanodeHostNameMethod),
                        MethodType.methodType(Object.class)).getTarget();
                this.datanodeHostnameSupplier = (Supplier<String>) datanodeHostNameSupplierTarget
                        .bindTo(bindToStream).invoke();

                if (LOG.isDebugEnabled()) {
                    LOG.debug("Using 'getCurrentDatanodeHostName' as datanodeHostNameSupplier.");
                }
            } catch (Throwable t) {
                this.datanodeHostnameSupplier = () -> "";
                if (LOG.isDebugEnabled()) {
                    LOG.debug("No datanodeHostNameSupplier available.", t);
                }
            }
        }
    }

    // handle cases where we have to perform a reverse lookup if
    // hostname is an IP
    String dnHostname = this.datanodeHostnameSupplier.get();
    String cachedHostname = HOSTNAME_CACHE.get(dnHostname);
    if (cachedHostname == null) {
        try {
            // strip port if necessary
            int portIndex = dnHostname.indexOf(":");
            cachedHostname = InetAddress
                    .getByName(portIndex == -1 ? dnHostname : dnHostname.substring(0, portIndex)).getHostName();
        } catch (UnknownHostException e) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Could not determine hostname for " + dnHostname, e);
            }
            cachedHostname = "";
        }
        HOSTNAME_CACHE.put(dnHostname, cachedHostname);
    }
    return cachedHostname;
}