/** * Copyright 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.messaging.api.jmx; import java.util.Date; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicLong; import net.roboconf.messaging.api.messages.Message; /** * A blocking queue with additional attributes to measure activity. * @author Vincent Zurczak - Linagora */ public class RoboconfMessageQueue extends LinkedBlockingQueue<Message> { private static final long serialVersionUID = 6728334259953445852L; private final AtomicLong receivedMessagesCount = new AtomicLong(); private final AtomicLong timestampOfLastReceivedMessage = new AtomicLong(); private final AtomicLong failedReceptionCount = new AtomicLong(); private final AtomicLong timestampOfLastReceptionFailure = new AtomicLong(); /** * Constructor. */ public RoboconfMessageQueue() { super(); } /** * Constructor (used only for tests). * @param capacity */ RoboconfMessageQueue( int capacity ) { super( capacity ); } // Methods to track activity. // Take a look at the unit tests. // - addAll() invokes add(). // - add() invokes offer(). // // - put() is ignored. // // So, we only override offer(). @Override public boolean offer( Message e ) { boolean result = super.offer( e ); if( result ) { this.receivedMessagesCount.incrementAndGet(); this.timestampOfLastReceivedMessage.set( new Date().getTime()); } return result; } @Override public void put( Message e ) throws InterruptedException { // As we cannot get precise metrics when this method is used, we just forbid its use. throw new RuntimeException( "This method is disabled for Roboconf." ); } // Custom methods /** * Resets the count of messages. */ public void reset() { this.receivedMessagesCount.set( 0 ); this.timestampOfLastReceivedMessage.set( 0 ); this.failedReceptionCount.set( 0 ); this.timestampOfLastReceptionFailure.set( 0 ); } /** * Method to notify a message was incorrectly received (e.g. error during deserialization). */ public void errorWhileReceivingMessage() { this.failedReceptionCount.incrementAndGet(); this.timestampOfLastReceptionFailure.set( new Date().getTime()); } // Getters public long getFailedReceptionCount() { return this.failedReceptionCount.get(); } public long getReceivedMessagesCount() { return this.receivedMessagesCount.get(); } public long getTimestampOfLastReceptionFailure() { return this.timestampOfLastReceptionFailure.get(); } public long getTimestampOfLastReceivedMessage() { return this.timestampOfLastReceivedMessage.get(); } }