2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 package org.apache.jk.status;
20 import java.util.Iterator;
21 import java.util.List;
23 import org.apache.catalina.ant.BaseRedirectorHelperTask;
24 import org.apache.tomcat.util.IntrospectionUtils;
25 import org.apache.tools.ant.BuildException;
26 import org.apache.tools.ant.Project;
29 * Ant task that implements the show <code>/jkstatus</code> command, supported
30 * by the mod_jk status (1.2.13) application.
32 * @author Peter Rossbach
33 * @version $Revision: 752644 $
36 public class JkStatusTask extends BaseRedirectorHelperTask {
39 * The descriptive information about this implementation.
41 private static final String info = "org.apache.jk.status.JkStatusTask/1.2";
44 * Store status as <code>resultProperty</code> prefix.
46 protected String resultproperty;
49 * Echo status at ant console
51 protected boolean echo = false;
54 * The login password for the <code>mod_jk status</code> page.
56 protected String password = null;
59 * The URL of the <code>mod_jk status</code> page to be used.
61 protected String url = "http://localhost:80/jkstatus";
64 * The login username for the <code>mod_jk status</code> page.
66 protected String username = null;
68 private String errorProperty;
70 private String worker;
72 private String loadbalancer;
75 * Return descriptive information about this implementation and the
76 * corresponding version number, in the format
77 * <code><description>/<version></code>.
79 public String getInfo() {
85 public String getPassword() {
86 return (this.password);
89 public void setPassword(String password) {
90 this.password = password;
93 public String getUrl() {
97 public void setUrl(String url) {
101 public String getUsername() {
102 return (this.username);
105 public void setUsername(String username) {
106 this.username = username;
110 * @return Returns the echo.
112 public boolean isEcho() {
120 public void setEcho(boolean echo) {
125 * @return Returns the resultproperty.
127 public String getResultproperty() {
128 return resultproperty;
132 * @param resultproperty
133 * The resultproperty to set.
135 public void setResultproperty(String resultproperty) {
136 this.resultproperty = resultproperty;
140 * @return Returns the loadbalancer.
142 public String getLoadbalancer() {
146 * @param loadbalancer The loadbalancer to set.
148 public void setLoadbalancer(String loadbalancer) {
149 this.loadbalancer = loadbalancer;
152 * @return Returns the worker.
154 public String getWorker() {
158 * @param worker The worker to set.
160 public void setWorker(String worker) {
161 this.worker = worker;
163 // --------------------------------------------------------- Public Methods
166 * Get jkstatus from server.
168 * @exception BuildException
169 * if a validation error occurs
171 public void execute() throws BuildException {
174 throw new BuildException("Must specify an 'url'");
176 boolean isWorkerOnly = worker != null && !"".equals(worker);
177 boolean isLoadbalancerOnly = loadbalancer != null
178 && !"".equals(loadbalancer);
180 StringBuffer error = new StringBuffer();
182 JkStatusAccessor accessor = new JkStatusAccessor();
183 JkStatus status = accessor.status(url, username, password);
184 if (status.result != null && !"OK".equals(status.result.type) ) {
185 if (getErrorProperty() != null) {
186 getProject().setNewProperty(errorProperty, status.result.message);
188 if (isFailOnError()) {
189 throw new BuildException(status.result.message);
191 handleErrorOutput(status.result.message);
197 if (!isWorkerOnly && !isLoadbalancerOnly) {
198 JkServer server = status.getServer();
199 JkSoftware software = status.getSoftware();
200 JkResult result = status.getResult();
201 if (resultproperty != null) {
202 createProperty(server, "server", "name");
203 createProperty(server, "server", "port");
204 createProperty(software, "web_server");
205 createProperty(software, "jk_version");
206 createProperty(result, "result", "type");
207 createProperty(result, "result", "message");
210 handleOutput("server name=" + server.getName() + ":"
211 + server.getPort() + " - " + software.getWeb_server() + " - " + software.getJk_version());
214 List balancers = status.getBalancers();
215 for (Iterator iter = balancers.iterator(); iter.hasNext();) {
216 JkBalancer balancer = (JkBalancer) iter.next();
217 String balancerIndex = null;
218 if (isLoadbalancerOnly) {
219 if (loadbalancer.equals(balancer.getName())) {
220 if (resultproperty != null) {
221 setPropertyBalancerOnly(balancer);
223 echoBalancer(balancer);
228 if (resultproperty != null) {
229 if ( balancer.getId() >= 0)
230 balancerIndex = Integer.toString(balancer.getId());
232 balancerIndex = balancer.getName() ;
234 setPropertyBalancer(balancer,balancerIndex);
236 echoBalancer(balancer);
238 List members = balancer.getBalancerMembers();
239 for (Iterator iterator = members.iterator(); iterator
241 JkBalancerMember member = (JkBalancerMember) iterator
244 if (worker.equals(member.getName())) {
245 if (resultproperty != null) {
246 setPropertyWorkerOnly(balancer, member);
252 if (resultproperty != null) {
253 setPropertyWorker(null, member);
256 if (member.getStatus() != null && !"OK".equals(member.getStatus())) {
257 error.append(" worker name=" + member.getName()
258 + " status=" + member.getStatus()
259 + " host=" + member.getAddress());
261 if (member.getState() != null &&
262 !("OK".equals(member.getState()) ||
263 "N/A".equals(member.getState()) ||
264 "OK/IDLE".equals(member.getState())) ){
265 error.append(" worker name=" + member.getName()
266 + " state=" + member.getState()
267 + " host=" + member.getAddress());
272 if (resultproperty != null && members.size() > 0) {
273 getProject().setNewProperty(
275 + balancer.getName() + ".length",
276 Integer.toString(members.size()));
278 List mappings = balancer.getBalancerMappings();
281 if( balancerIndex != null )
282 mapIndex = balancerIndex + ".map" ;
285 for (Iterator iterator = mappings.iterator(); iterator
287 JkBalancerMapping mapping = (JkBalancerMapping) iterator
289 if (resultproperty != null) {
290 String stringIndex2 ;
291 if( mapping.getId() >= 0) {
292 stringIndex2 = Integer.toString(mapping.getId()) ;
294 stringIndex2 = Integer.toString(j);
296 createProperty(mapping, mapIndex,
297 stringIndex2, "type");
298 createProperty(mapping, mapIndex,
299 stringIndex2, "uri");
300 createProperty(mapping, mapIndex,
301 stringIndex2, "context");
302 createProperty(mapping, mapIndex,
303 stringIndex2, "source");
308 if(mapping.source != null) {
311 + balancer.getName() + " mappingtype="
312 + mapping.getType() + " uri="
313 + mapping.getUri() + " source="
314 + mapping.getSource() ;
316 mappingOut = "balancer name="
317 + balancer.getName() + " mappingtype="
318 + mapping.getType() + " uri="
319 + mapping.getUri() + " context="
320 + mapping.getContext() ;
322 handleOutput(mappingOut);
325 if (resultproperty != null && mappings.size() > 0) {
326 getProject().setNewProperty(
328 + mapIndex + ".length",
329 Integer.toString(mappings.size()));
334 if (!isWorkerOnly && !isLoadbalancerOnly) {
335 if (resultproperty != null && balancers.size() > 0) {
336 getProject().setNewProperty(
337 resultproperty + ".length",
338 Integer.toString(balancers.size()));
341 } catch (Throwable t) {
342 error.append(t.getMessage());
343 if (getErrorProperty() != null) {
344 getProject().setNewProperty(errorProperty, error.toString());
346 if (isFailOnError()) {
347 throw new BuildException(t);
349 handleErrorOutput(t.getMessage());
353 if (error.length() != 0) {
354 if (getErrorProperty() != null) {
355 getProject().setNewProperty(errorProperty, error.toString());
357 if (isFailOnError()) {
358 // exception should be thrown only if failOnError == true
359 // or error line will be logged twice
360 throw new BuildException(error.toString());
369 private void echoWorker(JkBalancerMember member) {
371 StringBuffer state = new StringBuffer("worker name=") ;
372 state.append( member.getName()) ;
373 if(member.getStatus() != null) {
374 state.append(" status=");
375 state.append(member.getStatus());
377 if(member.getState() != null) {
378 state.append(" state=");
379 state.append(member.getState()) ;
381 state.append(" host=");
382 state.append(member.getAddress());
383 handleOutput(state.toString());
390 private void echoBalancer(JkBalancer balancer) {
392 handleOutput("balancer name=" + balancer.getName() + " type="
393 + balancer.getType());
400 private void setPropertyBalancerOnly(JkBalancer balancer) {
401 String prefix = resultproperty + "." + balancer.getName();
402 if(balancer.getId() >= 0 ) {
403 getProject().setNewProperty(prefix + ".id",
404 Integer.toString(balancer.getId()));
406 getProject().setNewProperty(prefix + ".type", balancer.getType());
407 getProject().setNewProperty(prefix + ".stick_session",
408 Boolean.toString(balancer.isSticky_session()));
409 getProject().setNewProperty(prefix + ".sticky_session_force",
410 Boolean.toString(balancer.isSticky_session_force()));
411 getProject().setNewProperty(prefix + ".retries",
412 Integer.toString(balancer.getRetries()));
413 getProject().setNewProperty(prefix + ".recover_time",
414 Integer.toString(balancer.getRecover_time()));
415 getProject().setNewProperty(prefix + ".method",
416 balancer.getMethod());
417 getProject().setNewProperty(prefix + ".good",
418 Integer.toString(balancer.getGood()));
419 getProject().setNewProperty(prefix + ".degraded",
420 Integer.toString(balancer.getDegraded()));
421 getProject().setNewProperty(prefix + ".bad",
422 Integer.toString(balancer.getBad()));
423 getProject().setNewProperty(prefix + ".busy",
424 Integer.toString(balancer.getBusy()));
425 getProject().setNewProperty(prefix + ".map_count",
426 Integer.toString(balancer.getMap_count()));
427 getProject().setNewProperty(prefix + ".member_count",
428 Integer.toString(balancer.getMember_count()));
429 getProject().setNewProperty(prefix + ".max_busy",
430 Integer.toString(balancer.getMax_busy()));
431 getProject().setNewProperty(prefix + ".time_to_maintenance_min",
432 Integer.toString(balancer.getTime_to_maintenance_min()));
433 getProject().setNewProperty(prefix + ".time_to_maintenance_max",
434 Integer.toString(balancer.getTime_to_maintenance_max()));
435 getProject().setNewProperty(prefix + ".lock",
442 * @param balancerIndex
444 private void setPropertyBalancer(JkBalancer balancer,String balancerIndex) {
445 if(balancer.id >= 0) {
446 createProperty(balancer, balancerIndex, "id");
449 createProperty(balancer, balancerIndex, "name");
450 createProperty(balancer, balancerIndex, "type");
451 createProperty(balancer, balancerIndex, "sticky_session");
452 createProperty(balancer, balancerIndex, "sticky_session_force");
453 createProperty(balancer, balancerIndex, "retries");
454 createProperty(balancer, balancerIndex, "recover_time");
455 if(balancer.getMethod() != null) {
456 createProperty(balancer, balancerIndex, "method");
458 if(balancer.getLock() != null) {
459 createProperty(balancer, balancerIndex, "lock");
461 if(balancer.getGood() >= 0) {
462 createProperty(balancer, balancerIndex, "good");
464 if(balancer.getDegraded() >= 0) {
465 createProperty(balancer, balancerIndex, "degraded");
467 if(balancer.getBad() >= 0) {
468 createProperty(balancer, balancerIndex, "bad");
470 if(balancer.getBusy() >= 0) {
471 createProperty(balancer, balancerIndex, "busy");
473 if(balancer.getMax_busy() >= 0) {
474 createProperty(balancer, balancerIndex, "max_busy");
476 if(balancer.getMember_count() >=0) {
477 createProperty(balancer, balancerIndex, "member_count");
479 if(balancer.getMap_count() >=0) {
480 createProperty(balancer, balancerIndex, "map_count");
482 if(balancer.getTime_to_maintenance_min() >=0) {
483 createProperty(balancer, balancerIndex, "time_to_maintenance_min");
485 if(balancer.getTime_to_maintenance_max() >=0) {
486 createProperty(balancer, balancerIndex, "time_to_maintenance_max");
491 * @param balancerIndex
494 private void setPropertyWorker(String balancerIndex, JkBalancerMember member) {
496 if(member.getId() >= 0) {
497 workerIndex = Integer.toString(member.getId());
498 createProperty(member, balancerIndex, workerIndex, "id");
499 createProperty(member, balancerIndex, workerIndex, "name");
501 workerIndex = member.getName();
503 createProperty(member, balancerIndex, workerIndex, "type");
504 createProperty(member, balancerIndex, workerIndex, "host");
505 createProperty(member, balancerIndex, workerIndex, "port");
506 createProperty(member, balancerIndex, workerIndex, "address");
507 if(member.getJvm_route() != null) {
508 createProperty(member, balancerIndex, workerIndex, "jvm_route");
510 if(member.getRoute() != null) {
511 createProperty(member, balancerIndex, workerIndex, "route");
513 if(member.getStatus() != null) {
514 createProperty(member, balancerIndex, workerIndex, "status");
516 if(member.getActivation() != null) {
517 createProperty(member, balancerIndex, workerIndex, "activation");
519 if(member.getState() != null) {
520 createProperty(member, balancerIndex, workerIndex, "state");
522 createProperty(member, balancerIndex, workerIndex, "lbfactor");
523 createProperty(member, balancerIndex, workerIndex, "lbvalue");
524 if(member.getLbmult() >= 0) {
525 createProperty(member, balancerIndex, workerIndex, "lbmult");
527 createProperty(member, balancerIndex, workerIndex, "elected");
528 createProperty(member, balancerIndex, workerIndex, "readed");
529 createProperty(member, balancerIndex, workerIndex, "busy");
530 if(member.getMax_busy() >= 0) {
531 createProperty(member, balancerIndex, workerIndex, "max_busy");
533 createProperty(member, balancerIndex, workerIndex, "transferred");
534 createProperty(member, balancerIndex, workerIndex, "errors");
535 if(member.getClient_errors() >= 0) {
536 createProperty(member, balancerIndex, workerIndex, "client_errors");
538 if(member.getDistance() >= 0) {
539 createProperty(member, balancerIndex, workerIndex, "distance");
541 if (member.getDomain() != null) {
542 createProperty(member, balancerIndex, workerIndex, "domain");
544 getProject().setNewProperty(resultproperty + "." + balancerIndex + "." + workerIndex +
547 if (member.getRedirect() != null) {
548 createProperty(member, balancerIndex, workerIndex, "redirect");
550 getProject().setNewProperty(resultproperty + "." + balancerIndex + "." + workerIndex +
559 private void setPropertyWorkerOnly(JkBalancer balancer,
560 JkBalancerMember member) {
561 //String prefix = resultproperty + "." + balancer.getName() + "." + member.getName();
562 String prefix = resultproperty + "." + member.getName();
563 Project currentProject = getProject();
564 if ( balancer.getId() >= 0) {
565 currentProject.setNewProperty(prefix + ".lb.id",
566 Integer.toString(balancer.getId()));
568 //currentProject.setNewProperty(prefix + ".lb.name", balancer.getName());
569 if( member.getId() >= 0) {
570 currentProject.setNewProperty(prefix + ".id",
571 Integer.toString(member.getId()));
573 currentProject.setNewProperty(prefix + ".type", member.getType());
574 if (member.getJvm_route() != null) {
575 currentProject.setNewProperty(prefix + ".jvm_route", member.getJvm_route());
577 if (member.getRoute() != null) {
578 currentProject.setNewProperty(prefix + ".route", member.getRoute());
580 if (member.getStatus() != null) {
581 currentProject.setNewProperty(prefix + ".status", member.getStatus());
583 if (member.getActivation() != null) {
584 currentProject.setNewProperty(prefix + ".activation", member.getActivation());
586 if (member.getState() != null) {
587 currentProject.setNewProperty(prefix + ".state", member.getState());
589 currentProject.setNewProperty(prefix + ".host", member.getHost());
590 currentProject.setNewProperty(prefix + ".address", member.getAddress());
591 currentProject.setNewProperty(prefix + ".port",
592 Integer.toString(member.getPort()));
593 currentProject.setNewProperty(prefix + ".lbfactor",
594 Integer.toString(member.getLbfactor()));
595 currentProject.setNewProperty(prefix + ".lbvalue",
596 Long.toString(member.getLbvalue()));
597 if(member.getLbmult() >= 0) {
598 currentProject.setNewProperty(prefix + ".lbmult",
599 Long.toString(member.getLbmult()));
601 currentProject.setNewProperty(prefix + ".elected",
602 Long.toString(member.getElected()));
603 currentProject.setNewProperty(prefix + ".readed",
604 Long.toString(member.getReaded()));
605 currentProject.setNewProperty(prefix + ".transferred",
606 Long.toString(member.getTransferred()));
607 currentProject.setNewProperty(prefix + ".busy",
608 Integer.toString(member.getBusy()));
609 if(member.getMax_busy() >= 0) {
610 currentProject.setNewProperty(prefix + ".max_busy",
611 Long.toString(member.getMax_busy()));
613 currentProject.setNewProperty(prefix + ".errors",
614 Long.toString(member.getErrors()));
615 if(member.getClient_errors() >= 0) {
616 currentProject.setNewProperty(prefix + ".client_errors",
617 Long.toString(member.getClient_errors()));
619 if(member.getDistance() >= 0) {
620 currentProject.setNewProperty(prefix + ".distance",
621 Integer.toString(member.getDistance()));
623 if (member.getDomain() != null) {
624 currentProject.setNewProperty(prefix + ".domain", member.getDomain());
626 currentProject.setNewProperty(prefix + ".domain", "");
628 if (member.getRedirect() != null) {
629 currentProject.setNewProperty(prefix + ".redirect",
630 member.getRedirect());
632 currentProject.setNewProperty(prefix + ".redirect", "");
634 if(member.getTime_to_recover() >= 0) {
635 currentProject.setNewProperty(prefix + ".time_to_recover",
636 Integer.toString(member.getTime_to_recover()));
638 if(member.getTime_to_recover_min() >= 0) {
639 currentProject.setNewProperty(prefix + ".time_to_recover_min",
640 Integer.toString(member.getTime_to_recover_min()));
642 if(member.getTime_to_recover_max() >= 0) {
643 currentProject.setNewProperty(prefix + ".time_to_recover_max",
644 Integer.toString(member.getTime_to_recover_max()));
645 currentProject.setNewProperty(prefix + ".time_to_recover",
646 (Integer.toString((member.getTime_to_recover_min()
647 + member.getTime_to_recover_max()) / 2)));
653 * Set ant property for save error state
655 * @see org.apache.catalina.ant.BaseRedirectorHelperTask#setErrorProperty(java.lang.String)
657 public void setErrorProperty(String arg0) {
658 errorProperty = arg0;
659 super.setErrorProperty(arg0);
663 * @return Returns the errorProperty.
665 public String getErrorProperty() {
666 return errorProperty;
669 protected void createProperty(Object result, String attribute) {
670 createProperty(result, null, null, attribute);
673 protected void createProperty(Object result, String arraymark,
675 createProperty(result, arraymark, null, attribute);
679 * create result as property with name from attribute resultproperty
681 protected void createProperty(Object result, String arraymark,
682 String arraymark2, String attribute) {
683 if (resultproperty != null) {
684 Object value = IntrospectionUtils.getProperty(result, attribute);
685 if (value != null ) {
686 StringBuffer propertyname = new StringBuffer(resultproperty);
688 if (result instanceof JkBalancer) {
689 if (arraymark != null) {
690 propertyname.append(".");
691 propertyname.append(arraymark);
693 } else if (result instanceof JkServer) {
694 if (arraymark != null) {
695 propertyname.append(".");
696 propertyname.append(arraymark);
698 } else if (result instanceof JkSoftware) {
699 if (arraymark != null) {
700 propertyname.append(".");
701 propertyname.append(arraymark);
703 } else if (result instanceof JkResult) {
704 if (arraymark != null) {
705 propertyname.append(".");
706 propertyname.append(arraymark);
708 } else if (result instanceof JkBalancerMember) {
709 if (arraymark != null) {
710 propertyname.append(".");
711 propertyname.append(arraymark);
713 if (arraymark2 != null) {
714 propertyname.append(".");
715 propertyname.append(arraymark2);
717 } else if (result instanceof JkBalancerMapping) {
718 if (arraymark != null) {
719 propertyname.append(".");
720 propertyname.append(arraymark);
722 if (arraymark2 != null) {
723 propertyname.append(".");
724 propertyname.append(arraymark2);
727 propertyname.append(".");
728 propertyname.append(attribute);
729 getProject().setNewProperty(propertyname.toString(),