001 package railo.runtime.config; 002 003 import java.net.MalformedURLException; 004 import java.net.URL; 005 import java.util.HashMap; 006 import java.util.Iterator; 007 import java.util.Map; 008 009 import railo.commons.collections.HashTable; 010 import railo.commons.io.SystemUtil; 011 import railo.commons.io.res.Resource; 012 import railo.commons.lang.ClassUtil; 013 import railo.commons.lang.PCLCollection; 014 import railo.commons.lang.StringUtil; 015 import railo.commons.lang.SystemOut; 016 import railo.loader.engine.CFMLEngine; 017 import railo.runtime.CFMLFactoryImpl; 018 import railo.runtime.Mapping; 019 import railo.runtime.MappingImpl; 020 import railo.runtime.engine.CFMLEngineImpl; 021 import railo.runtime.exp.ApplicationException; 022 import railo.runtime.exp.PageException; 023 import railo.runtime.monitor.IntervallMonitor; 024 import railo.runtime.monitor.RequestMonitor; 025 import railo.runtime.op.Caster; 026 import railo.runtime.reflection.Reflector; 027 import railo.runtime.security.SecurityManager; 028 import railo.runtime.security.SecurityManagerImpl; 029 import railo.runtime.type.scope.Cluster; 030 import railo.runtime.type.scope.ClusterRemote; 031 import railo.runtime.type.scope.ClusterWrap; 032 import railo.runtime.type.util.ArrayUtil; 033 034 /** 035 * config server impl 036 */ 037 public final class ConfigServerImpl extends ConfigImpl implements ConfigServer { 038 039 040 private final CFMLEngineImpl engine; 041 private Map initContextes; 042 private Map contextes; 043 private SecurityManager defaultSecurityManager; 044 private Map managers=new HashTable(); 045 private String defaultPassword; 046 private Resource rootDir; 047 private URL updateLocation; 048 private String updateType=""; 049 private ConfigListener configListener; 050 private Map<String, String> labels; 051 private RequestMonitor[] requestMonitors; 052 private IntervallMonitor[] intervallMonitors; 053 private boolean monitoringEnabled=false; 054 private int delay=0; 055 private boolean captcha=false; 056 private static ConfigServerImpl instance; 057 058 /** 059 * @param engine 060 * @param initContextes 061 * @param contextes 062 * @param configDir 063 * @param configFile 064 */ 065 protected ConfigServerImpl(CFMLEngineImpl engine,Map initContextes, Map contextes, Resource configDir, Resource configFile) { 066 super(null,configDir, configFile); 067 this.engine=engine; 068 this.initContextes=initContextes; 069 this.contextes=contextes; 070 this.rootDir=configDir; 071 instance=this; 072 } 073 074 /** 075 * @return the configListener 076 */ 077 public ConfigListener getConfigListener() { 078 return configListener; 079 } 080 081 /** 082 * @param configListener the configListener to set 083 */ 084 public void setConfigListener(ConfigListener configListener) { 085 this.configListener = configListener; 086 } 087 088 089 090 /** 091 * @see railo.runtime.config.ConfigImpl#getConfigServerImpl() 092 */ 093 protected ConfigServerImpl getConfigServerImpl() { 094 return this; 095 } 096 097 /** 098 * @see railo.runtime.config.ConfigImpl#getConfigServer(java.lang.String) 099 */ 100 public ConfigServer getConfigServer(String password) { 101 return this; 102 } 103 104 105 public ConfigServer getConfigServer() { 106 return this; 107 } 108 109 /** 110 * @see railo.runtime.config.ConfigServer#getConfigWebs() 111 */ 112 public ConfigWeb[] getConfigWebs() { 113 114 Iterator it = initContextes.keySet().iterator(); 115 ConfigWeb[] webs=new ConfigWeb[initContextes.size()]; 116 int index=0; 117 while(it.hasNext()) { 118 webs[index++]=((CFMLFactoryImpl)initContextes.get(it.next())).getConfig(); 119 } 120 return webs; 121 } 122 123 /** 124 * @see railo.runtime.config.ConfigServer#getConfigWeb(java.lang.String) 125 */ 126 public ConfigWeb getConfigWeb(String realpath) { 127 return getConfigWebImpl(realpath); 128 } 129 130 /** 131 * returns CongigWeb Implementtion 132 * @param realpath 133 * @return ConfigWebImpl 134 */ 135 protected ConfigWebImpl getConfigWebImpl(String realpath) { 136 Iterator it = initContextes.keySet().iterator(); 137 while(it.hasNext()) { 138 ConfigWebImpl cw=((CFMLFactoryImpl)initContextes.get(it.next())).getConfigWebImpl(); 139 if(cw.getServletContext().getRealPath("/").equals(realpath)) 140 return cw; 141 } 142 return null; 143 } 144 145 public ConfigWebImpl getConfigWebById(String id) { 146 Iterator it = initContextes.keySet().iterator(); 147 148 while(it.hasNext()) { 149 ConfigWebImpl cw=((CFMLFactoryImpl)initContextes.get(it.next())).getConfigWebImpl(); 150 if(cw.getId().equals(id)) 151 return cw; 152 } 153 return null; 154 } 155 156 /** 157 * @return JspFactoryImpl array 158 */ 159 public CFMLFactoryImpl[] getJSPFactories() { 160 Iterator it = initContextes.keySet().iterator(); 161 CFMLFactoryImpl[] factories=new CFMLFactoryImpl[initContextes.size()]; 162 int index=0; 163 while(it.hasNext()) { 164 factories[index++]=(CFMLFactoryImpl)initContextes.get(it.next()); 165 } 166 return factories; 167 } 168 /** 169 * @see railo.runtime.config.ConfigServer#getJSPFactoriesAsMap() 170 */ 171 public Map getJSPFactoriesAsMap() { 172 return initContextes; 173 } 174 175 /** 176 * @see railo.runtime.config.ConfigServer#getSecurityManager(java.lang.String) 177 */ 178 public SecurityManager getSecurityManager(String id) { 179 Object o=managers.get(id); 180 if(o!=null) return (SecurityManager) o; 181 return defaultSecurityManager.cloneSecurityManager(); 182 } 183 184 /** 185 * @see railo.runtime.config.ConfigServer#hasIndividualSecurityManager(java.lang.String) 186 */ 187 public boolean hasIndividualSecurityManager(String id) { 188 return managers.containsKey(id); 189 } 190 191 /** 192 * @param defaultSecurityManager 193 */ 194 protected void setDefaultSecurityManager(SecurityManager defaultSecurityManager) { 195 this.defaultSecurityManager=defaultSecurityManager; 196 } 197 198 /** 199 * @param id 200 * @param securityManager 201 */ 202 protected void setSecurityManager(String id, SecurityManager securityManager) { 203 managers.put(id,securityManager); 204 } 205 206 /** 207 * @param id 208 */ 209 protected void removeSecurityManager(String id) { 210 managers.remove(id); 211 } 212 213 /** 214 * @see railo.runtime.config.ConfigServer#getDefaultSecurityManager() 215 */ 216 public SecurityManager getDefaultSecurityManager() { 217 return defaultSecurityManager; 218 } 219 /** 220 * @return Returns the defaultPassword. 221 */ 222 protected String getDefaultPassword() { 223 return defaultPassword; 224 } 225 /** 226 * @param defaultPassword The defaultPassword to set. 227 */ 228 protected void setDefaultPassword(String defaultPassword) { 229 this.defaultPassword = defaultPassword; 230 } 231 232 /** 233 * @see railo.runtime.config.ConfigServer#getCFMLEngine() 234 */ 235 public CFMLEngine getCFMLEngine() { 236 return engine; 237 } 238 public CFMLEngineImpl getCFMLEngineImpl() { 239 return engine; 240 } 241 242 243 /** 244 * @return Returns the rootDir. 245 */ 246 public Resource getRootDirectory() { 247 return rootDir; 248 } 249 250 /** 251 * @see railo.runtime.config.Config#getUpdateType() 252 */ 253 public String getUpdateType() { 254 return updateType; 255 } 256 257 /** 258 * @see railo.runtime.config.ConfigServer#setUpdateType(java.lang.String) 259 */ 260 public void setUpdateType(String updateType) { 261 if(!StringUtil.isEmpty(updateType)) 262 this.updateType = updateType; 263 } 264 265 /** 266 * @see railo.runtime.config.Config#getUpdateLocation() 267 */ 268 public URL getUpdateLocation() { 269 return updateLocation; 270 } 271 272 /** 273 * @see railo.runtime.config.ConfigServer#setUpdateLocation(java.net.URL) 274 */ 275 public void setUpdateLocation(URL updateLocation) { 276 this.updateLocation = updateLocation; 277 } 278 279 /** 280 * @see railo.runtime.config.ConfigServer#setUpdateLocation(java.lang.String) 281 */ 282 public void setUpdateLocation(String strUpdateLocation) throws MalformedURLException { 283 setUpdateLocation(new URL(strUpdateLocation)); 284 } 285 286 /** 287 * @see railo.runtime.config.ConfigServer#setUpdateLocation(java.lang.String, java.net.URL) 288 */ 289 public void setUpdateLocation(String strUpdateLocation, URL defaultValue) { 290 try { 291 setUpdateLocation(strUpdateLocation); 292 } catch (MalformedURLException e) { 293 setUpdateLocation(defaultValue); 294 } 295 } 296 297 /** 298 * @see railo.runtime.config.Config#getSecurityManager() 299 */ 300 public SecurityManager getSecurityManager() { 301 SecurityManagerImpl sm = (SecurityManagerImpl) getDefaultSecurityManager();//.cloneSecurityManager(); 302 //sm.setAccess(SecurityManager.TYPE_ACCESS_READ,SecurityManager.ACCESS_PROTECTED); 303 //sm.setAccess(SecurityManager.TYPE_ACCESS_WRITE,SecurityManager.ACCESS_PROTECTED); 304 return sm; 305 } 306 307 /** 308 * @return the instance 309 */ 310 public static ConfigServerImpl getInstance() { 311 return instance; 312 } 313 314 public void setLabels(Map<String, String> labels) { 315 this.labels=labels; 316 } 317 public Map<String, String> getLabels() { 318 if(labels==null) labels=new HashMap<String, String>(); 319 return labels; 320 } 321 322 public RequestMonitor[] getRequestMonitors() { 323 return requestMonitors; 324 } 325 326 public RequestMonitor getRequestMonitor(String name) throws ApplicationException { 327 for(int i=0;i<requestMonitors.length;i++){ 328 if(requestMonitors[i].getName().equalsIgnoreCase(name)) 329 return requestMonitors[i]; 330 } 331 throw new ApplicationException("there is no request monitor registered with name ["+name+"]"); 332 } 333 334 protected void setRequestMonitors(RequestMonitor[] monitors) { 335 this.requestMonitors=monitors;; 336 } 337 public IntervallMonitor[] getIntervallMonitors() { 338 return intervallMonitors; 339 } 340 public IntervallMonitor getIntervallMonitor(String name) throws ApplicationException { 341 for(int i=0;i<intervallMonitors.length;i++){ 342 if(intervallMonitors[i].getName().equalsIgnoreCase(name)) 343 return intervallMonitors[i]; 344 } 345 throw new ApplicationException("there is no intervall monitor registered with name ["+name+"]"); 346 } 347 348 protected void setIntervallMonitors(IntervallMonitor[] monitors) { 349 this.intervallMonitors=monitors;; 350 } 351 public boolean isMonitoringEnabled() { 352 return monitoringEnabled; 353 } 354 355 protected void setMonitoringEnabled(boolean monitoringEnabled) { 356 this.monitoringEnabled=monitoringEnabled;; 357 } 358 359 360 protected void setLoginDelay(int delay) { 361 this.delay=delay; 362 } 363 364 protected void setLoginCaptcha(boolean captcha) { 365 this.captcha=captcha; 366 } 367 368 @Override 369 public int getLoginDelay() { 370 return delay; 371 } 372 373 @Override 374 public boolean getLoginCaptcha() { 375 return captcha; 376 } 377 378 @Override 379 public Resource getConfigServerDir() { 380 return getConfigDir(); 381 } 382 383 public static Cluster createClusterScope(Config config) throws PageException { 384 ConfigServer cs=config instanceof ConfigWebImpl?((ConfigWebImpl)config).getConfigServerImpl():(ConfigServer)config; 385 Cluster cluster=null; 386 387 try { 388 if(Reflector.isInstaneOf(cs.getClusterClass(), Cluster.class)){ 389 cluster=(Cluster) ClassUtil.loadInstance( 390 cs.getClusterClass(), 391 ArrayUtil.OBJECT_EMPTY 392 ); 393 cluster.init(cs); 394 } 395 else if(Reflector.isInstaneOf(cs.getClusterClass(), ClusterRemote.class)){ 396 ClusterRemote cb=(ClusterRemote) ClassUtil.loadInstance( 397 cs.getClusterClass(), 398 ArrayUtil.OBJECT_EMPTY 399 ); 400 401 cluster=new ClusterWrap(cs,cb); 402 //cluster.init(cs); 403 } 404 } 405 catch (Exception e) { 406 throw Caster.toPageException(e); 407 } 408 return cluster; 409 } 410 411 412 413 /** 414 * if free permspace gen is lower than 10000000 bytes, railo shrinks all classloaders 415 * @param cs 416 */ 417 public static void checkPermGenSpace(Config config, boolean check) { 418 ConfigServer cs=config instanceof ConfigWebImpl?((ConfigWebImpl)config).getConfigServerImpl():(ConfigServer)config; 419 //print.e(Runtime.getRuntime().freeMemory()); 420 // Runtime.getRuntime().freeMemory()<200000 || 421 // long pgs=SystemUtil.getFreePermGenSpaceSize(); 422 int promille=SystemUtil.getFreePermGenSpacePromille(); 423 424 // Pen Gen Space info not available 425 if(promille==-1) {//if(pgs==-1) { 426 if(countLoadedPages(cs)>500) 427 shrink(cs); 428 } 429 else if(!check || promille<50){//else if(!check || pgs<1024*1024){ 430 SystemOut.printDate(cs.getErrWriter(),"+Free Perm Gen Space is less than 1mb (free:"+((SystemUtil.getFreePermGenSpaceSize())/1024)+"kb), shrink all template classloaders"); 431 // first just call GC and check if it help 432 System.gc(); 433 //if(SystemUtil.getFreePermGenSpaceSize()>1024*1024) 434 if(SystemUtil.getFreePermGenSpacePromille()>50) 435 return; 436 437 shrink(cs); 438 } 439 } 440 441 private static void shrink(ConfigServer cs) { 442 ConfigWeb[] webs = cs.getConfigWebs(); 443 int count=0; 444 for(int i=0;i<webs.length;i++){ 445 count+=shrink((ConfigWebImpl) webs[i],false); 446 } 447 if(count==0) { 448 for(int i=0;i<webs.length;i++){ 449 shrink((ConfigWebImpl) webs[i],true); 450 } 451 } 452 } 453 454 private static int shrink(ConfigWebImpl config, boolean force) { 455 int count=0; 456 count+=shrink(config.getMappings(),force); 457 count+=shrink(config.getCustomTagMappings(),force); 458 count+=shrink(config.getComponentMappings(),force); 459 count+=shrink(config.getFunctionMapping(),force); 460 count+=shrink(config.getServerFunctionMapping(),force); 461 count+=shrink(config.getTagMapping(),force); 462 count+=shrink(config.getServerTagMapping(),force); 463 count+=shrink(((ConfigWebImpl)config).getServerTagMapping(),force); 464 return count; 465 } 466 467 private static int shrink(Mapping[] mappings, boolean force) { 468 int count=0; 469 for(int i=0;i<mappings.length;i++){ 470 count+=shrink(mappings[i],force); 471 } 472 return count; 473 } 474 475 private static int shrink(Mapping mapping, boolean force) { 476 try { 477 PCLCollection pcl = ((MappingImpl)mapping).getPCLCollection(); 478 if(pcl!=null)return pcl.shrink(force); 479 } 480 catch (Throwable t) { 481 t.printStackTrace(); 482 } 483 return 0; 484 } 485 486 public static long countLoadedPages(ConfigServer cs) { 487 long count=0; 488 ConfigWeb[] webs = cs.getConfigWebs(); 489 for(int i=0;i<webs.length;i++){ 490 count+=_count((ConfigWebImpl) webs[i]); 491 } 492 return count; 493 } 494 private static long _count(ConfigWebImpl config) { 495 long count=0; 496 count+=_count(config.getMappings()); 497 count+=_count(config.getCustomTagMappings()); 498 count+=_count(config.getComponentMappings()); 499 count+=_count(config.getFunctionMapping()); 500 count+=_count(config.getServerFunctionMapping()); 501 count+=_count(config.getTagMapping()); 502 count+=_count(config.getServerTagMapping()); 503 count+=_count(((ConfigWebImpl)config).getServerTagMapping()); 504 return count; 505 } 506 507 private static long _count(Mapping[] mappings) { 508 long count=0; 509 for(int i=0;i<mappings.length;i++){ 510 count+=_count(mappings[i]); 511 } 512 return count; 513 } 514 515 private static long _count(Mapping mapping) { 516 PCLCollection pcl = ((MappingImpl)mapping).getPCLCollection(); 517 return pcl==null?0:pcl.count(); 518 } 519 520 }