All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.roboconf.agent.monitoring.internal.rest.RestHandler Maven / Gradle / Ivy
/**
* Copyright 2014-2016 Linagora, Université Joseph Fourier, Floralis
*
* The present code is developed in the scope of the joint LINAGORA -
* Université Joseph Fourier - Floralis research program and is designated
* as a "Result" pursuant to the terms and conditions of the LINAGORA
* - Université Joseph Fourier - Floralis research program. Each copyright
* holder of Results enumerated here above fully & independently holds complete
* ownership of the complete Intellectual Property rights applicable to the whole
* of said Results, and may freely exploit it in any manner which does not infringe
* the moral rights of the other copyright holders.
*
* 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.roboconf.agent.monitoring.internal.rest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import net.roboconf.agent.monitoring.api.IMonitoringHandler;
import net.roboconf.core.model.beans.Instance;
import net.roboconf.core.utils.Utils;
import net.roboconf.messaging.api.messages.from_agent_to_dm.MsgNotifAutonomic;
/**
* Handler to check the value returned by a REST call on a URL.
* @author Pierre-Yves Gibello - Linagora
*/
public class RestHandler implements IMonitoringHandler {
static final String HANDLER_NAME = "rest";
private static final String USER_AGENT = "Mozilla/34.0";
private static final String CHECK = "check";
private static final String THAT = "that";
private static final String CONDITION_PATTERN = "(\\w+)\\s+(==|=|>=|>|<=|<)\\s+(\\S+)";
private static final String WHOLE_PATTERN = CHECK + "\\s+(\\S+)\\s+" + THAT + "\\s+" + CONDITION_PATTERN;
private final Logger logger = Logger.getLogger(getClass().getName());
private String applicationName, scopedInstancePath, eventId;
String url, conditionParameter, conditionOperator, conditionThreshold;
@Override
public String getName() {
return HANDLER_NAME;
}
@Override
public void setAgentId( String applicationName, String scopedInstancePath ) {
this.applicationName = applicationName;
this.scopedInstancePath = scopedInstancePath;
}
@Override
public void reset( Instance associatedInstance, String eventId, String rawRulesText ) {
this.eventId = eventId;
Matcher m = Pattern.compile( WHOLE_PATTERN, Pattern.CASE_INSENSITIVE ).matcher( rawRulesText );
if( m .find()) {
this.url = m.group( 1 );
this.conditionParameter = m.group( 2 );
this.conditionOperator = m.group( 3 );
this.conditionThreshold = m.group( 4 );
} else {
this.logger.severe( "Invalid content for the 'rest' handler in the agent's monitoring." );
}
}
@Override
public MsgNotifAutonomic process() {
MsgNotifAutonomic result = null;
String response = null;
if( this.url != null )
response = this.url.startsWith("https:") ? httpsQuery() : httpQuery();
if( response != null )
response = response.replace('{', ' ').replace('}', ' ').trim();
else
response = "";
HashMap map = new HashMap ();
for( String s : response.split( "\\n" )) {
String kv[] = s.split(":");
if( kv.length == 2 )
map.put( kv[0].replace("\"", " ").trim(), kv[ 1 ]);
else
break;
}
if( map.isEmpty()) {
this.logger.warning( "The REST response could not be parsed." );
this.logger.finer( "Received response: " + response );
} else if( evalCondition( map )) {
result = new MsgNotifAutonomic( this.applicationName, this.scopedInstancePath, this.eventId, response.toString());
}
return result;
}
/**
* Evaluates a condition (eg. "lag>=100") using data in key-pair value map (e.g. <"lag","50">).
* @param valueMap The values (key-pairs) on which to evaluate the condition.
* @return true if the condition is met, false otherwise
*/
boolean evalCondition( Map map ) {
boolean result = false;
String value = map.get( this.conditionParameter );
if( value != null ) {
try {
Double doubleValue = Double.parseDouble( value );
Double thresholdValue = Double.parseDouble( this.conditionThreshold );
// Do not use arithmetic operators with doubles...
int comparison = doubleValue.compareTo( thresholdValue );
if( ">".equals( this.conditionOperator ))
result = comparison > 0;
else if( ">=".equals( this.conditionOperator ))
result = comparison >= 0;
else if( "<".equals( this.conditionOperator ))
result = comparison < 0;
else if( "<=".equals( this.conditionOperator ))
result = comparison <= 0;
else
result = comparison == 0;
} catch( NumberFormatException e ) {
if( "==".equals( this.conditionOperator ) || "=".equals( this.conditionOperator ))
result = Objects.equals( value, this.conditionThreshold );
else
this.logger.fine( "Invalid double. " + e.getMessage());
}
}
return result;
}
/**
* Query a https URL, ignoring certificates.
* @return The query response
*/
private String httpsQuery() {
String response = null;
try {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new LocalX509TrustManager()};
// Install the all-trusting trust manager
final SSLContext sc = SSLContext.getInstance("SSL");
sc.init( null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory( sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new LocalHostnameVerifier();
HttpsURLConnection.setDefaultHostnameVerifier( allHostsValid );
URL restUrl = new URL( this.url );
HttpsURLConnection conn = (HttpsURLConnection) restUrl.openConnection();
response = query( conn );
} catch( Exception e ) {
this.logger.severe( "Cannot issue GET on URL " + this.url + ". Monitoring notification is discarded." );
Utils.logException(this.logger, e);
}
return response;
}
/**
* Query a http URL.
* @return The query response
*/
private String httpQuery() {
String response = null;
try {
URL restUrl = new URL( this.url );
HttpURLConnection conn = (HttpURLConnection) restUrl.openConnection();
response = query( conn );
} catch( Exception e ) {
this.logger.severe( "Cannot issue GET on URL " + this.url + ". Monitoring notification is discarded." );
Utils.logException(this.logger, e);
}
return response;
}
private String query( HttpURLConnection conn ) throws IOException {
conn.setRequestMethod( "GET" );
conn.setRequestProperty( "User-Agent", USER_AGENT );
ByteArrayOutputStream os = new ByteArrayOutputStream();
InputStream in = conn.getInputStream();
Utils.copyStreamSafely( in, os );
return os.toString("UTF-8");
}
/**
* @author Pierre-Yves Gibello - Linagora
*/
static class LocalX509TrustManager implements X509TrustManager {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
// nothing
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
// nothing
}
}
/**
* @author Pierre-Yves Gibello - Linagora
*/
static class LocalHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
// Never verify
return false;
}
}
}