/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.naming;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URI;
import java.util.Enumeration;
import org.jboss.bootstrap.api.as.server.JBossASBasedServer;
import org.jboss.logging.Logger;
/**
*
*
* @author Brian Stansberry
*
* @version $Revision: $
*/
public class NamingProviderURLWriter
{
public static final String DEFAULT_PERSIST_FILE_NAME = "jnp-service.url";
private static final Logger log = Logger.getLogger(NamingProviderURLWriter.class);
private String bootstrapUrl;
private String bindAddress;
private int port;
private JBossASBasedServer<?,?> server;
private URI outputDir;
private String filename = DEFAULT_PERSIST_FILE_NAME;
public URI getOutputDirURI()
{
return outputDir;
}
public void setOutputDirURL(URI dir)
{
this.outputDir = dir;
}
public String getOutputFileName()
{
return filename == null ? DEFAULT_PERSIST_FILE_NAME : filename;
}
public void setOutputFileName(String name)
{
this.filename = name;
}
public void setServer(JBossASBasedServer<?,?> server)
{
this.server = server;
}
public String getBootstrapURL()
{
return bootstrapUrl;
}
public void setBootstrapURL(String url)
{
this.bootstrapUrl = url;
}
public String getBootstrapAddress()
{
return bindAddress;
}
public void setBootstrapAddress(String bindAddress)
{
this.bindAddress = bindAddress;
}
public int getBootstrapPort()
{
return port;
}
public void setBootstrapPort(int port)
{
this.port = port;
}
public void start() throws Exception
{
establishBootStrapURL();
if (bootstrapUrl != null)
{
File base = null;
if (outputDir == null)
{
if (server != null)
{
base = new File(server.getConfiguration().getServerDataLocation().toURI());
outputDir = base.toURI();
}
}
else
{
base = new File(outputDir);
}
if (base != null)
{
base.mkdirs();
File file = new File(base, getOutputFileName());
if (file.exists())
{
file.delete();
}
PrintWriter writer = null;
try
{
if (log.isTraceEnabled())
{
log.trace("Creating file " + file);
}
file.createNewFile();
file.deleteOnExit();
writer = new PrintWriter(file);
writer.println(bootstrapUrl);
writer.flush();
}
catch (Exception e)
{
handleOutputFileCreationException(file.toURI(), e);
}
finally
{
if (writer != null)
{
writer.close();
}
}
}
else
{
log.warn("No directory specified for " + getOutputFileName() +
" cannot write the naming service url. Please configure either " +
"the 'server' property or the 'outputDir' property.");
}
}
else
{
log.debug("No URLs to write");
}
}
/** JBAS-7674 Try to intelligently deal with case where Windows has the file locked */
private void handleOutputFileCreationException(URI outputFile, Exception e)
{
boolean handled = false;
FileReader fr = null;
try
{
File f = new File(outputFile);
if (f.exists())
{
fr = new FileReader(f);
String existing = new BufferedReader(fr).readLine();
if (existing != null && this.bootstrapUrl.equals(existing.trim()))
{
log.info("Experienced a problem (" + e +
") updating the naming service URL file " + outputFile +
" but the current contents are correct.");
}
else
{
log.error("Cannot update naming service URL file " + outputFile, e);
}
handled = true;
}
}
catch (Exception ignored)
{
;
}
finally
{
if (fr != null)
{
try
{
fr.close();
}
catch (Exception ignored) {}
}
}
if (!handled)
{
log.error("Cannot create a naming service URL file at " + outputFile, e);
}
}
public void stop() throws Exception
{
if (outputDir != null)
{
String outputFile = "";
try
{
File f = new File(new File(outputDir), getOutputFileName());
outputFile = f.getAbsolutePath();
f.delete();
}
catch (Exception e)
{
log.warn("Failed to delete JNP URL file " + outputFile + " due to " + e);
}
}
}
protected void establishBootStrapURL() throws IOException
{
if (getBootstrapURL() == null && getBootstrapAddress() != null)
{
InetAddress addr = InetAddress.getByName(getBootstrapAddress());
if (addr.isAnyLocalAddress())
{
addr = findLoopbackAddress();
if (addr == null)
{
addr = InetAddress.getLocalHost();
}
}
// Build the bootstrap URL
StringBuilder sb = new StringBuilder("jnp://");
if (addr instanceof Inet6Address)
{
sb.append('[');
sb.append(addr.getHostAddress());
sb.append(']');
}
else
{
sb.append(addr.getHostAddress());
}
sb.append(':');
sb.append(getBootstrapPort());
setBootstrapURL(sb.toString());
}
}
private static InetAddress findLoopbackAddress() throws SocketException
{
Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
while (ifaces.hasMoreElements())
{
NetworkInterface iface = ifaces.nextElement();
Enumeration<InetAddress> addrs = iface.getInetAddresses();
while (addrs.hasMoreElements())
{
InetAddress addr = addrs.nextElement();
if (addr.isLoopbackAddress())
{
return addr;
}
}
}
return null;
}
}