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;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.MultipartTransactionAware;
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 class MultipartMessageManager {
29 * Map for tx id and type of request, to keep track of all the request sent
30 * by Statistics Manager. Statistics Manager won't entertain any multipart
31 * response for which it didn't send the request.
33 private final Map<TxIdEntry,Long> txIdToRequestTypeMap = new ConcurrentHashMap<>();
35 * Map to keep track of the request tx id for flow table statistics request.
36 * Because flow table statistics multi part response do not contains the table id.
38 private final Map<TxIdEntry,Short> txIdTotableIdMap = new ConcurrentHashMap<>();
39 private final long lifetimeNanos;
41 public MultipartMessageManager(long lifetimeNanos) {
42 this.lifetimeNanos = lifetimeNanos;
45 private static final class TxIdEntry {
46 private final TransactionId txId;
48 public TxIdEntry(TransactionId txId) {
51 public TransactionId getTxId() {
55 public int hashCode() {
58 result = prime * result + ((txId == null) ? 0 : txId.hashCode());
62 public boolean equals(Object obj) {
69 if (!(obj instanceof TxIdEntry)) {
72 TxIdEntry other = (TxIdEntry) obj;
75 if (other.txId != null) {
78 } else if (!txId.equals(other.txId)) {
85 public String toString() {
86 return "TxIdEntry [txId=" + txId + ']';
90 public void recordExpectedTableTransaction(TransactionId id, Short tableId) {
91 recordExpectedTransaction(id);
92 txIdTotableIdMap.put(new TxIdEntry(id), Preconditions.checkNotNull(tableId));
95 public Short isExpectedTableTransaction(TransactionAware transaction) {
97 if (transaction instanceof MultipartTransactionAware) {
98 more = ((MultipartTransactionAware)transaction).isMoreReplies();
101 if (!isExpectedTransaction(transaction, more)) {
105 final TxIdEntry key = new TxIdEntry(transaction.getTransactionId());
106 if (more != null && more.booleanValue()) {
107 return txIdTotableIdMap.get(key);
109 return txIdTotableIdMap.remove(key);
113 public void recordExpectedTransaction(TransactionId id) {
114 TxIdEntry entry = new TxIdEntry(Preconditions.checkNotNull(id));
115 txIdToRequestTypeMap.put(entry, getExpiryTime());
118 private boolean isExpectedTransaction(TransactionAware transaction, Boolean more) {
119 final TxIdEntry entry = new TxIdEntry(transaction.getTransactionId());
120 if (more != null && more.booleanValue()) {
121 return txIdToRequestTypeMap.containsKey(entry);
123 return txIdToRequestTypeMap.remove(entry) != null;
127 public boolean isExpectedTransaction(TransactionAware transaction) {
129 if (transaction instanceof MultipartTransactionAware) {
130 more = ((MultipartTransactionAware)transaction).isMoreReplies();
133 return isExpectedTransaction(transaction, more);
136 private Long getExpiryTime() {
137 return System.nanoTime() + lifetimeNanos;
140 public void cleanStaleTransactionIds() {
141 final long now = System.nanoTime();
143 for (Iterator<TxIdEntry> it = txIdToRequestTypeMap.keySet().iterator();it.hasNext();){
144 TxIdEntry txIdEntry = it.next();
146 Long expiryTime = txIdToRequestTypeMap.get(txIdEntry);
147 if(now > expiryTime){
149 txIdTotableIdMap.remove(txIdEntry);