Yuta HIGUCHI
Committed by Yuta Higuchi

Add probes to DistributedIntentStore

Change-Id: I23a5823d3924392dc17166404a17fc1918c01453
......@@ -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.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 +52,13 @@ import java.util.concurrent.ConcurrentHashMap;
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 @@ public class DistributedIntentStore
@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,7 +153,14 @@ public class DistributedIntentStore
}
@Override
public MetricsService metricsService() {
return metricsService;
}
@Override
public IntentEvent createIntent(Intent intent) {
Context timer = startTimer(createIntentTimer);
try {
boolean absent = intents.putIfAbsent(intent.id(), intent);
if (!absent) {
// duplicate, ignore
......@@ -126,10 +168,15 @@ public class DistributedIntentStore
} else {
return this.setState(intent, IntentState.SUBMITTED);
}
} finally {
stopTimer(timer);
}
}
@Override
public IntentEvent removeIntent(IntentId intentId) {
Context timer = startTimer(removeIntentTimer);
try {
Intent intent = intents.remove(intentId);
installable.remove(intentId);
if (intent == null) {
......@@ -141,32 +188,56 @@ public class DistributedIntentStore
transientStates.remove(intentId);
// TODO: Should we callremoveInstalledIntents if this Intent was
return event;
} finally {
stopTimer(timer);
}
}
@Override
public long getIntentCount() {
Context timer = startTimer(getIntentCountTimer);
try {
return intents.size();
} finally {
stopTimer(timer);
}
}
@Override
public Iterable<Intent> getIntents() {
Context timer = startTimer(getIntentsTimer);
try {
return ImmutableSet.copyOf(intents.values());
} finally {
stopTimer(timer);
}
}
@Override
public Intent getIntent(IntentId intentId) {
Context timer = startTimer(getIntentTimer);
try {
return intents.get(intentId);
} finally {
stopTimer(timer);
}
}
@Override
public IntentState getIntentState(IntentId id) {
Context timer = startTimer(getIntentStateTimer);
try {
final IntentState localState = transientStates.get(id);
if (localState != null) {
return localState;
}
return states.get(id);
} finally {
stopTimer(timer);
}
}
// FIXME temporary workaround until we fix our state machine
private void verify(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) {
if (onlyLogTransitionError) {
if (!expression) {
......@@ -179,6 +250,8 @@ public class DistributedIntentStore
@Override
public IntentEvent setState(Intent intent, IntentState state) {
Context timer = startTimer(setStateTimer);
try {
final IntentId id = intent.id();
IntentEvent.Type evtType = null;
final IntentState prevParking;
......@@ -248,20 +321,38 @@ public class DistributedIntentStore
return null;
}
return new IntentEvent(evtType, intent);
} finally {
stopTimer(timer);
}
}
@Override
public void setInstallableIntents(IntentId intentId, List<Intent> result) {
Context timer = startTimer(setInstallableIntentsTimer);
try {
installable.put(intentId, result);
} finally {
stopTimer(timer);
}
}
@Override
public List<Intent> getInstallableIntents(IntentId intentId) {
Context timer = startTimer(getInstallableIntentsTimer);
try {
return installable.get(intentId);
} finally {
stopTimer(timer);
}
}
@Override
public void removeInstalledIntents(IntentId intentId) {
Context timer = startTimer(removeInstalledIntentsTimer);
try {
installable.remove(intentId);
} finally {
stopTimer(timer);
}
}
}
......
......@@ -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 com.hazelcast.core.Member;
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 java.util.concurrent.ConcurrentHashMap;
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 @@ public class HazelcastIntentStore
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,7 +156,14 @@ public class HazelcastIntentStore
}
@Override
public MetricsService metricsService() {
return metricsService;
}
@Override
public IntentEvent createIntent(Intent intent) {
Context timer = startTimer(createIntentTimer);
try {
Intent existing = intents.putIfAbsent(intent.id(), intent);
if (existing != null) {
// duplicate, ignore
......@@ -128,10 +171,15 @@ public class HazelcastIntentStore
} else {
return this.setState(intent, IntentState.SUBMITTED);
}
} finally {
stopTimer(timer);
}
}
@Override
public IntentEvent removeIntent(IntentId intentId) {
Context timer = startTimer(removeIntentTimer);
try {
Intent intent = intents.remove(intentId);
installable.remove(intentId);
if (intent == null) {
......@@ -143,30 +191,53 @@ public class HazelcastIntentStore
transientStates.remove(intentId);
// TODO: Should we callremoveInstalledIntents if this Intent was
return event;
} finally {
stopTimer(timer);
}
}
@Override
public long getIntentCount() {
Context timer = startTimer(getIntentCountTimer);
try {
return intents.size();
} finally {
stopTimer(timer);
}
}
@Override
public Iterable<Intent> getIntents() {
Context timer = startTimer(getIntentsTimer);
try {
return ImmutableSet.copyOf(intents.values());
} finally {
stopTimer(timer);
}
}
@Override
public Intent getIntent(IntentId intentId) {
Context timer = startTimer(getIntentTimer);
try {
return intents.get(intentId);
} finally {
stopTimer(timer);
}
}
@Override
public IntentState getIntentState(IntentId id) {
Context timer = startTimer(getIntentStateTimer);
try {
final IntentState localState = transientStates.get(id);
if (localState != null) {
return localState;
}
return states.get(id);
} finally {
stopTimer(timer);
}
}
private void verify(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) {
......@@ -181,6 +252,9 @@ public class HazelcastIntentStore
@Override
public IntentEvent setState(Intent intent, IntentState state) {
Context timer = startTimer(setStateTimer);
try {
final IntentId id = intent.id();
IntentEvent.Type type = null;
final IntentState prevParking;
......@@ -236,21 +310,39 @@ public class HazelcastIntentStore
return null;
}
return new IntentEvent(type, intent);
} finally {
stopTimer(timer);
}
}
@Override
public void setInstallableIntents(IntentId intentId, List<Intent> result) {
Context timer = startTimer(setInstallableIntentsTimer);
try {
installable.put(intentId, result);
} finally {
stopTimer(timer);
}
}
@Override
public List<Intent> getInstallableIntents(IntentId intentId) {
Context timer = startTimer(getInstallableIntentsTimer);
try {
return installable.get(intentId);
} finally {
stopTimer(timer);
}
}
@Override
public void removeInstalledIntents(IntentId intentId) {
Context timer = startTimer(removeInstalledIntentsTimer);
try {
installable.remove(intentId);
} finally {
stopTimer(timer);
}
}
public final class RemoteIntentStateListener extends EntryAdapter<IntentId, IntentState> {
......