/******************************************************************************* * Copyright (c) 2013 GigaSpaces Technologies Ltd. All rights reserved * * 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 org.robobninjas.riemann.spring; import com.aphyr.riemann.Proto; import com.google.common.base.Throwables; import com.google.common.collect.Iterables; import com.google.common.collect.Queues; import org.robobninjas.riemann.json.RiemannEventObjectMapper; import org.robobninjas.riemann.spring.server.RiemannProcess; import org.robotninjas.riemann.client.RiemannTcpClient; import org.robotninjas.riemann.client.RiemannTcpConnection; import org.robotninjas.riemann.pubsub.QueryResultListener; import org.robotninjas.riemann.pubsub.RiemannPubSubClient; import org.robotninjas.riemann.pubsub.RiemannPubSubConnection; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.PropertySource; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Inject; import java.io.IOException; import java.lang.reflect.Method; import java.net.URISyntaxException; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import static org.fest.assertions.api.Assertions.assertThat; /** * Tests Riemann tcp tcpClient. * * @author Itai Frenkel * @since 3.0.1 */ @ContextConfiguration(classes = { RiemannIT.Config.class }) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class RiemannIT extends AbstractTestNGSpringContextTests implements QueryResultListener { private BlockingQueue<String> events = Queues.newArrayBlockingQueue(10); @Override public void handleResult(String result) { events.add(result); } /** */ @Configuration @PropertySource("org/robobninjas/riemann/spring/riemann-test.properties") @Import({ RiemannTestConfiguration.class }) static class Config { @Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } } // component being tested @Inject private RiemannProcess riemannProcess; @Inject private RiemannTcpClient tcpClient; private RiemannTcpConnection tcpConnection; @Inject private RiemannPubSubClient pubSubClient; private RiemannPubSubConnection pubSubConnection; @Inject RiemannEventObjectMapper objectMapper; @BeforeMethod public void establishConnection(Method method) { logger.info("establishing connections before test " + method.getName()); tcpConnection = makeConnection(); pubSubConnection = continuousQuery(); } @AfterMethod(alwaysRun = true) public void closeConnection(Method method) throws IOException, InterruptedException { logger.info("closing connections after test " + method.getName()); if (tcpConnection != null) { tcpConnection.close(); } if (pubSubConnection != null) { pubSubConnection.close(); } } @Test(timeOut = 60000) public void testSendWithAck() throws InterruptedException { boolean success = sendWithAck(); assertThat(success).isEqualTo(Boolean.TRUE); } @Test(dependsOnMethods = {"testSendWithAck" }, timeOut = 60000) public void testQuery() throws InterruptedException { sendWithAck(); List<Proto.Event> events = query(); assertThat(Iterables.getOnlyElement(events).getMetricD()).isEqualTo(5.3); } @Test(dependsOnMethods = {"testSendWithAck" }, timeOut = 60000) public void testContinuousQuery() throws InterruptedException, IOException { sendWithAck(); String json = events.take(); assertThat(objectMapper.readEvent(json).getMetricD()).isEqualTo(5.3); } private List<Proto.Event> query() throws InterruptedException { try { return tcpConnection.query(queryString()).get(); } catch (ExecutionException e) { throw Throwables.propagate(e); } } private RiemannTcpConnection makeConnection() { try { return tcpClient.makeConnection(); } catch (InterruptedException e) { throw Throwables.propagate(e); } } private boolean sendWithAck() { final Future<Boolean> isOk = tcpConnection.sendWithAck(createEvent()); try { return isOk.get(); } catch (InterruptedException e) { throw Throwables.propagate(e); } catch (ExecutionException e) { throw Throwables.propagate(e); } } private Proto.Event createEvent() { return Proto.Event .newBuilder() .setService("fridge") .setState("running") .setMetricD(5.3) .addTags("appliance") .addTags("cold") .build(); } private String queryString() { return "tagged \"cold\" and metric > 0"; } private RiemannPubSubConnection continuousQuery() { try { return this.pubSubClient.makeConnection(queryString(), true, this); } catch (InterruptedException e) { throw Throwables.propagate(e); } catch (URISyntaxException e) { throw Throwables.propagate(e); } } }