2 * Copyright IBM Corporation, 2013. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.md.statistics.manager;
10 import java.util.Iterator;
12 import java.util.concurrent.ConcurrentHashMap;
13 import java.util.concurrent.TimeUnit;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
18 import com.google.common.base.Preconditions;
21 * Main responsibility of the class is to manage multipart response
22 * for multipart request. It also handles the flow aggregate request
23 * and response mapping.
24 * @author avishnoi@in.ibm.com
27 public class MultipartMessageManager {
28 private static final int NUMBER_OF_WAIT_CYCLES = 2;
31 * Map for tx id and type of request, to keep track of all the request sent
32 * by Statistics Manager. Statistics Manager won't entertain any multipart
33 * response for which it didn't send the request.
35 private final Map<TxIdEntry,Long> txIdToRequestTypeMap = new ConcurrentHashMap<>();
37 * Map to keep track of the request tx id for flow table statistics request.
38 * Because flow table statistics multi part response do not contains the table id.
40 private final Map<TxIdEntry,Short> txIdTotableIdMap = new ConcurrentHashMap<>();
42 private static final class TxIdEntry {
43 private final StatsRequestType requestType;
44 private final TransactionId txId;
46 public TxIdEntry(TransactionId txId, StatsRequestType requestType){
48 this.requestType = requestType;
50 public TransactionId getTxId() {
53 public StatsRequestType getRequestType() {
57 public int hashCode() {
60 result = prime * result + ((txId == null) ? 0 : txId.hashCode());
64 public boolean equals(Object obj) {
71 if (!(obj instanceof TxIdEntry)) {
74 TxIdEntry other = (TxIdEntry) obj;
77 if (other.txId != null) {
80 } else if (!txId.equals(other.txId)) {
87 public String toString() {
88 return "TxIdEntry [txId=" + txId + ", requestType=" + requestType + "]";
92 public void recordExpectedTableTransaction(TransactionId id, StatsRequestType type, Short tableId) {
93 recordExpectedTransaction(id, type);
94 txIdTotableIdMap.put(new TxIdEntry(id, null), Preconditions.checkNotNull(tableId));
97 public Short isExpectedTableTransaction(TransactionAware transaction, Boolean more) {
98 if (!isExpectedTransaction(transaction, more)) {
102 final TxIdEntry key = new TxIdEntry(transaction.getTransactionId(), null);
103 if (more != null && more.booleanValue()) {
104 return txIdTotableIdMap.get(key);
106 return txIdTotableIdMap.remove(key);
110 public void recordExpectedTransaction(TransactionId id, StatsRequestType type) {
111 TxIdEntry entry = new TxIdEntry(Preconditions.checkNotNull(id), Preconditions.checkNotNull(type));
112 txIdToRequestTypeMap.put(entry, getExpiryTime());
115 public boolean isExpectedTransaction(TransactionAware transaction, Boolean more) {
116 TxIdEntry entry = new TxIdEntry(transaction.getTransactionId(), null);
117 if (more != null && more.booleanValue()) {
118 return txIdToRequestTypeMap.containsKey(entry);
120 return txIdToRequestTypeMap.remove(entry) != null;
124 private static Long getExpiryTime(){
125 return System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(
126 StatisticsProvider.STATS_COLLECTION_MILLIS*NUMBER_OF_WAIT_CYCLES);
129 public enum StatsRequestType {
141 public void cleanStaleTransactionIds() {
142 final long now = System.nanoTime();
144 for (Iterator<TxIdEntry> it = txIdToRequestTypeMap.keySet().iterator();it.hasNext();){
145 TxIdEntry txIdEntry = it.next();
147 Long expiryTime = txIdToRequestTypeMap.get(txIdEntry);
148 if(now > expiryTime){
150 txIdTotableIdMap.remove(txIdEntry);