alshabib

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

Showing 96 changed files with 1731 additions and 441 deletions
......@@ -184,13 +184,13 @@ public class ReactiveForwarding {
// Install the flow rule to handle this type of message from now on.
Ethernet inPkt = context.inPacket().parsed();
TrafficSelector.Builder builder = new DefaultTrafficSelector.Builder();
TrafficSelector.Builder builder = DefaultTrafficSelector.builder();
builder.matchEthType(inPkt.getEtherType())
.matchEthSrc(inPkt.getSourceMAC())
.matchEthDst(inPkt.getDestinationMAC())
.matchInport(context.inPacket().receivedFrom().port());
TrafficTreatment.Builder treat = new DefaultTrafficTreatment.Builder();
TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder();
treat.setOutput(portNumber);
FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(),
......
package org.onlab.onos.cli.net;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.net.HostId;
import org.onlab.onos.net.flow.DefaultTrafficSelector;
import org.onlab.onos.net.flow.DefaultTrafficTreatment;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.net.host.HostService;
import org.onlab.onos.net.intent.HostToHostIntent;
import org.onlab.onos.net.intent.IntentId;
import org.onlab.onos.net.intent.IntentService;
/**
* Lists all shortest-paths paths between the specified source and
* destination devices.
*/
@Command(scope = "onos", name = "add-intent",
description = "Installs HostToHostIntent between the specified source and destination devices")
public class IntentInstallCommand extends AbstractShellCommand {
@Argument(index = 0, name = "src", description = "Source device ID",
required = true, multiValued = false)
String src = null;
@Argument(index = 1, name = "dst", description = "Destination device ID",
required = true, multiValued = false)
String dst = null;
private static long id = 1;
@Override
protected void execute() {
IntentService service = get(IntentService.class);
HostService hosts = get(HostService.class);
HostId srcId = HostId.hostId(src);
HostId dstId = HostId.hostId(dst);
TrafficSelector.Builder builder = DefaultTrafficSelector.builder();
builder.matchEthSrc(hosts.getHost(srcId).mac())
.matchEthDst(hosts.getHost(dstId).mac());
TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder();
HostToHostIntent intent =
new HostToHostIntent(new IntentId(id++), srcId, dstId,
builder.build(), treat.build());
log.info("Adding intent {}", intent);
service.submit(intent);
}
}
......@@ -57,6 +57,13 @@
</completers>
</command>
<command>
<action class="org.onlab.onos.cli.net.IntentInstallCommand"/>
<completers>
<ref component-id="hostIdCompleter"/>
</completers>
</command>
<command>
<action class="org.onlab.onos.cli.net.ClustersListCommand"/>
</command>
<command>
......
......@@ -18,9 +18,9 @@ public class DefaultEdgeLink extends DefaultLink implements EdgeLink {
* @param providerId provider identity
* @param hostPoint host-side connection point
* @param hostLocation location where host attaches to the network
* @param isIngress true to indicated host-to-network direction; false
* @param isIngress true to indicate host-to-network direction; false
* for network-to-host direction
* @param annotations optional key/value annotations
* @param annotations optional key/value annotations
*/
public DefaultEdgeLink(ProviderId providerId, ConnectPoint hostPoint,
HostLocation hostLocation, boolean isIngress,
......@@ -42,4 +42,20 @@ public class DefaultEdgeLink extends DefaultLink implements EdgeLink {
public HostLocation hostLocation() {
return hostLocation;
}
/**
* Creates a phantom edge link, to an unspecified end-station. This link
* does not represent any actually discovered link stored in the system.
*
* @param edgePort network edge port
* @param isIngress true to indicate host-to-network direction; false
* for network-to-host direction
* @return new phantom edge link
*/
public static DefaultEdgeLink createEdgeLink(HostLocation edgePort,
boolean isIngress) {
return new DefaultEdgeLink(ProviderId.NONE,
new ConnectPoint(HostId.NONE, PortNumber.P0),
edgePort, isIngress);
}
}
......
......@@ -10,6 +10,14 @@ import java.net.URI;
*/
public final class HostId extends ElementId {
private static final String NIC = "nic";
/**
* Represents either no host, or an unspecified host; used for creating
* open ingress/egress edge links.
*/
public static final HostId NONE = hostId(NIC + ":none-0");
// Public construction is prohibited
private HostId(URI uri) {
super(uri);
......@@ -43,8 +51,7 @@ public final class HostId extends ElementId {
* @return host identifier
*/
public static HostId hostId(MacAddress mac, VlanId vlanId) {
// FIXME: use more efficient means of encoding
return hostId("nic" + ":" + mac + "-" + vlanId);
return hostId(NIC + ":" + mac + "-" + vlanId);
}
/**
......
......@@ -9,6 +9,8 @@ import com.google.common.primitives.UnsignedLongs;
*/
public final class PortNumber {
public static final PortNumber P0 = portNumber(0);
// TODO: revisit the max and the logical port value assignments
private static final long MAX_NUMBER = (2L * Integer.MAX_VALUE) + 1;
......
package org.onlab.onos.net.flow;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import com.google.common.collect.ImmutableSet;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.flow.criteria.Criteria;
import org.onlab.onos.net.flow.criteria.Criterion;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.slf4j.Logger;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
* Default traffic selector implementation.
*/
public final class DefaultTrafficSelector implements TrafficSelector {
private final Set<Criterion> selector;
private final Set<Criterion> criteria;
private DefaultTrafficSelector(Set<Criterion> selector) {
this.selector = Collections.unmodifiableSet(selector);
/**
* Creates a new traffic selector with the specified criteria.
*
* @param criteria criteria
*/
private DefaultTrafficSelector(Set<Criterion> criteria) {
this.criteria = Collections.unmodifiableSet(criteria);
}
@Override
public Set<Criterion> criteria() {
return selector;
return criteria;
}
@Override
public int hashCode() {
return Objects.hash(selector);
return Objects.hash(criteria);
}
@Override
......@@ -40,23 +47,50 @@ public final class DefaultTrafficSelector implements TrafficSelector {
}
if (obj instanceof DefaultTrafficSelector) {
DefaultTrafficSelector that = (DefaultTrafficSelector) obj;
return Objects.equals(selector, that.selector);
return Objects.equals(criteria, that.criteria);
}
return false;
}
/**
* Returns a new traffic selector builder.
*
* @return traffic selector builder
*/
public static TrafficSelector.Builder builder() {
return new Builder();
}
/**
* Returns a new traffic selector builder primed to produce entities
* patterned after the supplied selector.
*
* @return traffic selector builder
*/
public static TrafficSelector.Builder builder(TrafficSelector selector) {
return new Builder(selector);
}
public static class Builder implements TrafficSelector.Builder {
/**
* Builder of traffic selector entities.
*/
public static final class Builder implements TrafficSelector.Builder {
private final Logger log = getLogger(getClass());
private final Map<Criterion.Type, Criterion> selector = new HashMap<>();
private final Set<Criterion> selector = new HashSet<>();
private Builder() {
}
private Builder(TrafficSelector selector) {
for (Criterion c : selector.criteria()) {
add(c);
}
}
@Override
public Builder add(Criterion criterion) {
selector.add(criterion);
selector.put(criterion.type(), criterion);
return this;
}
......@@ -107,7 +141,7 @@ public final class DefaultTrafficSelector implements TrafficSelector {
@Override
public TrafficSelector build() {
return new DefaultTrafficSelector(selector);
return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values()));
}
}
......
package org.onlab.onos.net.flow;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.flow.instructions.Instruction;
import org.onlab.onos.net.flow.instructions.Instructions;
......@@ -14,10 +8,24 @@ import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.slf4j.Logger;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Default traffic treatment implementation.
*/
public final class DefaultTrafficTreatment implements TrafficTreatment {
private final List<Instruction> instructions;
/**
* Creates a new traffic treatment from the specified list of instructions.
*
* @param instructions treatment instructions
*/
private DefaultTrafficTreatment(List<Instruction> instructions) {
this.instructions = Collections.unmodifiableList(instructions);
}
......@@ -28,12 +36,19 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
}
/**
* Builds a list of treatments following the following order.
* Modifications -> Group -> Output (including drop)
* Returns a new traffic treatment builder.
*
* @return traffic treatment builder
*/
public static TrafficTreatment.Builder builder() {
return new Builder();
}
public static class Builder implements TrafficTreatment.Builder {
/**
* Builds a list of treatments following the following order.
* Modifications -> Group -> Output (including drop)
*/
public static final class Builder implements TrafficTreatment.Builder {
private final Logger log = getLogger(getClass());
......@@ -47,27 +62,31 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
// TODO: should be a list of instructions based on modification objects
List<Instruction> modifications = new LinkedList<>();
// Creates a new builder
private Builder() {
}
public Builder add(Instruction instruction) {
if (drop) {
return this;
}
switch (instruction.type()) {
case DROP:
drop = true;
break;
case OUTPUT:
outputs.add(instruction);
break;
case L2MODIFICATION:
case L3MODIFICATION:
// TODO: enforce modification order if any
modifications.add(instruction);
break;
case GROUP:
groups.add(instruction);
break;
default:
log.warn("Unknown instruction type {}", instruction.type());
case DROP:
drop = true;
break;
case OUTPUT:
outputs.add(instruction);
break;
case L2MODIFICATION:
case L3MODIFICATION:
// TODO: enforce modification order if any
modifications.add(instruction);
break;
case GROUP:
groups.add(instruction);
break;
default:
log.warn("Unknown instruction type {}", instruction.type());
}
return this;
}
......
package org.onlab.onos.net.intent;
//TODO is this the right package?
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A list of BatchOperationEntry.
*
* @param <T> the enum of operators <br>
* This enum must be defined in each sub-classes.
*
* This enum must be defined in each sub-classes.
*/
public abstract class BatchOperation<T extends BatchOperationEntry<?, ?>> {
private List<T> ops;
/**
......
package org.onlab.onos.net.intent;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Objects;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import com.google.common.base.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Abstraction of connectivity intent for traffic matching some criteria.
......@@ -26,17 +25,18 @@ public abstract class ConnectivityIntent extends AbstractIntent {
/**
* Creates a connectivity intent that matches on the specified intent
* and applies the specified action.
* and applies the specified treatement.
*
* @param id intent identifier
* @param match traffic match
* @param action action
* @throws NullPointerException if the match or action is null
* @param intentId intent identifier
* @param selector traffic selector
* @param treatement treatement
* @throws NullPointerException if the selector or treatement is null
*/
protected ConnectivityIntent(IntentId id, TrafficSelector match, TrafficTreatment action) {
super(id);
this.selector = checkNotNull(match);
this.treatment = checkNotNull(action);
protected ConnectivityIntent(IntentId intentId, TrafficSelector selector,
TrafficTreatment treatement) {
super(intentId);
this.selector = checkNotNull(selector);
this.treatment = checkNotNull(treatement);
}
/**
......
package org.onlab.onos.net.intent;
import com.google.common.base.MoreObjects;
import org.onlab.onos.net.HostId;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Abstraction of end-station to end-station connectivity.
*/
public class HostToHostIntent extends ConnectivityIntent {
private final HostId src;
private final HostId dst;
/**
* Creates a new point-to-point intent with the supplied ingress/egress
* ports.
*
* @param intentId intent identifier
* @param selector action
* @param treatment ingress port
* @throws NullPointerException if {@code ingressPort} or {@code egressPort}
* is null.
*/
public HostToHostIntent(IntentId intentId, HostId src, HostId dst,
TrafficSelector selector, TrafficTreatment treatment) {
super(intentId, selector, treatment);
this.src = checkNotNull(src);
this.dst = checkNotNull(dst);
}
/**
* Returns the port on which the ingress traffic should be connected to the
* egress.
*
* @return ingress port
*/
public HostId getSrc() {
return src;
}
/**
* Returns the port on which the traffic should egress.
*
* @return egress port
*/
public HostId getDst() {
return dst;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (!super.equals(o)) {
return false;
}
HostToHostIntent that = (HostToHostIntent) o;
return Objects.equals(this.src, that.src)
&& Objects.equals(this.dst, that.dst);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), src, dst);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("id", getId())
.add("selector", getTrafficSelector())
.add("treatmetn", getTrafficTreatment())
.add("src", src)
.add("dst", dst)
.toString();
}
}
......@@ -2,7 +2,7 @@ package org.onlab.onos.net.intent;
/**
* Abstraction of an application level intent.
*
* <p/>
* Make sure that an Intent should be immutable when a new type is defined.
*/
public interface Intent extends BatchOperationTarget {
......
package org.onlab.onos.net.intent;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.MoreObjects;
import org.onlab.onos.event.AbstractEvent;
import java.util.Objects;
import com.google.common.base.MoreObjects;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A class to represent an intent related event.
*/
public class IntentEvent {
public class IntentEvent extends AbstractEvent<IntentState, Intent> {
// TODO: determine a suitable parent class; if one does not exist, consider introducing one
// TODO: determine a suitable parent class; if one does not exist, consider
// introducing one
private final long time;
private final Intent intent;
......@@ -21,13 +23,14 @@ public class IntentEvent {
/**
* Creates an event describing a state change of an intent.
*
* @param intent subject intent
* @param state new intent state
* @param intent subject intent
* @param state new intent state
* @param previous previous intent state
* @param time time the event created in milliseconds since start of epoch
* @param time time the event created in milliseconds since start of epoch
* @throws NullPointerException if the intent or state is null
*/
public IntentEvent(Intent intent, IntentState state, IntentState previous, long time) {
super(state, intent);
this.intent = checkNotNull(intent);
this.state = checkNotNull(state);
this.previous = previous;
......@@ -35,16 +38,6 @@ public class IntentEvent {
}
/**
* Constructor for serializer.
*/
protected IntentEvent() {
this.intent = null;
this.state = null;
this.previous = null;
this.time = 0;
}
/**
* Returns the state of the intent which caused the event.
*
* @return the state of the intent
......
......@@ -26,7 +26,7 @@ public class IntentException extends RuntimeException {
* Constructs an exception with the specified message and the underlying cause.
*
* @param message the message describing the specific nature of the error
* @param cause the underlying cause of this error
* @param cause the underlying cause of this error
*/
public IntentException(String message, Throwable cause) {
super(message, cause);
......
......@@ -10,9 +10,9 @@ public interface IntentExtensionService {
/**
* Registers the specified compiler for the given intent class.
*
* @param cls intent class
* @param cls intent class
* @param compiler intent compiler
* @param <T> the type of intent
* @param <T> the type of intent
*/
<T extends Intent> void registerCompiler(Class<T> cls, IntentCompiler<T> compiler);
......@@ -34,9 +34,9 @@ public interface IntentExtensionService {
/**
* Registers the specified installer for the given installable intent class.
*
* @param cls installable intent class
* @param cls installable intent class
* @param installer intent installer
* @param <T> the type of installable intent
* @param <T> the type of installable intent
*/
<T extends InstallableIntent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer);
......
......@@ -2,7 +2,7 @@ package org.onlab.onos.net.intent;
/**
* Intent identifier suitable as an external key.
*
* <p/>
* This class is immutable.
*/
public final class IntentId implements BatchOperationTarget {
......
package org.onlab.onos.net.intent;
import org.onlab.onos.event.EventListener;
/**
* Listener for {@link IntentEvent intent events}.
*/
public interface IntentEventListener {
/**
* Processes the specified intent event.
*
* @param event the event to process
*/
void event(IntentEvent event);
public interface IntentListener extends EventListener<IntentEvent> {
}
......
package org.onlab.onos.net.intent;
import java.util.Set;
/**
* Service for application submitting or withdrawing their intents.
......@@ -8,9 +7,9 @@ import java.util.Set;
public interface IntentService {
/**
* Submits an intent into the system.
*
* This is an asynchronous request meaning that any compiling
* or installation activities may be done at later time.
* <p/>
* This is an asynchronous request meaning that any compiling or
* installation activities may be done at later time.
*
* @param intent intent to be submitted
*/
......@@ -18,9 +17,9 @@ public interface IntentService {
/**
* Withdraws an intent from the system.
*
* This is an asynchronous request meaning that the environment
* may be affected at later time.
* <p/>
* This is an asynchronous request meaning that the environment may be
* affected at later time.
*
* @param intent intent to be withdrawn
*/
......@@ -29,20 +28,27 @@ public interface IntentService {
/**
* Submits a batch of submit &amp; withdraw operations. Such a batch is
* assumed to be processed together.
*
* This is an asynchronous request meaning that the environment
* may be affected at later time.
* <p/>
* This is an asynchronous request meaning that the environment may be
* affected at later time.
*
* @param operations batch of intent operations
*/
void execute(IntentOperations operations);
/**
* Returns immutable set of intents currently in the system.
* Returns an iterable of intents currently in the system.
*
* @return set of intents
*/
Set<Intent> getIntents();
Iterable<Intent> getIntents();
/**
* Returns the number of intents currently in the system.
*
* @return number of intents
*/
long getIntentCount();
/**
* Retrieves the intent specified by its identifier.
......@@ -56,7 +62,8 @@ public interface IntentService {
* Retrieves the state of an intent by its identifier.
*
* @param id intent identifier
* @return the intent state or null if one with the given identifier is not found
* @return the intent state or null if one with the given identifier is not
* found
*/
IntentState getIntentState(IntentId id);
......@@ -65,12 +72,12 @@ public interface IntentService {
*
* @param listener listener to be added
*/
void addListener(IntentEventListener listener);
void addListener(IntentListener listener);
/**
* Removes the specified listener for intent events.
*
* @param listener listener to be removed
*/
void removeListener(IntentEventListener listener);
void removeListener(IntentListener listener);
}
......
package org.onlab.onos.net.intent;
import org.onlab.onos.store.Store;
import java.util.List;
/**
* Manages inventory of end-station intents; not intended for direct use.
*/
public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> {
/**
* Creates a new intent.
*
* @param intent intent
* @return appropriate event or null if no change resulted
*/
IntentEvent createIntent(Intent intent);
/**
* Removes the specified intent from the inventory.
*
* @param intentId intent identification
* @return removed state transition event or null if intent was not found
*/
IntentEvent removeIntent(IntentId intentId);
/**
* Returns the number of intents in the store.
*/
long getIntentCount();
/**
* Returns a collection of all intents in the store.
*
* @return iterable collection of all intents
*/
Iterable<Intent> getIntents();
/**
* Returns the intent with the specified identifer.
*
* @param intentId intent identification
* @return intent or null if not found
*/
Intent getIntent(IntentId intentId);
/**
* Returns the state of the specified intent.
*
* @param intentId intent identification
* @return current intent state
*/
IntentState getIntentState(IntentId intentId);
/**
* Sets the state of the specified intent to the new state.
*
* @param intent intent whose state is to be changed
* @param newState new state
* @return state transition event
*/
IntentEvent setState(Intent intent, IntentState newState);
/**
* Adds the installable intents which resulted from compilation of the
* specified original intent.
*
* @param intentId original intent identifier
* @param installableIntents compiled installable intents
* @return compiled state transition event
*/
IntentEvent addInstallableIntents(IntentId intentId,
List<InstallableIntent> installableIntents);
/**
* Returns the list of the installable events associated with the specified
* original intent.
*
* @param intentId original intent identifier
* @return compiled installable intents
*/
List<InstallableIntent> getInstallableIntents(IntentId intentId);
// TODO: this should be triggered from with the store as a result of removeIntent call
/**
* Removes any installable intents which resulted from compilation of the
* specified original intent.
*
* @param intentId original intent identifier
* @return compiled state transition event
*/
void removeInstalledIntents(IntentId intentId);
}
package org.onlab.onos.net.intent;
import org.onlab.onos.store.StoreDelegate;
/**
* Intent store delegate abstraction.
*/
public interface IntentStoreDelegate extends StoreDelegate<IntentEvent> {
}
......@@ -30,18 +30,20 @@ public class MultiPointToSinglePointIntent extends ConnectivityIntent {
* @param action action
* @param ingressPorts set of ports from which ingress traffic originates
* @param egressPort port to which traffic will egress
* @throws NullPointerException if {@code ingressPorts} or
* {@code egressPort} is null.
* @throws NullPointerException if {@code ingressPorts} or
* {@code egressPort} is null.
* @throws IllegalArgumentException if the size of {@code ingressPorts} is
* not more than 1
* not more than 1
*/
public MultiPointToSinglePointIntent(IntentId id, TrafficSelector match, TrafficTreatment action,
Set<ConnectPoint> ingressPorts, ConnectPoint egressPort) {
public MultiPointToSinglePointIntent(IntentId id, TrafficSelector match,
TrafficTreatment action,
Set<ConnectPoint> ingressPorts,
ConnectPoint egressPort) {
super(id, match, action);
checkNotNull(ingressPorts);
checkArgument(!ingressPorts.isEmpty(),
"there should be at least one ingress port");
"there should be at least one ingress port");
this.ingressPorts = Sets.newHashSet(ingressPorts);
this.egressPort = checkNotNull(egressPort);
......
......@@ -3,30 +3,30 @@ package org.onlab.onos.net.intent;
import org.onlab.onos.net.ConnectPoint;
// TODO: consider if this intent should be sub-class of ConnectivityIntent
/**
* An optical layer Intent for a connectivity from a transponder port to another
* transponder port.
* <p>
* <p/>
* This class doesn't accepts lambda specifier. This class computes path between
* ports and assign lambda automatically. The lambda can be specified using
* OpticalPathFlow class.
*/
public class OpticalConnectivityIntent extends AbstractIntent {
protected ConnectPoint srcConnectPoint;
protected ConnectPoint dstConnectPoint;
protected ConnectPoint src;
protected ConnectPoint dst;
/**
* Constructor.
*
* @param id ID for this new Intent object.
* @param srcConnectPoint The source transponder port.
* @param dstConnectPoint The destination transponder port.
* @param id ID for this new Intent object.
* @param src The source transponder port.
* @param dst The destination transponder port.
*/
public OpticalConnectivityIntent(IntentId id,
ConnectPoint srcConnectPoint, ConnectPoint dstConnectPoint) {
public OpticalConnectivityIntent(IntentId id, ConnectPoint src, ConnectPoint dst) {
super(id);
this.srcConnectPoint = srcConnectPoint;
this.dstConnectPoint = dstConnectPoint;
this.src = src;
this.dst = dst;
}
/**
......@@ -34,8 +34,8 @@ public class OpticalConnectivityIntent extends AbstractIntent {
*/
protected OpticalConnectivityIntent() {
super();
this.srcConnectPoint = null;
this.dstConnectPoint = null;
this.src = null;
this.dst = null;
}
/**
......@@ -44,7 +44,7 @@ public class OpticalConnectivityIntent extends AbstractIntent {
* @return The source transponder port.
*/
public ConnectPoint getSrcConnectPoint() {
return srcConnectPoint;
return src;
}
/**
......@@ -52,7 +52,7 @@ public class OpticalConnectivityIntent extends AbstractIntent {
*
* @return The source transponder port.
*/
public ConnectPoint getDstConnectPoint() {
return dstConnectPoint;
public ConnectPoint getDst() {
return dst;
}
}
......
......@@ -12,7 +12,7 @@ import com.google.common.base.MoreObjects;
/**
* Abstraction of explicitly path specified connectivity intent.
*/
public class PathIntent extends PointToPointIntent {
public class PathIntent extends PointToPointIntent implements InstallableIntent {
private final Path path;
......
package org.onlab.onos.net.intent;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Objects;
import com.google.common.base.MoreObjects;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import com.google.common.base.MoreObjects;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Abstraction of point-to-point connectivity.
......@@ -23,15 +22,17 @@ public class PointToPointIntent extends ConnectivityIntent {
* ports.
*
* @param id intent identifier
* @param match traffic match
* @param action action
* @param selector traffic selector
* @param treatment treatment
* @param ingressPort ingress port
* @param egressPort egress port
* @throws NullPointerException if {@code ingressPort} or {@code egressPort} is null.
*/
public PointToPointIntent(IntentId id, TrafficSelector match, TrafficTreatment action,
ConnectPoint ingressPort, ConnectPoint egressPort) {
super(id, match, action);
public PointToPointIntent(IntentId id, TrafficSelector selector,
TrafficTreatment treatment,
ConnectPoint ingressPort,
ConnectPoint egressPort) {
super(id, selector, treatment);
this.ingressPort = checkNotNull(ingressPort);
this.egressPort = checkNotNull(egressPort);
}
......
package org.onlab.onos.net.intent;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Objects;
import java.util.Set;
import com.google.common.base.MoreObjects;
import com.google.common.collect.Sets;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import com.google.common.base.MoreObjects;
import com.google.common.collect.Sets;
import java.util.Objects;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Abstraction of single source, multiple destination connectivity intent.
......@@ -25,23 +24,24 @@ public class SinglePointToMultiPointIntent extends ConnectivityIntent {
* Creates a new single-to-multi point connectivity intent.
*
* @param id intent identifier
* @param match traffic match
* @param action action
* @param selector traffic selector
* @param treatment treatment
* @param ingressPort port on which traffic will ingress
* @param egressPorts set of ports on which traffic will egress
* @throws NullPointerException if {@code ingressPort} or
* {@code egressPorts} is null
* @throws NullPointerException if {@code ingressPort} or
* {@code egressPorts} is null
* @throws IllegalArgumentException if the size of {@code egressPorts} is
* not more than 1
* not more than 1
*/
public SinglePointToMultiPointIntent(IntentId id, TrafficSelector match, TrafficTreatment action,
public SinglePointToMultiPointIntent(IntentId id, TrafficSelector selector,
TrafficTreatment treatment,
ConnectPoint ingressPort,
Set<ConnectPoint> egressPorts) {
super(id, match, action);
super(id, selector, treatment);
checkNotNull(egressPorts);
checkArgument(!egressPorts.isEmpty(),
"there should be at least one egress port");
"there should be at least one egress port");
this.ingressPort = checkNotNull(ingressPort);
this.egressPorts = Sets.newHashSet(egressPorts);
......
/**
* Intent Package. TODO
* Set of abstractions for conveying high-level intents for treatment of
* selected network traffic by allowing applications to express the
* <em>what</em> rather than the <em>how</em>. This makes such instructions
* largely independent of topology and device specifics, thus allowing them to
* survive topology mutations.
*/
package org.onlab.onos.net.intent;
\ No newline at end of file
......
......@@ -24,7 +24,7 @@ public abstract class DefaultPacketContext implements PacketContext {
this.inPkt = inPkt;
this.outPkt = outPkt;
this.block = new AtomicBoolean(block);
this.builder = new DefaultTrafficTreatment.Builder();
this.builder = DefaultTrafficTreatment.builder();
}
@Override
......
......@@ -3,6 +3,7 @@ package org.onlab.onos.net.provider;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* External identity of a {@link org.onlab.onos.net.provider.Provider} family.
......@@ -19,10 +20,22 @@ import static com.google.common.base.MoreObjects.toStringHelper;
*/
public class ProviderId {
/**
* Represents no provider ID.
*/
public static final ProviderId NONE = new ProviderId();
private final String scheme;
private final String id;
private final boolean ancillary;
// For serialization
private ProviderId() {
scheme = null;
id = null;
ancillary = false;
}
/**
* Creates a new primary provider identifier from the specified string.
* The providers are expected to follow the reverse DNS convention, e.g.
......@@ -45,8 +58,8 @@ public class ProviderId {
* @param ancillary ancillary provider indicator
*/
public ProviderId(String scheme, String id, boolean ancillary) {
this.scheme = scheme;
this.id = id;
this.scheme = checkNotNull(scheme, "Scheme cannot be null");
this.id = checkNotNull(id, "ID cannot be null");
this.ancillary = ancillary;
}
......
package org.onlab.onos.store;
import org.onlab.onos.cluster.MastershipTerm;
import org.onlab.onos.net.DeviceId;
//TODO: Consider renaming to DeviceClockProviderService?
/**
* Interface for feeding term information to a logical clock service
* that vends per device timestamps.
*/
public interface ClockProviderService {
/**
* Updates the mastership term for the specified deviceId.
* @param deviceId device identifier.
* @param term mastership term.
*/
public void setMastershipTerm(DeviceId deviceId, MastershipTerm term);
}
package org.onlab.onos.store;
import org.onlab.onos.cluster.MastershipTerm;
import org.onlab.onos.net.DeviceId;
// TODO: Consider renaming to DeviceClockService?
......@@ -15,12 +14,4 @@ public interface ClockService {
* @return timestamp.
*/
public Timestamp getTimestamp(DeviceId deviceId);
// TODO: Should this be here or separate as Admin service, etc.?
/**
* Updates the mastership term for the specified deviceId.
* @param deviceId device identifier.
* @param term mastership term.
*/
public void setMastershipTerm(DeviceId deviceId, MastershipTerm term);
}
......
......@@ -2,7 +2,15 @@ package org.onlab.onos.store;
/**
* Opaque version structure.
* <p>
* Classes implementing this interface must also implement
* {@link #hashCode()} and {@link #equals(Object)}.
*/
public interface Timestamp extends Comparable<Timestamp> {
@Override
public abstract int hashCode();
@Override
public abstract boolean equals(Object obj);
}
......
......@@ -16,8 +16,8 @@ import org.onlab.onos.net.flow.TrafficTreatment;
public abstract class ConnectivityIntentTest extends IntentTest {
public static final IntentId IID = new IntentId(123);
public static final TrafficSelector MATCH = (new DefaultTrafficSelector.Builder()).build();
public static final TrafficTreatment NOP = (new DefaultTrafficTreatment.Builder()).build();
public static final TrafficSelector MATCH = DefaultTrafficSelector.builder().build();
public static final TrafficTreatment NOP = DefaultTrafficTreatment.builder().build();
public static final ConnectPoint P1 = new ConnectPoint(DeviceId.deviceId("111"), PortNumber.portNumber(0x1));
public static final ConnectPoint P2 = new ConnectPoint(DeviceId.deviceId("222"), PortNumber.portNumber(0x2));
......
......@@ -11,19 +11,19 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Fake implementation of the intent service to assist in developing tests
* of the interface contract.
* Fake implementation of the intent service to assist in developing tests of
* the interface contract.
*/
public class FakeIntentManager implements TestableIntentService {
private final Map<IntentId, Intent> intents = new HashMap<>();
private final Map<IntentId, IntentState> intentStates = new HashMap<>();
private final Map<IntentId, List<InstallableIntent>> installables = new HashMap<>();
private final Set<IntentEventListener> listeners = new HashSet<>();
private final Set<IntentListener> listeners = new HashSet<>();
private final Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> compilers = new HashMap<>();
private final Map<Class<? extends InstallableIntent>,
IntentInstaller<? extends InstallableIntent>> installers = new HashMap<>();
private final Map<Class<? extends InstallableIntent>, IntentInstaller<? extends InstallableIntent>> installers
= new HashMap<>();
private final ExecutorService executor = Executors.newSingleThreadExecutor();
private final List<IntentException> exceptions = new ArrayList<>();
......@@ -76,7 +76,8 @@ public class FakeIntentManager implements TestableIntentService {
private <T extends InstallableIntent> IntentInstaller<T> getInstaller(T intent) {
@SuppressWarnings("unchecked")
IntentInstaller<T> installer = (IntentInstaller<T>) installers.get(intent.getClass());
IntentInstaller<T> installer = (IntentInstaller<T>) installers.get(intent
.getClass());
if (installer == null) {
throw new IntentException("no installer for class " + intent.getClass());
}
......@@ -125,7 +126,6 @@ public class FakeIntentManager implements TestableIntentService {
}
}
// Sets the internal state for the given intent and dispatches an event
private void setState(Intent intent, IntentState state) {
IntentState previous = intentStates.get(intent.getId());
......@@ -175,6 +175,11 @@ public class FakeIntentManager implements TestableIntentService {
}
@Override
public long getIntentCount() {
return intents.size();
}
@Override
public Intent getIntent(IntentId id) {
return intents.get(id);
}
......@@ -185,23 +190,24 @@ public class FakeIntentManager implements TestableIntentService {
}
@Override
public void addListener(IntentEventListener listener) {
public void addListener(IntentListener listener) {
listeners.add(listener);
}
@Override
public void removeListener(IntentEventListener listener) {
public void removeListener(IntentListener listener) {
listeners.remove(listener);
}
private void dispatch(IntentEvent event) {
for (IntentEventListener listener : listeners) {
for (IntentListener listener : listeners) {
listener.event(event);
}
}
@Override
public <T extends Intent> void registerCompiler(Class<T> cls, IntentCompiler<T> compiler) {
public <T extends Intent> void registerCompiler(Class<T> cls,
IntentCompiler<T> compiler) {
compilers.put(cls, compiler);
}
......@@ -216,7 +222,8 @@ public class FakeIntentManager implements TestableIntentService {
}
@Override
public <T extends InstallableIntent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer) {
public <T extends InstallableIntent> void registerInstaller(Class<T> cls,
IntentInstaller<T> installer) {
installers.put(cls, installer);
}
......@@ -227,7 +234,7 @@ public class FakeIntentManager implements TestableIntentService {
@Override
public Map<Class<? extends InstallableIntent>,
IntentInstaller<? extends InstallableIntent>> getInstallers() {
IntentInstaller<? extends InstallableIntent>> getInstallers() {
return Collections.unmodifiableMap(installers);
}
......@@ -252,7 +259,8 @@ public class FakeIntentManager implements TestableIntentService {
if (!installers.containsKey(intent.getClass())) {
Class<?> cls = intent.getClass();
while (cls != Object.class) {
// As long as we're within the InstallableIntent class descendants
// As long as we're within the InstallableIntent class
// descendants
if (InstallableIntent.class.isAssignableFrom(cls)) {
IntentInstaller<?> installer = installers.get(cls);
if (installer != null) {
......
......@@ -51,7 +51,7 @@ public class IntentServiceTest {
@Test
public void basics() {
// Make sure there are no intents
assertEquals("incorrect intent count", 0, service.getIntents().size());
assertEquals("incorrect intent count", 0, service.getIntentCount());
// Register a compiler and an installer both setup for success.
service.registerCompiler(TestIntent.class, new TestCompiler(new TestInstallableIntent(INSTALLABLE_IID)));
......@@ -73,8 +73,7 @@ public class IntentServiceTest {
validateEvents(intent, SUBMITTED, COMPILED, INSTALLED);
// Make sure there is just one intent (and is ours)
assertEquals("incorrect intent count", 1, service.getIntents().size());
assertEquals("incorrect intent", intent, service.getIntent(intent.getId()));
assertEquals("incorrect intent count", 1, service.getIntentCount());
// Reset the listener events
listener.events.clear();
......@@ -250,7 +249,7 @@ public class IntentServiceTest {
// Fixture to track emitted intent events
protected class TestListener implements IntentEventListener {
protected class TestListener implements IntentListener {
final List<IntentEvent> events = new ArrayList<>();
@Override
......
......@@ -38,7 +38,7 @@ import org.onlab.onos.net.device.DeviceStoreDelegate;
import org.onlab.onos.net.device.PortDescription;
import org.onlab.onos.net.provider.AbstractProviderRegistry;
import org.onlab.onos.net.provider.AbstractProviderService;
import org.onlab.onos.store.ClockService;
import org.onlab.onos.store.ClockProviderService;
import org.slf4j.Logger;
/**
......@@ -80,7 +80,7 @@ public class DeviceManager
protected MastershipTermService termService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ClockService clockService;
protected ClockProviderService clockProviderService;
@Activate
public void activate() {
......@@ -274,7 +274,7 @@ public class DeviceManager
if (event.master().equals(clusterService.getLocalNode().id())) {
MastershipTerm term = mastershipService.requestTermService()
.getMastershipTerm(event.subject());
clockService.setMastershipTerm(event.subject(), term);
clockProviderService.setMastershipTerm(event.subject(), term);
applyRole(event.subject(), MastershipRole.MASTER);
} else {
applyRole(event.subject(), MastershipRole.STANDBY);
......
......@@ -242,15 +242,16 @@ implements FlowRuleService, FlowRuleProviderRegistry {
}
private boolean checkRuleLiveness(FlowRule swRule, FlowRule storedRule) {
int timeout = storedRule.timeout();
if (storedRule.packets() != swRule.packets()) {
deadRounds.get(swRule).set(0);
return true;
}
return (deadRounds.get(swRule).getAndIncrement() *
FlowRuleProvider.POLL_INTERVAL) <= timeout;
return true;
// int timeout = storedRule.timeout();
// if (storedRule.packets() != swRule.packets()) {
// deadRounds.get(swRule).set(0);
// return true;
// }
//
// return (deadRounds.get(swRule).getAndIncrement() *
// FlowRuleProvider.POLL_INTERVAL) <= timeout;
//
}
// Posts the specified event to the local event dispatcher.
......
......@@ -4,9 +4,9 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import org.jboss.netty.util.Timeout;
......@@ -59,15 +59,14 @@ public class HostMonitor implements TimerTask {
private final Set<IpAddress> monitoredAddresses;
private final Map<ProviderId, HostProvider> hostProviders;
private final ConcurrentMap<ProviderId, HostProvider> hostProviders;
private final long probeRate;
private static final long DEFAULT_PROBE_RATE = 30000; // milliseconds
private long probeRate = DEFAULT_PROBE_RATE;
private final Timeout timeout;
public HostMonitor(
DeviceService deviceService,
PacketService packetService,
public HostMonitor(DeviceService deviceService, PacketService packetService,
HostManager hostService) {
this.deviceService = deviceService;
......@@ -77,15 +76,7 @@ public class HostMonitor implements TimerTask {
monitoredAddresses = new HashSet<>();
hostProviders = new ConcurrentHashMap<>();
probeRate = 30000; // milliseconds
timeout = Timer.getTimer().newTimeout(this, 0, TimeUnit.MILLISECONDS);
addDefaultAddresses();
}
private void addDefaultAddresses() {
//monitoredAddresses.add(IpAddress.valueOf("10.0.0.1"));
}
void addMonitoringFor(IpAddress ip) {
......@@ -104,10 +95,6 @@ public class HostMonitor implements TimerTask {
hostProviders.put(provider.id(), provider);
}
void unregisterHostProvider(HostProvider provider) {
// TODO find out how to call this
}
@Override
public void run(Timeout timeout) throws Exception {
for (IpAddress ip : monitoredAddresses) {
......@@ -121,7 +108,9 @@ public class HostMonitor implements TimerTask {
} else {
for (Host host : hosts) {
HostProvider provider = hostProviders.get(host.providerId());
if (provider != null) {
if (provider == null) {
hostProviders.remove(host.providerId(), null);
} else {
provider.triggerProbe(host);
}
}
......@@ -161,7 +150,7 @@ public class HostMonitor implements TimerTask {
List<Instruction> instructions = new ArrayList<>();
instructions.add(Instructions.createOutput(port.number()));
TrafficTreatment treatment = new DefaultTrafficTreatment.Builder()
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.setOutput(port.number())
.build();
......
package org.onlab.onos.net.intent.impl;
import org.onlab.onos.net.intent.IdGenerator;
/**
* Base class of {@link IdGenerator} implementations which use {@link IdBlockAllocator} as
* backend.
*
* @param <T> the type of ID
*/
public abstract class AbstractBlockAllocatorBasedIdGenerator<T> implements IdGenerator<T> {
protected final IdBlockAllocator allocator;
protected IdBlock idBlock;
/**
* Constructs an ID generator which use {@link IdBlockAllocator} as backend.
*
* @param allocator
*/
protected AbstractBlockAllocatorBasedIdGenerator(IdBlockAllocator allocator) {
this.allocator = allocator;
this.idBlock = allocator.allocateUniqueIdBlock();
}
@Override
public synchronized T getNewId() {
try {
return convertFrom(idBlock.getNextId());
} catch (UnavailableIdException e) {
idBlock = allocator.allocateUniqueIdBlock();
return convertFrom(idBlock.getNextId());
}
}
/**
* Returns an ID instance of {@code T} type from the long value.
*
* @param value original long value
* @return ID instance
*/
protected abstract T convertFrom(long value);
}
package org.onlab.onos.net.intent.impl;
public class DummyIdBlockAllocator implements IdBlockAllocator {
private long blockTop;
private static final long BLOCK_SIZE = 0x1000000L;
/**
* Returns a block of IDs which are unique and unused.
* Range of IDs is fixed size and is assigned incrementally as this method
* called.
*
* @return an IdBlock containing a set of unique IDs
*/
@Override
public IdBlock allocateUniqueIdBlock() {
synchronized (this) {
long blockHead = blockTop;
long blockTail = blockTop + BLOCK_SIZE;
IdBlock block = new IdBlock(blockHead, BLOCK_SIZE);
blockTop = blockTail;
return block;
}
}
@Override
public IdBlock allocateUniqueIdBlock(long range) {
throw new UnsupportedOperationException("Not supported yet");
}
}
package org.onlab.onos.net.intent.impl;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
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.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.Path;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.intent.HostToHostIntent;
import org.onlab.onos.net.intent.IdGenerator;
import org.onlab.onos.net.intent.Intent;
import org.onlab.onos.net.intent.IntentCompiler;
import org.onlab.onos.net.intent.IntentExtensionService;
import org.onlab.onos.net.intent.IntentId;
import org.onlab.onos.net.intent.PathIntent;
import org.onlab.onos.net.topology.PathService;
/**
* A intent compiler for {@link HostToHostIntent}.
*/
@Component(immediate = true)
public class HostToHostIntentCompiler
implements IntentCompiler<HostToHostIntent> {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected IntentExtensionService intentManager;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PathService pathService;
private IdGenerator<IntentId> intentIdGenerator;
@Activate
public void activate() {
IdBlockAllocator idBlockAllocator = new DummyIdBlockAllocator();
intentIdGenerator = new IdBlockAllocatorBasedIntentIdGenerator(idBlockAllocator);
intentManager.registerCompiler(HostToHostIntent.class, this);
}
@Deactivate
public void deactivate() {
intentManager.unregisterCompiler(HostToHostIntent.class);
}
@Override
public List<Intent> compile(HostToHostIntent intent) {
Set<Path> paths = pathService.getPaths(intent.getSrc(), intent.getDst());
if (paths.isEmpty()) {
throw new PathNotFoundException();
}
Path path = paths.iterator().next();
return Arrays.asList((Intent) new PathIntent(
intentIdGenerator.getNewId(),
intent.getTrafficSelector(),
intent.getTrafficTreatment(),
new ConnectPoint(intent.getSrc(), PortNumber.ALL),
new ConnectPoint(intent.getDst(), PortNumber.ALL),
path));
}
}
package org.onlab.onos.net.intent.impl;
import static com.google.common.base.Preconditions.checkArgument;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
import com.google.common.base.MoreObjects;
/**
* A class representing an ID space.
*/
public final class IdBlock {
private final long start;
private final long size;
private final AtomicLong currentId;
/**
* Constructs a new ID block with the specified size and initial value.
*
* @param start initial value of the block
* @param size size of the block
* @throws IllegalArgumentException if the size is less than or equal to 0
*/
public IdBlock(long start, long size) {
checkArgument(size > 0, "size should be more than 0, but %s", size);
this.start = start;
this.size = size;
this.currentId = new AtomicLong(start);
}
// TODO: consider if this method is needed or not
/**
* Returns the initial value.
*
* @return initial value
*/
public long getStart() {
return start;
}
// TODO: consider if this method is needed or not
/**
* Returns the last value.
*
* @return last value
*/
public long getEnd() {
return start + size - 1;
}
/**
* Returns the block size.
*
* @return block size
*/
public long getSize() {
return size;
}
/**
* Returns the next ID in the block.
*
* @return next ID
* @throws UnavailableIdException if there is no available ID in the block.
*/
public long getNextId() {
final long id = currentId.getAndIncrement();
if (id > getEnd()) {
throw new UnavailableIdException(String.format(
"used all IDs in allocated space (size: %d, end: %d, current: %d)",
size, getEnd(), id
));
}
return id;
}
// TODO: Do we really need equals and hashCode? Should it contain currentId?
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
IdBlock that = (IdBlock) o;
return Objects.equals(this.start, that.start)
&& Objects.equals(this.size, that.size)
&& Objects.equals(this.currentId.get(), that.currentId.get());
}
@Override
public int hashCode() {
return Objects.hash(start, size, currentId);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("start", start)
.add("size", size)
.add("currentId", currentId)
.toString();
}
}
package org.onlab.onos.net.intent.impl;
/**
* An interface that gives unique ID spaces.
*/
public interface IdBlockAllocator {
/**
* Allocates a unique Id Block.
*
* @return Id Block.
*/
IdBlock allocateUniqueIdBlock();
/**
* Allocates next unique id and retrieve a new range of ids if needed.
*
* @param range range to use for the identifier
* @return Id Block.
*/
IdBlock allocateUniqueIdBlock(long range);
}
package org.onlab.onos.net.intent.impl;
import org.onlab.onos.net.intent.IntentId;
/**
* An implementation of {@link org.onlab.onos.net.intent.IdGenerator} of intent ID,
* which uses {@link IdBlockAllocator}.
*/
public class IdBlockAllocatorBasedIntentIdGenerator extends AbstractBlockAllocatorBasedIdGenerator<IntentId> {
/**
* Constructs an intent ID generator, which uses the specified ID block allocator
* to generate a global unique intent ID.
*
* @param allocator the ID block allocator to use for generating intent IDs
*/
public IdBlockAllocatorBasedIntentIdGenerator(IdBlockAllocator allocator) {
super(allocator);
}
@Override
protected IntentId convertFrom(long value) {
return new IntentId(value);
}
}
package org.onlab.onos.net.intent.impl;
import org.onlab.onos.net.intent.IntentException;
/**
* An exception thrown when a intent compilation fails.
*/
public class IntentCompilationException extends IntentException {
private static final long serialVersionUID = 235237603018210810L;
public IntentCompilationException() {
super();
}
public IntentCompilationException(String message) {
super(message);
}
public IntentCompilationException(String message, Throwable cause) {
super(message, cause);
}
}
package org.onlab.onos.net.intent.impl;
import org.onlab.onos.net.intent.IntentException;
/**
* An exception thrown when intent installation fails.
*/
public class IntentInstallationException extends IntentException {
private static final long serialVersionUID = 3720268258616014168L;
public IntentInstallationException() {
super();
}
public IntentInstallationException(String message) {
super(message);
}
public IntentInstallationException(String message, Throwable cause) {
super(message, cause);
}
}
package org.onlab.onos.net.intent.impl;
import org.onlab.onos.net.intent.IntentException;
/**
* An exception thrown when intent removal failed.
*/
public class IntentRemovalException extends IntentException {
private static final long serialVersionUID = -5259226322037891951L;
public IntentRemovalException() {
super();
}
public IntentRemovalException(String message) {
super(message);
}
public IntentRemovalException(String message, Throwable cause) {
super(message, cause);
}
}
package org.onlab.onos.net.intent.impl;
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.onlab.onos.ApplicationId;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.flow.DefaultFlowRule;
import org.onlab.onos.net.flow.DefaultTrafficSelector;
import org.onlab.onos.net.flow.DefaultTrafficTreatment;
import org.onlab.onos.net.flow.FlowRule;
import org.onlab.onos.net.flow.FlowRuleService;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.net.intent.IntentExtensionService;
import org.onlab.onos.net.intent.IntentInstaller;
import org.onlab.onos.net.intent.PathIntent;
import java.util.Iterator;
/**
* Installer for {@link PathIntent path connectivity intents}.
*/
@Component(immediate = true)
public class PathIntentInstaller implements IntentInstaller<PathIntent> {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected IntentExtensionService intentManager;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowRuleService flowRuleService;
private final ApplicationId appId = ApplicationId.getAppId();
@Activate
public void activate() {
intentManager.registerInstaller(PathIntent.class, this);
}
@Deactivate
public void deactivate() {
intentManager.unregisterInstaller(PathIntent.class);
}
@Override
public void install(PathIntent intent) {
TrafficSelector.Builder builder =
DefaultTrafficSelector.builder(intent.getTrafficSelector());
Iterator<Link> links = intent.getPath().links().iterator();
ConnectPoint prev = links.next().dst();
while (links.hasNext()) {
builder.matchInport(prev.port());
Link link = links.next();
TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder();
treat.setOutput(link.src().port());
FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
builder.build(), treat.build(),
0, appId, 30);
flowRuleService.applyFlowRules(rule);
prev = link.dst();
}
}
@Override
public void uninstall(PathIntent intent) {
//TODO
}
}
package org.onlab.onos.net.intent.impl;
import org.onlab.onos.net.intent.IntentException;
/**
* An exception thrown when a path is not found.
*/
public class PathNotFoundException extends IntentException {
private static final long serialVersionUID = -2087045731049914733L;
public PathNotFoundException() {
super();
}
public PathNotFoundException(String message) {
super(message);
}
public PathNotFoundException(String message, Throwable cause) {
super(message, cause);
}
}
package org.onlab.onos.net.intent.impl;
/**
* Represents that there is no available IDs.
*/
public class UnavailableIdException extends RuntimeException {
private static final long serialVersionUID = -2287403908433720122L;
/**
* Constructs an exception with no message and no underlying cause.
*/
public UnavailableIdException() {
}
/**
* Constructs an exception with the specified message.
*
* @param message the message describing the specific nature of the error
*/
public UnavailableIdException(String message) {
super(message);
}
/**
* Constructs an exception with the specified message and the underlying cause.
*
* @param message the message describing the specific nature of the error
* @param cause the underlying cause of this error
*/
public UnavailableIdException(String message, Throwable cause) {
super(message, cause);
}
}
/**
* Core subsystem for tracking high-level intents for treatment of selected
* network traffic.
*/
package org.onlab.onos.net.intent.impl;
\ No newline at end of file
......@@ -43,7 +43,6 @@ import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
@Component(immediate = true)
@Service
public class ProxyArpManager implements ProxyArpService {
......@@ -128,7 +127,7 @@ public class ProxyArpManager implements ProxyArpService {
Ethernet arpReply = buildArpReply(dst, eth);
// TODO: check send status with host service.
TrafficTreatment.Builder builder = new DefaultTrafficTreatment.Builder();
TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
builder.setOutput(src.location().port());
packetService.emit(new DefaultOutboundPacket(src.location().deviceId(),
builder.build(), ByteBuffer.wrap(arpReply.serialize())));
......@@ -148,7 +147,7 @@ public class ProxyArpManager implements ProxyArpService {
if (h == null) {
flood(eth);
} else {
TrafficTreatment.Builder builder = new DefaultTrafficTreatment.Builder();
TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
builder.setOutput(h.location().port());
packetService.emit(new DefaultOutboundPacket(h.location().deviceId(),
builder.build(), ByteBuffer.wrap(eth.serialize())));
......@@ -166,7 +165,7 @@ public class ProxyArpManager implements ProxyArpService {
synchronized (externalPorts) {
for (Entry<Device, PortNumber> entry : externalPorts.entries()) {
builder = new DefaultTrafficTreatment.Builder();
builder = DefaultTrafficTreatment.builder();
builder.setOutput(entry.getValue());
packetService.emit(new DefaultOutboundPacket(entry.getKey().id(),
builder.build(), buf));
......
package org.onlab.onos.store.cluster.impl;
import de.javakaffee.kryoserializers.URISerializer;
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.Service;
import org.onlab.onos.cluster.ControllerNode;
import org.onlab.onos.cluster.DefaultControllerNode;
import org.onlab.onos.cluster.NodeId;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DefaultDevice;
import org.onlab.onos.net.DefaultLink;
import org.onlab.onos.net.DefaultPort;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Element;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.LinkKey;
import org.onlab.onos.net.MastershipRole;
import org.onlab.onos.net.Port;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.provider.ProviderId;
import org.onlab.onos.store.cluster.messaging.MessageSubject;
import org.onlab.onos.store.cluster.messaging.SerializationService;
import org.onlab.onos.store.serializers.ConnectPointSerializer;
import org.onlab.onos.store.serializers.DefaultLinkSerializer;
import org.onlab.onos.store.serializers.DefaultPortSerializer;
import org.onlab.onos.store.serializers.DeviceIdSerializer;
import org.onlab.onos.store.serializers.IpPrefixSerializer;
import org.onlab.onos.store.serializers.LinkKeySerializer;
import org.onlab.onos.store.serializers.NodeIdSerializer;
import org.onlab.onos.store.serializers.PortNumberSerializer;
import org.onlab.onos.store.serializers.ProviderIdSerializer;
import org.onlab.packet.IpPrefix;
import org.onlab.onos.store.serializers.KryoPoolUtil;
import org.onlab.util.KryoPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
/**
* Factory for parsing messages sent between cluster members.
*/
......@@ -72,34 +42,10 @@ public class MessageSerializer implements SerializationService {
* Sets up the common serialzers pool.
*/
protected void setupKryoPool() {
// FIXME Slice out types used in common to separate pool/namespace.
serializerPool = KryoPool.newBuilder()
.register(ArrayList.class,
HashMap.class,
ControllerNode.State.class,
Device.Type.class,
DefaultControllerNode.class,
DefaultDevice.class,
MastershipRole.class,
Port.class,
Element.class,
Link.Type.class,
MessageSubject.class
)
.register(IpPrefix.class, new IpPrefixSerializer())
.register(URI.class, new URISerializer())
.register(NodeId.class, new NodeIdSerializer())
.register(ProviderId.class, new ProviderIdSerializer())
.register(DeviceId.class, new DeviceIdSerializer())
.register(PortNumber.class, new PortNumberSerializer())
.register(DefaultPort.class, new DefaultPortSerializer())
.register(LinkKey.class, new LinkKeySerializer())
.register(ConnectPoint.class, new ConnectPointSerializer())
.register(DefaultLink.class, new DefaultLinkSerializer())
.register(KryoPoolUtil.API)
// TODO: Should MessageSubject be in API bundle?
.register(MessageSubject.class)
.build()
.populate(1);
}
......@@ -114,4 +60,4 @@ public class MessageSerializer implements SerializationService {
public byte[] encode(Object payload) {
return serializerPool.serialize(payload);
}
}
\ No newline at end of file
}
......
/**
* Implementation of the cluster messaging mechanism.
*/
package org.onlab.onos.store.cluster.messaging.impl;
\ No newline at end of file
package org.onlab.onos.store.impl;
package org.onlab.onos.store.common.impl;
import static com.google.common.base.Preconditions.checkArgument;
......@@ -9,12 +9,11 @@ import org.onlab.onos.store.Timestamp;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ComparisonChain;
// If it is store specific, implement serializable interfaces?
/**
* Default implementation of Timestamp.
* TODO: Better documentation.
*/
public final class OnosTimestamp implements Timestamp {
public final class MastershipBasedTimestamp implements Timestamp {
private final int termNumber;
private final int sequenceNumber;
......@@ -25,15 +24,16 @@ public final class OnosTimestamp implements Timestamp {
* @param termNumber the mastership termNumber
* @param sequenceNumber the sequenceNumber number within the termNumber
*/
public OnosTimestamp(int termNumber, int sequenceNumber) {
public MastershipBasedTimestamp(int termNumber, int sequenceNumber) {
this.termNumber = termNumber;
this.sequenceNumber = sequenceNumber;
}
@Override
public int compareTo(Timestamp o) {
checkArgument(o instanceof OnosTimestamp, "Must be OnosTimestamp", o);
OnosTimestamp that = (OnosTimestamp) o;
checkArgument(o instanceof MastershipBasedTimestamp,
"Must be MastershipBasedTimestamp", o);
MastershipBasedTimestamp that = (MastershipBasedTimestamp) o;
return ComparisonChain.start()
.compare(this.termNumber, that.termNumber)
......@@ -51,10 +51,10 @@ public final class OnosTimestamp implements Timestamp {
if (this == obj) {
return true;
}
if (!(obj instanceof OnosTimestamp)) {
if (!(obj instanceof MastershipBasedTimestamp)) {
return false;
}
OnosTimestamp that = (OnosTimestamp) obj;
MastershipBasedTimestamp that = (MastershipBasedTimestamp) obj;
return Objects.equals(this.termNumber, that.termNumber) &&
Objects.equals(this.sequenceNumber, that.sequenceNumber);
}
......@@ -84,4 +84,11 @@ public final class OnosTimestamp implements Timestamp {
public int sequenceNumber() {
return sequenceNumber;
}
// Default constructor for serialization
@Deprecated
protected MastershipBasedTimestamp() {
this.termNumber = -1;
this.sequenceNumber = -1;
}
}
......
package org.onlab.onos.store.common.impl;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Objects;
import org.onlab.onos.store.Timestamp;
/**
* Wrapper class to store Timestamped value.
* @param <T>
*/
public final class Timestamped<T> {
private final Timestamp timestamp;
private final T value;
/**
* Creates a time stamped value.
*
* @param value to be timestamp
* @param timestamp the timestamp
*/
public Timestamped(T value, Timestamp timestamp) {
this.value = checkNotNull(value);
this.timestamp = checkNotNull(timestamp);
}
/**
* Returns the value.
* @return value
*/
public T value() {
return value;
}
/**
* Returns the time stamp.
* @return time stamp
*/
public Timestamp timestamp() {
return timestamp;
}
/**
* Tests if this timestamped value is newer than the other.
*
* @param other timestamped value
* @return true if this instance is newer.
*/
public boolean isNewer(Timestamped<T> other) {
return this.timestamp.compareTo(checkNotNull(other).timestamp()) > 0;
}
@Override
public int hashCode() {
return timestamp.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Timestamped)) {
return false;
}
@SuppressWarnings("unchecked")
Timestamped<T> that = (Timestamped<T>) obj;
return Objects.equals(this.timestamp, that.timestamp);
}
// Default constructor for serialization
@Deprecated
protected Timestamped() {
this.value = null;
this.timestamp = null;
}
}
/**
* Common abstractions and facilities for implementing distributed store
* using gossip protocol.
*/
package org.onlab.onos.store.common.impl;
......@@ -12,14 +12,18 @@ import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.cluster.MastershipTerm;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.store.ClockProviderService;
import org.onlab.onos.store.ClockService;
import org.onlab.onos.store.Timestamp;
import org.onlab.onos.store.impl.OnosTimestamp;
import org.onlab.onos.store.common.impl.MastershipBasedTimestamp;
import org.slf4j.Logger;
/**
* Clock service to issue Timestamp based on Device Mastership.
*/
@Component(immediate = true)
@Service
public class OnosClockService implements ClockService {
public class DeviceClockManager implements ClockService, ClockProviderService {
private final Logger log = getLogger(getClass());
......@@ -43,7 +47,7 @@ public class OnosClockService implements ClockService {
if (term == null) {
throw new IllegalStateException("Requesting timestamp for a deviceId without mastership");
}
return new OnosTimestamp(term.termNumber(), ticker.incrementAndGet());
return new MastershipBasedTimestamp(term.termNumber(), ticker.incrementAndGet());
}
@Override
......
/**
* Implementation of device store using distributed distributed p2p synchronization protocol.
*/
package org.onlab.onos.store.device.impl;
\ No newline at end of file
package org.onlab.onos.store.device.impl;
......
......@@ -42,6 +42,7 @@ import com.google.common.collect.ImmutableSet.Builder;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
//TODO: Add support for multiple provider and annotations
/**
* Manages inventory of infrastructure links using a protocol that takes into consideration
* the order in which events occur.
......
/**
* Implementation of link store using distributed p2p synchronization protocol.
*/
package org.onlab.onos.store.link.impl;
\ No newline at end of file
package org.onlab.onos.store.link.impl;
......
package org.onlab.onos.store.serializers;
import org.onlab.onos.store.impl.OnosTimestamp;
import org.onlab.onos.store.common.impl.MastershipBasedTimestamp;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
// To be used if Timestamp ever needs to cross bundle boundary.
/**
* Kryo Serializer for {@link OnosTimestamp}.
* Kryo Serializer for {@link MastershipBasedTimestamp}.
*/
public class OnosTimestampSerializer extends Serializer<OnosTimestamp> {
public class MastershipBasedTimestampSerializer extends Serializer<MastershipBasedTimestamp> {
/**
* Default constructor.
*/
public OnosTimestampSerializer() {
public MastershipBasedTimestampSerializer() {
// non-null, immutable
super(false, true);
}
@Override
public void write(Kryo kryo, Output output, OnosTimestamp object) {
public void write(Kryo kryo, Output output, MastershipBasedTimestamp object) {
output.writeInt(object.termNumber());
output.writeInt(object.sequenceNumber());
}
@Override
public OnosTimestamp read(Kryo kryo, Input input, Class<OnosTimestamp> type) {
public MastershipBasedTimestamp read(Kryo kryo, Input input, Class<MastershipBasedTimestamp> type) {
final int term = input.readInt();
final int sequence = input.readInt();
return new OnosTimestamp(term, sequence);
return new MastershipBasedTimestamp(term, sequence);
}
}
......
package org.onlab.onos.store.common.impl;
import static org.junit.Assert.*;
import java.nio.ByteBuffer;
import org.junit.Test;
import org.onlab.onos.store.Timestamp;
import org.onlab.onos.store.serializers.MastershipBasedTimestampSerializer;
import org.onlab.util.KryoPool;
import com.google.common.testing.EqualsTester;
/**
* Test of {@link MastershipBasedTimestamp}.
*/
public class MastershipBasedTimestampTest {
private static final Timestamp TS_1_1 = new MastershipBasedTimestamp(1, 1);
private static final Timestamp TS_1_2 = new MastershipBasedTimestamp(1, 2);
private static final Timestamp TS_2_1 = new MastershipBasedTimestamp(2, 1);
private static final Timestamp TS_2_2 = new MastershipBasedTimestamp(2, 2);
@Test
public final void testBasic() {
final int termNumber = 5;
final int sequenceNumber = 6;
MastershipBasedTimestamp ts = new MastershipBasedTimestamp(termNumber,
sequenceNumber);
assertEquals(termNumber, ts.termNumber());
assertEquals(sequenceNumber, ts.sequenceNumber());
}
@Test
public final void testCompareTo() {
assertTrue(TS_1_1.compareTo(TS_1_1) == 0);
assertTrue(TS_1_1.compareTo(new MastershipBasedTimestamp(1, 1)) == 0);
assertTrue(TS_1_1.compareTo(TS_1_2) < 0);
assertTrue(TS_1_2.compareTo(TS_1_1) > 0);
assertTrue(TS_1_2.compareTo(TS_2_1) < 0);
assertTrue(TS_1_2.compareTo(TS_2_2) < 0);
assertTrue(TS_2_1.compareTo(TS_1_1) > 0);
assertTrue(TS_2_2.compareTo(TS_1_1) > 0);
}
@Test
public final void testEqualsObject() {
new EqualsTester()
.addEqualityGroup(new MastershipBasedTimestamp(1, 1),
new MastershipBasedTimestamp(1, 1), TS_1_1)
.addEqualityGroup(new MastershipBasedTimestamp(1, 2),
new MastershipBasedTimestamp(1, 2), TS_1_2)
.addEqualityGroup(new MastershipBasedTimestamp(2, 1),
new MastershipBasedTimestamp(2, 1), TS_2_1)
.addEqualityGroup(new MastershipBasedTimestamp(2, 2),
new MastershipBasedTimestamp(2, 2), TS_2_2)
.testEquals();
}
@Test
public final void testKryoSerializable() {
final ByteBuffer buffer = ByteBuffer.allocate(1 * 1024 * 1024);
final KryoPool kryos = KryoPool.newBuilder()
.register(MastershipBasedTimestamp.class)
.build();
kryos.serialize(TS_2_1, buffer);
buffer.flip();
Timestamp copy = kryos.deserialize(buffer);
new EqualsTester()
.addEqualityGroup(TS_2_1, copy)
.testEquals();
}
@Test
public final void testKryoSerializableWithHandcraftedSerializer() {
final ByteBuffer buffer = ByteBuffer.allocate(1 * 1024 * 1024);
final KryoPool kryos = KryoPool.newBuilder()
.register(MastershipBasedTimestamp.class, new MastershipBasedTimestampSerializer())
.build();
kryos.serialize(TS_1_2, buffer);
buffer.flip();
Timestamp copy = kryos.deserialize(buffer);
new EqualsTester()
.addEqualityGroup(TS_1_2, copy)
.testEquals();
}
}
package org.onlab.onos.store.common.impl;
import static org.junit.Assert.*;
import java.nio.ByteBuffer;
import org.junit.Test;
import org.onlab.onos.store.Timestamp;
import org.onlab.util.KryoPool;
import com.google.common.testing.EqualsTester;
/**
* Test of {@link Timestamped}.
*/
public class TimestampedTest {
private static final Timestamp TS_1_1 = new MastershipBasedTimestamp(1, 1);
private static final Timestamp TS_1_2 = new MastershipBasedTimestamp(1, 2);
private static final Timestamp TS_2_1 = new MastershipBasedTimestamp(2, 1);
@Test
public final void testHashCode() {
Timestamped<String> a = new Timestamped<>("a", TS_1_1);
Timestamped<String> b = new Timestamped<>("b", TS_1_1);
assertTrue("value does not impact hashCode",
a.hashCode() == b.hashCode());
}
@Test
public final void testEquals() {
Timestamped<String> a = new Timestamped<>("a", TS_1_1);
Timestamped<String> b = new Timestamped<>("b", TS_1_1);
assertTrue("value does not impact equality",
a.equals(b));
new EqualsTester()
.addEqualityGroup(new Timestamped<>("a", TS_1_1),
new Timestamped<>("b", TS_1_1),
new Timestamped<>("c", TS_1_1))
.addEqualityGroup(new Timestamped<>("a", TS_1_2),
new Timestamped<>("b", TS_1_2),
new Timestamped<>("c", TS_1_2))
.addEqualityGroup(new Timestamped<>("a", TS_2_1),
new Timestamped<>("b", TS_2_1),
new Timestamped<>("c", TS_2_1))
.testEquals();
}
@Test
public final void testValue() {
final Integer n = Integer.valueOf(42);
Timestamped<Integer> tsv = new Timestamped<>(n, TS_1_1);
assertSame(n, tsv.value());
}
@Test(expected = NullPointerException.class)
public final void testValueNonNull() {
new Timestamped<>(null, TS_1_1);
}
@Test(expected = NullPointerException.class)
public final void testTimestampNonNull() {
new Timestamped<>("Foo", null);
}
@Test
public final void testIsNewer() {
Timestamped<String> a = new Timestamped<>("a", TS_1_2);
Timestamped<String> b = new Timestamped<>("b", TS_1_1);
assertTrue(a.isNewer(b));
assertFalse(b.isNewer(a));
}
@Test
public final void testKryoSerializable() {
final ByteBuffer buffer = ByteBuffer.allocate(1 * 1024 * 1024);
final KryoPool kryos = KryoPool.newBuilder()
.register(Timestamped.class,
MastershipBasedTimestamp.class)
.build();
Timestamped<String> original = new Timestamped<>("foobar", TS_1_1);
kryos.serialize(original, buffer);
buffer.flip();
Timestamped<String> copy = kryos.deserialize(buffer);
new EqualsTester()
.addEqualityGroup(original, copy)
.testEquals();
}
}
......@@ -47,6 +47,7 @@ import static com.google.common.cache.CacheBuilder.newBuilder;
import static org.onlab.onos.net.device.DeviceEvent.Type.*;
import static org.slf4j.LoggerFactory.getLogger;
//TODO: Add support for multiple provider and annotations
/**
* Manages inventory of infrastructure devices using Hazelcast-backed map.
*/
......
......@@ -4,27 +4,15 @@ import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.cluster.MastershipTerm;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.store.ClockService;
import org.onlab.onos.store.Timestamp;
import org.onlab.onos.store.ClockProviderService;
// FIXME: Code clone in onos-core-trivial, onos-core-hz-net
/**
* Dummy implementation of {@link ClockService}.
* Dummy implementation of {@link ClockProviderService}.
*/
@Component(immediate = true)
@Service
public class NoOpClockService implements ClockService {
@Override
public Timestamp getTimestamp(DeviceId deviceId) {
return new Timestamp() {
@Override
public int compareTo(Timestamp o) {
throw new IllegalStateException("Never expected to be used.");
}
};
}
public class NoOpClockProviderService implements ClockProviderService {
@Override
public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) {
......
......@@ -38,6 +38,7 @@ import com.google.common.collect.Multimap;
import com.google.common.collect.ImmutableSet.Builder;
import com.hazelcast.core.IMap;
//TODO: Add support for multiple provider and annotations
/**
* Manages inventory of infrastructure links using Hazelcast-backed map.
*/
......
......@@ -3,7 +3,6 @@ package org.onlab.onos.store.serializers;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.ElementId;
import org.onlab.onos.net.PortNumber;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
......@@ -15,7 +14,7 @@ import com.esotericsoftware.kryo.io.Output;
public class ConnectPointSerializer extends Serializer<ConnectPoint> {
/**
* Default constructor.
* Creates {@link ConnectPointSerializer} serializer instance.
*/
public ConnectPointSerializer() {
// non-null, immutable
......
......@@ -16,7 +16,7 @@ import com.esotericsoftware.kryo.io.Output;
public class DefaultLinkSerializer extends Serializer<DefaultLink> {
/**
* Default constructor.
* Creates {@link DefaultLink} serializer instance.
*/
public DefaultLinkSerializer() {
// non-null, immutable
......
......@@ -16,7 +16,7 @@ public final class DefaultPortSerializer extends
Serializer<DefaultPort> {
/**
* Default constructor.
* Creates {@link DefaultPort} serializer instance.
*/
public DefaultPortSerializer() {
// non-null, immutable
......
......@@ -14,6 +14,14 @@ import com.esotericsoftware.kryo.io.Output;
*/
public final class DeviceIdSerializer extends Serializer<DeviceId> {
/**
* Creates {@link DeviceId} serializer instance.
*/
public DeviceIdSerializer() {
// non-null, immutable
super(false, true);
}
@Override
public void write(Kryo kryo, Output output, DeviceId object) {
kryo.writeObject(output, object.uri());
......
......@@ -19,6 +19,9 @@ public class ImmutableMapSerializer extends FamilySerializer<ImmutableMap<?, ?>>
private final MapSerializer mapSerializer = new MapSerializer();
/**
* Creates {@link ImmutableMap} serializer instance.
*/
public ImmutableMapSerializer() {
// non-null, immutable
super(false, true);
......
......@@ -18,6 +18,9 @@ public class ImmutableSetSerializer extends FamilySerializer<ImmutableSet<?>> {
private final CollectionSerializer serializer = new CollectionSerializer();
/**
* Creates {@link ImmutableSet} serializer instance.
*/
public ImmutableSetSerializer() {
// non-null, immutable
super(false, true);
......
package org.onlab.onos.store.serializers;
import org.onlab.packet.IpAddress;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
/**
* Kryo Serializer for {@link IpAddress}.
*/
public class IpAddressSerializer extends Serializer<IpAddress> {
/**
* Creates {@link IpAddress} serializer instance.
*/
public IpAddressSerializer() {
// non-null, immutable
super(false, true);
}
@Override
public void write(Kryo kryo, Output output,
IpAddress object) {
byte[] octs = object.toOctets();
output.writeInt(octs.length);
output.writeBytes(octs);
output.writeInt(object.prefixLength());
}
@Override
public IpAddress read(Kryo kryo, Input input,
Class<IpAddress> type) {
int octLen = input.readInt();
byte[] octs = new byte[octLen];
input.read(octs);
int prefLen = input.readInt();
return IpAddress.valueOf(octs, prefLen);
}
}
......@@ -13,7 +13,7 @@ import com.esotericsoftware.kryo.io.Output;
public final class IpPrefixSerializer extends Serializer<IpPrefix> {
/**
* Default constructor.
* Creates {@link IpPrefix} serializer instance.
*/
public IpPrefixSerializer() {
// non-null, immutable
......
package org.onlab.onos.store.serializers;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import org.onlab.onos.cluster.ControllerNode;
import org.onlab.onos.cluster.DefaultControllerNode;
import org.onlab.onos.cluster.MastershipTerm;
import org.onlab.onos.cluster.NodeId;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DefaultAnnotations;
import org.onlab.onos.net.DefaultDevice;
import org.onlab.onos.net.DefaultLink;
import org.onlab.onos.net.DefaultPort;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Element;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.LinkKey;
import org.onlab.onos.net.MastershipRole;
import org.onlab.onos.net.Port;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.provider.ProviderId;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.util.KryoPool;
import de.javakaffee.kryoserializers.URISerializer;
public final class KryoPoolUtil {
/**
* KryoPool which can serialize ON.lab misc classes.
*/
public static final KryoPool MISC = KryoPool.newBuilder()
.register(IpPrefix.class, new IpPrefixSerializer())
.register(IpAddress.class, new IpAddressSerializer())
.build();
// TODO: Populate other classes
/**
* KryoPool which can serialize API bundle classes.
*/
public static final KryoPool API = KryoPool.newBuilder()
.register(MISC)
.register(
//
ArrayList.class,
HashMap.class,
//
ControllerNode.State.class,
Device.Type.class,
DefaultAnnotations.class,
DefaultControllerNode.class,
DefaultDevice.class,
MastershipRole.class,
Port.class,
Element.class,
Link.Type.class
)
.register(URI.class, new URISerializer())
.register(NodeId.class, new NodeIdSerializer())
.register(ProviderId.class, new ProviderIdSerializer())
.register(DeviceId.class, new DeviceIdSerializer())
.register(PortNumber.class, new PortNumberSerializer())
.register(DefaultPort.class, new DefaultPortSerializer())
.register(LinkKey.class, new LinkKeySerializer())
.register(ConnectPoint.class, new ConnectPointSerializer())
.register(DefaultLink.class, new DefaultLinkSerializer())
.register(MastershipTerm.class, new MastershipTermSerializer())
.register(MastershipRole.class, new MastershipRoleSerializer())
.build();
// not to be instantiated
private KryoPoolUtil() {}
}
package org.onlab.onos.store.serializers;
import de.javakaffee.kryoserializers.URISerializer;
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.Service;
import org.onlab.onos.cluster.ControllerNode;
import org.onlab.onos.cluster.DefaultControllerNode;
import org.onlab.onos.cluster.NodeId;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DefaultAnnotations;
import org.onlab.onos.net.DefaultDevice;
import org.onlab.onos.net.DefaultLink;
import org.onlab.onos.net.DefaultPort;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Element;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.LinkKey;
import org.onlab.onos.net.MastershipRole;
import org.onlab.onos.net.Port;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.provider.ProviderId;
import org.onlab.packet.IpPrefix;
import org.onlab.util.KryoPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
/**
* Serialization service using Kryo.
......@@ -58,33 +36,8 @@ public class KryoSerializationManager implements KryoSerializationService {
* Sets up the common serialzers pool.
*/
protected void setupKryoPool() {
// FIXME Slice out types used in common to separate pool/namespace.
serializerPool = KryoPool.newBuilder()
.register(ArrayList.class,
HashMap.class,
ControllerNode.State.class,
Device.Type.class,
DefaultAnnotations.class,
DefaultControllerNode.class,
DefaultDevice.class,
MastershipRole.class,
Port.class,
Element.class,
Link.Type.class
)
.register(IpPrefix.class, new IpPrefixSerializer())
.register(URI.class, new URISerializer())
.register(NodeId.class, new NodeIdSerializer())
.register(ProviderId.class, new ProviderIdSerializer())
.register(DeviceId.class, new DeviceIdSerializer())
.register(PortNumber.class, new PortNumberSerializer())
.register(DefaultPort.class, new DefaultPortSerializer())
.register(LinkKey.class, new LinkKeySerializer())
.register(ConnectPoint.class, new ConnectPointSerializer())
.register(DefaultLink.class, new DefaultLinkSerializer())
.register(KryoPoolUtil.API)
.build()
.populate(1);
}
......
......@@ -2,6 +2,7 @@ package org.onlab.onos.store.serializers;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.LinkKey;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
......@@ -13,7 +14,7 @@ import com.esotericsoftware.kryo.io.Output;
public class LinkKeySerializer extends Serializer<LinkKey> {
/**
* Default constructor.
* Creates {@link LinkKey} serializer instance.
*/
public LinkKeySerializer() {
// non-null, immutable
......
......@@ -12,6 +12,14 @@ import com.esotericsoftware.kryo.io.Output;
*/
public class MastershipRoleSerializer extends Serializer<MastershipRole> {
/**
* Creates {@link MastershipRole} serializer instance.
*/
public MastershipRoleSerializer() {
// non-null, immutable
super(false, true);
}
@Override
public MastershipRole read(Kryo kryo, Input input, Class<MastershipRole> type) {
final String role = kryo.readObject(input, String.class);
......
......@@ -2,7 +2,6 @@ package org.onlab.onos.store.serializers;
import org.onlab.onos.cluster.MastershipTerm;
import org.onlab.onos.cluster.NodeId;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
......@@ -13,6 +12,14 @@ import com.esotericsoftware.kryo.io.Output;
*/
public class MastershipTermSerializer extends Serializer<MastershipTerm> {
/**
* Creates {@link MastershipTerm} serializer instance.
*/
public MastershipTermSerializer() {
// non-null, immutable
super(false, true);
}
@Override
public MastershipTerm read(Kryo kryo, Input input, Class<MastershipTerm> type) {
final NodeId node = new NodeId(kryo.readObject(input, String.class));
......
......@@ -4,6 +4,7 @@ import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import org.onlab.onos.cluster.NodeId;
/**
......@@ -11,6 +12,14 @@ import org.onlab.onos.cluster.NodeId;
*/
public final class NodeIdSerializer extends Serializer<NodeId> {
/**
* Creates {@link NodeId} serializer instance.
*/
public NodeIdSerializer() {
// non-null, immutable
super(false, true);
}
@Override
public void write(Kryo kryo, Output output, NodeId object) {
kryo.writeObject(output, object.toString());
......
......@@ -14,7 +14,7 @@ public final class PortNumberSerializer extends
Serializer<PortNumber> {
/**
* Default constructor.
* Creates {@link PortNumber} serializer instance.
*/
public PortNumberSerializer() {
// non-null, immutable
......
......@@ -13,7 +13,7 @@ import com.esotericsoftware.kryo.io.Output;
public class ProviderIdSerializer extends Serializer<ProviderId> {
/**
* Default constructor.
* Creates {@link ProviderId} serializer instance.
*/
public ProviderIdSerializer() {
// non-null, immutable
......
......@@ -3,16 +3,11 @@ package org.onlab.onos.store.serializers;
import static org.onlab.onos.net.DeviceId.deviceId;
import static org.onlab.onos.net.PortNumber.portNumber;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.onlab.onos.cluster.MastershipTerm;
import org.onlab.onos.cluster.NodeId;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DefaultDevice;
......@@ -22,7 +17,6 @@ import org.onlab.onos.net.Device;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.Link;
import org.onlab.onos.net.LinkKey;
import org.onlab.onos.net.MastershipRole;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.provider.ProviderId;
import org.onlab.packet.IpPrefix;
......@@ -32,8 +26,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.testing.EqualsTester;
import de.javakaffee.kryoserializers.URISerializer;
public class KryoSerializerTests {
private static final ProviderId PID = new ProviderId("of", "foo");
private static final DeviceId DID1 = deviceId("of:foo");
......@@ -54,38 +46,12 @@ public class KryoSerializerTests {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
kryos = KryoPool.newBuilder()
.register(
ArrayList.class,
HashMap.class
)
.register(
Device.Type.class,
Link.Type.class
// ControllerNode.State.class,
// DefaultControllerNode.class,
// MastershipRole.class,
// Port.class,
// Element.class,
)
.register(ConnectPoint.class, new ConnectPointSerializer())
.register(DefaultLink.class, new DefaultLinkSerializer())
.register(DefaultPort.class, new DefaultPortSerializer())
.register(DeviceId.class, new DeviceIdSerializer())
.register(KryoPoolUtil.API)
.register(ImmutableMap.class, new ImmutableMapSerializer())
.register(ImmutableSet.class, new ImmutableSetSerializer())
.register(IpPrefix.class, new IpPrefixSerializer())
.register(LinkKey.class, new LinkKeySerializer())
.register(NodeId.class, new NodeIdSerializer())
.register(PortNumber.class, new PortNumberSerializer())
.register(ProviderId.class, new ProviderIdSerializer())
.register(DefaultDevice.class)
.register(URI.class, new URISerializer())
.register(MastershipRole.class, new MastershipRoleSerializer())
.register(MastershipTerm.class, new MastershipTermSerializer())
.build();
}
......
......@@ -4,27 +4,15 @@ import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.cluster.MastershipTerm;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.store.ClockService;
import org.onlab.onos.store.Timestamp;
import org.onlab.onos.store.ClockProviderService;
//FIXME: Code clone in onos-core-trivial, onos-core-hz-net
/**
* Dummy implementation of {@link ClockService}.
* Dummy implementation of {@link ClockProviderService}.
*/
@Component(immediate = true)
@Service
public class NoOpClockService implements ClockService {
@Override
public Timestamp getTimestamp(DeviceId deviceId) {
return new Timestamp() {
@Override
public int compareTo(Timestamp o) {
throw new IllegalStateException("Never expected to be used.");
}
};
}
public class NoOpClockProviderService implements ClockProviderService {
@Override
public void setMastershipTerm(DeviceId deviceId, MastershipTerm term) {
......
package org.onlab.onos.store.trivial.impl;
import static org.onlab.onos.net.intent.IntentState.COMPILED;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.Service;
import org.onlab.onos.net.intent.InstallableIntent;
import org.onlab.onos.net.intent.Intent;
import org.onlab.onos.net.intent.IntentEvent;
import org.onlab.onos.net.intent.IntentId;
import org.onlab.onos.net.intent.IntentState;
import org.onlab.onos.net.intent.IntentStore;
import org.onlab.onos.net.intent.IntentStoreDelegate;
import org.onlab.onos.store.AbstractStore;
import org.slf4j.Logger;
import com.google.common.collect.ImmutableSet;
@Component(immediate = true)
@Service
public class SimpleIntentStore
extends AbstractStore<IntentEvent, IntentStoreDelegate>
implements IntentStore {
private final Logger log = getLogger(getClass());
private final Map<IntentId, Intent> intents = new HashMap<>();
private final Map<IntentId, IntentState> states = new HashMap<>();
private final Map<IntentId, List<InstallableIntent>> installable = new HashMap<>();
@Activate
public void activate() {
log.info("Started");
}
@Deactivate
public void deactivate() {
log.info("Stopped");
}
@Override
public IntentEvent createIntent(Intent intent) {
intents.put(intent.getId(), intent);
return this.setState(intent, IntentState.SUBMITTED);
}
@Override
public IntentEvent removeIntent(IntentId intentId) {
Intent intent = intents.remove(intentId);
installable.remove(intentId);
IntentEvent event = this.setState(intent, IntentState.WITHDRAWN);
states.remove(intentId);
return event;
}
@Override
public long getIntentCount() {
return intents.size();
}
@Override
public Iterable<Intent> getIntents() {
return ImmutableSet.copyOf(intents.values());
}
@Override
public Intent getIntent(IntentId intentId) {
return intents.get(intentId);
}
@Override
public IntentState getIntentState(IntentId id) {
return states.get(id);
}
// TODO return dispatch event here... replace with state transition methods
@Override
public IntentEvent setState(Intent intent, IntentState newState) {
IntentId id = intent.getId();
IntentState oldState = states.get(id);
states.put(id, newState);
return new IntentEvent(intent, newState, oldState, System.currentTimeMillis());
}
@Override
public IntentEvent addInstallableIntents(IntentId intentId, List<InstallableIntent> result) {
installable.put(intentId, result);
return this.setState(intents.get(intentId), COMPILED);
}
@Override
public List<InstallableIntent> getInstallableIntents(IntentId intentId) {
return installable.get(intentId);
}
@Override
public void removeInstalledIntents(IntentId intentId) {
installable.remove(intentId);
}
}
......@@ -32,6 +32,7 @@ import static org.onlab.onos.net.Link.Type.INDIRECT;
import static org.onlab.onos.net.link.LinkEvent.Type.*;
import static org.slf4j.LoggerFactory.getLogger;
// TODO: Add support for multiple provider and annotations
/**
* Manages inventory of infrastructure links using trivial in-memory structures
* implementation.
......
......@@ -480,7 +480,7 @@
<group>
<title>Core Subsystems</title>
<packages>
org.onlab.onos.cluster.impl:org.onlab.onos.net.device.impl:org.onlab.onos.net.link.impl:org.onlab.onos.net.host.impl:org.onlab.onos.net.topology.impl:org.onlab.onos.net.packet.impl:org.onlab.onos.net.flow.impl:org.onlab.onos.store.trivial.*:org.onlab.onos.net.*.impl:org.onlab.onos.event.impl:org.onlab.onos.store.*
org.onlab.onos.cluster.impl:org.onlab.onos.net.device.impl:org.onlab.onos.net.link.impl:org.onlab.onos.net.host.impl:org.onlab.onos.net.topology.impl:org.onlab.onos.net.packet.impl:org.onlab.onos.net.flow.impl:org.onlab.onos.store.trivial.*:org.onlab.onos.net.*.impl:org.onlab.onos.event.impl:org.onlab.onos.store.*:org.onlab.onos.net.intent.impl
</packages>
</group>
<group>
......
......@@ -113,7 +113,7 @@ public class FlowRuleBuilder {
}
private TrafficTreatment buildTreatment() {
TrafficTreatment.Builder builder = new DefaultTrafficTreatment.Builder();
TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
// If this is a drop rule
if (actions.size() == 0) {
builder.drop();
......@@ -198,7 +198,7 @@ public class FlowRuleBuilder {
}
private TrafficSelector buildSelector() {
TrafficSelector.Builder builder = new DefaultTrafficSelector.Builder();
TrafficSelector.Builder builder = DefaultTrafficSelector.builder();
for (MatchField<?> field : match.getMatchFields()) {
switch (field.id) {
case IN_PORT:
......
......@@ -181,7 +181,7 @@ public class OpenFlowPacketProviderTest {
}
private static TrafficTreatment treatment(Instruction ... insts) {
TrafficTreatment.Builder builder = new DefaultTrafficTreatment.Builder();
TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
for (Instruction i : insts) {
builder.add(i);
}
......
......@@ -21,7 +21,7 @@ export PATH="$PATH:."
# e.g. 'o api', 'o dev', 'o'
function o {
cd $(find $ONOS_ROOT/ -type d | egrep -v '\.git|target' | \
egrep "${1:-$ONOS_ROOT}" | head -n 1)
egrep "${1:-$ONOS_ROOT}" | egrep -v "$ONOS_ROOT/.+/src/" | head -n 1)
}
# Short-hand for 'mvn clean install' for us lazy folk
......
......@@ -11,7 +11,7 @@ public class MetricsFeature {
*
* @param newName name of the Feature
*/
MetricsFeature(final String newName) {
public MetricsFeature(final String newName) {
name = newName;
}
......
......@@ -2,16 +2,43 @@ package org.onlab.netty;
import java.util.concurrent.TimeUnit;
import org.onlab.metrics.MetricsComponent;
import org.onlab.metrics.MetricsFeature;
import org.onlab.metrics.MetricsManager;
import com.codahale.metrics.Timer;
public final class SimpleClient {
private SimpleClient() {}
private SimpleClient() {
}
public static void main(String... args) throws Exception {
NettyMessagingService messaging = new TestNettyMessagingService(9081);
MetricsManager metrics = new MetricsManager();
messaging.activate();
metrics.activate();
MetricsFeature feature = new MetricsFeature("timers");
MetricsComponent component = metrics.registerComponent("NettyMessaging");
Timer sendAsyncTimer = metrics.createTimer(component, feature, "AsyncSender");
final int warmup = 100;
for (int i = 0; i < warmup; i++) {
Timer.Context context = sendAsyncTimer.time();
messaging.sendAsync(new Endpoint("localhost", 8080), "simple", "Hello World");
context.stop();
}
metrics.registerMetric(component, feature, "AsyncTimer", sendAsyncTimer);
messaging.sendAsync(new Endpoint("localhost", 8080), "simple", "Hello World");
Response<String> response = messaging.sendAndReceive(new Endpoint("localhost", 8080), "echo", "Hello World");
System.out.println("Got back:" + response.get(2, TimeUnit.SECONDS));
Timer sendAndReceiveTimer = metrics.createTimer(component, feature, "SendAndReceive");
final int iterations = 1000000;
for (int i = 0; i < iterations; i++) {
Timer.Context context = sendAndReceiveTimer.time();
Response<String> response = messaging
.sendAndReceive(new Endpoint("localhost", 8080), "echo",
"Hello World");
System.out.println("Got back:" + response.get(2, TimeUnit.SECONDS));
context.stop();
}
metrics.registerMetric(component, feature, "AsyncTimer", sendAndReceiveTimer);
}
public static class TestNettyMessagingService extends NettyMessagingService {
......