@ -56,8 +56,7 @@ import net.yacy.kelondro.workflow.WorkflowThread;
import net.yacy.peers.Seed ;
import net.yacy.search.SwitchboardConstants ;
public class serverSwitch
{
public class serverSwitch {
// configuration management
private final File configFile ;
@ -71,12 +70,11 @@ public class serverSwitch
private final ConcurrentMap < String , String > configRemoved ;
private final NavigableMap < String , BusyThread > workerThreads ;
private YaCyHttpServer httpserver ; // implemented HttpServer
private ConcurrentMap < String , Integer > upnpPortMap = new ConcurrentHashMap < > ( ) ;
private boolean isConnectedViaUpnp ;
public serverSwitch (
final File dataPath ,
final File appPath ,
final String initPath ,
final String configPath ) {
public serverSwitch ( final File dataPath , final File appPath ,
final String initPath , final String configPath ) {
// we initialize the switchboard with a property file,
// but maintain these properties then later in a new 'config' file
// to reset all changed configs, the config file must
@ -85,10 +83,13 @@ public class serverSwitch
// file name of the config file
this . dataPath = dataPath ;
this . appPath = appPath ;
this . configComment = "This is an automatically generated file, updated by serverAbstractSwitch and initialized by " + initPath ;
this . configComment = "This is an automatically generated file, updated by serverAbstractSwitch and initialized by "
+ initPath ;
final File initFile = new File ( appPath , initPath ) ;
this . configFile = new File ( dataPath , configPath ) ; // propertiesFile(config);
this . firstInit = ! this . configFile . exists ( ) ; // this is true if the application was started for the first time
this . firstInit = ! this . configFile . exists ( ) ; // this is true if the
// application was started
// for the first time
new File ( this . configFile . getParent ( ) ) . mkdir ( ) ;
// predefine init's
@ -124,7 +125,8 @@ public class serverSwitch
initProps . putAll ( this . configProps ) ;
this . configProps = initProps ;
// save result; this may initially create a config file after initialization
// save result; this may initially create a config file after
// initialization
saveConfig ( ) ;
}
@ -142,25 +144,30 @@ public class serverSwitch
}
/ * *
* get my public IP , either set statically or figure out dynamic
* This method is deprecated because there may be more than one public IPs of this peer ,
* get my public IP , either set statically or figure out dynamic This method
* is deprecated because there may be more than one public IPs of this peer ,
* i . e . one IPv4 and one IPv6 . Please use myPublicIPs ( ) instead
*
* @return the public IP of this peer , if known
* /
@Deprecated
public String myPublicIP ( ) {
// if a static IP was configured, we have to return it here ...
final String staticIP = getConfig ( "staticIP" , "" ) ;
if ( staticIP . length ( ) > 0 ) return staticIP ;
if ( staticIP . length ( ) > 0 )
return staticIP ;
// otherwise we return the real IP address of this host
final InetAddress pLIP = Domains . myPublicLocalIP ( ) ;
if ( pLIP ! = null ) return pLIP . getHostAddress ( ) ;
if ( pLIP ! = null )
return pLIP . getHostAddress ( ) ;
return null ;
}
/ * *
* Get all my public IPs . If there was a static IP assignment , only one , that IP is returned .
* Get all my public IPs . If there was a static IP assignment , only one ,
* that IP is returned .
*
* @return a set of IPs which are supposed to be my own public IPs
* /
public Set < String > myPublicIPs ( ) {
@ -175,15 +182,57 @@ public class serverSwitch
Set < String > h = new LinkedHashSet < > ( ) ;
for ( InetAddress i : Domains . myPublicIPv6 ( ) ) {
String s = i . getHostAddress ( ) ;
if ( Seed . isProperIP ( s ) ) h . add ( s ) ;
if ( Seed . isProperIP ( s ) )
h . add ( s ) ;
}
for ( InetAddress i : Domains . myPublicIPv4 ( ) ) {
String s = i . getHostAddress ( ) ;
if ( Seed . isProperIP ( s ) ) h . add ( s ) ;
if ( Seed . isProperIP ( s ) )
h . add ( s ) ;
}
return h ;
}
/ * *
* Gets public port . May differ from local port due to NATting . This method
* will eventually removed once nobody used IPv4 anymore , but until then we
* have to live with it .
*
* @param key
* original key from config ( for example "port" or "port.ssl" )
* @param dflt
* default value which will be used if no value is found
* @return the public port of this system on its IPv4 address
*
* @see # getLocalPort ( String , int )
* /
public int getPublicPort ( final String key , final int dflt ) {
if ( isConnectedViaUpnp & & upnpPortMap . containsKey ( key ) ) {
return upnpPortMap . get ( key ) . intValue ( ) ;
}
// TODO: add way of setting and retrieving port for manual NAT
return getConfigInt ( key , dflt ) ;
}
/ * *
* Wrapper for { @link # getConfigInt ( String , int ) } to have a more consistent
* API .
*
* @param key
* original key from config ( for example "port" or "port.ssl" )
* @param dflt
* default value which will be used if no value is found
* @return the local port of this system
* @see # getPublicPort ( String , int )
* /
public int getLocalPort ( final String key , final int dflt ) {
return getConfigInt ( key , dflt ) ;
}
// a logger for this switchboard
public void setLog ( final ConcurrentLog log ) {
this . log = log ;
@ -195,10 +244,12 @@ public class serverSwitch
/ * *
* add whole map of key - value pairs to config
*
* @param otherConfigs
* /
public void setConfig ( final Map < String , String > otherConfigs ) {
final Iterator < Map . Entry < String , String > > i = otherConfigs . entrySet ( ) . iterator ( ) ;
final Iterator < Map . Entry < String , String > > i = otherConfigs . entrySet ( )
. iterator ( ) ;
Map . Entry < String , String > entry ;
while ( i . hasNext ( ) ) {
entry = i . next ( ) ;
@ -237,8 +288,11 @@ public class serverSwitch
/ * *
* Gets a configuration parameter from the properties .
*
* @param key name of the configuration parameter
* @param dflt default value which will be used in case parameter can not be found or if it is invalid
* @param key
* name of the configuration parameter
* @param dflt
* default value which will be used in case parameter can not be
* found or if it is invalid
* @return value if the parameter or default value
* /
public String getConfig ( final String key , final String dflt ) {
@ -255,8 +309,11 @@ public class serverSwitch
/ * *
* Gets a configuration parameter from the properties .
*
* @param key name of the configuration parameter
* @param dflt default value which will be used in case parameter can not be found or if it is invalid
* @param key
* name of the configuration parameter
* @param dflt
* default value which will be used in case parameter can not be
* found or if it is invalid
* @return value if the parameter or default value
* /
public long getConfigLong ( final String key , final long dflt ) {
@ -270,8 +327,11 @@ public class serverSwitch
/ * *
* Gets a configuration parameter from the properties .
*
* @param key name of the configuration parameter
* @param dflt default value which will be used in case parameter can not be found or if it is invalid
* @param key
* name of the configuration parameter
* @param dflt
* default value which will be used in case parameter can not be
* found or if it is invalid
* @return value if the parameter or default value
* /
public float getConfigFloat ( final String key , final float dflt ) {
@ -282,16 +342,44 @@ public class serverSwitch
}
}
public boolean isConnectedViaUpnp ( ) {
return isConnectedViaUpnp ;
}
public void setConnectedViaUpnp ( final boolean isConnectedViaUpnp ) {
this . isConnectedViaUpnp = isConnectedViaUpnp ;
if ( ! isConnectedViaUpnp ) {
upnpPortMap . clear ( ) ;
}
}
public void setUpnpPorts ( final String key , final int port ) {
upnpPortMap . put ( key , Integer . valueOf ( port ) ) ;
}
public void removeUpnpPort ( final String key ) {
upnpPortMap . remove ( key ) ;
}
/ * *
* Gets a configuration parameter from the properties .
*
* @param key name of the configuration parameter
* @param dflt default value which will be used in case parameter can not be found or if it is invalid
* @param key
* name of the configuration parameter
* @param dflt
* default value which will be used in case parameter can not be
* found or if it is invalid
* @return value if the parameter or default value
* /
public int getConfigInt ( final String key , final int dflt ) {
try {
return Integer . parseInt ( getConfig ( key , Integer . toString ( dflt ) ) ) ;
} catch ( final NumberFormatException e ) {
return dflt ;
}
@ -300,8 +388,11 @@ public class serverSwitch
/ * *
* Gets a configuration parameter from the properties .
*
* @param key name of the configuration parameter
* @param dflt default value which will be used in case parameter can not be found or if it is invalid
* @param key
* name of the configuration parameter
* @param dflt
* default value which will be used in case parameter can not be
* found or if it is invalid
* @return value if the parameter or default value
* /
public boolean getConfigBool ( final String key , final boolean dflt ) {
@ -311,12 +402,15 @@ public class serverSwitch
/ * *
* Create a File instance for a configuration setting specifying a path .
*
* @param key config key
* @param dflt default path value , that is used when there is no value < code > key < / code > in the
* configuration .
* @return if the value of the setting is an absolute path String , then the returned File is derived from
* this setting only . Otherwise the path ' s file is constructed from the applications root path +
* the relative path setting .
* @param key
* config key
* @param dflt
* default path value , that is used when there is no value
* < code > key < / code > in the configuration .
* @return if the value of the setting is an absolute path String , then the
* returned File is derived from this setting only . Otherwise the
* path ' s file is constructed from the applications root path + the
* relative path setting .
* /
public File getDataPath ( final String key , final String dflt ) {
return getFileByPath ( key , dflt , this . dataPath ) ;
@ -324,6 +418,7 @@ public class serverSwitch
/ * *
* return file at path from config entry "key" , or fallback to default dflt
*
* @param key
* @param dflt
* @return
@ -335,7 +430,8 @@ public class serverSwitch
private File getFileByPath ( String key , String dflt , File prefix ) {
final String path = getConfig ( key , dflt ) . replace ( '\\' , '/' ) ;
final File f = new File ( path ) ;
return ( f . isAbsolute ( ) ? new File ( f . getAbsolutePath ( ) ) : new File ( prefix , path ) ) ;
return ( f . isAbsolute ( ) ? new File ( f . getAbsolutePath ( ) ) : new File (
prefix , path ) ) ;
}
public Iterator < String > configKeys ( ) {
@ -352,7 +448,8 @@ public class serverSwitch
}
/ * *
* Gets configuration parameters which have been removed during initialization .
* Gets configuration parameters which have been removed during
* initialization .
*
* @return contains parameter name as key and parameter value as value
* /
@ -360,13 +457,10 @@ public class serverSwitch
return this . configRemoved ;
}
public void deployThread (
final String threadName ,
public void deployThread ( final String threadName ,
final String threadShortDescription ,
final String threadLongDescription ,
final String threadMonitorURL ,
final BusyThread newThread ,
final long startupDelay ) {
final String threadLongDescription , final String threadMonitorURL ,
final BusyThread newThread , final long startupDelay ) {
deployThread (
threadName ,
threadShortDescription ,
@ -380,15 +474,11 @@ public class serverSwitch
Double . parseDouble ( getConfig ( threadName + "_loadprereq" , "9.0" ) ) ) ;
}
public void deployThread (
final String threadName ,
public void deployThread ( final String threadName ,
final String threadShortDescription ,
final String threadLongDescription ,
final String threadMonitorURL ,
final BusyThread newThread ,
final long startupDelay ,
final long initialIdleSleep ,
final long initialBusySleep ,
final String threadLongDescription , final String threadMonitorURL ,
final BusyThread newThread , final long startupDelay ,
final long initialIdleSleep , final long initialBusySleep ,
final long initialMemoryPreRequisite ,
final double initialLoadPreRequisite ) {
if ( newThread . isAlive ( ) ) {
@ -419,13 +509,16 @@ public class serverSwitch
setConfig ( threadName + "_memprereq" , initialMemoryPreRequisite ) ;
}
try {
final double load = Double . parseDouble ( getConfig ( threadName + "_loadprereq" , "novalue" ) ) ;
final double load = Double . parseDouble ( getConfig ( threadName
+ "_loadprereq" , "novalue" ) ) ;
newThread . setLoadPreReqisite ( load ) ;
} catch ( final NumberFormatException e ) {
newThread . setLoadPreReqisite ( initialLoadPreRequisite ) ;
setConfig ( threadName + "_loadprereq" , ( float ) initialLoadPreRequisite ) ;
setConfig ( threadName + "_loadprereq" ,
( float ) initialLoadPreRequisite ) ;
}
newThread . setDescription ( threadShortDescription , threadLongDescription , threadMonitorURL ) ;
newThread . setDescription ( threadShortDescription , threadLongDescription ,
threadMonitorURL ) ;
this . workerThreads . put ( threadName , newThread ) ;
// start the thread
if ( this . workerThreads . containsKey ( threadName ) ) {
@ -437,16 +530,15 @@ public class serverSwitch
return this . workerThreads . get ( threadName ) ;
}
public void setThreadPerformance (
final String threadName ,
final long idleMillis ,
final long busyMillis ,
final long memprereqBytes ,
final double loadprereq ) {
public void setThreadPerformance ( final String threadName ,
final long idleMillis , final long busyMillis ,
final long memprereqBytes , final double loadprereq ) {
final BusyThread thread = this . workerThreads . get ( threadName ) ;
if ( thread ! = null ) {
setConfig ( threadName + "_idlesleep" , thread . setIdleSleep ( idleMillis ) ) ;
setConfig ( threadName + "_busysleep" , thread . setBusySleep ( busyMillis ) ) ;
setConfig ( threadName + "_idlesleep" ,
thread . setIdleSleep ( idleMillis ) ) ;
setConfig ( threadName + "_busysleep" ,
thread . setBusySleep ( busyMillis ) ) ;
setConfig ( threadName + "_memprereq" , memprereqBytes ) ;
thread . setMemPreReqisite ( memprereqBytes ) ;
setConfig ( threadName + "_loadprereq" , ( float ) loadprereq ) ;
@ -454,9 +546,11 @@ public class serverSwitch
}
}
public synchronized void terminateThread ( final String threadName , final boolean waitFor ) {
public synchronized void terminateThread ( final String threadName ,
final boolean waitFor ) {
if ( this . workerThreads . containsKey ( threadName ) ) {
( ( WorkflowThread ) this . workerThreads . get ( threadName ) ) . terminate ( waitFor ) ;
( ( WorkflowThread ) this . workerThreads . get ( threadName ) )
. terminate ( waitFor ) ;
this . workerThreads . remove ( threadName ) ;
}
}
@ -471,12 +565,14 @@ public class serverSwitch
public synchronized void terminateAllThreads ( final boolean waitFor ) {
Iterator < String > e = this . workerThreads . keySet ( ) . iterator ( ) ;
while ( e . hasNext ( ) ) {
( ( WorkflowThread ) this . workerThreads . get ( e . next ( ) ) ) . terminate ( false ) ;
( ( WorkflowThread ) this . workerThreads . get ( e . next ( ) ) )
. terminate ( false ) ;
}
if ( waitFor ) {
e = this . workerThreads . keySet ( ) . iterator ( ) ;
while ( e . hasNext ( ) ) {
( ( WorkflowThread ) this . workerThreads . get ( e . next ( ) ) ) . terminate ( true ) ;
( ( WorkflowThread ) this . workerThreads . get ( e . next ( ) ) )
. terminate ( true ) ;
e . remove ( ) ;
}
}
@ -504,15 +600,18 @@ public class serverSwitch
}
/ * *
* Retrieve text data ( e . g . config file ) from file file may be an url or a filename with path relative to
* rootPath parameter
* Retrieve text data ( e . g . config file ) from file file may be an url or a
* filename with path relative to rootPath parameter
*
* @param file url or filename
* @param rootPath searchpath for file
* @param file file to use when remote fetching fails ( null if unused )
* @param file
* url or filename
* @param rootPath
* searchpath for file
* @param file
* file to use when remote fetching fails ( null if unused )
* /
public Reader getConfigFileFromWebOrLocally ( final String uri , final String rootPath , final File file )
throws IOException ,
public Reader getConfigFileFromWebOrLocally ( final String uri ,
final String rootPath , final File file ) throws IOException ,
FileNotFoundException {
if ( uri . startsWith ( "http://" ) | | uri . startsWith ( "https://" ) ) {
final String [ ] uris = uri . split ( "," ) ;
@ -520,10 +619,21 @@ public class serverSwitch
netdef = netdef . trim ( ) ;
try {
final RequestHeader reqHeader = new RequestHeader ( ) ;
reqHeader . put ( HeaderFramework . USER_AGENT , ClientIdentification . yacyInternetCrawlerAgent . userAgent ) ;
final HTTPClient client = new HTTPClient ( ClientIdentification . yacyInternetCrawlerAgent ) ;
reqHeader
. put ( HeaderFramework . USER_AGENT ,
ClientIdentification . yacyInternetCrawlerAgent . userAgent ) ;
final HTTPClient client = new HTTPClient (
ClientIdentification . yacyInternetCrawlerAgent ) ;
client . setHeader ( reqHeader . entrySet ( ) ) ;
byte [ ] data = client . GETbytes ( uri , getConfig ( SwitchboardConstants . ADMIN_ACCOUNT_USER_NAME , "admin" ) , getConfig ( SwitchboardConstants . ADMIN_ACCOUNT_B64MD5 , "" ) , false ) ;
byte [ ] data = client
. GETbytes (
uri ,
getConfig (
SwitchboardConstants . ADMIN_ACCOUNT_USER_NAME ,
"admin" ) ,
getConfig (
SwitchboardConstants . ADMIN_ACCOUNT_B64MD5 ,
"" ) , false ) ;
if ( data = = null | | data . length = = 0 ) {
continue ;
}
@ -533,7 +643,8 @@ public class serverSwitch
f . write ( data ) ;
f . close ( ) ;
}
return new InputStreamReader ( new BufferedInputStream ( new ByteArrayInputStream ( data ) ) ) ;
return new InputStreamReader ( new BufferedInputStream (
new ByteArrayInputStream ( data ) ) ) ;
} catch ( final Exception e ) {
continue ;
}
@ -543,8 +654,10 @@ public class serverSwitch
}
throw new FileNotFoundException ( ) ;
}
final File f = ( uri . length ( ) > 0 & & uri . startsWith ( "/" ) ) ? new File ( uri ) : new File ( rootPath , uri ) ;
if ( f . exists ( ) ) return new FileReader ( f ) ;
final File f = ( uri . length ( ) > 0 & & uri . startsWith ( "/" ) ) ? new File ( uri )
: new File ( rootPath , uri ) ;
if ( f . exists ( ) )
return new FileReader ( f ) ;
throw new FileNotFoundException ( f . toString ( ) ) ;
}
@ -562,7 +675,8 @@ public class serverSwitch
/ * *
* Generates a random password of a given length .
*
* @param length length o password
* @param length
* length o password
* @return password of given length
* /
public String genRandomPassword ( final int length ) {
@ -570,13 +684,16 @@ public class serverSwitch
pwGenerator . nextBytes ( bytes ) ;
return Digest . encodeMD5Hex ( bytes ) ;
}
/ * *
* set / remember jetty server
*
* @param jettyserver
* /
public void setHttpServer ( YaCyHttpServer jettyserver ) {
this . httpserver = jettyserver ;
}
public YaCyHttpServer getHttpServer ( ) {
return httpserver ;
}