* @return thread numbers for TcpHandler's eventloopGroups
*/
ThreadConfiguration getThreadConfiguration();
- /**
- * @return Statistics configuration
- */
- StatisticsConfiguration getStatisticsConfiguration();
}
\ No newline at end of file
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
+
package org.opendaylight.openflowjava.protocol.api.connection;
/**
+ * Used for StatisticsCounter configuration
+ *
* @author madamjak
- *
*/
public interface StatisticsConfiguration {
- Boolean getStatisticsCollect();
- Integer getLogReportDelay();
-}
+
+ /**
+ * @return true if statistics are / will be collected, false otherwise
+ */
+ boolean getStatisticsCollect();
+
+ /**
+ * @return delay between two statistics logs (in milliseconds)
+ */
+ int getLogReportDelay();
+}
\ No newline at end of file
counterLastReadValue.set(0l);\r
}\r
\r
- @Override\r
- public String toString() {\r
+ /**\r
+ * @return last and current count for specified statistic\r
+ */\r
+ public String getStat() {\r
long cntPrevVal = getCounterLastReadValue();\r
long cntCurValue = getCounterValue();\r
return String.format("+%d | %d",cntCurValue-cntPrevVal,cntCurValue);\r
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
+import org.opendaylight.openflowjava.protocol.spi.statistics.StatisticsHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* @author madamjak
*
*/
-public final class StatisticsCounters {
+public final class StatisticsCounters implements StatisticsHandler {
/**
* Default delay between two writings into log (milliseconds)
countersMap.put(cet, new Counter());
}
runCounting = false;
- this.logReportPeriod = -1;
+ this.logReportPeriod = 0;
this.runLogReport = false;
LOGGER.debug("StaticsCounters has been created");
}
/**
- * Start counting
- * @param resetCounters - true = statistics counters will be reset before start counting
- * @param reportToLogs - true = statistics counters will periodically write to log
- * @param logReportDelay - delay between two writings into logs in milliseconds (for details see startLogReport(int logReportDelay))
+ * Start counting (counters are set to 0 before counting starts)
+ * @param reportToLogs - true = statistic counters will periodically log
+ * @param logReportDelay - delay between two logs (in milliseconds)
*/
- public void startCounting(boolean resetCounters, boolean reportToLogs, int logReportDelay){
+ public void startCounting(boolean reportToLogs, int logReportDelay){
if (runCounting) {
return;
}
- LOGGER.debug("Start counting...");
+ resetCounters();
+ LOGGER.debug("Counting started...");
if(reportToLogs){
startLogReport(logReportDelay);
}
- if(resetCounters){
- resetCounters();
- }
runCounting = true;
}
- /**
- * Start counting (counters are set to 0 before start counting)
- * @param reportToLogs - true = statistics counters will periodically write to log
- * @param logReportDelay - delay between two writings into logs in milliseconds (for details see startLogReport(int logReportDelay))
- */
- public void startCounting(boolean reportToLogs, int logReportDelay){
- if (runCounting) {
- return;
- }
- startCounting(true,reportToLogs,logReportDelay);
- }
-
/**
* Stop counting, values in counters are untouched, log reporter is stopped
*/
}
/**
- * Start write statistics into logs, if writing is run calling has no effect.
- * If method is called without previous setting of report delay than DEFAULT_LOG_REPORT_PERIOD will be used.
- */
- public void startLogReport(){
- if(runLogReport){
- return;
- }
- if(this.logReportPeriod <= 0){
- this.logReportPeriod = DEFAULT_LOG_REPORT_PERIOD;
- }
- if(this.logReportPeriod <= MINIMAL_LOG_REPORT_PERIOD){
- this.logReportPeriod = MINIMAL_LOG_REPORT_PERIOD;
- }
- logReporter = new Timer("SC_Timer");
- logReporter.schedule(new LogReporterTask(this), this.logReportPeriod,this.logReportPeriod);
- runLogReport = true;
- LOGGER.debug("Statistics log reporter has been scheduled with period {} ms", this.logReportPeriod);
- }
-
- /**
- * Start write statistics into logs with given delay between writings, if writing is run calling has no effect.
- * @param logReportDelay - delay between two writings into logs (milliseconds).
- * It is mandatory if reportToLogs is true, value have to be greater than 0 (zero)
- * If value is smaller than MINIMAL_LOG_REPORT_PERIOD, the value MINIMAL_LOG_REPORT_PERIOD will be used.
- * @exception IllegalArgumentException if logReportDelay is not greater than 0 (zero)
+ * Prints statistics with given delay between logs
+ * @param logReportDelay - delay between two logs (in milliseconds)
+ * @exception IllegalArgumentException if logReportDelay is less than 0
*/
public void startLogReport(int logReportDelay){
if(runLogReport){
return;
}
if(logReportDelay <= 0){
- throw new IllegalArgumentException("logReportPeriod have to bee greater than 0 zero");
+ throw new IllegalArgumentException("logReportDelay has to be greater than 0");
}
if(logReportDelay < MINIMAL_LOG_REPORT_PERIOD){
this.logReportPeriod = MINIMAL_LOG_REPORT_PERIOD;
} else {
this.logReportPeriod = logReportDelay;
}
- startLogReport();
+ logReporter = new Timer("SC_Timer");
+ logReporter.schedule(new LogReporterTask(this), this.logReportPeriod, this.logReportPeriod);
+ runLogReport = true;
+ LOGGER.debug("Statistics log reporter has been scheduled with period {} ms", this.logReportPeriod);
}
/**
- * Stop write statistics into logs, counting does not stop
+ * Stops logging, counting continues
*/
public void stopLogReport(){
if(runLogReport){
}
/**
- * Get counter by counter event type
+ * Get counter by CounterEventType
* @param counterEventKey key to identify counter (can not be null)
* @return - Counter object or null if counter has not been enabled
* @exception - IllegalArgumentException if counterEventKey is null
}
}
- /**
- * Set values of all counter to 0 (zero)
- */
+ @Override
public void resetCounters() {
for(CounterEventTypes cet : enabledCounters){
countersMap.get(cet).reset();
LOGGER.debug("StaticsCounters has been reset");
}
+ @Override
+ public String printStatistics() {
+ StringBuilder strBuilder = new StringBuilder();
+ for(CounterEventTypes cet : getEnabledCounters()){
+ strBuilder.append(cet.name() + ": " + getCountersMap().get(cet).getStat() + "\n");
+ }
+ return strBuilder.toString();
+ }
+
/**
* internal class to process logReporter
* @author madamjak
@Override
public void run() {
- for(CounterEventTypes cet : sc.getEnabledCounters()){
- LOG.debug(cet.toString() + ": " + sc.getCountersMap().get(cet).toString());
- }
+ for(CounterEventTypes cet : sc.getEnabledCounters()){
+ LOG.debug(cet.name() + ": " + sc.getCountersMap().get(cet).getStat());
+ }
}
}
-}
+}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328;
+
+import org.opendaylight.openflowjava.protocol.api.connection.StatisticsConfiguration;
+import org.opendaylight.openflowjava.protocol.spi.statistics.StatisticsHandler;
+import org.opendaylight.openflowjava.statistics.StatisticsCounters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+* This is the definition of statistics collection module identity.
+*/
+public class StatisticsCollectionModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328.AbstractStatisticsCollectionModule {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(StatisticsCollectionModule.class);
+
+ public StatisticsCollectionModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public StatisticsCollectionModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328.StatisticsCollectionModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void customValidation() {
+ // add custom validation form module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ final Statistics statistics = getStatistics();
+ final StatisticsCounters statsCounter = StatisticsCounters.getInstance();
+ StatisticsConfiguration statsConfig = null;
+ if (statistics != null) {
+ statsConfig = new StatisticsConfiguration() {
+
+ @Override
+ public boolean getStatisticsCollect() {
+ if (statistics.getStatisticsCollect() != null) {
+ return statistics.getStatisticsCollect().booleanValue();
+ }
+ return false;
+ }
+
+ @Override
+ public int getLogReportDelay() {
+ if (statistics.getLogReportDelay() != null) {
+ return statistics.getLogReportDelay().intValue();
+ }
+ return 0;
+ }
+ };
+ } else {
+ LOGGER.error("STATISTICS ARE NULL");
+ }
+ LOGGER.error("config " + statsConfig);
+ if (statsConfig != null) {
+ statsCounter.startCounting(statsConfig.getStatisticsCollect(), statsConfig.getLogReportDelay());
+ } else {
+ LOGGER.debug("Unable to start StatisticCounter - wrong configuration");
+ }
+
+ /* Internal MXBean implementation */
+ final StatisticsCollectionRuntimeMXBean collectionBean = new StatisticsCollectionRuntimeMXBean() {
+
+ @Override
+ public String printOfjavaStatistics() {
+ if (statsCounter != null) {
+ return statsCounter.printStatistics();
+ }
+ return "Statistics collection is not avaliable.";
+ }
+ @Override
+ public String getMsgStatistics() {
+ return printOfjavaStatistics();
+ }
+ @Override
+ public String resetOfjavaStatistics() {
+ statsCounter.resetCounters();
+ return "Statistics have been reset";
+ }
+ };
+
+ /* MXBean registration */
+ final StatisticsCollectionRuntimeRegistration runtimeReg =
+ getRootRuntimeBeanRegistratorWrapper().register(collectionBean);
+
+ /* Internal StatisticsCollectionService implementation */
+ final class AutoClosableStatisticsCollection implements StatisticsHandler, AutoCloseable {
+
+ @Override
+ public void close() {
+ if (runtimeReg != null) {
+ try {
+ runtimeReg.close();
+ }
+ catch (Exception e) {
+ String errMsg = "Error by stoping StatisticsCollectionService.";
+ LOGGER.error(errMsg, e);
+ throw new IllegalStateException(errMsg, e);
+ }
+ }
+ LOGGER.info("StatisticsCollection Service consumer (instance {} turn down.)", this);
+ }
+
+ @Override
+ public void resetCounters() {
+ statsCounter.resetCounters();
+ }
+
+ @Override
+ public String printStatistics() {
+ return statsCounter.printStatistics();
+ }
+ }
+
+ AutoCloseable ret = new AutoClosableStatisticsCollection();
+ LOGGER.info("StatisticsCollection service (instance {}) initialized.", ret);
+ return ret;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+* Generated file
+*
+* Generated from: yang module name: openflow-switch-connection-provider-impl yang module local name: statistics-collection-service-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Thu Nov 13 12:52:26 CET 2014
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328;
+public class StatisticsCollectionModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328.AbstractStatisticsCollectionModuleFactory {
+
+}
import java.net.UnknownHostException;
import org.opendaylight.openflowjava.protocol.api.connection.ConnectionConfiguration;
-import org.opendaylight.openflowjava.protocol.api.connection.StatisticsConfiguration;
import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration;
import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration;
import org.opendaylight.openflowjava.protocol.impl.core.SwitchConnectionProviderImpl;
-import org.opendaylight.openflowjava.statistics.StatisticsCounters;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol;
public java.lang.AutoCloseable createInstance() {
LOG.info("SwitchConnectionProvider started.");
SwitchConnectionProviderImpl switchConnectionProviderImpl = new SwitchConnectionProviderImpl();
- StatisticsCounters sc = StatisticsCounters.getInstance();
try {
ConnectionConfiguration connConfiguration = createConnectionConfiguration();
switchConnectionProviderImpl.setConfiguration(connConfiguration);
- startStatistics(sc, connConfiguration.getStatisticsConfiguration());
} catch (UnknownHostException e) {
throw new IllegalArgumentException(e.getMessage(), e);
}
return switchConnectionProviderImpl;
}
-
/**
* @return instance configuration object
* @throws UnknownHostException
final Tls tlsConfig = getTls();
final Threads threads = getThreads();
final TransportProtocol transportProtocol = getTransportProtocol();
- final Statistics statistics = getStatistics();
-
+
return new ConnectionConfiguration() {
@Override
public InetAddress getAddress() {
}
};
}
- @Override
- public StatisticsConfiguration getStatisticsConfiguration(){
- return new StatisticsConfiguration() {
- @Override
- public Boolean getStatisticsCollect() {
- if(statistics == null){
- return false;
- }
- if (statistics.getStatisticsCollect() == null){
- return false;
- }
- return statistics.getStatisticsCollect();
- }
- @Override
- public Integer getLogReportDelay() {
- if(statistics == null){
- return -1;
- }
- if(statistics.getLogReportDelay() == null){
- return -1;
- };
- return statistics.getLogReportDelay();
- }
- };
- }
};
}
}
}
- /**
- * Configure and start Statistics Counters by configuration parameters.
- * No operations is performed if:
- * - statisticsConfig is null
- * - sc is null
- * - sc is not null and if counting is running
- * @param sc - statistic counter to configure and start
- * @param statisticsConfig - configuration parameters
- */
- private static void startStatistics(StatisticsCounters sc, StatisticsConfiguration statisticsConfig){
- if(statisticsConfig == null){
- return;
- }
- if(sc == null || sc.isRunCounting()){
- return;
- }
- Boolean toCollectStats = statisticsConfig.getStatisticsCollect();
- Integer logDelay = statisticsConfig.getLogReportDelay();
- if(toCollectStats != null && toCollectStats.booleanValue()){
- int logPeriod = -1;
- if(logDelay != null){
- logPeriod = logDelay.intValue();
- }
- if(logPeriod >0){
- sc.startCounting(true, logPeriod);
- } else {
- sc.startCounting(false, 0);
- }
- }
- }
-
/**
* @param value
* @return
import openflow-switch-connection-provider {prefix openflow-switch-connection-provider; revision-date 2014-03-28; }
import ietf-inet-types {prefix ietf-inet; revision-date 2010-09-24; }
import openflow-configuration {prefix of-config; revision-date 2014-06-30; }
+ import rpc-context { prefix rpcx; revision-date 2013-06-17; }
description
"openflow-switch-connection-provider";
config:java-name-prefix SwitchConnectionProvider;
}
+ identity statistics-collection-service-impl {
+ description
+ "This is the definition of statistics collection module identity.";
+ base config:module-type;
+ config:provided-service openflow-switch-connection-provider:statistics-collection-service;
+ config:java-name-prefix StatisticsCollection;
+ }
augment "/config:modules/config:module/config:configuration" {
case openflow-switch-connection-provider-impl {
type uint16;
}
}
+ }
+
+ case statistics-collection-service-impl {
+ when "/config:modules/config:module/config:type = 'statistics-collection-service-impl'";
+
container statistics {
leaf statistics-collect {
- description "Toggle of collecting statistics";
+ description "Toggle statistics collecting";
type boolean;
}
leaf log-report-delay {
type uint16;
}
}
+ list openflow-switch-connection-provider {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity openflow-switch-connection-provider:openflow-switch-connection-provider;
+ }
+ }
+ }
+ }
+ }
+
+ augment "/config:modules/config:module/config:state" {
+ case statistics-collection-service-impl {
+ when "/config:modules/config:module/config:type = 'statistics-collection-service-impl'";
+
+ description
+ "MXBean designed for Message Statistic providing to JConsole.";
+
+ leaf msgStatistics {
+ type string;
+ }
+
+ rpcx:rpc-context-instance "print-ofjava-statistics-rpc";
+ rpcx:rpc-context-instance "reset-ofjava-statistics-rpc";
+ }
+ }
+
+ identity print-ofjava-statistics-rpc;
+ identity reset-ofjava-statistics-rpc;
+
+ rpc print-ofjava-statistics {
+ description
+ "Shortcut JMX call to printOfjavaStatistics.";
+ input {
+ uses rpcx:rpc-context-ref {
+ refine context-instance {
+ rpcx:rpc-context-instance print-ofjava-statistics-rpc;
+ }
+ }
+ }
+ output {
+ leaf result {
+ type string;
+ }
+ }
+ }
+
+ rpc reset-ofjava-statistics {
+ description
+ "Shortcut JMX call to resetOfjavaStatistics.";
+ input {
+ uses rpcx:rpc-context-ref {
+ refine context-instance {
+ rpcx:rpc-context-instance reset-ofjava-statistics-rpc;
+ }
+ }
+ }
+ output {
+ leaf result {
+ type string;
+ }
}
}
}
\ No newline at end of file
ofDecoder.setDeserializationFactory(mockDeserializationFactory);
outList = new ArrayList<>();
statCounters = StatisticsCounters.getInstance();
- statCounters.startCounting(true, false, 0);
+ statCounters.startCounting(false, 0);
}
/**
ofEncoder = new OFEncoder() ;
ofEncoder.setSerializationFactory(mockSerializationFactory) ;
statCounters = StatisticsCounters.getInstance();
- statCounters.startCounting(true,false, 0);
+ statCounters.startCounting(false, 0);
}
/**
public void setUp() {
MockitoAnnotations.initMocks(this);
statCounters = StatisticsCounters.getInstance();
- statCounters.startCounting(true,false, 0);
+ statCounters.startCounting(false, 0);
}
/**
import java.net.InetAddress;
import org.opendaylight.openflowjava.protocol.api.connection.ConnectionConfiguration;
-import org.opendaylight.openflowjava.protocol.api.connection.StatisticsConfiguration;
import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration;
import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328.modules.module.configuration.openflow._switch.connection.provider.impl.Statistics;
/**
* @author michal.polkorab
private TlsConfiguration tlsConfig;
private long switchIdleTimeout;
private ThreadConfiguration threadConfig;
- private TransportProtocol protocol;
- private Statistics statistics;
/**
* Creates {@link ConnectionConfigurationImpl}
public void setThreadConfiguration(ThreadConfiguration threadConfig) {
this.threadConfig = threadConfig;
}
-
- @Override
- public StatisticsConfiguration getStatisticsConfiguration() {
- // TODO Auto-generated method stub
- return null;
- }
}
\ No newline at end of file
@Before
public void initTest(){
statCounters = StatisticsCounters.getInstance();
- statCounters.startCounting(true,false, 0);
+ statCounters.startCounting(false, 0);
}
/**
statCounters.startLogReport(testDelay);
Assert.assertTrue("Wrong - logRepoter is not running", statCounters.isRunLogReport());
Assert.assertEquals("Wrong - bad logReportPeriod", testDelay, statCounters.getLogReportPeriod());
- statCounters.startLogReport();
- Assert.assertTrue("Wrong - logRepoter is not running", statCounters.isRunLogReport());
- Assert.assertEquals("Wrong - bad logReportPeriod", testDelay, statCounters.getLogReportPeriod());
statCounters.stopLogReport();
Assert.assertFalse("Wrong - logRepoter is running", statCounters.isRunLogReport());
statCounters.startLogReport(statCounters.MINIMAL_LOG_REPORT_PERIOD / 2);
*/
@Test(expected = IllegalArgumentException.class)
public void testLogReportBadPeriod(){
- statCounters.startLogReport(-1);
+ statCounters.startLogReport(0);
}
/**
<configuration>
<instructions>
<Export-Package>
- org.opendaylight.openflowjava.protocol.spi.connection*,
+ org.opendaylight.openflowjava.protocol.spi*,
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.*
</Export-Package>
</instructions>
--- /dev/null
+/*\r
+ * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.openflowjava.protocol.spi.statistics;\r
+\r
+/**\r
+ * Used for JConsole service\r
+ * \r
+ * @author michal.polkorab\r
+ */\r
+public interface StatisticsHandler {\r
+\r
+ /**\r
+ * Resets all counters\r
+ */\r
+ public void resetCounters();\r
+\r
+ /**\r
+ * Prints statistics\r
+ * @return statistics\r
+ */\r
+ public String printStatistics();\r
+}
\ No newline at end of file
base "config:service-type";
config:java-class "org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider";
}
+
+ identity statistics-collection-service {
+ description
+ "StatisticsHandlerService interface as a StatisticsCollection interface identity";
+ base config:service-type;
+ config:java-class "org.opendaylight.openflowjava.protocol.spi.statistics.StatisticsHandler";
+ }
}
\ No newline at end of file