Add probes to DistributedIntentStore
Change-Id: I23a5823d3924392dc17166404a17fc1918c01453
diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/DistributedIntentStore.java b/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/DistributedIntentStore.java
index aa060a9..5974b62 100644
--- a/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/DistributedIntentStore.java
+++ b/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/DistributedIntentStore.java
@@ -15,6 +15,8 @@
*/
package org.onlab.onos.store.intent.impl;
+import com.codahale.metrics.Timer;
+import com.codahale.metrics.Timer.Context;
import com.google.common.base.Verify;
import com.google.common.collect.ImmutableSet;
@@ -24,6 +26,8 @@
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
+import org.onlab.metrics.MetricsService;
+import org.onlab.onos.core.MetricsHelper;
import org.onlab.onos.net.intent.Intent;
import org.onlab.onos.net.intent.IntentEvent;
import org.onlab.onos.net.intent.IntentId;
@@ -48,12 +52,13 @@
import static org.onlab.onos.net.intent.IntentState.*;
import static org.slf4j.LoggerFactory.getLogger;
+import static org.onlab.metrics.MetricsUtil.*;
@Component(immediate = true, enabled = true)
@Service
public class DistributedIntentStore
extends AbstractStore<IntentEvent, IntentStoreDelegate>
- implements IntentStore {
+ implements IntentStore, MetricsHelper {
/** Valid parking state, which can transition to INSTALLED. */
private static final Set<IntentState> PRE_INSTALLED = EnumSet.of(SUBMITTED, INSTALLED, FAILED);
@@ -81,11 +86,41 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DatabaseService dbService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected MetricsService metricsService;
+
// TODO make this configurable
private boolean onlyLogTransitionError = true;
+ private Timer createIntentTimer;
+ private Timer removeIntentTimer;
+ private Timer setInstallableIntentsTimer;
+ private Timer getInstallableIntentsTimer;
+ private Timer removeInstalledIntentsTimer;
+ private Timer setStateTimer;
+ private Timer getIntentCountTimer;
+ private Timer getIntentsTimer;
+ private Timer getIntentTimer;
+ private Timer getIntentStateTimer;
+
+
+ private Timer createResponseTimer(String methodName) {
+ return createTimer("IntentStore", methodName, "responseTime");
+ }
+
@Activate
public void activate() {
+ createIntentTimer = createResponseTimer("createIntent");
+ removeIntentTimer = createResponseTimer("removeIntent");
+ setInstallableIntentsTimer = createResponseTimer("setInstallableIntents");
+ getInstallableIntentsTimer = createResponseTimer("getInstallableIntents");
+ removeInstalledIntentsTimer = createResponseTimer("removeInstalledIntents");
+ setStateTimer = createResponseTimer("setState");
+ getIntentCountTimer = createResponseTimer("getIntentCount");
+ getIntentsTimer = createResponseTimer("getIntents");
+ getIntentTimer = createResponseTimer("getIntent");
+ getIntentStateTimer = createResponseTimer("getIntentState");
+
// FIXME: We need a way to add serializer for intents which has been plugged-in.
// As a short term workaround, relax Kryo config to
// registrationRequired=false
@@ -118,55 +153,91 @@
}
@Override
+ public MetricsService metricsService() {
+ return metricsService;
+ }
+
+ @Override
public IntentEvent createIntent(Intent intent) {
- boolean absent = intents.putIfAbsent(intent.id(), intent);
- if (!absent) {
- // duplicate, ignore
- return null;
- } else {
- return this.setState(intent, IntentState.SUBMITTED);
+ Context timer = startTimer(createIntentTimer);
+ try {
+ boolean absent = intents.putIfAbsent(intent.id(), intent);
+ if (!absent) {
+ // duplicate, ignore
+ return null;
+ } else {
+ return this.setState(intent, IntentState.SUBMITTED);
+ }
+ } finally {
+ stopTimer(timer);
}
}
@Override
public IntentEvent removeIntent(IntentId intentId) {
- Intent intent = intents.remove(intentId);
- installable.remove(intentId);
- if (intent == null) {
- // was already removed
- return null;
+ Context timer = startTimer(removeIntentTimer);
+ try {
+ Intent intent = intents.remove(intentId);
+ installable.remove(intentId);
+ if (intent == null) {
+ // was already removed
+ return null;
+ }
+ IntentEvent event = this.setState(intent, WITHDRAWN);
+ states.remove(intentId);
+ transientStates.remove(intentId);
+ // TODO: Should we callremoveInstalledIntents if this Intent was
+ return event;
+ } finally {
+ stopTimer(timer);
}
- IntentEvent event = this.setState(intent, WITHDRAWN);
- states.remove(intentId);
- transientStates.remove(intentId);
- // TODO: Should we callremoveInstalledIntents if this Intent was
- return event;
}
@Override
public long getIntentCount() {
- return intents.size();
+ Context timer = startTimer(getIntentCountTimer);
+ try {
+ return intents.size();
+ } finally {
+ stopTimer(timer);
+ }
}
@Override
public Iterable<Intent> getIntents() {
- return ImmutableSet.copyOf(intents.values());
+ Context timer = startTimer(getIntentsTimer);
+ try {
+ return ImmutableSet.copyOf(intents.values());
+ } finally {
+ stopTimer(timer);
+ }
}
@Override
public Intent getIntent(IntentId intentId) {
- return intents.get(intentId);
+ Context timer = startTimer(getIntentTimer);
+ try {
+ return intents.get(intentId);
+ } finally {
+ stopTimer(timer);
+ }
}
@Override
public IntentState getIntentState(IntentId id) {
- final IntentState localState = transientStates.get(id);
- if (localState != null) {
- return localState;
+ Context timer = startTimer(getIntentStateTimer);
+ try {
+ final IntentState localState = transientStates.get(id);
+ if (localState != null) {
+ return localState;
+ }
+ return states.get(id);
+ } finally {
+ stopTimer(timer);
}
- return states.get(id);
}
+ // FIXME temporary workaround until we fix our state machine
private void verify(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) {
if (onlyLogTransitionError) {
if (!expression) {
@@ -179,89 +250,109 @@
@Override
public IntentEvent setState(Intent intent, IntentState state) {
- final IntentId id = intent.id();
- IntentEvent.Type evtType = null;
- final IntentState prevParking;
- boolean transitionedToParking = true;
- boolean updated;
+ Context timer = startTimer(setStateTimer);
+ try {
+ final IntentId id = intent.id();
+ IntentEvent.Type evtType = null;
+ final IntentState prevParking;
+ boolean transitionedToParking = true;
+ boolean updated;
- // parking state transition
- switch (state) {
- case SUBMITTED:
- prevParking = states.get(id);
- if (prevParking == null) {
- updated = states.putIfAbsent(id, SUBMITTED);
- verify(updated, "Conditional replace %s => %s failed", prevParking, SUBMITTED);
- } else {
- verify(prevParking == WITHDRAWN,
- "Illegal state transition attempted from %s to SUBMITTED",
- prevParking);
- updated = states.replace(id, prevParking, SUBMITTED);
- verify(updated, "Conditional replace %s => %s failed", prevParking, SUBMITTED);
+ // parking state transition
+ switch (state) {
+ case SUBMITTED:
+ prevParking = states.get(id);
+ if (prevParking == null) {
+ updated = states.putIfAbsent(id, SUBMITTED);
+ verify(updated, "Conditional replace %s => %s failed", prevParking, SUBMITTED);
+ } else {
+ verify(prevParking == WITHDRAWN,
+ "Illegal state transition attempted from %s to SUBMITTED",
+ prevParking);
+ updated = states.replace(id, prevParking, SUBMITTED);
+ verify(updated, "Conditional replace %s => %s failed", prevParking, SUBMITTED);
+ }
+ evtType = IntentEvent.Type.SUBMITTED;
+ break;
+
+ case INSTALLED:
+ prevParking = states.get(id);
+ verify(PRE_INSTALLED.contains(prevParking),
+ "Illegal state transition attempted from %s to INSTALLED",
+ prevParking);
+ updated = states.replace(id, prevParking, INSTALLED);
+ verify(updated, "Conditional replace %s => %s failed", prevParking, INSTALLED);
+ evtType = IntentEvent.Type.INSTALLED;
+ break;
+
+ case FAILED:
+ prevParking = states.get(id);
+ updated = states.replace(id, prevParking, FAILED);
+ verify(updated, "Conditional replace %s => %s failed", prevParking, FAILED);
+ evtType = IntentEvent.Type.FAILED;
+ break;
+
+ case WITHDRAWN:
+ prevParking = states.get(id);
+ verify(PRE_WITHDRAWN.contains(prevParking),
+ "Illegal state transition attempted from %s to WITHDRAWN",
+ prevParking);
+ updated = states.replace(id, prevParking, WITHDRAWN);
+ verify(updated, "Conditional replace %s => %s failed", prevParking, WITHDRAWN);
+ evtType = IntentEvent.Type.WITHDRAWN;
+ break;
+
+ default:
+ transitionedToParking = false;
+ prevParking = null;
+ break;
}
- evtType = IntentEvent.Type.SUBMITTED;
- break;
+ if (transitionedToParking) {
+ log.debug("Parking State change: {} {}=>{}", id, prevParking, state);
+ // remove instance local state
+ transientStates.remove(id);
+ } else {
+ // Update instance local state, which includes non-parking state transition
+ final IntentState prevTransient = transientStates.put(id, state);
+ log.debug("Transient State change: {} {}=>{}", id, prevTransient, state);
+ }
- case INSTALLED:
- prevParking = states.get(id);
- verify(PRE_INSTALLED.contains(prevParking),
- "Illegal state transition attempted from %s to INSTALLED",
- prevParking);
- updated = states.replace(id, prevParking, INSTALLED);
- verify(updated, "Conditional replace %s => %s failed", prevParking, INSTALLED);
- evtType = IntentEvent.Type.INSTALLED;
- break;
-
- case FAILED:
- prevParking = states.get(id);
- updated = states.replace(id, prevParking, FAILED);
- verify(updated, "Conditional replace %s => %s failed", prevParking, FAILED);
- evtType = IntentEvent.Type.FAILED;
- break;
-
- case WITHDRAWN:
- prevParking = states.get(id);
- verify(PRE_WITHDRAWN.contains(prevParking),
- "Illegal state transition attempted from %s to WITHDRAWN",
- prevParking);
- updated = states.replace(id, prevParking, WITHDRAWN);
- verify(updated, "Conditional replace %s => %s failed", prevParking, WITHDRAWN);
- evtType = IntentEvent.Type.WITHDRAWN;
- break;
-
- default:
- transitionedToParking = false;
- prevParking = null;
- break;
+ if (evtType == null) {
+ return null;
+ }
+ return new IntentEvent(evtType, intent);
+ } finally {
+ stopTimer(timer);
}
- if (transitionedToParking) {
- log.debug("Parking State change: {} {}=>{}", id, prevParking, state);
- // remove instance local state
- transientStates.remove(id);
- } else {
- // Update instance local state, which includes non-parking state transition
- final IntentState prevTransient = transientStates.put(id, state);
- log.debug("Transient State change: {} {}=>{}", id, prevTransient, state);
- }
-
- if (evtType == null) {
- return null;
- }
- return new IntentEvent(evtType, intent);
}
@Override
public void setInstallableIntents(IntentId intentId, List<Intent> result) {
- installable.put(intentId, result);
+ Context timer = startTimer(setInstallableIntentsTimer);
+ try {
+ installable.put(intentId, result);
+ } finally {
+ stopTimer(timer);
+ }
}
@Override
public List<Intent> getInstallableIntents(IntentId intentId) {
- return installable.get(intentId);
+ Context timer = startTimer(getInstallableIntentsTimer);
+ try {
+ return installable.get(intentId);
+ } finally {
+ stopTimer(timer);
+ }
}
@Override
public void removeInstalledIntents(IntentId intentId) {
- installable.remove(intentId);
+ Context timer = startTimer(removeInstalledIntentsTimer);
+ try {
+ installable.remove(intentId);
+ } finally {
+ stopTimer(timer);
+ }
}
}
diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/HazelcastIntentStore.java b/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/HazelcastIntentStore.java
index 1cde0c9..001ab7e 100644
--- a/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/HazelcastIntentStore.java
+++ b/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/HazelcastIntentStore.java
@@ -15,6 +15,8 @@
*/
package org.onlab.onos.store.intent.impl;
+import com.codahale.metrics.Timer;
+import com.codahale.metrics.Timer.Context;
import com.google.common.base.Verify;
import com.google.common.collect.ImmutableSet;
import com.hazelcast.core.EntryAdapter;
@@ -26,7 +28,11 @@
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
+import org.onlab.metrics.MetricsService;
+import org.onlab.onos.core.MetricsHelper;
import org.onlab.onos.net.intent.Intent;
import org.onlab.onos.net.intent.IntentEvent;
import org.onlab.onos.net.intent.IntentId;
@@ -48,12 +54,13 @@
import static org.onlab.onos.net.intent.IntentState.*;
import static org.slf4j.LoggerFactory.getLogger;
+import static org.onlab.metrics.MetricsUtil.*;
@Component(immediate = true, enabled = false)
@Service
public class HazelcastIntentStore
extends AbstractHazelcastStore<IntentEvent, IntentStoreDelegate>
- implements IntentStore {
+ implements IntentStore, MetricsHelper {
/** Valid parking state, which can transition to INSTALLED. */
private static final Set<IntentState> PRE_INSTALLED = EnumSet.of(SUBMITTED, INSTALLED, FAILED);
@@ -72,12 +79,41 @@
private SMap<IntentId, List<Intent>> installable;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected MetricsService metricsService;
+
// TODO make this configurable
private boolean onlyLogTransitionError = true;
+ private Timer createIntentTimer;
+ private Timer removeIntentTimer;
+ private Timer setInstallableIntentsTimer;
+ private Timer getInstallableIntentsTimer;
+ private Timer removeInstalledIntentsTimer;
+ private Timer setStateTimer;
+ private Timer getIntentCountTimer;
+ private Timer getIntentsTimer;
+ private Timer getIntentTimer;
+ private Timer getIntentStateTimer;
+
+ private Timer createResponseTimer(String methodName) {
+ return createTimer("IntentStore", methodName, "responseTime");
+ }
+
@Override
@Activate
public void activate() {
+ createIntentTimer = createResponseTimer("createIntent");
+ removeIntentTimer = createResponseTimer("removeIntent");
+ setInstallableIntentsTimer = createResponseTimer("setInstallableIntents");
+ getInstallableIntentsTimer = createResponseTimer("getInstallableIntents");
+ removeInstalledIntentsTimer = createResponseTimer("removeInstalledIntents");
+ setStateTimer = createResponseTimer("setState");
+ getIntentCountTimer = createResponseTimer("getIntentCount");
+ getIntentsTimer = createResponseTimer("getIntents");
+ getIntentTimer = createResponseTimer("getIntent");
+ getIntentStateTimer = createResponseTimer("getIntentState");
+
// FIXME: We need a way to add serializer for intents which has been plugged-in.
// As a short term workaround, relax Kryo config to
// registrationRequired=false
@@ -120,53 +156,88 @@
}
@Override
+ public MetricsService metricsService() {
+ return metricsService;
+ }
+
+ @Override
public IntentEvent createIntent(Intent intent) {
- Intent existing = intents.putIfAbsent(intent.id(), intent);
- if (existing != null) {
- // duplicate, ignore
- return null;
- } else {
- return this.setState(intent, IntentState.SUBMITTED);
+ Context timer = startTimer(createIntentTimer);
+ try {
+ Intent existing = intents.putIfAbsent(intent.id(), intent);
+ if (existing != null) {
+ // duplicate, ignore
+ return null;
+ } else {
+ return this.setState(intent, IntentState.SUBMITTED);
+ }
+ } finally {
+ stopTimer(timer);
}
}
@Override
public IntentEvent removeIntent(IntentId intentId) {
- Intent intent = intents.remove(intentId);
- installable.remove(intentId);
- if (intent == null) {
- // was already removed
- return null;
+ Context timer = startTimer(removeIntentTimer);
+ try {
+ Intent intent = intents.remove(intentId);
+ installable.remove(intentId);
+ if (intent == null) {
+ // was already removed
+ return null;
+ }
+ IntentEvent event = this.setState(intent, WITHDRAWN);
+ states.remove(intentId);
+ transientStates.remove(intentId);
+ // TODO: Should we callremoveInstalledIntents if this Intent was
+ return event;
+ } finally {
+ stopTimer(timer);
}
- IntentEvent event = this.setState(intent, WITHDRAWN);
- states.remove(intentId);
- transientStates.remove(intentId);
- // TODO: Should we callremoveInstalledIntents if this Intent was
- return event;
}
@Override
public long getIntentCount() {
- return intents.size();
+ Context timer = startTimer(getIntentCountTimer);
+ try {
+ return intents.size();
+ } finally {
+ stopTimer(timer);
+ }
}
@Override
public Iterable<Intent> getIntents() {
- return ImmutableSet.copyOf(intents.values());
+ Context timer = startTimer(getIntentsTimer);
+ try {
+ return ImmutableSet.copyOf(intents.values());
+ } finally {
+ stopTimer(timer);
+ }
}
@Override
public Intent getIntent(IntentId intentId) {
- return intents.get(intentId);
+ Context timer = startTimer(getIntentTimer);
+ try {
+ return intents.get(intentId);
+ } finally {
+ stopTimer(timer);
+ }
}
@Override
public IntentState getIntentState(IntentId id) {
- final IntentState localState = transientStates.get(id);
- if (localState != null) {
- return localState;
+ Context timer = startTimer(getIntentStateTimer);
+ try {
+ final IntentState localState = transientStates.get(id);
+ if (localState != null) {
+ return localState;
+ }
+ return states.get(id);
+ } finally {
+ stopTimer(timer);
}
- return states.get(id);
}
private void verify(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) {
@@ -181,76 +252,97 @@
@Override
public IntentEvent setState(Intent intent, IntentState state) {
- final IntentId id = intent.id();
- IntentEvent.Type type = null;
- final IntentState prevParking;
- boolean transientStateChangeOnly = false;
+ Context timer = startTimer(setStateTimer);
+ try {
- // parking state transition
- switch (state) {
- case SUBMITTED:
- prevParking = states.get(id);
- if (prevParking == null) {
- IntentState existing = states.putIfAbsent(id, SUBMITTED);
- verify(existing == null, "Conditional replace %s => %s failed", prevParking, SUBMITTED);
- } else {
- verify(prevParking == WITHDRAWN,
- "Illegal state transition attempted from %s to SUBMITTED",
- prevParking);
- boolean updated = states.replace(id, prevParking, SUBMITTED);
- verify(updated, "Conditional replace %s => %s failed", prevParking, SUBMITTED);
+ final IntentId id = intent.id();
+ IntentEvent.Type type = null;
+ final IntentState prevParking;
+ boolean transientStateChangeOnly = false;
+
+ // parking state transition
+ switch (state) {
+ case SUBMITTED:
+ prevParking = states.get(id);
+ if (prevParking == null) {
+ IntentState existing = states.putIfAbsent(id, SUBMITTED);
+ verify(existing == null, "Conditional replace %s => %s failed", prevParking, SUBMITTED);
+ } else {
+ verify(prevParking == WITHDRAWN,
+ "Illegal state transition attempted from %s to SUBMITTED",
+ prevParking);
+ boolean updated = states.replace(id, prevParking, SUBMITTED);
+ verify(updated, "Conditional replace %s => %s failed", prevParking, SUBMITTED);
+ }
+ type = IntentEvent.Type.SUBMITTED;
+ break;
+ case INSTALLED:
+ prevParking = states.replace(id, INSTALLED);
+ verify(PRE_INSTALLED.contains(prevParking),
+ "Illegal state transition attempted from %s to INSTALLED",
+ prevParking);
+ type = IntentEvent.Type.INSTALLED;
+ break;
+ case FAILED:
+ prevParking = states.replace(id, FAILED);
+ type = IntentEvent.Type.FAILED;
+ break;
+ case WITHDRAWN:
+ prevParking = states.replace(id, WITHDRAWN);
+ verify(PRE_WITHDRAWN.contains(prevParking),
+ "Illegal state transition attempted from %s to WITHDRAWN",
+ prevParking);
+ type = IntentEvent.Type.WITHDRAWN;
+ break;
+ default:
+ transientStateChangeOnly = true;
+ prevParking = null;
+ break;
}
- type = IntentEvent.Type.SUBMITTED;
- break;
- case INSTALLED:
- prevParking = states.replace(id, INSTALLED);
- verify(PRE_INSTALLED.contains(prevParking),
- "Illegal state transition attempted from %s to INSTALLED",
- prevParking);
- type = IntentEvent.Type.INSTALLED;
- break;
- case FAILED:
- prevParking = states.replace(id, FAILED);
- type = IntentEvent.Type.FAILED;
- break;
- case WITHDRAWN:
- prevParking = states.replace(id, WITHDRAWN);
- verify(PRE_WITHDRAWN.contains(prevParking),
- "Illegal state transition attempted from %s to WITHDRAWN",
- prevParking);
- type = IntentEvent.Type.WITHDRAWN;
- break;
- default:
- transientStateChangeOnly = true;
- prevParking = null;
- break;
- }
- if (!transientStateChangeOnly) {
- log.debug("Parking State change: {} {}=>{}", id, prevParking, state);
- }
- // Update instance local state, which includes non-parking state transition
- final IntentState prevTransient = transientStates.put(id, state);
- log.debug("Transient State change: {} {}=>{}", id, prevTransient, state);
+ if (!transientStateChangeOnly) {
+ log.debug("Parking State change: {} {}=>{}", id, prevParking, state);
+ }
+ // Update instance local state, which includes non-parking state transition
+ final IntentState prevTransient = transientStates.put(id, state);
+ log.debug("Transient State change: {} {}=>{}", id, prevTransient, state);
- if (type == null) {
- return null;
+ if (type == null) {
+ return null;
+ }
+ return new IntentEvent(type, intent);
+ } finally {
+ stopTimer(timer);
}
- return new IntentEvent(type, intent);
}
@Override
public void setInstallableIntents(IntentId intentId, List<Intent> result) {
- installable.put(intentId, result);
+ Context timer = startTimer(setInstallableIntentsTimer);
+ try {
+ installable.put(intentId, result);
+ } finally {
+ stopTimer(timer);
+ }
}
@Override
public List<Intent> getInstallableIntents(IntentId intentId) {
- return installable.get(intentId);
+ Context timer = startTimer(getInstallableIntentsTimer);
+ try {
+ return installable.get(intentId);
+ } finally {
+ stopTimer(timer);
+ }
}
@Override
public void removeInstalledIntents(IntentId intentId) {
- installable.remove(intentId);
+ Context timer = startTimer(removeInstalledIntentsTimer);
+ try {
+ installable.remove(intentId);
+ } finally {
+ stopTimer(timer);
+ }
}
public final class RemoteIntentStateListener extends EntryAdapter<IntentId, IntentState> {