/**
* Copyright 2014-2017 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.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.roboconf.agent.monitoring.internal.rest.RestHandler.LocalHostnameVerifier;
import net.roboconf.agent.monitoring.internal.rest.RestHandler.LocalX509TrustManager;
import net.roboconf.messaging.api.messages.from_agent_to_dm.MsgNotifAutonomic;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Pierre-Yves Gibello - Linagora
*/
public class RestHandlerTest {
private static final Level LOG_LEVEL = Level.FINE;
private static final String EVENT_NAME = "whatever";
private static final String APP_NAME = "app";
private static final String SCOPED_INSTANCE_PATH = "/root";
private final Logger logger = Logger.getLogger( getClass().getName());
@Test
public void testConstructor() {
final String url = "http://localhost:1234";
final String query = "check " + url + " that ";
String filter = "lag = 0";
RestHandler handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, query + filter );
Assert.assertEquals( url, handler.url );
Assert.assertEquals( "lag", handler.conditionParameter );
Assert.assertEquals( "0", handler.conditionThreshold );
Assert.assertEquals( "=", handler.conditionOperator );
filter = "lag == 0";
handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, query + filter );
Assert.assertEquals( url, handler.url );
Assert.assertEquals( "lag", handler.conditionParameter );
Assert.assertEquals( "0", handler.conditionThreshold );
Assert.assertEquals( "==", handler.conditionOperator );
filter = "toto >= 10.0";
handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, query + filter );
Assert.assertEquals( url, handler.url );
Assert.assertEquals( "toto", handler.conditionParameter );
Assert.assertEquals( "10.0", handler.conditionThreshold );
Assert.assertEquals( ">=", handler.conditionOperator );
filter = " titi < toto ";
handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, query + filter );
Assert.assertEquals( url, handler.url );
Assert.assertEquals( "titi", handler.conditionParameter );
Assert.assertEquals( "toto", handler.conditionThreshold );
Assert.assertEquals( "<", handler.conditionOperator );
filter = "something == 'this'";
handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, query + filter );
Assert.assertEquals( url, handler.url );
Assert.assertEquals( "something", handler.conditionParameter );
Assert.assertEquals( "'this'", handler.conditionThreshold );
Assert.assertEquals( "==", handler.conditionOperator );
filter = "lag <= 0";
handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, query + filter );
Assert.assertEquals( url, handler.url );
Assert.assertEquals( "lag", handler.conditionParameter );
Assert.assertEquals( "0", handler.conditionThreshold );
Assert.assertEquals( "<=", handler.conditionOperator );
filter = "toto > 11235";
handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, query + filter );
Assert.assertEquals( url, handler.url );
Assert.assertEquals( "toto", handler.conditionParameter );
Assert.assertEquals( "11235", handler.conditionThreshold );
Assert.assertEquals( ">", handler.conditionOperator );
filter = "toto >== 11235";
handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, query + filter );
Assert.assertNull( handler.url );
Assert.assertNull( handler.conditionParameter );
Assert.assertNull( handler.conditionThreshold );
Assert.assertNull( handler.conditionOperator );
filter = "toto>11235";
handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, query + filter );
Assert.assertNull( handler.url );
Assert.assertNull( handler.conditionParameter );
Assert.assertNull( handler.conditionThreshold );
Assert.assertNull( handler.conditionOperator );
}
@Test
public void testEvalCondition() throws Exception {
RestHandler handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, "check url that lag = 0" );
Map<String,String> map = new HashMap<String,String> ();
Assert.assertFalse( handler.evalCondition( map ));
map.put( "undefined", "1.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "1.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "-1.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "0.0" );
Assert.assertTrue( handler.evalCondition( map ));
map.clear();
map.put( "lag", "0" );
Assert.assertTrue( handler.evalCondition( map ));
map.clear();
handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, "check url that lag >= 0" );
map.put( "lag", "1.0" );
Assert.assertTrue( handler.evalCondition( map ));
map.clear();
map.put( "lag", "-1.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "0.0" );
Assert.assertTrue( handler.evalCondition( map ));
map.clear();
handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, "check url that lag == 0" );
map.put( "lag", "1.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "-1.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "yes" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "0.0" );
Assert.assertTrue( handler.evalCondition( map ));
map.clear();
handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, "check url that lag > 0" );
map.put( "lag", "1.0" );
Assert.assertTrue( handler.evalCondition( map ));
map.clear();
map.put( "lag", "-1.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "0.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, "check url that lag <= 0" );
map.put( "lag", "1.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "-1.0" );
Assert.assertTrue( handler.evalCondition( map ));
map.clear();
map.put( "lag", "0.0" );
Assert.assertTrue( handler.evalCondition( map ));
map.clear();
handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, "check url that lag < 0" );
map.put( "lag", "1.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "-1.0" );
Assert.assertTrue( handler.evalCondition( map ));
map.clear();
map.put( "lag", "0.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "yes" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, "check url that lag == yes" );
map.put( "lag", "1.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "-1.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "0.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "yes" );
Assert.assertTrue( handler.evalCondition( map ));
handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, "check url that lag = yes" );
map.put( "lag", "1.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "-1.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "0.0" );
Assert.assertFalse( handler.evalCondition( map ));
map.clear();
map.put( "lag", "yes" );
Assert.assertTrue( handler.evalCondition( map ));
}
@Test
public void testLocalClasses() {
LocalX509TrustManager trustManager = new LocalX509TrustManager();
Assert.assertNull( trustManager.getAcceptedIssuers());
trustManager.checkClientTrusted( null, null );
trustManager.checkServerTrusted( null, null );
Assert.assertFalse( new LocalHostnameVerifier().verify( null, null ));
}
@Test
public void testProcess_http() throws Exception {
final String url = "http://localhost";
String expected = "\"lag\":0";
MsgNotifAutonomic msg = queryMockedHttpServer( url, expected );
Assert.assertNotNull( msg );
Assert.assertEquals( APP_NAME, msg.getApplicationName());
Assert.assertEquals( EVENT_NAME, msg.getEventName());
Assert.assertEquals( SCOPED_INSTANCE_PATH, msg.getScopedInstancePath());
Assert.assertEquals( expected, msg.getEventInfo());
expected = "{\"lag\":100}";
msg = queryMockedHttpServer( url, expected );
Assert.assertNull( msg );
}
@Test
public void testProcess_http_invalidResult() throws Exception {
final String url = "http://localhost";
String expected = "{\"lag\":100:80}";
MsgNotifAutonomic msg = queryMockedHttpServer( url, expected );
Assert.assertNull( msg );
}
@Test
public void testProcess_invalidHttp() throws Exception {
final String query = "Check http://localhost:8985 that lag = 0";
RestHandler handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, query );
Assert.assertNull( handler.process());
}
@Test
public void testProcess_invalidHttps() throws Exception {
final String query = "Check https://localhost:8985 that lag = 0";
RestHandler handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, query );
Assert.assertNull( handler.process());
}
@Test
public void testProcess_invalidQuery() throws Exception {
final String query = "Check https://localhost:8985 that lag";
RestHandler handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, query );
Assert.assertNull( handler.process());
}
private MsgNotifAutonomic queryMockedHttpServer( String url, String result ) throws Exception {
int port = 50080;
final String query = "Check " + url + ":" + port + " that lag = 0";
// Mock a HTTP server by running a simple socket server.
// This server will only handle one connection.
Thread thread = new WebServerThread(RestHandlerTest.this.logger, port, result);
// Start our server
thread.start();
Thread.sleep( 500 );
// Then, prepare our client.
RestHandler handler = new RestHandler();
handler.setAgentId( APP_NAME, SCOPED_INSTANCE_PATH );
handler.reset( null, EVENT_NAME, query );
MsgNotifAutonomic msg = handler.process();
// Wait for the server to die.
thread.join();
return msg;
}
/**
* @author Pierre-Yves Gibello - Linagora
*/
private static class WebServerThread extends Thread {
private final Logger logger;
private final int port;
private final String result;
public WebServerThread(Logger logger, int port, String result) {
this.logger = logger;
this.port = port;
this.result = result;
}
@Override
public void run() {
ServerSocket socketServer = null;
try {
try {
this.logger.log( LOG_LEVEL, "The socket server is about to start." );
socketServer = new ServerSocket(this.port);
this.logger.log( LOG_LEVEL, "The socket server was started." );
Socket socket = socketServer.accept();
this.logger.log( LOG_LEVEL, "The socket server received a connection." );
PrintWriter writer = new PrintWriter( new OutputStreamWriter( socket.getOutputStream(), StandardCharsets.UTF_8 ), false );
writer.print("HTTP/1.1 200 OK\n\n" + this.result);
writer.flush();
socket.shutdownOutput();
socket.close();
} finally {
if( socketServer != null )
socketServer.close();
this.logger.log( LOG_LEVEL, "The socket server was closed." );
}
} catch( IOException e ) {
// nothing
}
}
}
}