/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.apache.usergrid.persistence.qakka.api; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang.RandomStringUtils; import org.apache.usergrid.persistence.qakka.core.QueueMessage; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.net.URISyntaxException; import java.util.*; public class PerformanceTest { private static final Logger logger = LoggerFactory.getLogger( PerformanceTest.class ); @Test @Ignore("needs exernal Tomcat an Cassandra") public void testSendAndGetMessagePerformance() throws URISyntaxException, JsonProcessingException { Client client = ClientBuilder.newClient(); WebTarget target = client.target("http://macsnoopdave2013:8080/api/"); // create a queue String queueName = "pt_queue_" + RandomStringUtils.randomAlphanumeric( 10 ); Map<String, Object> queueMap = new HashMap<String, Object>() {{ put("name", queueName); }}; target.path("queues").request().post( Entity.entity( queueMap, MediaType.APPLICATION_JSON_TYPE)); // send some messages int numMessages = 20000; { ObjectMapper mapper = new ObjectMapper(); List<Long> times = new ArrayList<>( numMessages ); int errorCount = 0; int counter = 0; for (int i = 0; i < numMessages; i++) { final int number = i; Map<String, Object> messageMap = new HashMap<String, Object>() {{ put( "message", "this is message #" + number ); put( "valid", true ); }}; String body = mapper.writeValueAsString( messageMap ); long startTime = System.currentTimeMillis(); Response post = target.path( "queues" ).path( queueName ).path( "messages" ) .request().post( Entity.entity( body, MediaType.APPLICATION_OCTET_STREAM_TYPE ) ); long stopTime = System.currentTimeMillis(); times.add( stopTime - startTime ); if ( post.getStatus() != 200 ) { errorCount++; } if ( ++counter % 500 == 0 ) { logger.debug("Sent {} messages with error count {}", counter, errorCount); } try { Thread.sleep(5); } catch ( Exception intentionallyIgnored ) {}; } Long total = times.stream().mapToLong( time -> time ).sum(); Long max = times.stream().max( Comparator.comparing( time -> time ) ).get(); Long min = times.stream().min( Comparator.comparing( time -> time ) ).get(); Double average = times.stream().mapToLong( time -> time ).average().getAsDouble(); logger.debug( "\n>>>>>>> Total send time {}ms, min {}ms, max {}ms, average {}ms errors {}\n\n", total, min, max, average, errorCount ); } // get all messages, checking for dups { Set<UUID> messageIds = new HashSet<>(); List<Long> times = new ArrayList<>( numMessages ); int errorCount = 0; int counter = 0; for (int j = 0; j < numMessages; j++) { long startTime = System.currentTimeMillis(); Response response = target.path( "queues" ).path( queueName ).path( "messages" ).request().get(); long stopTime = System.currentTimeMillis(); times.add( stopTime - startTime ); if ( ++counter % 500 == 0 ) { logger.debug("Got {} messages with error count {}", counter, errorCount); } if ( response .getStatus() != 200 ) { errorCount++; continue; } ApiResponse apiResponse = response.readEntity( ApiResponse.class ); QueueMessage queueMessage = apiResponse.getQueueMessages().iterator().next(); if (messageIds.contains( queueMessage.getQueueMessageId() )) { Assert.fail( "Message fetched twice: " + queueMessage.getQueueMessageId() ); } else { messageIds.add( queueMessage.getQueueMessageId() ); } } Assert.assertEquals( numMessages, messageIds.size() ); Long total = times.stream().mapToLong( time -> time ).sum(); Long max = times.stream().max( Comparator.comparing( time -> time ) ).get(); Long min = times.stream().min( Comparator.comparing( time -> time ) ).get(); Double average = times.stream().mapToLong( time -> time ).average().getAsDouble(); logger.debug( "\n>>>>>>> Total get time {}ms, min {}ms, max {}ms, average {}ms errors {}\n\n", total, min, max, average, errorCount ); } } }