net.bull.javamelody.internal.model.RemoteCall Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javamelody-core Show documentation
Show all versions of javamelody-core Show documentation
Monitoring of JavaEE applications
/*
* Copyright 2008-2019 by Emeric Vernat
*
* This file is part of Java Melody.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.bull.javamelody.internal.model; // NOPMD
import java.io.IOException;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import net.bull.javamelody.internal.common.HttpParameter;
import net.bull.javamelody.internal.common.HttpPart;
import net.bull.javamelody.internal.common.I18N;
import net.bull.javamelody.internal.model.SamplingProfiler.SampledMethod;
/**
* Collecteur de données pour une application sur un serveur distant.
* @author Emeric Vernat
*/
class RemoteCall {
private final URL url;
private String cookies;
/**
* Constructeur.
* @param url URL
*/
RemoteCall(URL url) {
super();
assert url != null;
this.url = url;
}
/**
* Constructeur.
* @param url String
* @throws MalformedURLException e
*/
RemoteCall(String url) throws MalformedURLException {
super();
assert url != null;
if (url.indexOf('?') == -1) {
this.url = new URL(url + "?format=serialized");
} else {
this.url = new URL(url + "&format=serialized");
}
}
// utilisée dans scripts Jenkins par exemple
// see https://github.com/javamelody/javamelody/wiki/ScriptsAndAlerts
JavaInformations collectJavaInformations() throws IOException {
final URL jvmUrl = new URL(url.toString() + '&' + HttpParameter.PART + '=' + HttpPart.JVM);
final List list = collectForUrl(jvmUrl);
return list.get(0);
}
// utilisée dans scripts Jenkins par exemple
String collectMBeanAttribute(String jmxValueParameter) throws IOException {
final URL mbeanAttributeUrl = new URL(
url.toString() + '&' + HttpParameter.JMX_VALUE + '=' + jmxValueParameter);
return collectForUrl(mbeanAttributeUrl);
}
// utilisée dans scripts Jenkins par exemple
double collectGraphLastValue(String graph) throws IOException {
final URL lastValueUrl = new URL(url.toString() + '&' + HttpParameter.PART + '='
+ HttpPart.LAST_VALUE + '&' + HttpParameter.GRAPH + '=' + graph);
return collectForUrl(lastValueUrl);
}
// result contains statistics in instances of Counter and also an instance of JavaInformations
List collectData() throws IOException {
return collectForUrl(url);
}
// pourrait être utilisée dans scripts Jenkins par exemple
List executeActionAndCollectData(Action action, String counterName,
String sessionId, String threadId, String jobId, String cacheId) throws IOException {
assert action != null;
final URL actionUrl = getActionUrl(action, counterName, sessionId, threadId, jobId,
cacheId);
return collectForUrl(actionUrl);
}
URL getActionUrl(Action action, String counterName, String sessionId, String threadId,
String jobId, String cacheId) throws MalformedURLException {
final StringBuilder actionUrl = new StringBuilder(url.toString());
actionUrl.append("&action=").append(action);
if (counterName != null) {
actionUrl.append("&counter=").append(counterName);
}
if (sessionId != null) {
actionUrl.append("&sessionId=").append(sessionId);
}
if (threadId != null) {
actionUrl.append("&threadId=").append(threadId);
}
if (jobId != null) {
actionUrl.append("&jobId=").append(jobId);
}
if (cacheId != null) {
actionUrl.append("&cacheId=").append(cacheId);
}
return new URL(actionUrl.toString());
}
List collectSessionInformations(String sessionId) throws IOException {
// sessionId est null si on veut toutes les sessions
if (sessionId == null) {
// récupération à la demande des sessions
final URL sessionsUrl = new URL(
url.toString() + '&' + HttpParameter.PART + '=' + HttpPart.SESSIONS);
return collectForUrl(sessionsUrl);
}
final URL sessionsUrl = new URL(url.toString() + '&' + HttpParameter.PART + '='
+ HttpPart.SESSIONS + '&' + HttpParameter.SESSION_ID + '=' + sessionId);
final SessionInformations session = collectForUrl(sessionsUrl);
if (session != null) {
return Collections.singletonList(session);
}
// si session est null, alors la session a été invalidée
return Collections.emptyList();
}
List collectHotspots() throws IOException {
// récupération à la demande des hotspots
final URL hotspotsUrl = new URL(
url.toString() + '&' + HttpParameter.PART + '=' + HttpPart.HOTSPOTS);
return collectForUrl(hotspotsUrl);
}
HeapHistogram collectHeapHistogram() throws IOException {
// récupération à la demande de HeapHistogram
final URL heapHistoUrl = new URL(
url.toString() + '&' + HttpParameter.PART + '=' + HttpPart.HEAP_HISTO);
return collectForUrl(heapHistoUrl);
}
DatabaseInformations collectDatabaseInformations(int requestIndex) throws IOException {
final URL databaseUrl = new URL(url.toString() + '&' + HttpParameter.PART + '='
+ HttpPart.DATABASE + '&' + HttpParameter.REQUEST + '=' + requestIndex);
return collectForUrl(databaseUrl);
}
@SuppressWarnings("unchecked")
List> collectConnectionInformations() throws IOException {
// récupération à la demande des connections
final List> connectionInformations = new ArrayList>();
final URL connectionsUrl = new URL(
url.toString() + '&' + HttpParameter.PART + '=' + HttpPart.CONNECTIONS);
final Object result = collectForUrl(connectionsUrl);
if (result instanceof List && !((List>) result).isEmpty()
&& ((List>) result).get(0) instanceof List) {
// pour le serveur de collecte
final List> connections = (List>) result;
connectionInformations.addAll(connections);
} else {
final List connections = (List) result;
connectionInformations.add(connections);
}
return connectionInformations;
}
@SuppressWarnings("unchecked")
Map> collectProcessInformations() throws IOException {
// récupération à la demande des processus
final String title = I18N.getString("Processus");
final Map> processesByTitle = new LinkedHashMap>();
final URL processUrl = new URL(
url.toString() + '&' + HttpParameter.PART + '=' + HttpPart.PROCESSES);
final Object result = collectForUrl(processUrl);
if (result instanceof Map) {
// pour le serveur de collecte et pour les nodes dans Jenkins
final Map> processByTitle = (Map>) result;
for (final Map.Entry> entry : processByTitle
.entrySet()) {
String node = entry.getKey();
if (!node.startsWith(title)) {
// si serveur de collecte alors il y a déjà un titre, mais pas pour les nodes Jenkins
node = title + " (" + entry.getKey() + ')';
}
final List processList = entry.getValue();
processesByTitle.put(node, processList);
}
} else {
final List processList = (List) result;
processesByTitle.put(title + " (" + getHostAndPort(url) + ')', processList);
}
return processesByTitle;
}
List collectJndiBindings(String path) throws IOException {
// récupération à la demande des bindings JNDI,
// contrairement aux requêtes en cours ou aux processus, un serveur de l'application suffira
// car l'arbre JNDI est en général identique dans tout l'éventuel cluster
final URL jndiUrl = new URL(url.toString() + '&' + HttpParameter.PART + '=' + HttpPart.JNDI
+ (path != null ? '&' + HttpParameter.PATH.toString() + '=' + path : ""));
return collectForUrl(jndiUrl);
}
@SuppressWarnings("unchecked")
Map> collectMBeans() throws IOException {
// récupération à la demande des MBeans
final String title = I18N.getString("MBeans");
final Map> mbeansByTitle = new LinkedHashMap>();
final URL mbeansUrl = new URL(
url.toString() + '&' + HttpParameter.PART + '=' + HttpPart.MBEANS);
final Object result = collectForUrl(mbeansUrl);
if (result instanceof Map) {
// pour le serveur de collecte et les nodes dans Jenkins
final Map> mbeansByNodeName = (Map>) result;
for (final Map.Entry> entry : mbeansByNodeName.entrySet()) {
String node = entry.getKey();
if (!node.startsWith(title)) {
// si serveur de collecte alors il y a déjà un titre, mais pas pour les nodes Jenkins
node = title + " (" + entry.getKey() + ')';
}
final List mbeans = entry.getValue();
mbeansByTitle.put(node, mbeans);
}
} else {
final List mbeans = (List) result;
mbeansByTitle.put(title + " (" + getHostAndPort(url) + ')', mbeans);
}
return mbeansByTitle;
}
Map collectWebappDependencies() throws IOException {
// récupération à la demande des dépendances
final URL dependenciesUrl = new URL(
url.toString() + '&' + HttpParameter.PART + '=' + HttpPart.DEPENDENCIES);
return collectForUrl(dependenciesUrl);
}
Map collectWebappVersions() throws IOException {
final URL webappVersionsUrl = new URL(
url.toString() + '&' + HttpParameter.PART + '=' + HttpPart.WEBAPP_VERSIONS);
return collectForUrl(webappVersionsUrl);
}
Map> collectCurrentRequests() throws IOException {
// récupération à la demande des requêtes en cours
final URL currentRequestsUrl = new URL(
url.toString() + '&' + HttpParameter.PART + '=' + HttpPart.CURRENT_REQUESTS);
return collectForUrl(currentRequestsUrl);
}
Map collectJRobins(int width, int height) throws IOException {
final URL jrobinNamesUrl = new URL(url.toString() + '&' + HttpParameter.PART + '='
+ HttpPart.JROBINS + '&' + HttpParameter.WIDTH + '=' + width + '&'
+ HttpParameter.HEIGHT + '=' + height);
return collectForUrl(jrobinNamesUrl);
}
Map collectOtherJRobins(int width, int height) throws IOException {
final URL otherJRobinNamesUrl = new URL(url.toString() + '&' + HttpParameter.PART + '='
+ HttpPart.OTHER_JROBINS + '&' + HttpParameter.WIDTH + '=' + width + '&'
+ HttpParameter.HEIGHT + '=' + height);
return collectForUrl(otherJRobinNamesUrl);
}
byte[] collectJRobin(String graphName, int width, int height) throws IOException {
final URL jrobinUrl = new URL(url.toString() + '&' + HttpParameter.GRAPH + '=' + graphName
+ '&' + HttpParameter.PART + '=' + HttpPart.JROBINS + '&' + HttpParameter.WIDTH
+ '=' + width + '&' + HttpParameter.HEIGHT + '=' + height);
return collectForUrl(jrobinUrl);
}
String collectSqlRequestExplainPlan(String sqlRequest) throws IOException {
final URL explainPlanUrl = new URL(
url.toString() + '&' + HttpParameter.PART + '=' + HttpPart.EXPLAIN_PLAN);
final Map headers = new HashMap();
headers.put(HttpParameter.REQUEST.getName(), sqlRequest);
if (cookies != null) {
headers.put("Cookie", cookies);
}
final LabradorRetriever labradorRetriever = new LabradorRetriever(explainPlanUrl, headers);
return labradorRetriever.call();
}
private T collectForUrl(URL myUrl) throws IOException {
final LabradorRetriever labradorRetriever;
if (cookies != null) {
final Map headers = Collections.singletonMap("Cookie", cookies);
labradorRetriever = new LabradorRetriever(myUrl, headers);
} else {
labradorRetriever = new LabradorRetriever(myUrl);
}
return labradorRetriever.call();
}
static String getHostAndPort(URL url) {
if (url.getPort() != -1) {
return url.getHost() + ':' + url.getPort();
}
// port est -1 si c'est le port par défaut (80)
return url.getHost();
}
URL getURL() {
return url;
}
void setCookies(String cookies) {
// cookies peut être null
this.cookies = cookies;
}
}