![JAR search and dependency download from the Maven repository](/logo.png)
io.sovaj.heartbeat.api.impl.MonitoringSession Maven / Gradle / Ivy
The newest version!
package io.sovaj.heartbeat.api.impl;
import io.sovaj.heartbeat.api.IMonitor;
import io.sovaj.heartbeat.api.TestElement;
import io.sovaj.heartbeat.api.Type;
import io.sovaj.heartbeat.api.jaxb2.*;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
/**
* Permet d'executer un certain nombre de tests, de collecter les resultats de
* l'execution et de produire ce resultat sous forme XML. Le flux XML correspond
* a un schema XSD precis. Cette classe est a usage interne, elle ne doit pas
* etre utilisee directement par les applications utilisatrices.
*/
public class MonitoringSession {
private final JAXBContext jaxbContext;
/**
* Message d'erreur.
*/
private static final String MSG_NON_EXECUTED_TEST = "Non-executed test";
/**
* Niveau d'indentation du XML.
*/
private static final int INDENT = 4;
/**
* Les stack traces remont�es dans le message XML ne d�passeront pas
* MAX_LINE_ALLOWED_STACK_TRACE lignes.
*/
private static final int MAX_LINE_ALLOWED_STACK_TRACE = 20;
/**
* Dur�e sp�ciale servant � signifier "dur�e invalide".
*/
private static final long INVALID_DURATION = -9999L;
/**
* El�ment XML Application associ� � la session.
*/
private ApplicationTest application;
/**
* Cr�� une instance de session de monitoring
*
* @param webAppName nom de l'application � monitorer
*/
public MonitoringSession(String webAppName) {
this(webAppName, null, null);
}
/**
* Cr�� une instance de session de monitoring
*
* @param webAppName nom de l'application � monitorer
* @param nodeName nom du noeud WAS o� se trouve l'application � monitorer
*/
public MonitoringSession(String webAppName, String nodeName) {
this(webAppName, nodeName, null);
}
/**
* Cr�� une instance de session de monitoring
*
* @param webAppName nom de l'application � monitorer
* @param nodeName nom du noeud WAS o� se trouve l'application � monitorer
* @param appServerName nom du serveur physique sur lequel se trouve le WAS
*/
public MonitoringSession(String webAppName, String nodeName, String appServerName) {
application = new ApplicationTest();
application.setWebAppName(webAppName);
final Calendar now = Calendar.getInstance(Locale.US);
now.setTime(new Date());
application.setStartMonitoring(now);
application.setNodeName(nodeName);
application.setAppServerName(appServerName);
application.setSchemaVersion(1.0);
try {
jaxbContext = JAXBContext.newInstance(ApplicationTest.class);
} catch (JAXBException e) {
throw new RuntimeException("Could not initialize JaxBContext : " + e.getMessage(), e);
}
}
/**
* Ex�cution d'un test technique.
*
* @param mon impl�mentation du test � ex�cuter.
*/
public void doTechnicalTest(IMonitor mon) {
checkMandatory("mon", mon);
final TestElement testResult = mon.monitor();
addTechnicalTest(testResult);
}
/**
* Ex�cution d'un test de d�pendance.
*
* @param mon impl�mentation du test � ex�cuter.
*/
public void doDependencyTest(IMonitor mon) {
checkMandatory("mon", mon);
final TestElement testResult = mon.monitor();
addDependencyTest(testResult);
}
/**
* Rajoute un test technique � la session de monitoring.
*
* @param monitoredElement �l�ment � monitorer
*/
private void addTechnicalTest(TestElement monitoredElement) {
if (application.getTechnicalTests() == null) {
application.setTechnicalTests(newGroup());
}
addTestToGroup(monitoredElement, application.getTechnicalTests());
}
/**
* Rajoute un test de d�pendance � la session de monitoring.
*
* @param monitoredElement �l�ment � monitorer
*/
private void addDependencyTest(TestElement monitoredElement) {
if (application.getDependencyTests() == null) {
application.setDependencyTests(newGroup());
}
addTestToGroup(monitoredElement, application.getDependencyTests());
}
/**
* Retourn le r�sultat des tests de monitoring au format XML. Dans le cas
* d'une servlet de monitoring, c'est cette m�thode qui doit �tre utilis�e
* pour retourner le flux XML.
*
* @return r�sultat des tests de monitoring au format XML
*/
public String toXML(boolean technical) {
verify(technical);
String resultXml = null;
try {
Marshaller m = jaxbContext.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
StringWriter writer = new StringWriter();
Result result = new StreamResult(writer);
m.marshal(application, result);
resultXml = writer.getBuffer().toString();
} catch (Exception e) {
resultXml = getStackTrace(e);
}
return resultXml;
}
public boolean isAllTestsOK(boolean technical, boolean functionnal) {
verify(technical);
boolean isOk = true;
if (technical && application.getTechnicalTests()!=null)
isOk = isOk && application.getTechnicalTests().getStatus() == GroupStatus.OK;
if (functionnal && application.getDependencyTests()!=null)
isOk = isOk && application.getDependencyTests().getStatus() == GroupStatus.OK;
return isOk;
}
/**
* V�rification de la coh�rence du mod�le associ� � la session de
* monitoring.
*/
private void verify(boolean verifyTechnical) {
// Must have a webapp name
if (application.getWebAppName() == null || application.getWebAppName().trim().length() == 0) {
application.setWebAppName("NEEDS A WEBAPP NAME !!!");
}
// Must have at least one technical test
if (verifyTechnical && application.getTechnicalTests() == null) {
final Group technicalTests = new Group();
application.setTechnicalTests(technicalTests);
technicalTests.setStatus(GroupStatus.KO);
final Test newTest = new Test();
technicalTests.getTests().add(newTest);
newTest.setName("no-technical-tests");
newTest.setErrorMessage("This application has no technical tests.");
newTest.setStatus(Status.KO);
newTest.setType(Type.OTHER.toString());
newTest.setDuration(0);
}
}
/**
* Cr�ation d'un noeud XML "Test" � partir d'un TestElement.
*
* @param testedElement TestElement
* @param xmlTest noeud XML de type Test, � cr�er vide via les m�thodes de
* XmlBeans.
* @return noeud XML
*/
private Test initTestXmlElement(TestElement testedElement, Test xmlTest) {
xmlTest.setName(testedElement.getName());
// Si j'ai un type, j'affecte le type.
// On ne doit pas faire set(null) sinon XmlBeans produira un �l�ment de
// type xsi:nil qui est ind�sirable : on pr�f�re l'absence de
// l'�l�ment.
if (testedElement.getType() != null) {
xmlTest.setType(testedElement.getType().toString());
}
// M�me principe pour "description" :
if (testedElement.getDescription() != null) {
xmlTest.setDescription(testedElement.getDescription());
}
// Calcul du status :
Status status;
String errorMessage = testedElement.getErrorMessage();
if (testedElement.getStatus() == null) {
// Il faut un status. Si on n'en a pas, on passe le test en KO.
status = Status.KO;
errorMessage = MSG_NON_EXECUTED_TEST;
} else {
// Lecture du status :
status = Status.valueOf(testedElement.getStatus().toString());
}
// Calcul de la dur�e d'ex�cution :
long duration;
if (testedElement.getStart() == null || testedElement.getStop() == null) {
// Il faut une date de d�but et de fin d'ex�uction du test.
// Ici, on n'en a pas : on passe donc le test en KO.
status = Status.KO;
errorMessage = MSG_NON_EXECUTED_TEST;
duration = INVALID_DURATION;
} else {
// Calcul de la dur�e d'ex�cution du test :
duration = testedElement.getStop().getTime() - testedElement.getStart().getTime();
}
// Affectation des noeuds status, duration et error-message :
xmlTest.setStatus(status);
xmlTest.setDuration(duration);
if (errorMessage == null) {
errorMessage = testedElement.getErrorMessage();
}
if (errorMessage != null) {
xmlTest.setErrorMessage(errorMessage);
}
// Calcul de la stack trace :
if (testedElement.getException() != null) {
final String stack = getStackTrace(testedElement.getException());
xmlTest.setStackTrace(stack);
}
return xmlTest;
}
/**
* Cr�ation d'un nouveau groupe.
*
* @return groupe.
*/
private Group newGroup() {
final Group newGroup = new Group();
newGroup.setStatus(GroupStatus.OK);
return newGroup;
}
/**
* Ajout d'un test � un groupe de tests et met � jour le status du groupe.
*
* @param monitoredElement test � ajouter.
* @param group groupe cible
*/
protected void addTestToGroup(TestElement monitoredElement, Group group) {
Test testXml = new Test();
group.getTests().add(testXml);
initTestXmlElement(monitoredElement, testXml);
// Mise � jour du status :
int severity = 0;
final GroupStatus[] status = new GroupStatus[]{GroupStatus.OK, GroupStatus.KO};
final List tests = group.getTests();
for (Test test : tests) {
// Association entre niveau de s�v�rit� et status, afin
// de permettre les comparaisons :
int curSeverity;
switch (test.getStatus()) {
case OK:
case SKIP:
curSeverity = 0;
break;
case KO:
curSeverity = 1;
break;
default:
// Cas impossible dans la pratique, sauf si on ajoute un nouveau
// status
// pas encore compris de ce code.
throw new IllegalStateException("Unknown Status enum value: " + test.getStatus().toString());
}
// Comparaison de la s�v�rit� et adaptation de la s�v�rit� du
// groupe :
if (curSeverity > severity) {
severity = curSeverity;
}
}
group.setStatus(status[severity]);
}
/**
* Only gets the 20 first rows of the stack trace.
*
* @param anException exception
* @return stacktrace
*/
private String getStackTrace(Throwable anException) {
final StringBuffer buffer = new StringBuffer();
StackTraceElement[] stackTraceElements;
stackTraceElements = anException.getStackTrace();
for (int i = 0; i < stackTraceElements.length && i < MAX_LINE_ALLOWED_STACK_TRACE; i++) {
buffer.append(stackTraceElements[i].toString()).append('\n');
}
if (anException.getCause() != null) {
buffer.append("(...)\n");
stackTraceElements = anException.getCause().getStackTrace();
for (int i = 0; i < stackTraceElements.length && i < MAX_LINE_ALLOWED_STACK_TRACE; i++) {
buffer.append(stackTraceElements[i].toString()).append('\n');
}
}
return buffer.toString();
}
/**
* V�rifie si une cha�ne est null ou vide. On n'utilise pas commons-lang car
* une des contraintes de cette API est d'avoir le moins possible de
* d�pendances.
*
* @param value cha�ne � v�rifier
* @return true si cha�ne vide
*/
protected boolean isBlank(String value) {
boolean isBlank;
if (value == null) {
isBlank = true;
} else {
isBlank = true;
for (int i = 0; i < value.length() && isBlank; i++) {
isBlank = Character.isWhitespace(value.charAt(i));
}
}
return isBlank;
}
/**
* V�rifie si un param�tre obligatoire est bien pr�sent. Lance une exception
* le cas �ch�ant.
*
* @param paramName nom du param�tre
* @param value valeur du param�tre
*/
private void checkMandatory(String paramName, Object value) {
if (value == null) {
throw new IllegalArgumentException(paramName + " is mandatory");
}
}
/**
* @return the application
*/
public ApplicationTest getApplication() {
return application;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy