Skip to content
Snippets Groups Projects
Commit 6005a767 authored by Munish Mehta's avatar Munish Mehta
Browse files

Merge branch 'master' of github.com:floodlight/floodlight

parents 3114415c 69ca41a9
No related branches found
No related tags found
No related merge requests found
Showing
with 180 additions and 182 deletions
......@@ -423,11 +423,11 @@ public class OFMessageFilterManager
packetClient.pushMessageAsync(sendMsg);
}
} catch (TTransportException e) {
log.error("Caught TTransportException: {}", e);
log.error("Caught TTransportException: {}", e.getMessage());
disconnectFromPSServer();
connectToPSServer();
} catch (Exception e) {
log.error("Caught exception: {}", e);
log.error("Caught exception: {}", e.getMessage());
disconnectFromPSServer();
connectToPSServer();
}
......
......@@ -18,8 +18,10 @@
package net.floodlightcontroller.core.internal;
import java.io.IOException;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
......@@ -37,11 +39,14 @@ import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFMessageListener;
import net.floodlightcontroller.core.IFloodlightProviderService.Role;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.types.MacVlanPair;
import net.floodlightcontroller.core.web.serializers.DPIDSerializer;
import net.floodlightcontroller.threadpool.IThreadPoolService;
import net.floodlightcontroller.util.TimedCache;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.map.ser.ToStringSerializer;
import org.jboss.netty.channel.Channel;
import org.openflow.protocol.OFFeaturesReply;
import org.openflow.protocol.OFFlowMod;
......@@ -82,8 +87,6 @@ public class OFSwitchImpl implements IOFSwitch {
protected Channel channel;
protected AtomicInteger transactionIdSource;
protected Map<Short, OFPhysicalPort> ports;
protected Long switchClusterId;
protected Map<MacVlanPair,Short> macVlanToPortMap;
protected Map<Integer,OFStatisticsFuture> statsFutureMap;
protected Map<Integer, IOFMessageListener> iofMsgListenersMap;
protected boolean connected;
......@@ -132,7 +135,6 @@ public class OFSwitchImpl implements IOFSwitch {
this.connectedSince = new Date();
this.transactionIdSource = new AtomicInteger();
this.ports = new ConcurrentHashMap<Short, OFPhysicalPort>();
this.switchClusterId = null;
this.connected = true;
this.statsFutureMap = new ConcurrentHashMap<Integer,OFStatisticsFuture>();
this.iofMsgListenersMap = new ConcurrentHashMap<Integer,IOFMessageListener>();
......@@ -241,27 +243,20 @@ public class OFSwitchImpl implements IOFSwitch {
channel.close();
}
@JsonIgnore
public OFFeaturesReply getFeaturesReply() {
return this.featuresReply;
}
public void setSwitchClusterId(Long id) {
this.switchClusterId = id;
}
public Long getSwitchClusterId() {
return switchClusterId;
}
public synchronized void setFeaturesReply(OFFeaturesReply featuresReply) {
this.featuresReply = featuresReply;
for (OFPhysicalPort port : featuresReply.getPorts()) {
ports.put(port.getPortNumber(), port);
}
this.switchClusterId = featuresReply.getDatapathId();
this.stringId = HexString.toHexString(featuresReply.getDatapathId());
}
@JsonIgnore
public synchronized List<OFPhysicalPort> getEnabledPorts() {
List<OFPhysicalPort> result = new ArrayList<OFPhysicalPort>();
for (OFPhysicalPort port : ports.values()) {
......@@ -280,9 +275,15 @@ public class OFSwitchImpl implements IOFSwitch {
ports.put(port.getPortNumber(), port);
}
@JsonIgnore
public Map<Short, OFPhysicalPort> getPorts() {
return ports;
}
@JsonProperty("ports")
public Collection<OFPhysicalPort> getPortCollection() {
return ports.values();
}
public synchronized void deletePort(short portNumber) {
ports.remove(portNumber);
......@@ -306,12 +307,15 @@ public class OFSwitchImpl implements IOFSwitch {
}
@Override
@JsonSerialize(using=DPIDSerializer.class)
@JsonProperty("dpid")
public long getId() {
if (this.featuresReply == null)
throw new RuntimeException("Features reply has not yet been set");
return this.featuresReply.getDatapathId();
}
@JsonIgnore
@Override
public String getStringId() {
return stringId;
......@@ -335,6 +339,7 @@ public class OFSwitchImpl implements IOFSwitch {
return connectedSince;
}
@JsonIgnore
@Override
public int getNextTransactionId() {
return this.transactionIdSource.incrementAndGet();
......@@ -409,6 +414,7 @@ public class OFSwitchImpl implements IOFSwitch {
this.threadPool = tp;
}
@JsonIgnore
@Override
public synchronized boolean isConnected() {
return connected;
......@@ -424,6 +430,7 @@ public class OFSwitchImpl implements IOFSwitch {
return role;
}
@JsonIgnore
@Override
public boolean isActive() {
return (role != Role.SLAVE);
......@@ -469,6 +476,7 @@ public class OFSwitchImpl implements IOFSwitch {
}
@Override
@JsonIgnore
public Map<Short, Long> getPortBroadcastHits() {
return this.portBroadcastCacheHitMap;
}
......@@ -517,6 +525,15 @@ public class OFSwitchImpl implements IOFSwitch {
public Lock getListenerWriteLock() {
return listenerLock.writeLock();
}
/**
* Get the IP Address for the switch
* @return the inet address
*/
@JsonSerialize(using=ToStringSerializer.class)
public SocketAddress getInetAddress() {
return channel.getRemoteAddress();
}
/**
* Send NX role request message to the switch requesting the specified role.
......
......@@ -17,10 +17,7 @@
package net.floodlightcontroller.core.web;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFSwitch;
......@@ -34,18 +31,10 @@ import org.restlet.resource.ServerResource;
*/
public class ControllerSwitchesResource extends ServerResource {
@Get("json")
public List<Map<String, String>> retrieve() {
List<Map<String, String>> switchIds = new ArrayList<Map<String, String>>();
public Collection<IOFSwitch> retrieve() {
IFloodlightProviderService floodlightProvider =
(IFloodlightProviderService)getContext().getAttributes().
get(IFloodlightProviderService.class.getCanonicalName());
Map<Long, IOFSwitch> switches = floodlightProvider.getSwitches();
for (IOFSwitch s: switches.values()) {
Map<String, String> m = new HashMap<String, String>();
m.put("dpid", s.getStringId());
switchIds.add(m);
}
return switchIds;
return floodlightProvider.getSwitches().values();
}
}
/**
* Copyright 2011, Big Switch Networks, Inc.
* Copyright 2011,2012 Big Switch Networks, Inc.
* Originally created by David Erickson, Stanford University
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
......@@ -15,7 +15,7 @@
* under the License.
**/
package org.openflow.protocol.serializers;
package net.floodlightcontroller.core.web.serializers;
import java.io.IOException;
......@@ -23,35 +23,18 @@ import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
import org.openflow.protocol.OFPhysicalPort;
import org.openflow.util.HexString;
public class OFPhysicalPortJSONSerializer extends JsonSerializer<OFPhysicalPort> {
/**
* Performs the serialization of a OFPhysicalPort object
*/
@Override
public void serialize(OFPhysicalPort port, JsonGenerator jGen, SerializerProvider serializer) throws IOException, JsonProcessingException {
jGen.writeStartObject();
jGen.writeNumberField("advertisedFeatures", port.getAdvertisedFeatures());
jGen.writeNumberField("config", port.getConfig());
jGen.writeNumberField("currentFeatures", port.getCurrentFeatures());
jGen.writeStringField("hardwareAddress", HexString.toHexString(port.getHardwareAddress()));
jGen.writeStringField("name", port.getName());
jGen.writeNumberField("peerFeatures", port.getPeerFeatures());
jGen.writeNumberField("portNumber", port.getPortNumber());
jGen.writeNumberField("state", port.getState());
jGen.writeNumberField("supportedFeatures", port.getSupportedFeatures());
jGen.writeEndObject();
}
/**
* Serialize a MAC as colon-separated hexadecimal
*/
public class ByteArrayMACSerializer extends JsonSerializer<byte[]> {
/**
* Tells SimpleModule that we are the serializer for OFPhysicalPort
*/
@Override
public Class<OFPhysicalPort> handledType() {
return OFPhysicalPort.class;
public void serialize(byte[] mac, JsonGenerator jGen,
SerializerProvider serializer)
throws IOException, JsonProcessingException {
jGen.writeString(HexString.toHexString(mac));
}
}
/**
* Copyright 2011,2012 Big Switch Networks, Inc.
* Originally created by David Erickson, Stanford University
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
**/
package net.floodlightcontroller.core.web.serializers;
import java.io.IOException;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
/**
* Serialize a short value as an unsigned short
*/
public class UShortSerializer extends JsonSerializer<Short> {
@Override
public void serialize(Short s, JsonGenerator jGen,
SerializerProvider serializer) throws IOException,
JsonProcessingException {
if (s == null) jGen.writeNull();
else jGen.writeNumber(s.shortValue() & 0xffff);
}
}
......@@ -858,11 +858,18 @@ IFlowReconcileListener, IInfoProvider, IHAListener {
if ((dlAddrArr[0] & 0x1) != 0)
return null;
long swDpid = ofmWithSwDpid.getSwitchDataPathId();
short inPort = ofmWithSwDpid.getOfMatch().getInputPort();
Long swDpid = null;
Short inPort = null;
if (isSource) {
swDpid = ofmWithSwDpid.getSwitchDataPathId();
inPort = ofmWithSwDpid.getOfMatch().getInputPort();
}
boolean learnap = true;
if (!isValidAttachmentPoint(swDpid, inPort)) {
if (swDpid == null ||
inPort == null ||
!isValidAttachmentPoint(swDpid, inPort)) {
// If this is an internal port or we otherwise don't want
// to learn on these ports. In the future, we should
// handle this case by labeling flows with something that
......
......@@ -4,7 +4,6 @@ import java.util.Arrays;
import net.floodlightcontroller.devicemanager.IDevice;
import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType;
import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryType;
/**
......@@ -14,8 +13,6 @@ public class FCQueryObj {
/** The caller of the flow cache query. */
public IFlowQueryHandler fcQueryHandler;
/** The query type. */
public FCQueryType queryType;
/** The application instance name. */
public String applInstName;
/** The vlan Id. */
......@@ -36,14 +33,37 @@ public class FCQueryObj {
/**
* Instantiates a new flow cache query object
*/
public FCQueryObj() {
queryType = FCQueryType.UNKNOWN;
public FCQueryObj(IFlowQueryHandler fcQueryHandler,
String applInstName,
Short vlan,
IDevice srcDevice,
IDevice dstDevice,
String callerName,
FCQueryEvType evType,
Object callerOpaqueObj) {
this.fcQueryHandler = fcQueryHandler;
this.applInstName = applInstName;
this.srcDevice = srcDevice;
this.dstDevice = dstDevice;
this.callerName = callerName;
this.evType = evType;
this.callerOpaqueObj = callerOpaqueObj;
if (vlan != null) {
this.vlans = new Short[] { vlan };
} else {
if (srcDevice != null) {
this.vlans = srcDevice.getVlanId();
} else if (dstDevice != null) {
this.vlans = dstDevice.getVlanId();
}
}
}
@Override
public String toString() {
return "FCQueryObj [fcQueryCaller=" + fcQueryHandler
+ ", queryType=" + queryType + ", applInstName="
+ ", applInstName="
+ applInstName + ", vlans=" + Arrays.toString(vlans)
+ ", dstDevice=" + dstDevice + ", srcDevice="
+ srcDevice + ", callerName=" + callerName + ", evType="
......
......@@ -16,6 +16,12 @@ public class FlowCacheQueryResp {
* query.
*/
public boolean moreFlag;
/**
* Set to true if the response has been sent to handler
*/
public boolean hasSent;
/**
* The flow list. If there are large number of flows to be returned
* then they may be returned in multiple callbacks.
......@@ -32,6 +38,7 @@ public class FlowCacheQueryResp {
qrFlowCacheObjList = new ArrayList<QRFlowCacheObj>();
queryObj = query;
moreFlag = false;
hasSent = false;
}
/* (non-Javadoc)
......@@ -39,12 +46,8 @@ public class FlowCacheQueryResp {
*/
@Override
public String toString() {
String s = queryObj.toString();
if (moreFlag) {
s += "; moreFlasg=True";
} else {
s += "; moreFlag=False";
}
String s = queryObj.toString() + "; moreFlasg=" + moreFlag +
"; hasSent=" + hasSent;
s += "; FlowCount=" + Integer.toString(qrFlowCacheObjList.size());
return s;
}
......
......@@ -33,10 +33,6 @@ public class FlowReconcileManager
* need to be reconciled with the current configuration of the controller.
*/
protected ListenerDispatcher<OFType, IFlowReconcileListener> flowReconcileListeners;
public OFMatchReconcile newOFMatchReconcile() {
return new OFMatchReconcile();
}
@Override
public synchronized void addFlowReconcileListener(IFlowReconcileListener listener) {
......@@ -89,19 +85,23 @@ public class FlowReconcileManager
}
@Override
public void updateFlowForDestinationDevice(IDevice device, FCQueryEvType fcEvType){
public void updateFlowForDestinationDevice(IDevice device,
IFlowQueryHandler handler,
FCQueryEvType fcEvType) {
// NO-OP
}
@Override
public void updateFlowForSourceDevice(IDevice device, FCQueryEvType fcEvType){
public void updateFlowForSourceDevice(IDevice device,
IFlowQueryHandler handler,
FCQueryEvType fcEvType) {
// NO-OP
}
@Override
public void flowQueryGenericHandler(FlowCacheQueryResp flowResp) {
if (flowResp.queryObj.evType != FCQueryEvType.GET) {
OFMatchReconcile ofmRc = newOFMatchReconcile();
OFMatchReconcile ofmRc = new OFMatchReconcile();;
/* Re-provision these flows */
for (QRFlowCacheObj entry : flowResp.qrFlowCacheObjList) {
/* reconcile the flows in entry */
......
......@@ -6,7 +6,6 @@ import net.floodlightcontroller.core.FloodlightContext;
import net.floodlightcontroller.core.FloodlightContextStore;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.devicemanager.SwitchPort;
import net.floodlightcontroller.devicemanager.IDevice;
import net.floodlightcontroller.core.module.IFloodlightService;
/**
......@@ -26,18 +25,6 @@ public interface IFlowCacheService extends IFloodlightService {
"net.floodlightcontroller.flowcache.appName";
public static final String FLOWCACHE_APP_INSTANCE_NAME =
"net.floodlightcontroller.flowcache.appInstanceName";
/**
* The Enum FCQueryType.
*/
public enum FCQueryType {
APPLINSTNAME, // The APPLINSTNAME.
APPLINSTNAME_VLAN, // The APPLINSTNAM e_ vlan.
ALLAPP_DESTDEVICE, // The destdevice for all application.
ALLAPP_SRCDEVICE, // The source device for all application.
ALLAPP_SRCDEVICE_DESTDEVICE, // The APPLINSTNAM srcdevic destdevice.
UNKNOWN, // The UNKNOWN.
}
/**
* The flow cache query event type indicating the event that triggered the
......@@ -97,71 +84,6 @@ public interface IFlowCacheService extends IFloodlightService {
*/
public void submitFlowCacheQuery(FCQueryObj query);
/**
* Get a new flow cache query object populated with the supplied parameters.
* The query type field id populated automatically based on the parameters
* passed.
*
* @param fcQueryCaller the caller of this API
* @param applInstName the application instance name
* @param callerOpaqueData opaque data passed by the caller which is
* returned unchanged in the corresponding callback.
* @return a new initialized flow cache query object
*/
public FCQueryObj newFCQueryObj(IFlowQueryHandler fcQueryHandler,
String applInstName,
String callerName,
FCQueryEvType evType,
Object callerOpaqueObj);
/**
* Get a new flow cache query object populated with the supplied parameters.
* The query type field id populated automatically based on the parameters
* passed.
*
* @param fcQueryCaller the caller of this API
* @param applInstName the application instance name
* @param vlan VLAN ID
* @param callerOpaqueData opaque data passed by the caller which is
* returned unchanged in the corresponding callback.
* @return a new initialized flow cache query object
*/
public FCQueryObj newFCQueryObj(IFlowQueryHandler fcQueryHandler,
String applInstName,
short vlan,
String callerName,
FCQueryEvType evType,
Object callerOpaqueObj);
/**
* Get a new flow cache query object populated with the supplied parameters.
* The query type field id populated automatically based on the parameters
* passed.
*
* @param fcQueryCaller the caller of this API
* @param applInstName the application instance name
* @param srcDevice source device object
* @param dstDevice destination device object
* @param callerOpaqueData opaque data passed by the caller which is
* returned unchanged in the corresponding callback.
* @return a new initialized flow cache query object
*/
public FCQueryObj newFCQueryObj(IFlowQueryHandler fcQueryHandler,
IDevice srcDevice,
IDevice dstDevice,
String callerName,
FCQueryEvType evType,
Object callerOpaqueObj);
/**
* Get a new flow cache query object populated with the supplied parameters.
* The query type field id populated automatically based on the parameters
* passed.
*
* @return a new uninitialized flow cache query object
*/
public FCQueryObj newFCQueryObj();
/**
* Deactivates all flows in the flow cache for which the source switch
* matches the given switchDpid. Note that the flows are NOT deleted
......@@ -245,18 +167,6 @@ public interface IFlowCacheService extends IFloodlightService {
*/
public boolean moveFlowToDifferentApplInstName(OFMatchReconcile ofMRc);
/**
* Move all the flows from their current application instance to a
* different application instance. This API can be used when all flows in
* an application instance move to a different application instance when
* the application instance configuration changes.
*
* @param curApplInstName current application instance name
* @param newApplInstName new application instance name
*/
public void moveFlowToDifferentApplInstName(String curApplInstName,
String newApplInstName);
/**
* Delete all flow from the specified switch
* @param sw
......
......@@ -43,10 +43,13 @@ public interface IFlowReconcileService extends IFloodlightService {
* new attachment point
*
* @param device device that has moved
* @param handler handler to process the flows
* @param fcEvType Event type that triggered the update
*
*/
public void updateFlowForDestinationDevice(IDevice device, FCQueryEvType fcEvType);
public void updateFlowForDestinationDevice(IDevice device,
IFlowQueryHandler handler,
FCQueryEvType fcEvType);
/**
* Updates the flows from a device
......@@ -56,10 +59,13 @@ public interface IFlowReconcileService extends IFloodlightService {
* new attachment point
*
* @param device device where the flow originates
* @param handler handler to process the flows
* @param fcEvType Event type that triggered the update
*
*/
public void updateFlowForSourceDevice(IDevice device, FCQueryEvType fcEvType);
public void updateFlowForSourceDevice(IDevice device,
IFlowQueryHandler handler,
FCQueryEvType fcEvType);
/**
* Generic flow query handler to insert FlowMods into the reconcile pipeline.
......
......@@ -47,11 +47,9 @@ import org.openflow.protocol.OFMatch;
import org.openflow.protocol.OFMessage;
import org.openflow.protocol.OFPacketIn;
import org.openflow.protocol.OFPacketOut;
import org.openflow.protocol.OFPort;
import org.openflow.protocol.OFType;
import org.openflow.protocol.action.OFAction;
import org.openflow.protocol.action.OFActionOutput;
import org.openflow.util.U16;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -534,29 +532,6 @@ public abstract class ForwardingBase implements
@Override
public void deviceMoved(IDevice device) {
// Build flow mod to delete based on destination mac == device mac
OFMatch match = new OFMatch();
match.setDataLayerDestination(Ethernet.toByteArray(device.getMACAddress()));
match.setWildcards(OFMatch.OFPFW_ALL ^ OFMatch.OFPFW_DL_DST);
long cookie =
AppCookie.makeCookie(FORWARDING_APP_ID, 0);
OFMessage fm = ((OFFlowMod) floodlightProvider.getOFMessageFactory()
.getMessage(OFType.FLOW_MOD))
.setCommand(OFFlowMod.OFPFC_DELETE)
.setOutPort((short) OFPort.OFPP_NONE.getValue())
.setMatch(match)
.setCookie(cookie)
.setLength(U16.t(OFFlowMod.MINIMUM_LENGTH));
// Flush to all switches
for (IOFSwitch outSw : floodlightProvider.getSwitches().values()) {
try {
outSw.write(fm, null);
} catch (IOException e) {
log.error("Failure sending flow mod delete for moved device",
e);
}
}
}
@Override
......
......@@ -21,16 +21,16 @@ import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Arrays;
import net.floodlightcontroller.core.web.serializers.ByteArrayMACSerializer;
import net.floodlightcontroller.core.web.serializers.UShortSerializer;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.jboss.netty.buffer.ChannelBuffer;
import org.openflow.protocol.serializers.OFPhysicalPortJSONSerializer;
/**
* Represents ofp_phy_port
* @author David Erickson (daviderickson@cs.stanford.edu) - Mar 25, 2010
*/
@JsonSerialize(using=OFPhysicalPortJSONSerializer.class)
public class OFPhysicalPort {
public static int MINIMUM_LENGTH = 48;
public static int OFP_ETH_ALEN = 6;
......@@ -221,6 +221,7 @@ public class OFPhysicalPort {
/**
* @return the portNumber
*/
@JsonSerialize(using=UShortSerializer.class)
public short getPortNumber() {
return portNumber;
}
......@@ -235,6 +236,7 @@ public class OFPhysicalPort {
/**
* @return the hardwareAddress
*/
@JsonSerialize(using=ByteArrayMACSerializer.class)
public byte[] getHardwareAddress() {
return hardwareAddress;
}
......
......@@ -18,17 +18,6 @@ import org.junit.Test;
import org.openflow.protocol.OFStatisticsRequest;
import org.openflow.protocol.OFType;
/**
* The Class FlowCacheTest. Tests flow cache operations for
* (a) adding a flow to the flow cache when flow mod is programmed
* (b) Deleting a flow from flow cache when flow mod removal mesg is received
* (c) Reprogramming a flow based on flows queried from flow cache when a
* device is moved.
* (d) Reprogramming a flow based on flows queried from flow cache when a
* link goes down.
*
* @author subrata
*/
public class FlowReconcileMgrTest extends FloodlightTestCase {
protected MockFloodlightProvider mockFloodlightProvider;
......@@ -81,7 +70,7 @@ public class FlowReconcileMgrTest extends FloodlightTestCase {
flowReconcileMgr.addFlowReconcileListener(r2);
flowReconcileMgr.addFlowReconcileListener(r3);
OFMatchReconcile ofmRcIn = flowReconcileMgr.newOFMatchReconcile();
OFMatchReconcile ofmRcIn = new OFMatchReconcile();
try {
flowReconcileMgr.reconcileFlow(ofmRcIn);
} catch (RuntimeException e) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment