1 52 53 package com.go.teaservlet; 54 55 import java.beans.*; 56 import java.io.*; 57 import java.util.*; 58 import java.net.*; 59 import javax.servlet.ServletConfig ; 60 import javax.servlet.ServletContext ; 61 import javax.servlet.ServletException ; 62 import javax.servlet.http.Cookie ; 63 64 import com.go.trove.log.Log; 65 import com.go.trove.util.BeanComparator; 66 import com.go.trove.io.CharToByteBuffer; 67 import com.go.trove.io.ByteBuffer; 68 import com.go.tea.util.BeanAnalyzer; 69 import com.go.teatools.*; 70 import com.go.teaservlet.util.ObjectIdentifier; 71 import java.rmi.RemoteException ; 73 import com.go.teaservlet.util.cluster.Restartable; 74 import com.go.teaservlet.util.cluster.Clustered; 75 import com.go.teaservlet.util.cluster.ClusterManager; 76 import com.go.teaservlet.util.cluster.TeaServletClusterHook; 77 78 85 public class AdminApplication implements AdminApp { 86 protected ApplicationConfig mConfig; 87 protected Log mLog; 88 protected TeaServlet mTeaServlet; 89 protected String mAdminKey; 90 protected String mAdminValue; 91 protected AppAdminLinks[] mAdminLinks; 92 TeaServletAdmin mAdmin; 94 String mClusterName; 95 int mRmiPort,mMulticastPort; 96 InetAddress mMulticastGroup; 97 ClusterManager mClusterManager; 98 99 109 public void init(ApplicationConfig config) { 110 mConfig = config; 111 mLog = config.getLog(); 112 113 mAdminKey = config.getInitParameter("admin.key"); 115 mAdminValue = config.getInitParameter("admin.value"); 116 117 List serverList = new ArrayList(); 118 119 137 138 ServletContext context = config.getServletContext(); 142 mTeaServlet = 143 (TeaServlet)context.getAttribute(TeaServlet.class.getName()); 144 if (mTeaServlet == null) { 145 mLog.warn("TeaServlet attribute not found"); 146 } 147 else { 148 149 try { 151 mAdmin = new TeaServletAdmin(mTeaServlet); 152 153 String servers = config 154 .getInitParameter("cluster.servers"); 155 String clusterName = config 156 .getInitParameter("cluster.name"); 157 int rmiPort = 1099; 158 int multicastPort = 1099; 159 InetAddress multicastGroup = null; 160 String netInterface = config 161 .getInitParameter("cluster.localNet"); 162 163 try { 164 rmiPort = Integer.parseInt(config 165 .getInitParameter("cluster.rmi.port")); 166 167 multicastPort = Integer.parseInt(config 168 .getInitParameter("cluster.multicast.port")); 169 170 multicastGroup = InetAddress.getByName(config 171 .getInitParameter("cluster.multicast.group")); 172 173 } 174 catch (NumberFormatException nfe) {} 175 catch (UnknownHostException uhe) {} 176 if (multicastGroup != null) { 177 mClusterManager = new ClusterManager(mAdmin, 178 clusterName, 179 null, 180 multicastGroup, 181 multicastPort, 182 rmiPort, 183 netInterface, 184 servers); 185 mClusterManager.joinCluster(); 186 mClusterManager.launchAuto(); 187 } 188 else if (servers != null) { 189 mClusterManager = new ClusterManager(mAdmin, 190 clusterName, 191 null, 192 rmiPort, 193 servers); 194 } 195 else { 196 mLog.debug("No cluster configured."); 197 } 198 } 199 catch (Exception e) { 200 mLog.warn(e); 201 } 202 } 203 } 204 205 public void destroy() { 206 if (mClusterManager != null) { 207 mClusterManager.killAuto(); 208 } 209 } 210 211 214 public Object createContext(ApplicationRequest request, 215 ApplicationResponse response) { 216 return new ContextImpl(request, response); 217 } 218 219 222 public Class getContextType() { 223 return AdminContext.class; 224 } 225 226 void adminCheck(ApplicationRequest request, ApplicationResponse response) 227 throws AbortTemplateException 228 { 229 if (mAdminKey == null) { 230 return; 231 } 232 233 String adminParam = request.getParameter(mAdminKey); 235 236 if (adminParam == null) { 238 Cookie [] cookies = request.getCookies(); 239 if (cookies != null) { 240 for (int i = 0; i < cookies.length; i++) { 241 Cookie cookie = cookies[i]; 242 if (cookie.getName().equals(mAdminKey)) { 243 adminParam = cookie.getValue(); 244 } 245 } 246 } 247 } 248 249 if (adminParam != null && adminParam.equals(mAdminValue)) { 250 Cookie c = new Cookie (mAdminKey, adminParam); 252 c.setMaxAge(24 * 60 * 60 * 7); 254 c.setPath("/"); 255 response.addCookie(c); 256 } 257 else { 258 260 mLog.warn("Unauthorized Admin access to " + 261 request.getRequestURI() + 262 " from " + request.getRemoteAddr() + 263 " - " + request.getRemoteHost() + 264 " - " + request.getRemoteUser()); 265 266 try { 267 response.sendError 268 (response.SC_NOT_FOUND, request.getRequestURI()); 269 } 270 catch (IOException e) { 271 } 272 273 throw new AbortTemplateException(); 274 } 275 } 276 277 281 public AppAdminLinks getAdminLinks() { 282 283 AppAdminLinks links = new AppAdminLinks(mConfig.getName()); 284 285 links.addAdminLink("Templates","/system/teaservlet/AdminTemplates"); 286 links.addAdminLink("Functions","/system/teaservlet/AdminFunctions"); 287 links.addAdminLink("Applications", 288 "/system/teaservlet/AdminApplications"); 289 links.addAdminLink("Logs","/system/teaservlet/LogViewer"); 290 links.addAdminLink("Servlet Engine", 291 "/system/teaservlet/AdminServletEngine"); 292 return links; 293 } 294 295 public class ContextImpl extends TeaToolsUtils implements AdminContext { 296 protected ApplicationRequest mRequest; 297 protected ApplicationResponse mResponse; 298 private TeaServletAdmin mTSAdmin; 299 300 protected ContextImpl(ApplicationRequest request, 301 ApplicationResponse response) { 302 mRequest = request; 303 mResponse = response; 304 } 305 306 public TeaServletAdmin getTeaServletAdmin() throws ServletException { 307 if (mTSAdmin != null) { 308 return mTSAdmin; 309 } 310 311 adminCheck(mRequest, mResponse); 312 mTSAdmin = mAdmin; 313 mTSAdmin.setTemplateLoadResult(null); 314 mTSAdmin.clearServerReloadStatus(); 316 317 if (mClusterManager != null) { 318 mTSAdmin.setClusteredServers(mClusterManager 319 .resolveServerNames()); 320 } 321 322 if (mTSAdmin.getAdminLinks() == null) { 324 325 List links = new ArrayList(); 327 links.add(getAdminLinks()); 328 329 Application[] apps = mTeaServlet 331 .getApplicationDepot().getApplications(); 332 for (int j = 0;j<apps.length;j++) { 333 if (apps[j] instanceof AdminApp 334 && !AdminApplication.this.equals(apps[j])) { 335 links.add(((AdminApp)apps[j]).getAdminLinks()); 336 } 337 } 338 mTSAdmin 339 .setAdminLinks((AppAdminLinks[])links 340 .toArray(new AppAdminLinks[links.size()])); 341 } 342 343 344 345 346 String param = mRequest.getParameter("reloadTemplates"); 348 if (param != null) { 349 Boolean all = new Boolean ("all".equals(param)); 350 351 try { 352 if (mRequest.getParameter("cluster") != null 353 && mClusterManager != null) { 354 clusterReload(mTSAdmin,all); 355 } 356 else { 357 mTSAdmin.restart(all); 358 } 359 } 360 catch (RemoteException re) { 361 re.printStackTrace(); 362 } 363 } 364 365 param = mRequest.getParameter("log"); 367 if (param != null) { 368 Log log; 369 try { 370 log = (Log)ObjectIdentifier.retrieve(param); 371 } 372 catch (ClassCastException e) { 373 log = null; 374 } 375 376 if (log != null) { 377 String setting = mRequest.getParameter("enabled"); 378 if (setting != null) { 379 log.setEnabled(setting.equals("true")); 380 } 381 setting = mRequest.getParameter("debug"); 382 if (setting != null) { 383 log.setDebugEnabled(setting.equals("true")); 384 } 385 setting = mRequest.getParameter("info"); 386 if (setting != null) { 387 log.setInfoEnabled(setting.equals("true")); 388 } 389 setting = mRequest.getParameter("warn"); 390 if (setting != null) { 391 log.setWarnEnabled(setting.equals("true")); 392 } 393 setting = mRequest.getParameter("error"); 394 if (setting != null) { 395 log.setErrorEnabled(setting.equals("true")); 396 } 397 } 398 399 try { 400 mResponse.sendRedirect(mRequest.getRequestURI()); 401 throw new AbortTemplateException(); 402 } 403 catch (IOException e) { 404 } 405 } 406 407 return mTSAdmin; 408 } 409 410 public String getObjectIdentifier(Object obj) { 411 return ObjectIdentifier.identify(obj); 412 } 413 414 public Class getClassForName(String classname) { 415 try { 416 ClassLoader cl = mTeaServlet.getApplicationDepot() 417 .getContextType().getClassLoader(); 418 if (cl == null) { 419 cl = ClassLoader.getSystemClassLoader(); 420 } 421 return cl.loadClass(classname); 422 } 423 catch (Exception cpe) { 424 mLog.warn(cpe); 425 return null; 426 } 427 } 428 429 433 public void streamClassBytes(String className) 434 throws AbortTemplateException 435 { 436 adminCheck(mRequest, mResponse); 437 438 mLog.debug("streamClassBytes: " + className); 439 440 if (className == null) { 441 return; 442 } 443 444 String classResource = className.replace('.', '/') + ".class"; 445 446 ClassLoader cl = mTeaServlet.getApplicationDepot().getContextType() 447 .getClassLoader(); 448 if (cl == null) { 449 cl = ClassLoader.getSystemClassLoader(); 450 } 451 452 InputStream in = cl.getResourceAsStream(classResource); 453 454 if (in != null) { 455 mLog.debug("streamClassBytes: Got InputStream for class: " + 456 className); 457 458 int len = 4000; 459 byte[] b = new byte[len]; 460 int bytesRead = 0; 461 ByteBuffer buffer = mResponse.getResponseBuffer(); 462 463 try { 464 while ((bytesRead = in.read(b, 0, len)) > 0) { 465 buffer.append(b, 0, bytesRead); 466 } 467 468 in.close(); 469 } 470 catch (Exception e) { 471 mResponse.setStatus(mResponse.SC_NOT_FOUND); 472 mLog.debug(e); 473 } 474 } 475 else { 476 mResponse.setStatus(mResponse.SC_NOT_FOUND); 477 } 478 479 mResponse.setContentType("application/java"); 480 } 481 482 483 486 public void dynamicTemplateCall(String templateName) 487 throws Exception { 488 dynamicTemplateCall(templateName,new Object [0]); 489 } 490 491 495 public void dynamicTemplateCall(String templateName, Object [] params) 496 throws Exception 497 { 498 com.go.tea.runtime.Context context = mResponse 499 .getHttpContext(); 500 com.go.tea.runtime.TemplateLoader.Template td = 501 mTeaServlet.getApplicationDepot() 502 .getTemplateDepot().findTemplate(templateName, 503 mRequest, 504 mResponse); 505 506 String [] paramNames = td.getParameterNames(); 508 Object [] oldParams = params; 509 if (oldParams == null 510 || oldParams.length != paramNames.length) { 511 params = new Object [paramNames.length]; 512 513 521 522 for (int j=0;j<paramNames.length;j++) { 523 params[j] = mRequest.getParameter(paramNames[j]); 524 if (params[j] == null && oldParams.length > j) { 525 params[j] = oldParams[j]; 526 } 527 } 528 } 529 530 td.execute(context, params); 531 } 532 533 public Object obtainContextByName(String appName) 534 throws ServletException { 535 ApplicationInfo[] applications = 536 getTeaServletAdmin().getApplications(); 537 for (int j=0;j<applications.length;j++) { 538 if (appName.equals(applications[j].getName())) { 539 return ((Application)applications[j].getValue()) 540 .createContext(mRequest,mResponse); 541 } 542 } 543 return null; 544 } 545 546 581 582 private void clusterReload(TeaServletAdmin admin, Boolean all) 583 throws RemoteException { 584 585 605 if (mClusterManager != null) { 606 607 mClusterManager.resolveServerNames(); 608 609 Clustered[] peers = 610 (Clustered[])mClusterManager.getCluster() 611 .getKnownPeers(); 612 613 final ClusterThread[] ct = new ClusterThread[peers.length]; 614 615 for (int i=0; i<peers.length; i++) { 616 Clustered peer = peers[i]; 617 ct[i] = new ClusterThread(admin, peer, all); 618 ct[i].start(); 619 620 } 621 622 Thread monitor = new Thread ("Template reload monitor") { 623 public void run() { 624 for (int i=0; i<ct.length; i++) { 625 if (ct[i] != null) { 626 try { 627 ct[i].join(); 628 } 629 catch (InterruptedException e) { 630 break; 631 } 632 } 633 } 634 } 635 }; 636 637 monitor.start(); 638 try { 639 monitor.join(30000); 641 } 642 catch (InterruptedException e) { 643 } 644 645 monitor.interrupt(); 646 647 for (int i=0; i<ct.length; i++) { 648 if (ct[i] != null) { 649 ct[i].interrupt(); 650 } 651 } 652 } 653 } 654 655 public TeaToolsContext.HandyClassInfo getHandyClassInfo(String fullClassName) { 656 if (fullClassName != null) { 657 Class clazz = getClassForName(fullClassName); 658 if (clazz != null) { 659 return getHandyClassInfo(clazz); 660 } 661 } 662 return null; 663 } 664 665 public TeaToolsContext.HandyClassInfo getHandyClassInfo(Class clazz) { 666 if (clazz != null) { 667 return new HandyClassInfoImpl(clazz); 668 } 669 return null; 670 } 671 672 public class HandyClassInfoImpl extends TypeDescription 673 implements TeaToolsContext.HandyClassInfo 674 { 675 676 HandyClassInfoImpl(Class clazz) { 677 super(clazz,ContextImpl.this); 678 } 679 } 680 } 681 682 private class ClusterThread extends Thread { 683 private TeaServletAdmin mTSAdmin; 684 private Clustered mClusterPeer; 685 private Boolean mAll; 686 687 public ClusterThread(TeaServletAdmin admin, 688 Clustered peer, 689 Boolean all) { 690 mTSAdmin = admin; 691 mClusterPeer = peer; 692 mAll = all; 693 694 } 695 696 public void run() { 697 try { 698 try { 699 ((Restartable)mClusterPeer).restart(mAll); 700 mTSAdmin.setServerReloadStatus(mClusterPeer 701 .getServerName(), 702 200, 703 ((Restartable)mClusterPeer) 704 .getStatus(mAll)); 705 } 706 catch (IOException e) { 707 e.printStackTrace(); 708 mTSAdmin.setServerReloadStatus 709 (mClusterPeer.getServerName(),500, e.toString()); 710 } 711 } 712 catch (RemoteException re) { 713 try { 714 mClusterManager.getCluster().removePeer(mClusterPeer); 715 } 716 catch (RemoteException re2) { 717 re2.printStackTrace(); 718 } 719 mTSAdmin.setServerReloadStatus 720 ("N/A",500, "Unknown host"); 721 } 722 } 723 } 724 } 725 | Popular Tags |