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 TransactionId txId;
45 public TxIdEntry(TransactionId txId) {
48 public TransactionId getTxId() {
52 public int hashCode() {
55 result = prime * result + ((txId == null) ? 0 : txId.hashCode());
59 public boolean equals(Object obj) {
66 if (!(obj instanceof TxIdEntry)) {
69 TxIdEntry other = (TxIdEntry) obj;
72 if (other.txId != null) {
75 } else if (!txId.equals(other.txId)) {
82 public String toString() {
83 return "TxIdEntry [txId=" + txId + ']';
87 public void recordExpectedTableTransaction(TransactionId id, Short tableId) {
88 recordExpectedTransaction(id);
89 txIdTotableIdMap.put(new TxIdEntry(id), Preconditions.checkNotNull(tableId));
92 public Short isExpectedTableTransaction(TransactionAware transaction, Boolean more) {
93 if (!isExpectedTransaction(transaction, more)) {
97 final TxIdEntry key = new TxIdEntry(transaction.getTransactionId());
98 if (more != null && more.booleanValue()) {
99 return txIdTotableIdMap.get(key);
101 return txIdTotableIdMap.remove(key);
105 public void recordExpectedTransaction(TransactionId id) {
106 TxIdEntry entry = new TxIdEntry(Preconditions.checkNotNull(id));
107 txIdToRequestTypeMap.put(entry, getExpiryTime());
110 public boolean isExpectedTransaction(TransactionAware transaction, Boolean more) {
111 TxIdEntry entry = new TxIdEntry(transaction.getTransactionId());
112 if (more != null && more.booleanValue()) {
113 return txIdToRequestTypeMap.containsKey(entry);
115 return txIdToRequestTypeMap.remove(entry) != null;
119 private static Long getExpiryTime(){
120 return System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(
121 StatisticsProvider.STATS_COLLECTION_MILLIS*NUMBER_OF_WAIT_CYCLES);
124 public void cleanStaleTransactionIds() {
125 final long now = System.nanoTime();
127 for (Iterator<TxIdEntry> it = txIdToRequestTypeMap.keySet().iterator();it.hasNext();){
128 TxIdEntry txIdEntry = it.next();
130 Long expiryTime = txIdToRequestTypeMap.get(txIdEntry);
131 if(now > expiryTime){
133 txIdTotableIdMap.remove(txIdEntry);