//: TLink.java
// TODO: get rid of some of the hard-wired numbers below, such as '200' for the addr cache limit
package de.desy.tine.addrUtils;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.util.ArrayList;
import de.desy.tine.client.TLinkFactory;
import de.desy.tine.client.TLink;
import de.desy.tine.csvUtils.csv;
import de.desy.tine.dataUtils.TDataType;
import de.desy.tine.definitions.*;
import de.desy.tine.server.logger.DbgLog;
import de.desy.tine.server.logger.MsgLog;
import de.desy.tine.startup.TInitializer;
import de.desy.tine.startup.TInitializerFactory;
import de.desy.tine.structUtils.TStructRegistry;
import de.desy.tine.types.*;
// TODO: change all of the hardwired 200s and 100s below ...
public final class TSrvEntry
{
private static TInitializer initializer = TInitializerFactory.getInstance().getInitializer();
private static TLinkFactory tlf = null;
private static TLinkFactory getLinkFactory()
{
if (tlf == null) tlf = TLinkFactory.getInstance();
return tlf;
}
private static final String fecHdr = "FecName, FecNetwork, FecNode, IPAddr, PortOffset, TineProtocol";
private static final String srvHdr = "Name, FecName, EqpModule, Context, SubSystem";
private static String crlf = System.getProperty("line.separator");
private static String cacheFilePath = null;
private static String tineHomePath = null;
private static final int CACHE_TABLE_LENGTH = 2048;
public static final String SRVEQM_NAME = "_SRV__";
public static final String SRVFEC_NAME = "NETWORK";
public static final String SRVEXP_NAME = "NETWORK";
public static final String DOOCSEQM = "DCSEQM";
public boolean isDoocsSrv()
{
return isDoocsSrv(eqmName);
}
public static boolean isDoocsSrv(String eqm)
{
return (eqm != null && eqm.compareTo(DOOCSEQM) == 0);
}
public static boolean isDoocsSrv(String context, String server)
{
String eqm = getSrvEntryEqmName(context,server);
return (eqm != null && eqm.compareTo(DOOCSEQM) == 0);
}
private static BufferedReader fecR = null;
private static BufferedReader ensR = null;
private static BufferedReader srvR = null;
private static BufferedReader fecCacheR = null;
private static BufferedWriter fecCacheW = null;
private static BufferedWriter srvCacheW = null;
private static String fecCacheFile = null;
private static String srvCacheFile = null;
private static boolean initialized = false;
private static boolean initializing = false;
private static int ensSrvCacheIndex = -1;
private static int ensDevCacheIndex = -1;
private static int gensSrvCacheIndex = -1;
private static int gensDevCacheIndex = -1;
public String srvName;
public String eqmName;
public String fecName;
public String cntName;
static NameCache[] srvNameCache = new NameCache[CACHE_TABLE_LENGTH];
static String[] modNameCache = new String[CACHE_TABLE_LENGTH];
static TFecEntry[] fecAddrCache = new TFecEntry[CACHE_TABLE_LENGTH];
static int modNameCacheLength = 0;
static int fecAddrCacheLength = 0;
static int NameCacheLength = 0;
static int numConfiguredNameServers = 0;
static int currentConfiguredNameServer = 0;
public static String currentConfiguredNameServerTag;
public static TFecEntry getFecEntry(String fecName)
{
if (fecName == null) return null;
for (int i=0; i<fecAddrCacheLength; i++)
{
if (fecAddrCache[i] == null) continue;
if (fecName.compareToIgnoreCase(fecAddrCache[i].fecName) == 0)
{
return fecAddrCache[i];
}
}
return null;
}
public static String getSrvEntryEqmName(String context,String server)
{
if (server == null) return null;
for (int i=0; i<NameCacheLength; i++)
{
if (context != null && context.length() > 0 &&
context.compareToIgnoreCase("DEFAULT") != 0 &&
context.compareToIgnoreCase(srvNameCache[i].cntName) != 0) continue;
if (server.compareToIgnoreCase(srvNameCache[i].srvName) == 0)
{
return modNameCache[srvNameCache[i].modNameIndex];
}
}
return null;
}
public TFecEntry fecAddr;
private csv srvFile;
static int debugLevel = 0;
public boolean isLegacy = false;
private String resolutionHistory = "";
public String getResolutionHistory() { return resolutionHistory; }
public static void reset()
{
// leave the configured ENS and GENS in the table ..
int keep = numConfiguredNameServers * 2;
if (modNameCacheLength > keep) modNameCacheLength = keep;
if (fecAddrCacheLength > keep) fecAddrCacheLength = keep;
if (NameCacheLength > keep) NameCacheLength = keep;
// and clear the acquired structures ...
TStructRegistry.clear();
}
public String toString(String srvName,String ctxName)
{
if (eqmName == null) return new String("module does not exist");
StaticAddress(srvName,ctxName);
String modstr = new String("");
modstr += "Local Equipment Module : " + eqmName.trim();
modstr += "\nFront End Computer : " + fecName.trim();
if (fecAddr != null && fecAddr.fecHost != null)
{
modstr += "\nIP Address : " + fecAddr.fecHost.getHostAddress();
modstr += "\nPort Offset : " + fecAddr.fecPortOffset;
modstr += "\nHost Name : " + fecAddr.fecHost.getHostName();
}
return modstr;
}
void StaticAddress(String srvName,String ctxName)
{
int i;
if (srvName == null || ctxName == null)
{
eqmName = ""; fecName = ""; cntName = "";
return;
}
cntName = ctxName;
if (isENSCall(srvName, ctxName)) srvName = currentConfiguredNameServerTag;
for (i=0; i<NameCacheLength; i++)
{
if (ctxName.length() > 0 &&
ctxName.compareToIgnoreCase("DEFAULT") != 0 &&
ctxName.compareToIgnoreCase(srvNameCache[i].cntName) != 0) continue;
if (srvName.compareToIgnoreCase(srvNameCache[i].srvName) == 0)
{
eqmName = modNameCache[srvNameCache[i].modNameIndex];
fecName = fecAddrCache[srvNameCache[i].fecNameIndex].fecName;
fecAddr = fecAddrCache[srvNameCache[i].fecNameIndex];
return;
}
}
// acquire name info from ens or file:
if (srvName.startsWith("ENS"))
{
eqmName = new String("ENSEQM");
fecName = new String("ENS");
cntName = new String("SITE");
}
if (srvName.compareTo("NAMEQRY") == 0)
{
eqmName = new String("ENSEQM");
fecName = new String("ENS");
cntName = new String("SITE");
}
if (srvName.startsWith("GENS"))
{
eqmName = new String("GRPEQM");
fecName = new String("GENS");
cntName = new String("SITE");
}
if (eqmName == null) return;
if (modNameCacheLength >= CACHE_TABLE_LENGTH) return;
if (fecAddrCacheLength >= CACHE_TABLE_LENGTH) return;
if (NameCacheLength >= CACHE_TABLE_LENGTH) return;
int nameCacheIndex = NameCacheLength;
srvNameCache[nameCacheIndex] = new NameCache();
for (i=0; i<modNameCacheLength; i++)
if (eqmName.compareTo(modNameCache[i]) == 0) break;
if (i == modNameCacheLength) modNameCache[modNameCacheLength++] = eqmName;
srvNameCache[nameCacheIndex].modNameIndex = i;
for (i=0; i<fecAddrCacheLength; i++)
if (fecName.compareTo(fecAddrCache[i].fecName) == 0) break;
if (i == fecAddrCacheLength)
{ // last ditch effort (works only if the address is hard-wired in the initializer)
TFecEntry tfe = new TFecEntry(fecName);
if (!tfe.fecRegistered) return;
fecAddrCache[fecAddrCacheLength] = tfe;
fecAddr = fecAddrCache[fecAddrCacheLength++];
if (fecName.startsWith("ENS")) numConfiguredNameServers++;
}
srvNameCache[nameCacheIndex].fecNameIndex = i;
srvNameCache[nameCacheIndex].srvName = srvName;
srvNameCache[nameCacheIndex].cntName = cntName;
if (nameCacheIndex < CACHE_TABLE_LENGTH) NameCacheLength++;
}
static int addNameServerToServerCache(TFecEntry sa)
{
debugLevel = TLinkFactory.debugLevel;
if (fecAddrCacheLength >= CACHE_TABLE_LENGTH ||
NameCacheLength >= CACHE_TABLE_LENGTH ||
numConfiguredNameServers > 10) return -1;
MsgLog.log("addNameServerToServerCache","Adding ENS "+numConfiguredNameServers+" ("+sa.fecHost.getHostAddress()+ ") to address cache",0,null,1);
synchronized(getLinkFactory().ensMutex)
{
if (ensSrvCacheIndex == -1) ensSrvCacheIndex = fecAddrCacheLength;
if (ensDevCacheIndex == -1) ensDevCacheIndex = NameCacheLength;
}
fecAddrCache[fecAddrCacheLength] = sa;
srvNameCache[NameCacheLength] = new NameCache();
srvNameCache[NameCacheLength].fecNameIndex = fecAddrCacheLength;
srvNameCache[NameCacheLength].modNameIndex = modNameCacheLength;
srvNameCache[NameCacheLength].srvName = sa.fecName; // fec = srv for ENS
srvNameCache[NameCacheLength].cntName = "SITE";
modNameCache[modNameCacheLength] = "ENSEQM";
fecAddrCacheLength++;
modNameCacheLength++;
NameCacheLength++;
numConfiguredNameServers++;
if (numConfiguredNameServers == 1) // been called at least once ...
{
currentConfiguredNameServerTag = new String(sa.fecName);
}
return 0;
}
static int addGroupServerToServerCache(TFecEntry sa)
{ // TODO: meld this cut-and-paster with the above routine ...
if (fecAddrCacheLength >= CACHE_TABLE_LENGTH ||
NameCacheLength >= CACHE_TABLE_LENGTH ||
numConfiguredNameServers > 10)
return -1;
if (debugLevel > 1) DbgLog.log("addGroupServerToServerCache","Adding GENS " + numConfiguredNameServers + " to address cache");
if (gensSrvCacheIndex == -1) gensSrvCacheIndex = fecAddrCacheLength;
if (gensDevCacheIndex == -1) gensDevCacheIndex = NameCacheLength;
fecAddrCache[fecAddrCacheLength] = sa;
srvNameCache[NameCacheLength] = new NameCache();
srvNameCache[NameCacheLength].fecNameIndex = fecAddrCacheLength;
srvNameCache[NameCacheLength].modNameIndex = modNameCacheLength;
srvNameCache[NameCacheLength].srvName = sa.fecName; // fec = srv for GENS
srvNameCache[NameCacheLength].cntName = "SITE";
modNameCache[modNameCacheLength] = "GRPEQM";
fecAddrCacheLength++;
NameCacheLength++;
modNameCacheLength++;
return 0;
}
static int addNameServer(String ip)
{
TFecEntry sa;
SrvAddr da;
da = new SrvAddr();
da.fecName = new String("ENS#" + numConfiguredNameServers);
da.eqmContext = new String("SITE");
da.eqmName = new String("ENSEQM");
da.ipAddr = new String(ip);
da.portOffset = 0;
da.inetProtocol = TTransport.UDP; // 2;
da.tineProtocol = TTransport.DEFAULT_PROTOCOL_LEVEL;
sa = new TFecEntry(da);
if (!sa.fecRegistered) return -1;
addNameServerToServerCache(sa);
// now add the GENS ...
da.fecName = new String("GENS#" + numConfiguredNameServers);
da.eqmName = new String("GRPEQM");
da.portOffset = 101;
sa = new TFecEntry(da);
if (!sa.fecRegistered) return -1;
addGroupServerToServerCache(sa);
return 0;
}
static Object srvEntryMutex = new Object();
public static String getAddrFileLocation()
{
if (cacheFilePath == null) setAddrFileLocation();
return new String(cacheFilePath);
}
static void setAddrFileLocation()
{
synchronized (srvEntryMutex)
{
if (initialized) return;
try
{
if (fecR.ready() && srvR.ready())
{
if (TLinkFactory.debugLevel > 1) DbgLog.log("SetAddrFileLocation","static database readers ready");
}
}
catch (Exception e)
{ // null or IO exception (just starting up ...)
fecR = initializer.getAddressResource();
srvR = initializer.getEquipmentResource();
}
if (initializing) return;
initializing = true;
String ensName;
TFecEntry sa;
currentConfiguredNameServerTag = new String("ENS"); // default
String ensEnv = System.getProperty("tine.ens");
if (ensEnv != null)
{ // property setting !
MsgLog.log("TSrvEntry.setAddrFileLocation", "ENS address set from property setting",0,null,1);
}
else
{ // try environment
if ((ensEnv=System.getenv("TINE_ENS")) != null)
{ // found this in the environment
MsgLog.log("TSrvEntry.setAddrFileLocation", "ENS address set from environment",0,null,1);
}
}
String[] ensLst = null;
if (ensEnv != null && ensEnv.length() > 0)
{
ensLst = ensEnv.split(",");
}
for (int i=0; i<5; i++)
{ // don't allow more than 5 configured name servers ...
if (ensLst != null)
{ // something from the environment (TINE_ENS)
if (i < ensLst.length)
{
addNameServer(ensLst[i]);
MsgLog.log("TSrvEntry.setAddrFileLocation", "ENS#"+i+" from environment or property",0,null,1);
}
continue;
}
ensName = new String("ENS#" + i);
if (debugLevel > 1) DbgLog.log("SetAddrFileLocation","ENS: looking for " + ensName);
ensR = initializer.getHostsResource(); // will be closed in the csv reader
if (ensR != null)
{ // there is a local cshosts.csv file !
sa = new TFecEntry(ensR,ensName);
if (!sa.fecRegistered)
{ // maybe a simple name is entered in the cshosts.csv file ?
sa = new TFecEntry(ensR,"ENS");
}
if (sa.fecRegistered)
{
MsgLog.log("TSrvEntry.setAddrFileLocation", "ENS#"+i+" from cshosts.csv",0,null,1);
}
}
else
{ // try to discover it
findNameServerFromDNS();
if (numConfiguredNameServers > 0)
{
for (int k=0; k<numConfiguredNameServers; k++)
MsgLog.log("TSrvEntry.setAddrFileLocation", "ENS#"+k+" from DNS",0,null,1);
break;
}
findNameServerOnNetwork();
if (numConfiguredNameServers > 0)
{
for (int k=0; k<numConfiguredNameServers; k++)
MsgLog.log("TSrvEntry.setAddrFileLocation", "ENS#"+k+" from multicast discovery",0,null,1);
break;
}
// not found in DNS/on network: use a hard-wired address
MsgLog.log("TSrvEntry.setAddrFileLocation", "ENS#"+i+" address hard-wired",0,null,1);
sa = new TFecEntry("ENS");
}
if (!sa.fecRegistered)
{
if (debugLevel > 1) DbgLog.log("SetAddrFileLocation",ensName + " Not Registered");
continue;
}
addNameServerToServerCache(sa);
// now add the GENS ...
SrvAddr da = new SrvAddr();
da.fecName = new String("GENS#" + numConfiguredNameServers);
da.eqmName = new String("GRPEQM");
da.ipAddr = sa.fecHost.getHostAddress();
da.portOffset = 101;
sa = new TFecEntry(da);
addGroupServerToServerCache(sa);
if (ensR == null) break;
}
if (ensR != null)
{ // there was a cshosts.csv found and we're finished with it
try { ensR.close(); } catch (Exception x) { x.printStackTrace(); }
}
if (tineHomePath == null) tineHomePath = initializer.getTineHome();
if (cacheFilePath == null)
{
cacheFilePath = initializer.getTineCache();
cacheFilePath += File.separator + "tine" + File.separator + "cache" + File.separator;
}
if (File.separatorChar == '\\') crlf = "\r\n";
srvCacheFile = cacheFilePath + "eqpdbase.csv";
fecCacheFile = cacheFilePath + "fecaddr.csv";
initialized = true;
initializing = false;
}
}
public TSrvEntry()
{
eqmName = ""; srvName = ""; cntName = ""; fecName = "";
setAddrFileLocation();
}
private static boolean isInSrvFile(SrvAddr srv)
{
boolean hasEntry = false;
csv csvf = new csv(srvCacheFile);
try
{
String s, hdr;
int srv_col = -1,eqn_col = -1 ,fec_col = -1,ctx_col = -1;
boolean done = false;
while((s=csvf.readLine()) != null)
{
if (s.length() == 0) continue;
if (s.startsWith("#") || s.startsWith(";") || s.startsWith("%")) continue;
if (!done)
{
hdr = s;
if ((srv_col=csvf.findcol(hdr,"NAME")) < 0) throw new NoSuchFieldException();
if ((eqn_col=csvf.findcol(hdr,"EQPMODULE")) < 0) throw new NoSuchFieldException();
if ((fec_col=csvf.findcol(hdr,"FECNAME")) < 0) throw new NoSuchFieldException();
if ((ctx_col=csvf.findcol(hdr,"CONTEXT")) < 0) throw new NoSuchFieldException();
done = true;
continue;
}
if (csvf.namcmp(srv.expName,s,srv_col) != 0) continue;
if (csvf.namcmp(srv.eqmName,s,eqn_col) != 0) continue;
if (csvf.namcmp(srv.fecName,s,fec_col) != 0) continue;
if (csvf.namcmp(srv.eqmContext,s,ctx_col) != 0) continue;
hasEntry = true;
break;
}
}
catch (Exception e)
{ // database corrupt or not found
MsgLog.log("TSrvEntry.isInSrvFile", e.getMessage(),TErrorList.database_not_loaded,e,1);
hasEntry = false;
}
finally
{
csvf.close();
}
return hasEntry;
}
private static boolean isInFecFile(SrvAddr srv)
{
boolean hasEntry = false;
csv csvf = new csv(fecCacheFile);
try
{
String s, hdr;
int fec_col = -1,ip_col = -1 ,port_col = -1,prot_col = -1;
boolean done = false;
while((s=csvf.readLine()) != null)
{
if (s.length() == 0) continue;
if (s.startsWith("#") || s.startsWith(";") || s.startsWith("%")) continue;
if (!done)
{
hdr = s;
if ((fec_col=csvf.findcol(hdr,"FEC_NAME")) < 0) throw new NoSuchFieldException();
if ((ip_col=csvf.findcol(hdr,"IP_ADDR")) < 0) throw new NoSuchFieldException();
if ((port_col=csvf.findcol(hdr,"PORT_OFFSET")) < 0) throw new NoSuchFieldException();
prot_col = csvf.findcol(hdr,"TINE_PROTOCOL");
done = true;
continue;
}
if (csvf.namcmp(srv.fecName,s,fec_col) != 0) continue;
if (csvf.namcmp(srv.ipAddr,s,ip_col) != 0) continue;
try
{
if (srv.portOffset != Integer.parseInt(csvf.colptr(port_col,s))) continue;
if (prot_col < 0) continue;
if (srv.tineProtocol != Integer.parseInt(csvf.colptr(prot_col,s))) continue;
}
catch (Exception e)
{
continue;
}
hasEntry = true;
break;
}
}
catch (Exception e)
{ // database corrupt or not found
MsgLog.log("TSrvEntry.isInFecFile", e.getMessage(),TErrorList.database_not_loaded,e,1);
hasEntry = false;
}
finally
{
csvf.close();
}
return hasEntry;
}
private static boolean addToSrvFile(SrvAddr srv)
{
boolean hasEntry = false;
boolean needHeader = true;
csv csvr = new csv(srvCacheFile);
try
{
File csvw = new File(cacheFilePath);
csvw.mkdirs();
csvw = new File(srvCacheFile + ".tmp");
if (csvw.exists() && csvw.lastModified() > System.currentTimeMillis() - 300000)
{ // file more recent than the last 5 minutes -> some other client app is updating ?
return false;
}
srvCacheW = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(srvCacheFile + ".tmp")));
String s, hdr;
int srv_col = -1,ctx_col = -1;
boolean done = false;
while((s=csvr.readLine()) != null)
{
if (s.length() == 0) continue;
if (s.startsWith("#") || s.startsWith(";") || s.startsWith("%")) continue;
if (!done)
{
hdr = s;
if ((srv_col=csvr.findcol(hdr,"NAME")) < 0) throw new NoSuchFieldException();
if ((ctx_col=csvr.findcol(hdr,"CONTEXT")) < 0) throw new NoSuchFieldException();
srvCacheW.write(srvHdr.trim() + crlf);
needHeader = false;
done = true;
continue;
}
if (csvr.namcmp(srv.expName,s,srv_col) == 0 &&
csvr.namcmp(srv.eqmContext,s,ctx_col) == 0)
{ // found the entry -> update the particulars
s = srv.expName.trim() + ", " + srv.fecName.trim() + ", " + srv.eqmName.trim()
+ ", " + srv.eqmContext.trim() + ", " + srv.subSystem.trim();
hasEntry = true;
}
srvCacheW.write(s + crlf);
}
if (needHeader) srvCacheW.write(srvHdr.trim() + crlf);
if (!hasEntry)
{ // it's a new one !
s = srv.expName.trim() + "," + srv.fecName.trim() + "," + srv.eqmName.trim()
+ "," + srv.eqmContext.trim() + "," + srv.subSystem.trim();
srvCacheW.write(s + crlf);
}
srvCacheW.close();
csvr.close();
csvw = new File(srvCacheFile);
csvw.delete();
File srvf = new File(srvCacheFile + ".tmp");
srvf.renameTo(new File(srvCacheFile));
}
catch (Exception e)
{ // database corrupt or not found
MsgLog.log("TSrvEntry.addToSrvFile", e.getMessage(),TErrorList.database_not_loaded,e,1);
hasEntry = false;
}
finally
{
csvr.close();
}
return hasEntry;
}
private static boolean addToFecFile(SrvAddr srv)
{
boolean needHeader = true;
boolean hasEntry = false;
csv csvr = new csv(fecCacheFile);
try
{
File csvw = new File(cacheFilePath);
csvw.mkdirs();
csvw = new File(fecCacheFile + ".tmp");
if (csvw.exists() && csvw.lastModified() > System.currentTimeMillis() - 300000)
{ // file more recent than the last 5 minutes -> some other client app is updating ?
return false;
}
fecCacheW = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fecCacheFile + ".tmp")));
String s, hdr;
int fec_col = -1;
boolean done = false;
while((s=csvr.readLine()) != null)
{
if (s.length() == 0) continue;
if (s.startsWith("#") || s.startsWith(";") || s.startsWith("%")) continue;
if (!done)
{
hdr = s;
if ((fec_col=csvr.findcol(hdr,"FEC_NAME")) < 0) throw new NoSuchFieldException();
fecCacheW.write(fecHdr.trim() + crlf);
done = true;
needHeader = false;
continue;
}
if (csvr.namcmp(srv.fecName,s,fec_col) == 0)
{
s = srv.fecName.trim() + ",00000000,000000000000," + srv.ipAddr.trim() + "," +
srv.portOffset + "," + srv.tineProtocol;
hasEntry = true;
}
fecCacheW.write(s + crlf);
}
if (needHeader) fecCacheW.write(fecHdr.trim() + crlf);
if (!hasEntry)
{ // it's a new one !
s = srv.fecName.trim() + ",00000000,000000000000," + srv.ipAddr.trim() + "," +
srv.portOffset + "," + srv.tineProtocol;
fecCacheW.write(s + crlf);
}
csvr.close();
fecCacheW.close();
csvw = new File(fecCacheFile);
csvw.delete();
File fecf = new File(fecCacheFile + ".tmp");
fecf.renameTo(new File(fecCacheFile));
}
catch (Exception e)
{ // database corrupt or not found
MsgLog.log("TSrvEntry.addToFecFile", e.getMessage(),TErrorList.database_not_loaded,e,1);
hasEntry = false;
}
finally
{
csvr.close();
}
return hasEntry;
}
private static boolean addToGroupCacheFile(String filename,String column,String tgt)
{
boolean needHeader = true;
boolean hasEntry = false;
String tfn = filename+".tmp";
String gfn = filename+".csv";
csv csvr = new csv(gfn);
BufferedWriter grpCacheW;
try
{
File csvw = new File(tfn);
if (csvw.exists() && csvw.lastModified() > System.currentTimeMillis() - 600000)
{ // file more recent than the last 5 minutes -> some other client app is updating ?
return false;
}
csvw = new File(tfn.substring(0, tfn.lastIndexOf(File.separatorChar)));
csvw.mkdirs();
grpCacheW = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tfn)));
String s, hdr;
int col = -1;
boolean done = false;
while((s=csvr.readLine()) != null)
{
if (s.length() == 0) continue;
if (s.startsWith("#") || s.startsWith(";") || s.startsWith("%")) continue;
if (!done)
{
hdr = s;
if ((col=csvr.findcol(hdr,column)) < 0) throw new NoSuchFieldException();
grpCacheW.write(column + crlf);
done = true;
needHeader = false;
continue;
}
if (csvr.namcmp(tgt,s,col) == 0) hasEntry = true;
grpCacheW.write(s + crlf);
}
if (needHeader) grpCacheW.write(column + crlf);
if (!hasEntry)
{ // it's a new one !
grpCacheW.write(tgt + crlf);
}
grpCacheW.close();
if (hasEntry)
{ // remove the .tmp file
new File(tfn).delete();
}
else
{ // do the shuffle ...
csvr.close();
new File(gfn).delete();
File tf = new File(tfn);
tf.renameTo(new File(gfn));
}
}
catch (Exception e)
{ // database corrupt or not found
MsgLog.log("TSrvEntry.addToGroupCacheFile", e.getMessage(),TErrorList.database_not_loaded,e,1);
hasEntry = false;
}
finally
{
csvr.close();
}
return hasEntry;
}
public static void addServerToGroupCacheFile(String ctx,String grp,String srv)
{
try
{ // trap null pointers and other garbage input with try/catch
String filename = cacheFilePath+"GROUPS"+File.separator+ctx+File.separator+grp;
addToGroupCacheFile(filename,"Members",srv);
}
catch (Exception ignore) {}
}
public static void addDeviceToMemberCacheFile(String ctx,String srv,String dev)
{
try
{ // trap null pointers and other garbage input with try/catch
String filename = cacheFilePath+"GROUPS"+File.separator+ctx+File.separator+srv+File.separator+"devices";
addToGroupCacheFile(filename,"Devices",dev);
}
catch (Exception ignore) {}
}
public static void addAddressToCacheFile(SrvAddr srv)
{
if (srv == null) return;
if (!isInSrvFile(srv)) addToSrvFile(srv);
if (!isInFecFile(srv)) addToFecFile(srv);
}
private int fillinAddressFromFileCache(String devName,String srvName,String ctxName)
{
int cc = TErrorList.non_existent;
String fn = srvFile.getFileName();
if (fn == null)
fn = TInitializerFactory.getInstance().getInitializer().getFecHome()+File.separator+"eqpdbase.csv";
if (ctxName == null) ctxName = "";
String msg;
String tag = makeMsgTag(srvName, ctxName);
try
{
if (devName != null) srvFile.mark();
String s, hdr;
int i, nam_col = -1,eqn_col = -1 ,srv_col = -1,ctxt_col = -1;
boolean done = false;
while((s=srvFile.readLine()) != null)
{
if (s.length() == 0) continue;
if (s.startsWith("#") || s.startsWith(";") || s.startsWith("%")) continue;
if (!done)
{
hdr = s;
if ((nam_col=srvFile.findcol(hdr,"NAME")) < 0) throw new NoSuchFieldException();
if ((eqn_col=srvFile.findcol(hdr,"EQPMODULE")) < 0) throw new NoSuchFieldException();
if ((srv_col=srvFile.findcol(hdr,"FECNAME")) < 0) throw new NoSuchFieldException();
if ((ctxt_col=srvFile.findcol(hdr,"CONTEXT")) < 0) throw new NoSuchFieldException();
done = true;
continue;
}
if (srvFile.namcmp(srvName,s,nam_col) == 0)
{
eqmName = srvFile.colptr(eqn_col,s);
fecName = srvFile.colptr(srv_col,s);
cntName = srvFile.colptr(ctxt_col,s);
if (ctxName.compareToIgnoreCase(cntName) != 0) continue;
if (fecName.compareTo("GENS") == 0 && devName != null)
{ // local file has resolved to the GENS !
String[] memLst = getGroupMembersFromFileCache(cntName, srvName);
for (i=0; i<memLst.length; i++)
{
if (groupFileHasDevice(cntName, memLst[i], devName))
{
String key = "/"+cntName+"/GENS/"+devName+"[*]";
TLinkFactory.getInstance().appendRedirectionList(key, cntName, memLst[i], devName, "*");
srvFile.rewind();
cc = fillinAddressFromFileCache(null,memLst[i],cntName);
break;
}
}
srvFile.close();
return cc;
}
if (modNameCacheLength >= CACHE_TABLE_LENGTH) break;
if (fecAddrCacheLength >= CACHE_TABLE_LENGTH) break;
if (NameCacheLength >= CACHE_TABLE_LENGTH) break;
int nameCacheIndex = NameCacheLength;
srvNameCache[nameCacheIndex] = new NameCache();
for (i=0; i<modNameCacheLength; i++)
if (eqmName.compareTo(modNameCache[i]) == 0) break;
if (i == modNameCacheLength) modNameCache[modNameCacheLength++] = eqmName;
srvNameCache[nameCacheIndex].modNameIndex = i;
for (i=0; i<fecAddrCacheLength; i++)
if (fecName.compareToIgnoreCase(fecAddrCache[i].fecName) == 0) break;
if (i == fecAddrCacheLength)
{ // it's a new one
fecCacheR = new BufferedReader(new InputStreamReader(new FileInputStream(fecCacheFile)));
fecAddrCache[fecAddrCacheLength] = new TFecEntry(fecCacheR,fecName);
if (fecAddrCache[fecAddrCacheLength].fecRegistered)
{ // local cache successful
msg = "found FEC address in local file cache "+fn;
resolutionHistory += msg + "\n";
MsgLog.log("TSrvEntry.fillinAddressFromFileCache",tag+" "+msg,0,null,1);
}
else
{ // try static cache
fecAddrCache[fecAddrCacheLength] = new TFecEntry(fecR,fecName);
if (fecAddrCache[fecAddrCacheLength].fecRegistered)
{
msg = "found FEC address in static file cache "+fn;
resolutionHistory += msg + "\n";
MsgLog.log("TSrvEntry.fillinAddressFromFileCache",tag+" "+msg,0,null,1);
}
}
if (fecAddrCache[fecAddrCacheLength].fecRegistered)
{ // okay to increment the cache table
fecAddr = fecAddrCache[fecAddrCacheLength++];
}
else
{ // not found anywhere !
fecAddr = null;
cc = TErrorList.non_existent_fec;
break;
}
}
else
{
if (fecAddr == null) fecAddr = fecAddrCache[i];
}
srvNameCache[nameCacheIndex].fecNameIndex = i;
srvNameCache[nameCacheIndex].srvName = srvName;
srvNameCache[nameCacheIndex].cntName = ctxName;
if (nameCacheIndex < CACHE_TABLE_LENGTH) NameCacheLength++;
// found it
cc = 0;
break;
}
}
}
catch (Exception e)
{ // database corrupt or not found
MsgLog.log("fillinAddressFromFileCache", e.getMessage(),TErrorList.database_not_loaded,e,1);
cc = TErrorList.database_not_loaded;
resolutionHistory += "fillinAddressFromFileCache: "+e.getMessage()+"\n";
}
finally
{
srvFile.close();
}
if (cc != 0)
{
msg = "address not found in file cache "+fn;
resolutionHistory += msg + "\n";
MsgLog.log("TSrvEntry.fillinAddressFromFileCache",tag+" "+msg,0,null,0);
}
return cc;
}
int getAddressFromFileCache(String devName,String srvName,String ctxName)
{
String lkupname;
setAddrFileLocation();
if (debugLevel > 1) DbgLog.log("getAddressFromFileCache","FILE lookup: looking for \\" + ctxName + "\\" + srvName);
if (srvName.startsWith("ENS") && numConfiguredNameServers > 0)
{
lkupname = currentConfiguredNameServerTag;
}
else if (srvName.startsWith("GENS") && numConfiguredNameServers > 0)
{
lkupname = "G" + currentConfiguredNameServerTag;
}
else
{
lkupname = srvName;
}
this.srvName = lkupname;
for (int i=0; i<NameCacheLength; i++)
{
if (ctxName.length() > 0 &&
ctxName.compareToIgnoreCase("DEFAULT") != 0 &&
ctxName.compareToIgnoreCase(srvNameCache[i].cntName) != 0) continue;
if (lkupname.compareToIgnoreCase(srvNameCache[i].srvName) == 0)
{
eqmName = modNameCache[srvNameCache[i].modNameIndex];
fecName = fecAddrCache[srvNameCache[i].fecNameIndex].fecName;
fecAddr = fecAddrCache[srvNameCache[i].fecNameIndex];
resolutionHistory += "address found in local cache\n";
return 0;
}
}
// try the dynamic cache
srvFile = new csv(srvCacheFile);
dbFilePath = cacheFilePath;
int cc = fillinAddressFromFileCache(devName,srvName,ctxName);
if (cc != 0)
{ // not found, try the static cache
srvFile = new csv(srvR);
dbFilePath = tineHomePath;
cc = fillinAddressFromFileCache(devName,srvName,ctxName);
}
return cc;
}
private static String dbFilePath = null;
public String[] getGroupMembersFromFileCache(String ctxName,String srvName)
{
String grpCacheFile = dbFilePath+"GROUPS"+File.separator+
ctxName+File.separator+srvName+".csv";
csv grpDbFile = new csv(grpCacheFile);
String fn = grpDbFile.getFileName();
if (fn == null)
fn = TInitializerFactory.getInstance().getInitializer().getFecHome()+File.separator+"eqpdbase.csv";
ArrayList<String> lst = new ArrayList<String>();
try
{
String s, hdr;
int mem_col = -1;
boolean done = false;
while((s=grpDbFile.readLine()) != null)
{
if (s.length() == 0) continue;
if (s.startsWith("#") || s.startsWith(";") || s.startsWith("%")) continue;
if (!done)
{
hdr = s;
if ((mem_col=grpDbFile.findcol(hdr,"MEMBERS")) < 0) throw new NoSuchFieldException();
done = true;
continue;
}
lst.add(srvFile.colptr(mem_col,s));
}
}
catch (Exception e)
{ // database corrupt or not found
MsgLog.log("getGroupMembersFromFileCache", e.getMessage(),TErrorList.database_not_loaded,e,1);
resolutionHistory += "getGroupMembersFromFileCache: "+e.getMessage()+"\n";
}
finally
{
grpDbFile.close();
}
return lst.toArray(new String[0]);
}
boolean groupFileHasDevice(String ctxName,String memName,String tgtName)
{
String grpCacheFile = dbFilePath+"GROUPS"+File.separator+
ctxName+File.separator+memName+File.separator+
"devices.csv";
csv grpDbFile = new csv(grpCacheFile);
String fn = grpDbFile.getFileName();
if (fn == null)
fn = TInitializerFactory.getInstance().getInitializer().getFecHome()+File.separator+"eqpdbase.csv";
boolean found = false;
try
{
String s, hdr;
int dev_col = -1;
boolean done = false;
while((s=grpDbFile.readLine()) != null)
{
if (s.length() == 0) continue;
if (s.startsWith("#") || s.startsWith(";") || s.startsWith("%")) continue;
if (!done)
{
hdr = s;
if ((dev_col=grpDbFile.findcol(hdr,"DEVICES")) < 0) throw new NoSuchFieldException();
done = true;
continue;
}
if (grpDbFile.namcmp(tgtName,s,dev_col) == 0)
{
found = true;
break;
}
}
}
catch (Exception e)
{ // database corrupt or not found
MsgLog.log("groupFileHasDevice", e.getMessage(),TErrorList.database_not_loaded,e,1);
resolutionHistory += "groupFileHasDevice: "+e.getMessage()+"\n";
}
finally
{
grpDbFile.close();
}
return found;
}
public static void which(String target)
{
String res = "";
try
{
String[] parts;
if (target.startsWith("/"))
{
parts = target.split("/");
if (parts.length > 2)
{
TSrvEntry se = new TSrvEntry(parts[2],parts[1]);
res = se.toString(parts[2],parts[1]);
}
}
else
{
if (target.compareToIgnoreCase("ENS") == 0 ||
target.compareToIgnoreCase("GENS") == 0)
{
TSrvEntry se = new TSrvEntry(target,"SITE");
res = se.toString(target,"SITE");
}
else
{
TFecEntry fe = TSrvEntry.getFecEntry(target);
if (fe != null)
{
res += "\nIP Address : " + fe.fecHost.getHostAddress();
res += "\nPort Offset : " + fe.fecPortOffset;
res += "\nHost Name : " + fe.fecHost.getHostName();
}
}
}
}
catch (Exception bail)
{
res = "error in supplied argument";
}
TLinkFactory.dbgPrint(res);
return;
}
public TSrvEntry(String devName,String srvName,String ctxName)
{
// getAddressFromFileCache(devName,srvName,ctxName);
getAddress(devName,srvName,ctxName);
}
public TSrvEntry(String srvName,String ctxName)
{
getAddress(null,srvName,ctxName);
}
public TSrvEntry(TLink lnk)
{
getAddress(lnk.devName,lnk.expName,lnk.cntName);
}
public boolean isENSCall(String srvName,String ctxName)
{
if (srvName == null) return false;
if (srvName.startsWith("ENS"))
{ // local systematics => context == "DEFAULT" then is an ENS Request
if (ctxName.compareToIgnoreCase("DEFAULT") == 0) return true;
if (ctxName.compareToIgnoreCase("SITE") == 0 || ctxName.compareToIgnoreCase("SERVICE") == 0)
{ // must exactly == "ENS"
if (srvName.compareTo("ENS") == 0) return true;
}
}
return false;
}
private static Object cacheMtx = new Object();
public void getAddress(String devName,String srvName,String ctxName)
{
int i;
if (srvName == null) return;
if (ctxName == null) ctxName = "";
debugLevel = TLinkFactory.debugLevel;
if (TLinkFactory.debugLevel > 1) DbgLog.log("getAddress","TModAddress() has been called from factory");
setAddrFileLocation();
if (TLinkFactory.debugLevel > 1) DbgLog.log("getAddress","looking for /" + ctxName + "/" + srvName);
String lkupname = srvName;
boolean isENSRequest = isENSCall(srvName,ctxName);
if (isENSRequest)
{
if (numConfiguredNameServers == 0)
{ // if I'm looking for the ENS and it's not configured, add static address to cache
MsgLog.log("getAddress","add static ENS address",0,null,1);
StaticAddress(srvName,ctxName);
if (numConfiguredNameServers != 0)
{
resolutionHistory += "ENS address configured statically\n";
}
else
{
resolutionHistory += "no static ENS entry available\n";
MsgLog.log("getAddress","no static ENS entry available",0,null,1);
}
return;
}
lkupname = currentConfiguredNameServerTag;
}
boolean isGENSRequest = false;
if (srvName.compareTo("GENS") == 0 && currentConfiguredNameServerTag != null)
{
lkupname = "G" + currentConfiguredNameServerTag;
if (TLinkFactory.debugLevel > 1) DbgLog.log("getAddress","setting GENS entry to " + lkupname);
int idx=0;
if ((idx=lkupname.indexOf('#')) != -1) lkupname = lkupname.substring(0, idx);
isGENSRequest = true;
}
this.srvName = lkupname;
synchronized(getLinkFactory().ensMutex)
{
for (i=0; i<NameCacheLength; i++)
{ // check address cache for requested device server
if (ctxName.length() > 0 &&
ctxName.compareToIgnoreCase("DEFAULT") != 0 &&
ctxName.compareToIgnoreCase(srvNameCache[i].cntName) != 0) continue;
if (lkupname.compareToIgnoreCase(srvNameCache[i].srvName) == 0)
{ // found an entry in the existing cache
eqmName = modNameCache[srvNameCache[i].modNameIndex];
fecName = fecAddrCache[srvNameCache[i].fecNameIndex].fecName;
if (eqmName.length() == 0 || fecName.length() == 0) continue; // invalid entry ?
fecAddr = fecAddrCache[srvNameCache[i].fecNameIndex];
isLegacy = fecAddr.getTineProtocol() < TTransport.DEFAULT_PROTOCOL_LEVEL;
if (TLinkFactory.debugLevel > 1) DbgLog.log("getAddress","found it in cache");
resolutionHistory += "address found in cache\n";
if (isENSRequest) ensDevCacheIndex = i;
if (isGENSRequest) gensDevCacheIndex = i;
return;
}
}
if (isENSRequest)
{ // standard ENS request
i = ensDevCacheIndex == -1 ? 0 : ensDevCacheIndex;
}
else if (isGENSRequest)
{ // standard GENS address
i = gensDevCacheIndex == -1 ? 1 : gensDevCacheIndex;
}
else
{
i = -1;
}
}
if (i >= 0)
{ // ENS request made it this far without a hit, so return canonical entry
eqmName = modNameCache[srvNameCache[i].modNameIndex];
fecName = fecAddrCache[srvNameCache[i].fecNameIndex].fecName;
fecAddr = fecAddrCache[srvNameCache[i].fecNameIndex];
resolutionHistory += "standard ENS address\n";
return;
}
synchronized (cacheMtx)
{ // if an ENS address request is underway, wait for it ...
if (srvName.compareTo(SRVEXP_NAME) == 0)
{ // asking the NETWORK for the address
if (NameCacheLength < CACHE_TABLE_LENGTH && modNameCacheLength < CACHE_TABLE_LENGTH && fecAddrCacheLength < CACHE_TABLE_LENGTH)
{ // add to cache ...
SrvAddr srv = new SrvAddr();
srv.ipAddr = getLinkFactory().getInitializer().getNetCastAddress();
srv.portOffset = 0;
srv.tineProtocol = TTransport.DEFAULT_PROTOCOL_LEVEL;
srv.fecName = SRVFEC_NAME; srv.eqmContext = "";
srv.eqmName = SRVEQM_NAME; srv.expName = SRVEXP_NAME;
fecAddrCache[fecAddrCacheLength] = new TFecEntry(srv);
modNameCache[modNameCacheLength] = SRVEQM_NAME;
srvNameCache[NameCacheLength] = new NameCache();
srvNameCache[NameCacheLength].cntName = "";
srvNameCache[NameCacheLength].srvName = SRVEXP_NAME;
srvNameCache[NameCacheLength].modNameIndex = modNameCacheLength;
srvNameCache[NameCacheLength].fecNameIndex = fecAddrCacheLength;
fecAddr = fecAddrCache[fecAddrCacheLength];
fecName = fecAddrCache[fecAddrCacheLength].fecName;
eqmName = SRVEQM_NAME;
NameCacheLength++; modNameCacheLength++; fecAddrCacheLength++;
resolutionHistory += "adding NETWORK to the address cache\n";
}
return;
}
if (numConfiguredNameServers == 0)
{
MsgLog.log("getAddress","No configured ENS",TErrorList.configuration_error,null,1);
resolutionHistory += "No configured ENS\n";
}
synchronized (fecAddrCache)
{
if (numConfiguredNameServers == 0 || // no configured ENS
getAddressFromENS(srvName,ctxName) != 0) // the ENS didn't have the address
{ // try the cache system (now 'devName' is important)
getAddressFromFileCache(devName,srvName,ctxName);
}
if (eqmName == null)
{ // address unknown
if (getLinkFactory().allowNeworkAddressResolution())
{ // -> one last chance to acquire the address
FECAddr fec = new FECAddr();
SrvAddr srv = new SrvAddr();
if (findServerOnNetwork(ctxName, "", srvName, fec, srv) == 0)
{
resolutionHistory += "address acquired from NETWORK\n";
if (addAddressToCache(srvName,ctxName,srv) == 0) return;
}
MsgLog.log("getAddress","No address available from network",TErrorList.address_unresolved,null,1);
}
String tag = makeMsgTag(srvName, ctxName);
resolutionHistory += "address is unresolved\n";
MsgLog.log("TSrvEntry.getAddress",tag+" address is unresolved",TErrorList.host_not_resolved,null,0);
if (srvName.compareToIgnoreCase("GLOBALS") == 0)
{ // address unknown but pin the equipment module name
MsgLog.log("getAddress", "globals server address for "+ctxName+" unresolved",TErrorList.address_unresolved,null,0);
return;
}
}
}
}
}
private static boolean legacyEns = false;
public static boolean isLegacyEns() { return legacyEns; }
public static void setLegacyEns(boolean value) { legacyEns = value; }
private static int lastENScc = TErrorList.not_initialized;
public static synchronized SrvAddr getSrvAddrFromENS(String dname,String cname)
{
synchronized (cacheMtx)
{ // don't go looking for an address at the same time we're scanning thru the cache for it.
if (numConfiguredNameServers == 0 ||
currentConfiguredNameServerTag == null) return null;
String tagName;
int cc = TErrorList.connection_timeout;
tagName = new String(currentConfiguredNameServerTag + "/");
tagName = cname.length() > 0 ? tagName.concat(cname) : tagName.concat("#2");
SrvAddr srv = new SrvAddr();
TDataType d_null = new TDataType();
TDataType d_srv = new TDataType(srv.toByteArray(legacyEns),"");
synchronized(getLinkFactory().ensMutex)
{
TLink ma = getLinkFactory().simpleLink(tagName,dname,d_srv,d_null,(short)1);
if (ma == null)
{
if (TLinkFactory.debugLevel > 1) DbgLog.log("getAddress","cannot create link to ENS");
return null;
}
ma.cannotNotifyFromWatchdogThread = true;
for (int i=0; i<2 && cc == TErrorList.connection_timeout; i++)
{ // watchdog thread won't handle the retries, so do it here
cc = ma.execute(TLink.defaultTimeout,true);
if (cc == TErrorList.illegal_data_size && !legacyEns)
{
legacyEns = true;
d_srv = new TDataType(srv.toByteArray(legacyEns),"");
ma = getLinkFactory().simpleLink(tagName,dname,d_srv,d_null,(short)1);
i = 0;
}
}
ma.close();
}
if (cc == TErrorList.link_blacklisted) cc = TErrorList.host_not_resolved;
lastENScc = cc;
if (cc == 0)
{
srv.toStruct(legacyEns);
if (srv.tineProtocol == 0) srv.tineProtocol = TTransport.DEFAULT_PROTOCOL_LEVEL;
return srv;
}
MsgLog.log("getAddress","link to ENS "+currentConfiguredNameServer+" : "+TErrorList.toString(cc),cc,null,1);
return null;
}
}
private int addAddressToCache(String srvName, String ctxName, SrvAddr srv)
{
if (srv == null)return TErrorList.argument_list_error;
int mod_idx, fec_idx;
boolean augmentModNameCacheLength = false;
boolean augmentNameCacheLength = false;
boolean replaceAddress = false;
eqmName = srv.eqmName;
if (ctxName == null) ctxName = "";
for (mod_idx=0; mod_idx<modNameCacheLength; mod_idx++)
{ // is it already in the tables ?
if (eqmName.compareTo(modNameCache[mod_idx]) == 0) break;
}
if (mod_idx == modNameCacheLength)
{ // didn't find it
if (modNameCacheLength >= CACHE_TABLE_LENGTH-1)
{ // and there's no room to grow
// TODO: recycle some of the older addresses ? (why does an app need to talk to 1000 different servers ?)
return TErrorList.resources_exhausted;
}
augmentModNameCacheLength = true;
}
modNameCache[mod_idx] = eqmName;
fecName = srv.fecName;
for (fec_idx=0; fec_idx<fecAddrCacheLength; fec_idx++)
{ // is it already in the tables ?
if (fecName.compareToIgnoreCase(fecAddrCache[fec_idx].fecName) == 0)
{ // found the fec name !
if (srv.ipAddr.compareTo(fecAddrCache[fec_idx].fecHost.getHostAddress()) != 0)
replaceAddress = true;
break;
}
}
if (augmentModNameCacheLength) modNameCacheLength++;
if (fec_idx == fecAddrCacheLength)
{ // didn't find it
if (fecAddrCacheLength >= CACHE_TABLE_LENGTH-1)
{ // and there's no room to grow
// TODO: recycle some of the older addresses ? (why does an app need to talk to 1000 different servers ?)
return TErrorList.resources_exhausted;
}
fecAddrCache[fec_idx] = new TFecEntry(srv);
fecAddrCacheLength++;
}
else if (replaceAddress)
{
fecAddrCache[fec_idx] = new TFecEntry(srv);
}
fecAddr = fecAddrCache[fec_idx];
int srv_idx;
for (srv_idx=0; srv_idx<NameCacheLength; srv_idx++)
{
if (ctxName.length() > 0 && ctxName.compareToIgnoreCase(srvNameCache[srv_idx].cntName) != 0) continue;
if (srvName.compareToIgnoreCase(srvNameCache[srv_idx].srvName) != 0) continue;
break;
}
if (srv_idx == NameCacheLength)
{ // not found in cache: at end of list
if (NameCacheLength >= CACHE_TABLE_LENGTH-1) return TErrorList.resources_exhausted;
srvNameCache[NameCacheLength] = new NameCache();
augmentNameCacheLength = true;
}
srvNameCache[srv_idx].modNameIndex = mod_idx;
srvNameCache[srv_idx].fecNameIndex = fec_idx;
srvNameCache[srv_idx].srvName = srvName;
srvNameCache[srv_idx].cntName = ctxName;
if (augmentNameCacheLength) NameCacheLength++;
isLegacy = srv.tineProtocol < TTransport.DEFAULT_PROTOCOL_LEVEL;
addAddressToCacheFile(srv); // add address to local file cache
if (TLinkFactory.debugLevel > 1) DbgLog.log("getAddress","ENS success");
return 0;
}
private String makeMsgTag(String srvName,String ctxName)
{
String tag = "/";
tag += ctxName == null ? "DEFAULT" : ctxName;
tag += "/" + srvName;
return tag;
}
public static void toggleENS()
{
synchronized(getLinkFactory().ensMutex)
{
int pre_toggle_ens = currentConfiguredNameServer;
currentConfiguredNameServer = (currentConfiguredNameServer+1) % numConfiguredNameServers;
currentConfiguredNameServerTag = new String("ENS#" + currentConfiguredNameServer);
MsgLog.log("TSrvEntry.toggleENS", "switch from ENS "+pre_toggle_ens+" to "+currentConfiguredNameServer,0,null,1);
}
}
public static String[] getKnownENSes()
{
int i,n=0;
ArrayList<String> al = new ArrayList<String>();
for (i=0; i<fecAddrCacheLength; i++)
{
if (fecAddrCache[i].fecName.startsWith("ENS#"))
{
al.add(fecAddrCache[i].fecHost.getHostAddress());
if (++n == numConfiguredNameServers) break;
}
}
return al.toArray(new String[0]);
}
public synchronized int getAddressFromENS(String srvName,String ctxName)
{
if (srvName == null) return TErrorList.argument_list_error;
if (isENSCall(srvName, ctxName)) return 0;
if (srvName.compareToIgnoreCase("NETWORK") == 0) return 0;
if (numConfiguredNameServers == 0) return 0;
if (getLinkFactory().isRunningStandAlone())
return TErrorList.not_accepted;
int n = 0;
String msg;
String tag = makeMsgTag(srvName,ctxName);
do
{
SrvAddr srv = getSrvAddrFromENS(srvName,ctxName);
if (srv != null)
{
addAddressToCache(srvName,ctxName,srv);
msg = "address acquired from ENS#"+currentConfiguredNameServer+" at "+fecAddrCache[ensDevCacheIndex].fecHost.getHostAddress();
resolutionHistory += msg + "\n";
MsgLog.log("TSrvEntry.getAddressFromENS",tag+" "+msg,0,null,1);
return 0;
}
msg = "address unknown to ENS#"+currentConfiguredNameServer+" at "+fecAddrCache[ensDevCacheIndex].fecHost.getHostAddress()+
" : "+TErrorList.getErrorString(lastENScc);
resolutionHistory += msg + "\n";
int cc = TErrorList.address_unknown;
MsgLog.log("TSrvEntry.getAddressFromENS",tag+" "+msg,cc,null,1);
currentConfiguredNameServer = (currentConfiguredNameServer+1) % numConfiguredNameServers;
currentConfiguredNameServerTag = new String("ENS#" + currentConfiguredNameServer);
MsgLog.log("getAddress","toggle to ENS "+currentConfiguredNameServerTag,cc,null,1);
} while (++n < numConfiguredNameServers);
if (TLinkFactory.debugLevel > 1) DbgLog.log("getAddress","ens failure");
return TErrorList.address_unknown;
}
private static InetAddress getHostIpv4Addr(String host)
{ // we just want a null or an address (no exception nonsense)
InetAddress iaddr = null;
try
{
iaddr = java.net.Inet4Address.getByName(host);
} catch (Exception ignore) {}
return iaddr;
}
private static int findNameServerFromDNS()
{
int cc = 0;
if (numConfiguredNameServers > 0) return 0;
InetAddress iaddr = getHostIpv4Addr("tineens");
if (iaddr == null) iaddr = getHostIpv4Addr("tineens1");
if (iaddr != null)
{ // try up to 3 ENSes ...
addNameServer(iaddr.getHostAddress());
if ((iaddr=getHostIpv4Addr("tineens2")) != null)
{
addNameServer(iaddr.getHostAddress());
if ((iaddr=getHostIpv4Addr("tineens3")) != null)
addNameServer(iaddr.getHostAddress());
}
}
else
{
cc = TErrorList.host_not_resolved;
}
return cc;
}
public static int findNameServerOnNetwork()
{
int cc = 0;
FECAddr fec = new FECAddr();
SrvAddr srv = new SrvAddr();
if (numConfiguredNameServers > 0) return 0;
if ((cc=findServerOnNetwork("", "ENSEQM", "", fec, srv)) == 0)
{
addNameServer(fec.strAdr);
}
return cc;
}
public static int findServerOnNetwork(String context,String eqmName,String exportName,FECAddr fec,SrvAddr srv)
{
int p=0,cc=0;
NAME16[] n16in = new NAME16[3];
NAME16[] n16out = new NAME16[5];
n16in[0] = new NAME16(context);
n16in[1] = new NAME16(eqmName);
n16in[2] = new NAME16(exportName);
TDataType dout = new TDataType(n16out);
TDataType din = new TDataType(n16in);
TLink tl = new TLink(SRVEXP_NAME,"SRVADDR",dout,din,TAccess.CA_READ);
cc = tl.execute(TLink.defaultTimeout, true);
if (cc == 0)
{
if (fec != null)
{
p = Integer.valueOf(n16out[0].getName());
fec.fecName = n16out[1].getName();
fec.portOffset = p;
byte[] bAdr = tl.linkPeer.getAddress();
int len = bAdr.length; if (len > 16) len = 16;
System.arraycopy(bAdr, 0, fec.netAdr, 0, len);
fec.strAdr = tl.linkPeer.getHostAddress();
}
if (srv != null)
{
srv.fecName = n16out[1].getName();
srv.eqmContext = n16out[2].getName();
srv.eqmName = n16out[3].getName();
srv.expName = n16out[4].getName();
srv.tineProtocol = TTransport.DEFAULT_PROTOCOL_LEVEL;
srv.ipAddr = tl.linkPeer.getHostAddress();
if (fec == null) p = Integer.valueOf(n16out[0].getName());
srv.portOffset = p;
}
}
return cc;
}
public TFecEntry getFecAddr()
{
return fecAddr;
}
public String getContextName()
{
return cntName;
}
public String getDeviceName()
{
return srvName;
}
public String getEqmName()
{
return eqmName;
}
public String getFecName()
{
return fecName;
}
}