public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpManager {
- private static final Logger s_logger = LoggerFactory.getLogger(BgpManager.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(BgpManager.class);
private BgpConfigurationManager bgpConfigurationMgr;
private FibDSWriter fibDSWriter;
private BgpConfiguration bgpConfiguration = new BgpConfiguration();
try {
wait();
} catch (InterruptedException e) {
- s_logger.error("InterruptedException while waiting for Bgp connection to initialize");
+ LOGGER.error("InterruptedException while waiting for Bgp connection to initialize");
return;
}
}
public void startBgpService() throws TException {
if(bgpThriftClient == null) {
- s_logger.info("Start Bgp Service - bgpThriftClient is null. Unable to start BGP service.");
+ LOGGER.info("Start Bgp Service - bgpThriftClient is null. Unable to start BGP service.");
return;
}
// Now try start bgp - if bgp is already Active, it will tell us, nothing to do then
try {
bgpThriftClient.startBgp((int)bgpConfiguration.getAsNum(), bgpConfiguration.getRouterId());
- s_logger.info("Started BGP with AS number " + (int)bgpConfiguration.getAsNum() + " and router id " + bgpConfiguration.getRouterId());
+ LOGGER.info("Started BGP with AS number " + (int)bgpConfiguration.getAsNum() + " and router id " + bgpConfiguration.getRouterId());
} catch (BgpRouterException be) {
if(be.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
- s_logger.info("bgp server already active");
+ LOGGER.info("bgp server already active");
return;
}
else if(be.getErrorCode() == BgpRouterException.BGP_ERR_NOT_INITED) {
- s_logger.error("bgp server connection not initialized.");
+ LOGGER.error("bgp server connection not initialized.");
reInitConn();
return;
}
else {
- s_logger.error("application error while starting bgp server " + be.getErrorCode());
+ LOGGER.error("application error while starting bgp server " + be.getErrorCode());
return;
}
} catch (TException t) {
- s_logger.error("Could not set up thrift connection with bgp server");
- //s_logger.trace("Transport error while starting bgp server ", t);
+ LOGGER.error("Could not set up thrift connection with bgp server");
+ //LOGGER.trace("Transport error while starting bgp server ", t);
reInitConn();
throw t;
} catch (Exception e) {
- s_logger.error("Error while starting bgp server");
- //s_logger.trace("Bgp Service not started due to exception", e);
+ LOGGER.error("Error while starting bgp server");
+ //LOGGER.trace("Bgp Service not started due to exception", e);
return;
}
@Override
public void onSessionInitiated(ProviderContext session) {
- s_logger.info("BgpManager Session Initiated");
+ LOGGER.info("BgpManager Session Initiated");
try {
final DataBroker dataBroker = session.getSALService(DataBroker.class);
bgpConfigurationMgr = new BgpConfigurationManager(dataBroker, bgpConfiguration, this);
fibDSWriter = new FibDSWriter(dataBroker);
} catch (Exception e) {
- s_logger.error("Error initializing services", e);
+ LOGGER.error("Error initializing services", e);
}
initializeBGPCommunication();
@Override
public void close() throws Exception {
- s_logger.info("BgpManager Closed");
+ LOGGER.info("BgpManager Closed");
//close the client and server ends of the thrift communication
if(bgpThriftClient != null)
protected void addNeighbor(String ipAddress, long asNum) throws TException {
if(bgpThriftClient == null) {
- s_logger.info("Add BGP Neighbor - bgpThriftClient is null. Unable to add BGP Neighbor.");
+ LOGGER.info("Add BGP Neighbor - bgpThriftClient is null. Unable to add BGP Neighbor.");
return;
}
try {
bgpThriftClient.addNeighbor(ipAddress, (int) asNum);
} catch (BgpRouterException b) {
- s_logger.error("Failed to add BGP neighbor " + ipAddress + "due to BgpRouter Exception number " + b.getErrorCode());
- s_logger.error("BgpRouterException trace ", b);
+ LOGGER.error("Failed to add BGP neighbor " + ipAddress + "due to BgpRouter Exception number " + b.getErrorCode());
+ LOGGER.error("BgpRouterException trace ", b);
} catch (TException t) {
- s_logger.error(String.format("Failed adding neighbor %s due to Transport error", ipAddress));
+ LOGGER.error(String.format("Failed adding neighbor %s due to Transport error", ipAddress));
reInitConn();
throw t;
} catch (Exception e) {
- s_logger.error(String.format("Failed adding neighbor %s", ipAddress));
+ LOGGER.error(String.format("Failed adding neighbor %s", ipAddress));
}
}
protected void deleteNeighbor(String ipAddress) throws TException {
if(bgpThriftClient == null) {
- s_logger.info("Delete BGP Neighbor - bgpThriftClient is null. Unable to delete BGP Neighbor.");
+ LOGGER.info("Delete BGP Neighbor - bgpThriftClient is null. Unable to delete BGP Neighbor.");
return;
}
try {
bgpThriftClient.delNeighbor(ipAddress);
} catch (BgpRouterException b) {
- s_logger.error("Failed to delete BGP neighbor " + ipAddress + "due to BgpRouter Exception number " + b.getErrorCode());
- s_logger.error("BgpRouterException trace ", b);
+ LOGGER.error("Failed to delete BGP neighbor " + ipAddress + "due to BgpRouter Exception number " + b.getErrorCode());
+ LOGGER.error("BgpRouterException trace ", b);
}catch (TException t) {
- s_logger.error(String.format("Failed deleting neighbor %s due to Transport error", ipAddress));
+ LOGGER.error(String.format("Failed deleting neighbor %s due to Transport error", ipAddress));
reInitConn();
throw t;
} catch (Exception e) {
- s_logger.error(String.format("Failed deleting neighbor %s", ipAddress));
+ LOGGER.error(String.format("Failed deleting neighbor %s", ipAddress));
}
}
@Override
public void addVrf(String rd, Collection<String> importRts, Collection<String> exportRts) throws Exception {
if(bgpThriftClient == null) {
- s_logger.info("Add BGP vrf - bgpThriftClient is null. Unable to add BGP vrf.");
+ LOGGER.info("Add BGP vrf - bgpThriftClient is null. Unable to add BGP vrf.");
return;
}
try {
bgpThriftClient.addVrf(rd, new ArrayList<>(importRts), new ArrayList<>(exportRts));
} catch (BgpRouterException b) {
- s_logger.error("Failed to add BGP vrf " + rd + "due to BgpRouter Exception number " + b.getErrorCode());
- s_logger.error("BgpRouterException trace ", b);
+ LOGGER.error("Failed to add BGP vrf " + rd + "due to BgpRouter Exception number " + b.getErrorCode());
+ LOGGER.error("BgpRouterException trace ", b);
throw b;
} catch (TException t) {
- s_logger.error(String.format("Failed adding vrf %s due to Transport error", rd));
+ LOGGER.error(String.format("Failed adding vrf %s due to Transport error", rd));
reInitConn();
throw t;
} catch (Exception e) {
- s_logger.error(String.format("Failed adding vrf %s", rd));
+ LOGGER.error(String.format("Failed adding vrf %s", rd));
throw e;
}
}
@Override
public void deleteVrf(String rd) throws Exception {
if(bgpThriftClient == null) {
- s_logger.info("Delete BGP vrf - bgpThriftClient is null. Unable to delete BGP vrf.");
+ LOGGER.info("Delete BGP vrf - bgpThriftClient is null. Unable to delete BGP vrf.");
return;
}
try {
bgpThriftClient.delVrf(rd);
} catch (BgpRouterException b) {
- s_logger.error("Failed to delete BGP vrf " + rd + "due to BgpRouter Exception number " + b.getErrorCode());
- s_logger.error("BgpRouterException trace ", b);
+ LOGGER.error("Failed to delete BGP vrf " + rd + "due to BgpRouter Exception number " + b.getErrorCode());
+ LOGGER.error("BgpRouterException trace ", b);
throw b;
} catch (TException t) {
- s_logger.error(String.format("Failed deleting vrf %s due to Transport error", rd));
+ LOGGER.error(String.format("Failed deleting vrf %s due to Transport error", rd));
reInitConn();
throw t;
} catch (Exception e) {
- s_logger.error(String.format("Failed deleting vrf %s", rd));
+ LOGGER.error(String.format("Failed deleting vrf %s", rd));
throw e;
}
}
try {
bgpThriftClient.addPrefix(rd, prefix, nextHop, vpnLabel);
} catch (BgpRouterException b) {
- s_logger.error("Failed to add BGP prefix " + prefix + "due to BgpRouter Exception number " + b.getErrorCode());
- s_logger.error("BgpRouterException trace ", b);
+ LOGGER.error("Failed to add BGP prefix " + prefix + "due to BgpRouter Exception number " + b.getErrorCode());
+ LOGGER.error("BgpRouterException trace ", b);
throw b;
} catch (TException t) {
- s_logger.error(String.format("Failed adding prefix entry <vrf:prefix:nexthop:vpnlabel> %s:%s:%s:%d due to Transport error",
+ LOGGER.error(String.format("Failed adding prefix entry <vrf:prefix:nexthop:vpnlabel> %s:%s:%s:%d due to Transport error",
rd, prefix, nextHop, vpnLabel));
reInitConn();
throw t;
} catch (Exception e) {
- s_logger.error(String.format("Failed adding prefix entry <vrf:prefix:nexthop:vpnlabel> %s:%s:%s:%d",
+ LOGGER.error(String.format("Failed adding prefix entry <vrf:prefix:nexthop:vpnlabel> %s:%s:%s:%d",
rd, prefix, nextHop, vpnLabel));
throw e;
}
try {
bgpThriftClient.delPrefix(rd, prefix);
} catch (BgpRouterException b) {
- s_logger.error("Failed to delete BGP prefix " + prefix + "due to BgpRouter Exception number " + b.getErrorCode());
- s_logger.error("BgpRouterException trace ", b);
+ LOGGER.error("Failed to delete BGP prefix " + prefix + "due to BgpRouter Exception number " + b.getErrorCode());
+ LOGGER.error("BgpRouterException trace ", b);
throw b;
} catch (TException t) {
- s_logger.error(String.format("Failed deleting prefix entry <vrf:prefix> %s:%s due to Transport error",
+ LOGGER.error(String.format("Failed deleting prefix entry <vrf:prefix> %s:%s due to Transport error",
rd, prefix));
reInitConn();
throw t;
} catch (Exception e) {
- s_logger.error(String.format("Failed deleting prefix entry <vrf:prefix> %s:%s",
+ LOGGER.error(String.format("Failed deleting prefix entry <vrf:prefix> %s:%s",
rd, prefix));
throw e;
}
bgpPort = port;
if(bgpThriftClient == null) {
- s_logger.error("Failed to connect to BGP server since Bgp Thrift Client is not initialized yet.");
+ LOGGER.error("Failed to connect to BGP server since Bgp Thrift Client is not initialized yet.");
return;
}
try {
bgpThriftClient.connect(host, port);
- s_logger.info("Connected to BGP server " + host + " on port " + port);
+ LOGGER.info("Connected to BGP server " + host + " on port " + port);
} catch (BgpRouterException b) {
- s_logger.error("Failed to connect to BGP server " + host + " on port " + port + " due to BgpRouter Exception number " + b.getErrorCode());
+ LOGGER.error("Failed to connect to BGP server " + host + " on port " + port + " due to BgpRouter Exception number " + b.getErrorCode());
//_logger.error("BgpRouterException trace ", b);
throw b;
} catch (TException t) {
- s_logger.error("Failed to initialize BGP Connection due to Transport error ");
+ LOGGER.error("Failed to initialize BGP Connection due to Transport error ");
throw t;
}
catch (Exception e) {
- s_logger.error("Failed to initialize BGP Connection ");
+ LOGGER.error("Failed to initialize BGP Connection ");
throw e;
}
}
try {
bgpConfiguration.setAsNum(asNum);
bgpConfiguration.setRouterId(routerId);
- } catch(Throwable e) {
- s_logger.error("failed configuring bgp ",e);
+ } catch(Exception e) {
+ LOGGER.error("failed configuring bgp ",e);
}
}
try {
bgpThriftClient.reInit();
- s_logger.info("Reinitialized connection to BGP Server " + bgpHost);
+ LOGGER.info("Reinitialized connection to BGP Server " + bgpHost);
} catch (BgpRouterException b) {
- s_logger.error("Failed to reinitialize connection to BGP server " + bgpHost + " on port " + bgpPort + " due to BgpRouter Exception number " + b.getErrorCode());
- s_logger.error("BgpRouterException trace ", b);
+ LOGGER.error("Failed to reinitialize connection to BGP server " + bgpHost + " on port " + bgpPort + " due to BgpRouter Exception number " + b.getErrorCode());
+ LOGGER.error("BgpRouterException trace ", b);
} catch (TException t) {
- s_logger.error("Failed to reinitialize BGP Connection due to Transport error.");
+ LOGGER.error("Failed to reinitialize BGP Connection due to Transport error.");
}
catch (Exception e) {
- s_logger.error("Failed to reinitialize BGP Connection.", e);
+ LOGGER.error("Failed to reinitialize BGP Connection.", e);
}
}
- /*public synchronized void startBgpSync() {
- boolean getRoutes = true;
- readBgpConfiguration();
- try {
- pushConfigurationToBgp();
-
- } catch (BgpRouterException b) {
- s_logger.error("Failed to push configuration to BGP due to BgpRouter Exception number " + b.getErrorCode());
- s_logger.error("BgpRouterException trace ", b);
- if(b.getErrorCode() == BgpRouterException.BGP_ERR_INACTIVE)
- getRoutes = false;
- } catch (Exception e) {
- s_logger.error("Failed to push configuration to bgp ", e);
- }
- if(getRoutes == true)
- pullConfigurationFromBgp();
- //controllerResyncLatch.countDown();
- }*/
-
- /*public void waitForControllerBgpResync() {
- try {
- controllerResyncLatch.await();
- } catch (InterruptedException e) {
- }
- }*/
-
- /*private void pullConfigurationFromBgp() {
- //get routes from bgp server
- s_logger.info("Starting bgp route sync");
- try {
- bgpThriftClient.doRouteSync();
- } catch (BgpRouterException b) {
- s_logger.error("Failed BGP Route sync due to BgpRouter Exception number " + b.getErrorCode());
- s_logger.error("BgpRouterException trace ", b);
- } catch (Exception e) {
- s_logger.error("Failed to pull configuration from bgp ", e);
- }
- }*/
-
- /*private BgpConfiguration readBgpConfiguration() {
- if (cache != null) {
- bgpConfiguration = cache.get("bgpConfiguration");
- if (bgpConfiguration == null) {
- s_logger.info("Created bgp configuration cache");
- bgpConfiguration = new BgpConfiguration();
- cache.put("bgpConfiguration", bgpConfiguration);
- } else {
- s_logger.info("Using bgp configuration cache");
- }
- }
- return bgpConfiguration;
- }*/
-
- /*public synchronized void pushConfigurationToBgp() throws Exception {
- if (bgpConfiguration.getAsNum() == 0) {
- s_logger.error("No as num configured, Skipping the push configuration to bgp ");
- throw new BgpRouterException(BgpRouterException.BGP_ERR_INACTIVE);
- //return;
- }
- if(bgpThriftClient == null) {
- s_logger.error("bgpThriftClient is null. Skipping the push configuration to bgp.");
- throw new BgpRouterException(BgpRouterException.BGP_ERR_INACTIVE);
- //return;
- }
-
- try {
- bgpThriftClient.startBgp((int)bgpConfiguration.getAsNum(), bgpConfiguration.getRouterId());
- s_logger.info("Started BGP with AS number " + (int)bgpConfiguration.getAsNum() + " and router id " + bgpConfiguration.getRouterId());
- } catch (BgpRouterException be) {
- if(be.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
- s_logger.info("bgp server already active");
- return; //the assumption here is that bgp server is configured already with neighbor, vrfs and routes as well
- } if(be.getErrorCode() == BgpRouterException.BGP_ERR_INACTIVE) {
- s_logger.info("bgp server inactive");
- throw be;
- }
-
- else {
- s_logger.error("application error while starting bgp server %d", be.getErrorCode());
- return;
- }
-
- } catch (SocketTimeoutException to) {
- s_logger.error("Socket Timeout error while starting bgp server", to);
- return;
- } catch (TException t) {
- s_logger.error("Transport error while starting bgp server ", t);
- return;
- } catch (Exception e) {
- s_logger.error("Error while starting bgp server", e);
- }
-
- if (bgpConfiguration.getNeighbourIp().trim().length() > 0) {
- try {
- bgpThriftClient.addNeighbor(bgpConfiguration.getNeighbourIp(), bgpConfiguration.getNeighbourAsNum());
- } catch (TException t) {
- s_logger.error("Failed to push vrf to bgp due to Transport error" );
- //retry connection
- reInitConn();
- addNeighbor(bgpConfiguration.getNeighbourIp(), bgpConfiguration.getNeighbourAsNum());
- } catch (Exception e) {
- s_logger.error("Error while starting bgp server", e);
- }
- }
-
- Tenant tenant;
- try {
- tenant = tenantManager.getTenant("NEUTRON");
- } catch (TenantNotFoundException e) {
- s_logger.error("Tenant not found. Skipping push configuration to bgp.");
- return;
- }
- if (tenant != null) {
- int tenantId = tenant.getTenantId();
-
- Set<VpnInstanceInfo> vpnInfos = l3Manager.getVpnInstanceManager().getVpnsForTenant(tenantId);
- s_logger.info("Number of vpns to configure is "+vpnInfos.size());
- for (VpnInstanceInfo vpnInfo: vpnInfos) {
- try {
- bgpThriftClient.addVrf(vpnInfo.getRouteDistinguisher(),
- new ArrayList<>(vpnInfo.getRtImportList()),
- new ArrayList<>(vpnInfo.getRtExportList()));
- } catch (TException t) {
- s_logger.error("Failed to push vrf to bgp due to Transport error" );
- //retry connection
- reInitConn();
- addVrf(vpnInfo.getRouteDistinguisher(), new ArrayList<>(vpnInfo.getRtImportList()),
- new ArrayList<>(vpnInfo.getRtExportList()));
- } catch (Exception e) {
- s_logger.error("Failed to push vrf to bgp ", e);
- }
- }
- for (VpnInstanceInfo vpnInfo: vpnInfos) {
- ConcurrentMap<FibInfo, Object> fibInfos = l3Manager.getVpnInstanceManager().
- getLocalFibInfosForRdCache(vpnInfo.getRouteDistinguisher());
- s_logger.info("Number of fib infos to configure is "+fibInfos.size());
- for (FibInfo fibInfo : fibInfos.keySet()) {
- try {
- bgpThriftClient.addPrefix(vpnInfo.getRouteDistinguisher(), fibInfo.getDestinationPrefix(),
- fibInfo.getNextHopPrefix(), (int) fibInfo.getLabel());
- } catch (TException t) {
- s_logger.error("Failed to push route to bgp due to Transport error" );
- reInitConn();
- addPrefix(vpnInfo.getRouteDistinguisher(), fibInfo.getDestinationPrefix(),
- fibInfo.getNextHopPrefix(), (int) fibInfo.getLabel());
- } catch (Exception e) {
- s_logger.error("Failed to push route to bgp ", e);
- }
- }
- }
- }
-
- }
- */
-
public void disconnect() {
bgpThriftClient.disconnect();
}
public class BgpRouter {
private TTransport transport;
- private TSocket sock;
private TProtocol protocol;
private static BgpConfigurator.Client bgpClient=null;
- private static final Logger logger = LoggerFactory.getLogger(BgpRouter.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(BgpRouter.class);
private final static int ADD_NBR = 1;
private final static int DEL_PFX = 6;
private final static int START_BGP = 7;
- //public final static int BGP_ERR_INITED = 101;
- //public final static int BGP_ERR_NOT_INITED = 102;
-
-
private final static int GET_RTS_INIT = 0;
private final static int GET_RTS_NEXT = 1;
this.bgpPort = bgpPort;
bop = new BgpOp();
try {
- logger.info("Connecting to BGP Server " + bgpHost + " on port " + bgpPort);
+ LOGGER.info("Connecting to BGP Server " + bgpHost + " on port " + bgpPort);
reInit();
} catch (Exception e) {
- logger.error("Failed connecting to BGP server ");
+ LOGGER.error("Failed connecting to BGP server ");
throw e;
}
}
public void disconnect() {
- if(transport != null)
+ if(transport != null) {
transport.close();
+ }
}
public void reInit()
throws TException, BgpRouterException {
- if(transport != null)
+ if(transport != null) {
transport.close();
+ }
transport = new TSocket(bgpHost, bgpPort);
((TSocket)transport).setTimeout(Constants.CL_SKT_TIMEO_MS);
transport.open();
protocol = new TBinaryProtocol(transport);
bgpClient = new BgpConfigurator.Client(protocol);
- if(bop == null)
+ if(bop == null) {
bop = new BgpOp();
+ }
}
private void dispatch(BgpOp op)
throws TException, BgpRouterException {
int result = 1;
- if (bgpClient == null)
+ if (bgpClient == null) {
throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
+ }
switch (op.type) {
case START_BGP:
break;
default: break;
}
- if (result != 0) throw new BgpRouterException(result);
+ if (result != 0) {
+ throw new BgpRouterException(result);
+ }
}
public void startBgp(int asNum, String rtrId)
bop.type = START_BGP;
bop.asNum = asNum;
bop.rtrId = rtrId;
- logger.info("Starting BGP Server with as number " + asNum + " and router ID " + rtrId);
+ LOGGER.info("Starting BGP Server with as number " + asNum + " and router ID " + rtrId);
dispatch(bop);
}
bop.type = ADD_NBR;
bop.nbrIp = nbrIp;
bop.nbrAsNum = nbrAsNum;
- logger.info("Adding BGP Neighbor " + nbrIp + " with as number " + nbrAsNum);
+ LOGGER.info("Adding BGP Neighbor " + nbrIp + " with as number " + nbrAsNum);
dispatch(bop);
}
throws TException, BgpRouterException {
bop.type = DEL_NBR;
bop.nbrIp = nbrIp;
- logger.info("Deleting BGP Neighbor " + nbrIp);
+ LOGGER.info("Deleting BGP Neighbor " + nbrIp);
dispatch(bop);
}
bop.rd = rd;
bop.irts = irts;
bop.erts = erts;
- logger.info("Adding BGP VRF rd: " + rd);
+ LOGGER.info("Adding BGP VRF rd: " + rd);
dispatch(bop);
}
throws TException, BgpRouterException {
bop.type = DEL_VRF;
bop.rd = rd;
- logger.info("Deleting BGP VRF rd: " + rd);
+ LOGGER.info("Deleting BGP VRF rd: " + rd);
dispatch(bop);
}
bop.pfx = prefix;
bop.nh = nexthop;
bop.lbl = label;
- logger.info("Adding BGP route - rd:" + rd + " prefix:" + prefix + " nexthop:" + nexthop + " label:" + label);
+ LOGGER.info("Adding BGP route - rd:" + rd + " prefix:" + prefix + " nexthop:" + nexthop + " label:" + label);
dispatch(bop);
}
bop.type = DEL_PFX;
bop.rd = rd;
bop.pfx = prefix;
- logger.info("Deleting BGP route - rd:" + rd + " prefix:" + prefix);
+ LOGGER.info("Deleting BGP route - rd:" + rd + " prefix:" + prefix);
dispatch(bop);
}
public int initRibSync(BgpSyncHandle handle)
throws TException, BgpRouterException {
- if (bgpClient == null)
+ if (bgpClient == null) {
throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
- if (handle.getState() == BgpSyncHandle.ITERATING)
+ }
+ if (handle.getState() == BgpSyncHandle.ITERATING) {
return BgpRouterException.BGP_ERR_IN_ITER;
+ }
handle.setState(BgpSyncHandle.INITED);
handle.setMore(1);
return 0;
public int endRibSync(BgpSyncHandle handle)
throws TException, BgpRouterException {
- if (bgpClient == null)
+ if (bgpClient == null) {
throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
+ }
int state = handle.getState();
switch (state) {
case BgpSyncHandle.INITED:
public Routes doRibSync(BgpSyncHandle handle)
throws TException, BgpRouterException {
- if (bgpClient == null)
+ if (bgpClient == null) {
throw new BgpRouterException(BgpRouterException.BGP_ERR_NOT_INITED);
+ }
int state = handle.getState();
if (state != BgpSyncHandle.INITED && state != BgpSyncHandle.ITERATING) {
Routes r = new Routes();
handle.setState(BgpSyncHandle.ITERATING);
int winSize = handle.getMaxCount()*handle.getRouteSize();
Routes outRoutes = bgpClient.getRoutes(op, winSize);
- if (outRoutes.errcode != 0)
- return outRoutes;
+ if (outRoutes.errcode != 0) {
+ return outRoutes;
+ }
handle.setMore(outRoutes.more);
- if (outRoutes.more == 0)
+ if (outRoutes.more == 0) {
handle.setState(BgpSyncHandle.DONE);
+ }
return outRoutes;
}
BgpSyncHandle bsh = BgpSyncHandle.getInstance();
try {
- logger.info("Starting BGP Route sync.. ");
+ LOGGER.info("Starting BGP Route sync.. ");
initRibSync(bsh);
while (bsh.getState() != bsh.DONE) {
Routes r = doRibSync(bsh);
if(r.getErrcode() == BgpRouterException.BGP_ERR_INACTIVE) {
//BGP server is inactive; log and return
- logger.error("BGP Server is inactive. Failed BGP Route sync");
+ LOGGER.error("BGP Server is inactive. Failed BGP Route sync");
return;
}
Iterator<Update> iter = r.getUpdatesIterator();
}
}
endRibSync(bsh);
- logger.info("Completed BGP Route sync.");
+ LOGGER.info("Completed BGP Route sync.");
} catch (Exception e) {
throw e;
}
};
- public List<Route> getRoutes()
- throws TException, BgpRouterException {
-
- BgpSyncHandle bsh = BgpSyncHandle.getInstance();
- List<Route> allRoutes = new ArrayList<Route>();
-
- try {
- initRibSync(bsh);
- while (bsh.getState() != bsh.DONE) {
- Routes r = doRibSync(bsh);
- Iterator<Update> iter = r.getUpdatesIterator();
- while (iter.hasNext()) {
- Update u = iter.next();
- Route route = new Route(u.rd, u.prefix, u.prefixlen, u.nexthop, u.label);
-
- allRoutes.add(route);
- }
- }
- endRibSync(bsh);
- } catch (Exception e) {
- throw e;
- }
- return allRoutes;
- };
-
}
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class BgpSyncHandle {
private static BgpSyncHandle handle = null;
+ private static final Logger LOGGER = LoggerFactory.getLogger(BgpSyncHandle.class);
private int more;
private int state;
public static final int ABORTED = 4;
public static final int NEVER_DONE = 5;
- public static final int default_tcp_sock_sz = 87380; //default receive buffer size on linux > 2.4 (SLES 11)
+ public static final int DEFAULT_TCP_SOCK_SZ = 87380; //default receive buffer size on linux > 2.4
private BgpSyncHandle() {
more = 1;
}
public static synchronized BgpSyncHandle getInstance() {
- if (handle == null)
+ if (handle == null) {
handle = new BgpSyncHandle();
+ }
return handle;
}
public int getMaxCount() {
//compute the max count of routes we would like to send
Socket skt = new Socket();
- int sockBufSz = default_tcp_sock_sz;
+ int sockBufSz = DEFAULT_TCP_SOCK_SZ;
try {
sockBufSz = skt.getReceiveBufferSize();
} catch (SocketException s) {
+ LOGGER.warn("Socket Exception while retrieving default socket buffer size");
}
try {
skt.close();
} catch (IOException e) {
+ LOGGER.warn("IO Exception while closing socket for retrieving default socket buffer size");
}
return sockBufSz/getRouteSize();
}
public class BgpThriftService {
- private static final Logger logger = LoggerFactory.getLogger(BgpThriftService.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(BgpThriftService.class);
private int port;
- //private int serverType;
private int maxWorkerThreads;
private int minWorkerThreads;
private TServerTransport serverTransport;
- //private TNonblockingServerTransport serverTransport;
private TServer server;
private BgpUpdateHandler notificationHandler;
private BgpManager bgpManager;
public BgpThriftService(BgpManager bgpMgr, FibDSWriter dsWriter) {
bgpManager = bgpMgr;
notificationHandler = new BgpUpdateHandler(bgpManager, dsWriter);
- //fibDSWriter = dsWriter;
}
public void start() {
- logger.info("BGP Thrift Server starting.");
+ LOGGER.info("BGP Thrift Server starting.");
startBgpThriftServer();
}
public void stop() {
- logger.info("BGP Thrift Server stopping.");
+ LOGGER.info("BGP Thrift Server stopping.");
stopBgpThriftServer();
}
* Destroy method called up after the bundle has been stopped
*/
public void destroy() {
- logger.debug("BGP Thrift Server destroy ");
+ LOGGER.debug("BGP Thrift Server destroy ");
}
/**
public void stopBgpThriftServer() {
try {
- logger.debug("Server stopping");
+ LOGGER.debug("Server stopping");
if (serverTransport != null) {
serverTransport.close();
server.stop();
} catch (Exception e) {
- logger.error("Error while stopping the server - {} {}", getClass().getName(), e.getMessage());
+ LOGGER.error("Error while stopping the server - {} {}", getClass().getName(), e.getMessage());
}
}
private class ThriftRunnable implements Runnable {
@Override
public void run() {
- //notificationHandler = new BgpUpdateHandler(bgpManager);
try {
serverTransport = new TServerSocket(port);
- //serverTransport = new TNonblockingServerSocket(port);
- logger.info("Server Socket on Port {} ", port);
- } catch (TTransportException e) {
- e.printStackTrace();
+ LOGGER.info("Server Socket on Port {} ", port);
+ } catch (TTransportException e) {
+ LOGGER.error("Transport Exception while starting bgp thrift server", e);
return;
}
/* This may need to change. Right now, its as good as a blocking server for each client (client would be
server = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport)
.maxWorkerThreads(maxWorkerThreads).minWorkerThreads(minWorkerThreads)
.processor(new BgpUpdater.Processor<BgpUpdateHandler>(notificationHandler)));
- /*
- THsHaServer.Args args = new THsHaServer.Args(serverTransport);
- args.workerThreads(10);
- server = new THsHaServer(args.processor(new BgpUpdater.Processor<BgpUpdateHandler>(notificationHandler)));*/
-
server.serve();
}
}
class BgpUpdateHandler implements BgpUpdater.Iface {
- private static final Logger logger = LoggerFactory.getLogger(BgpUpdateHandler.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(BgpUpdateHandler.class);
private BgpManager bgpManager;
private FibDSWriter fibDSWriter;
public void onUpdatePushRoute(String rd, String prefix, int plen,
String nexthop, int label) {
- logger.info("Route add ** " + rd + " ** " + prefix + "/" + plen
+ LOGGER.info("Route add ** " + rd + " ** " + prefix + "/" + plen
+ " ** " + nexthop + " ** " + label);
//Write to FIB in Data Store
fibDSWriter.addFibEntryToDS(rd, prefix + "/" + plen, nexthop, label);
}
public void onUpdateWithdrawRoute(String rd, String prefix, int plen) {
- logger.info("Route del ** " + rd + " ** " + prefix + "/" + plen);
+ LOGGER.info("Route del ** " + rd + " ** " + prefix + "/" + plen);
fibDSWriter.removeFibEntryFromDS(rd, prefix + "/" + plen);
}
public void onStartConfigResyncNotification() {
- logger.info("BGP (re)started");
+ LOGGER.info("BGP (re)started");
bgpManager.reInitConn();
}
<bundle>mvn:org.opendaylight.vpnservice/bgpmanager-impl/${project.version}</bundle>
<bundle>mvn:org.opendaylight.vpnservice/mdsalutil-api/${interfacemgr.version}</bundle>
<bundle>mvn:org.opendaylight.vpnservice/mdsalutil-impl/${interfacemgr.version}</bundle>
- <bundle>mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version}</bundle>
<bundle>mvn:org.opendaylight.vpnservice/interfacemgr-api/${interfacemgr.version}</bundle>
<bundle>mvn:org.opendaylight.vpnservice/interfacemgr-impl/${interfacemgr.version}</bundle>
+ <bundle>mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version}</bundle>
<bundle>mvn:org.opendaylight.vpnservice/nexthopmgr-impl/${nexthopmgr.version}</bundle>
<bundle>mvn:org.opendaylight.vpnservice/idmanager-impl/${idmanager.version}</bundle>
<bundle>mvn:org.opendaylight.vpnservice/fibmanager-impl/${fibmanager.version}</bundle>
<!--<bundle>wrap:mvn:javax.servlet/servlet-api/2.5</bundle>-->
<configfile finalname="bgpmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/bgpmanager-impl/${project.version}/xml/config</configfile>
<configfile finalname="mdsalutil-impl-default-config.xml">mvn:org.opendaylight.vpnservice/mdsalutil-impl/${interfacemgr.version}/xml/config</configfile>
- <configfile finalname="vpnmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version}/xml/config</configfile>
<configfile finalname="interfacemgr-impl-default-config.xml">mvn:org.opendaylight.vpnservice/interfacemgr-impl/${interfacemgr.version}/xml/config</configfile>
+ <configfile finalname="vpnmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version}/xml/config</configfile>
<configfile finalname="nexthopmgr-impl-default-config.xml">mvn:org.opendaylight.vpnservice/nexthopmgr-impl/${nexthopmgr.version}/xml/config</configfile>
<configfile finalname="idmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/idmanager-impl/${idmanager.version}/xml/config</configfile>
<configfile finalname="fibmanager-impl-default-config.xml">mvn:org.opendaylight.vpnservice/fibmanager-impl/${fibmanager.version}/xml/config</configfile>
<yang.ext.version>2013.09.07.7-SNAPSHOT</yang.ext.version>
<yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
<mdsal.version>1.2.0-SNAPSHOT</mdsal.version>
+ <vpns.mdsalutil.version>0.0.1-SNAPSHOT</vpns.mdsalutil.version>
</properties>
<dependencies>
<dependency>
<artifactId>model-inventory</artifactId>
<version>${mdsal.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.vpnservice</groupId>
+ <artifactId>mdsalutil-api</artifactId>
+ <version>${vpns.mdsalutil.version}</version>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
package org.opendaylight.vpnservice.interfacemgr.interfaces;
+import java.util.List;
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+
public interface IInterfaceManager {
- public void testApi();
+ public Long getPortForInterface(String ifName);
+ public long getDpnForInterface(String ifName);
+ public String getEndpointIpForDpn(long dpnId);
+ public List<MatchInfo> getInterfaceIngressRule(String ifName);
+ public List<ActionInfo> getInterfaceEgressActions(String ifName);
}
\ No newline at end of file
<dependency>
<groupId>org.opendaylight.vpnservice</groupId>
<artifactId>vpnmanager-impl</artifactId>
- <version>1.0-SNAPSHOT</version>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.vpnservice</groupId>
+ <artifactId>mdsalutil-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.vpnservice</groupId>
+ <artifactId>idmanager-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.vpnservice</groupId>
+ <artifactId>idmanager-impl</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Testing Dependencies -->
<dependency>
--- /dev/null
+package org.opendaylight.vpnservice.interfacemgr;
+
+public class IfmConstants {
+ public static final String IFM_IDPOOL_NAME = "interfaces";
+ public static final long IFM_IDPOOL_START = 1L;
+ public static final String IFM_IDPOOL_SIZE = "65535";
+ public static final String OF_URI_PREFIX = "openflow:";
+ public static final String OF_URI_SEPARATOR = ":";
+ public static final int DEFAULT_IFINDEX = 65536;
+
+}
package org.opendaylight.vpnservice.interfacemgr;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.AbstractDataChangeListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-
-import java.util.Iterator;
-import java.util.List;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.opendaylight.vpnservice.AbstractDataChangeListener;
public class IfmNodeConnectorListener extends AbstractDataChangeListener<NodeConnector> implements AutoCloseable{
private static final Logger LOG = LoggerFactory.getLogger(IfmNodeConnectorListener.class);
@Override
protected void update(InstanceIdentifier<NodeConnector> identifier, NodeConnector original, NodeConnector update) {
- LOG.trace("NodeConnectorUpdated: key: " + identifier + ", original=" + original + ", update=" + update );
ifManager.processPortUpdate(original, update);
}
--- /dev/null
+package org.opendaylight.vpnservice.interfacemgr;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.Pools;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPoolKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+
+public class IfmUtil {
+
+ public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
+ /*
+ * NodeConnectorId is of form 'openflow:dpnid:portnum'
+ */
+ String[] split = portId.getValue().split(IfmConstants.OF_URI_SEPARATOR);
+ return split[1];
+ }
+
+
+ public static NodeId buildDpnNodeId(long dpnId) {
+ return new NodeId(IfmConstants.OF_URI_PREFIX + dpnId);
+ }
+
+ public static InstanceIdentifier<Interface> buildId(String interfaceName) {
+ //TODO Make this generic and move to AbstractDataChangeListener or Utils.
+ InstanceIdentifierBuilder<Interface> idBuilder =
+ InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));
+ InstanceIdentifier<Interface> id = idBuilder.build();
+ return id;
+ }
+
+ public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
+ InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder =
+ InstanceIdentifier.builder(InterfacesState.class)
+ .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class,
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id = idBuilder.build();
+ return id;
+ }
+
+ public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey getStateInterfaceKeyFromName(
+ String name) {
+ return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(name);
+ }
+
+ public static InstanceIdentifier<IdPool> getPoolId(String poolName){
+ InstanceIdentifier.InstanceIdentifierBuilder<IdPool> idBuilder =
+ InstanceIdentifier.builder(Pools.class).child(IdPool.class, new IdPoolKey(poolName));
+ InstanceIdentifier<IdPool> id = idBuilder.build();
+ return id;
+ }
+}
*/
package org.opendaylight.vpnservice.interfacemgr;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
-import java.math.BigInteger;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state._interface.StatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state._interface.Statistics;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
-import com.google.common.util.concurrent.FutureCallback;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.AbstractDataChangeListener;
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
+import org.opendaylight.vpnservice.mdsalutil.ActionType;
+import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.vpnservice.AbstractDataChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.id.pool.GeneratedIds;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfMpls;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfStackedVlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.Mpls;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.StackedVlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
-public class InterfaceManager extends AbstractDataChangeListener<Interface> implements AutoCloseable{
+public class InterfaceManager extends AbstractDataChangeListener<Interface> implements AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(InterfaceManager.class);
private ListenerRegistration<DataChangeListener> listenerRegistration;
private final DataBroker broker;
+ private final IdManager idManager;
+ private final Map<NodeConnectorId, String> mapNcToInterfaceName = new ConcurrentHashMap<>();
+ private final Map<NodeId, String> dbDpnEndpoints = new ConcurrentHashMap<>();
private static final FutureCallback<Void> DEFAULT_CALLBACK =
new FutureCallback<Void>() {
public void onFailure(Throwable error) {
LOG.error("Error in Datastore write operation", error);
- };
+ }
};
- public InterfaceManager(final DataBroker db) {
+ public InterfaceManager(final DataBroker db, final IdManager idmgr) {
super(Interface.class);
broker = db;
+ idManager = idmgr;
registerListener(db);
}
@Override
protected void add(final InstanceIdentifier<Interface> identifier,
final Interface imgrInterface) {
- LOG.trace("key: " + identifier + ", value=" + imgrInterface );
+ LOG.trace("Adding interface key: " + identifier + ", value=" + imgrInterface );
addInterface(identifier, imgrInterface);
}
private InstanceIdentifier<Interface> buildId(final InstanceIdentifier<Interface> identifier) {
//TODO Make this generic and move to AbstractDataChangeListener or Utils.
final InterfaceKey key = identifier.firstKeyOf(Interface.class, InterfaceKey.class);
- String interfaceName = key.getName();
+ return buildId(key.getName());
+ }
+
+ private InstanceIdentifier<Interface> buildId(String interfaceName) {
+ //TODO Make this generic and move to AbstractDataChangeListener or Utils.
InstanceIdentifierBuilder<Interface> idBuilder =
InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));
InstanceIdentifier<Interface> id = idBuilder.build();
return id;
}
- private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> buildStateInterfaceId(String interfaceName) {
- //TODO Make this generic and move to AbstractDataChangeListener or Utils.
- InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder =
- InstanceIdentifier.builder(InterfacesState.class)
- .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class,
- new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName));
- InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id = idBuilder.build();
- return id;
- }
private void addInterface(final InstanceIdentifier<Interface> identifier,
- final Interface imgrInterface) {
- InstanceIdentifier<Interface> id = buildId(identifier);
- Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
- if(port.isPresent()) {
- Interface interf = port.get();
- NodeConnector nodeConn = getNodeConnectorFromInterface(interf);
- updateInterfaceState(identifier, interf, nodeConn);
- /* TODO:
- * 1. Get interface-id from id manager
- * 2. Update interface-state with following:
- * admin-status = set to enable value
- * oper-status = Down [?]
- * if-index = interface-id
- * FIXME:
- * 1. Get operational data from node-connector-id?
- *
- */
+ final Interface interf) {
+ NodeConnector nodeConn = getNodeConnectorFromDataStore(interf);
+ NodeConnectorId ncId = null;
+ updateInterfaceState(identifier, interf, nodeConn);
+ if (nodeConn == null) {
+ ncId = getNodeConnectorIdFromInterface(interf);
+ } else {
+ ncId = nodeConn.getId();
+ }
+ mapNcToInterfaceName.put(ncId, interf.getName());
+ if(interf.getType().isAssignableFrom(L3tunnel.class)) {
+ NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
+ IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class);
+ dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue());
+ LOG.trace("dbDpnEndpoints: {}",dbDpnEndpoints);
}
}
* if-index = interface-id
*/
InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id =
- buildStateInterfaceId(interf.getName());
+ IfmUtil.buildStateInterfaceId(interf.getName());
Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> stateIf =
read(LogicalDatastoreType.OPERATIONAL, id);
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface;
new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder();
if(!stateIf.isPresent()) {
// TODO: Get interface-id from IdManager
+ String ifName = interf.getName();
ifaceBuilder.setAdminStatus((interf.isEnabled()) ? org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Up :
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus.Down);
- ifaceBuilder.setOperStatus(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus.Down);
- ifaceBuilder.setIfIndex(200).setName(interf.getName()).setType(interf.getType());
- ifaceBuilder.setKey(getStateInterfaceKeyFromName(interf.getName()));
- //ifaceBuilder.setStatistics(createStatistics(interf.getName(), nodeConn));
+ ifaceBuilder.setOperStatus(getOperStatus(nodeConn));
+
+ ifaceBuilder.setIfIndex(getIfIndex(ifName)).setName(ifName).setType(interf.getType());
+ ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName));
stateIface = ifaceBuilder.build();
LOG.trace("Adding stateIface {} and id {} to OPERATIONAL DS", stateIface, id);
asyncWrite(LogicalDatastoreType.OPERATIONAL, id, stateIface, DEFAULT_CALLBACK);
if(interf.getType() != null) {
ifaceBuilder.setType(interf.getType());
}
-
+ ifaceBuilder.setOperStatus(getOperStatus(nodeConn));
stateIface = ifaceBuilder.build();
LOG.trace("updating OPERATIONAL data store with stateIface {} and id {}", stateIface, id);
asyncUpdate(LogicalDatastoreType.OPERATIONAL, id, stateIface, DEFAULT_CALLBACK);
}
}
- /*
- private void setAugmentations(
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder,
- InstanceIdentifier<Interface> identifier, Interface interf) {
- // TODO Add code for all augmentations
- InstanceIdentifier<IfL3tunnel> ifL3TunnelPath = identifier.augmentation(IfL3tunnel.class);
- Optional<IfL3tunnel> l3Tunnel = read(LogicalDatastoreType.CONFIGURATION, ifL3TunnelPath);
- String ifName = interf.getName();
- if(l3Tunnel.isPresent()) {
- l3Tunnel.get();
+ private Integer getIfIndex(String ifName) {
+ GetUniqueIdInput getIdInput = new GetUniqueIdInputBuilder()
+ .setPoolName(IfmConstants.IFM_IDPOOL_NAME).setIdKey(ifName)
+ .build();
+ //TODO: Proper error handling once IdManager code is complete
+ try {
+ Future<RpcResult<GetUniqueIdOutput>> result = idManager.getUniqueId(getIdInput);
+ RpcResult<GetUniqueIdOutput> rpcResult = result.get();
+ return rpcResult.getResult().getIdValue().intValue();
+ } catch (NullPointerException | InterruptedException | ExecutionException e) {
+ LOG.trace("",e);
}
- }
- */
-
- private Statistics createStatistics(String name, NodeConnector nodeConn) {
- Counter64 init64 = new Counter64(new BigInteger("0000000000000000"));
- Counter32 init32 = new Counter32((long) 0);
- StatisticsBuilder statBuilder = new StatisticsBuilder();
- statBuilder.setDiscontinuityTime(new DateAndTime("2015-04-04T00:00:00Z"))
- .setInBroadcastPkts(init64).setInDiscards(init32).setInErrors(init32).setInMulticastPkts(init64)
- .setInOctets(init64).setInUnicastPkts(init64).setInUnknownProtos(init32).setOutBroadcastPkts(init64)
- .setOutDiscards(init32).setOutErrors(init32).setOutMulticastPkts(init64).setOutOctets(init64)
- .setOutUnicastPkts(init64);
- return statBuilder.build();
+ /* This currently returns null, so let us get it from IdManager DS
+ * TODO: Start-delete-me
+ */
+
+ InstanceIdentifier<IdPool> id = IfmUtil.getPoolId(IfmConstants.IFM_IDPOOL_NAME);
+ Optional<IdPool> globalPool = read(LogicalDatastoreType.OPERATIONAL, id );
+ Long newIdValue = null;
+ if (globalPool.isPresent()) {
+ IdPool pool = globalPool.get();
+ List<GeneratedIds> generatedIds = pool.getGeneratedIds();
+ if ((generatedIds != null) && !generatedIds.isEmpty()) {
+ for (GeneratedIds gen_id : generatedIds) {
+ if (gen_id.getIdKey().equals(ifName)) {
+ newIdValue = gen_id.getIdValue();
+ LOG.debug("Id {} found for interface %s ", newIdValue, ifName);
+ return newIdValue.intValue();
+ }
+ }
+ }
+ }
+ //TODO: End-delete-me
+ LOG.debug("Unable to get valid ifIndex for interface {}", ifName);
+ return IfmConstants.DEFAULT_IFINDEX;
}
- private org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey getStateInterfaceKeyFromName(
- String name) {
- return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(name);
+ private OperStatus getOperStatus(NodeConnector nodeConn) {
+ LOG.trace("nodeConn is {}", nodeConn);
+ if(nodeConn == null) {
+ return OperStatus.Down;
+ }else {
+ return OperStatus.Up;
+ }
}
- private NodeConnector getNodeConnectorFromInterface(Interface interf) {
+ private NodeConnector getNodeConnectorFromDataStore(Interface interf) {
NodeConnectorId ncId = interf.getAugmentation(BaseIds.class).getOfPortId();
//TODO: Replace with MDSAL Util method
- NodeId nodeId = new NodeId(ncId.getValue().substring(0,ncId.getValue().lastIndexOf(":")));
+ NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
InstanceIdentifier<NodeConnector> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
.child(Node.class, new NodeKey(nodeId))
.child(NodeConnector.class, new NodeConnectorKey(ncId)).build();
return null;
}
+ private NodeConnectorId getNodeConnectorIdFromInterface(Interface interf) {
+ return interf.getAugmentation(BaseIds.class).getOfPortId();
+ }
+
private void delInterface(final InstanceIdentifier<Interface> identifier,
final Interface delInterface) {
InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id =
- buildStateInterfaceId(delInterface.getName());
+ IfmUtil.buildStateInterfaceId(delInterface.getName());
Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> stateIf =
read(LogicalDatastoreType.OPERATIONAL, id);
- if(!stateIf.isPresent()) {
+ if(stateIf.isPresent()) {
LOG.trace("deleting interfaces:state OPERATIONAL data store with id {}", id);
asyncRemove(LogicalDatastoreType.OPERATIONAL, id, DEFAULT_CALLBACK);
+ NodeConnectorId ncId = getNodeConnectorIdFromInterface(delInterface);
+ if(ncId != null) {
+ mapNcToInterfaceName.remove(ncId);
+ if(delInterface.getType().isAssignableFrom(L3tunnel.class)) {
+ Node node = getNodeFromDataStore(delInterface);
+ if((node != null) &&(node.getNodeConnector().isEmpty())) {
+ dbDpnEndpoints.remove(node.getId());
+ }
+ }
+ }
}
}
+ private Node getNodeFromDataStore(Interface interf) {
+ NodeConnectorId ncId = interf.getAugmentation(BaseIds.class).getOfPortId();
+ //TODO: Replace with MDSAL Util method
+ NodeId nodeId = getNodeIdFromNodeConnectorId(ncId);
+ InstanceIdentifier<Node> ncIdentifier = InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class, new NodeKey(nodeId)).build();
+
+ Optional<Node> dpn = read(LogicalDatastoreType.OPERATIONAL, ncIdentifier);
+ if(dpn.isPresent()) {
+ Node node = dpn.get();
+ LOG.trace("node: {}",node);
+ return node;
+ }
+ return null;
+ }
+
private void updateInterface(final InstanceIdentifier<Interface> identifier,
- final Interface original, final Interface udpate) {
+ final Interface original, final Interface update) {
InstanceIdentifier<Interface> id = buildId(identifier);
Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
if(port.isPresent()) {
Interface interf = port.get();
- //TODO: Update operational data
+ NodeConnector nc = getNodeConnectorFromDataStore(update);
+ updateInterfaceState(identifier, update, nc);
+ /*
+ * Alternative is to get from interf and update map irrespective if NCID changed or not.
+ */
+ if(nc != null) {
+ // Name doesn't change. Is it present in update?
+ mapNcToInterfaceName.put(nc.getId(), original.getName());
+ if(interf.getType().isAssignableFrom(L3tunnel.class)) {
+ NodeId nodeId = getNodeIdFromNodeConnectorId(nc.getId());
+ IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class);
+ dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue());
+ LOG.trace("dbEndpoints: {}",dbDpnEndpoints);
+ }
+ }
}
}
@Override
protected void remove(InstanceIdentifier<Interface> identifier, Interface del) {
- LOG.trace("key: " + identifier + ", value=" + del );
+ LOG.trace("remove - key: " + identifier + ", value=" + del );
delInterface(identifier, del);
}
@Override
protected void update(InstanceIdentifier<Interface> identifier, Interface original, Interface update) {
- LOG.trace("key: " + identifier + ", original=" + original + ", update=" + update );
+ LOG.trace("update - key: " + identifier + ", original=" + original + ", update=" + update );
updateInterface(identifier, original, update);
}
- private <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
+ protected <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- tx.put(datastoreType, path, data, true);
- Futures.addCallback(tx.submit(), callback);
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.put(datastoreType, path, data, true);
+ Futures.addCallback(tx.submit(), callback);
}
- private <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
+ protected <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- tx.merge(datastoreType, path, data, true);
- Futures.addCallback(tx.submit(), callback);
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.merge(datastoreType, path, data, true);
+ Futures.addCallback(tx.submit(), callback);
}
- private <T extends DataObject> void asyncRemove(LogicalDatastoreType datastoreType,
+ protected <T extends DataObject> void asyncRemove(LogicalDatastoreType datastoreType,
InstanceIdentifier<T> path, FutureCallback<Void> callback) {
- WriteTransaction tx = broker.newWriteOnlyTransaction();
- tx.delete(datastoreType, path);
- Futures.addCallback(tx.submit(), callback);
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.delete(datastoreType, path);
+ Futures.addCallback(tx.submit(), callback);
}
- public void processPortAdd(NodeConnector port) {
- String strPortId = port.getId().getValue();
+ void processPortAdd(NodeConnector port) {
+ NodeConnectorId portId = port.getId();
FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class);
- LOG.debug("PortAdd: PortId { "+strPortId+"} PortName {"+ofPort.getName()+"}");
+ LOG.debug("PortAdd: PortId { " + portId.getValue() + "} PortName {" + ofPort.getName() + "}");
+ String ifName = this.mapNcToInterfaceName.get(portId);
+ setInterfaceOperStatus(ifName, OperStatus.Up);
}
- public void processPortUpdate(NodeConnector oldPort, NodeConnector update) {
- String oldPortId = oldPort.getId().getValue();
- FlowCapableNodeConnector oldOfPort = oldPort.getAugmentation(FlowCapableNodeConnector.class);
- String strPortId = update.getId().getValue();
- FlowCapableNodeConnector ofPort = update.getAugmentation(FlowCapableNodeConnector.class);
- LOG.debug("PortUpdate: { "+strPortId+", "+ofPort.getName()+"}");
+ void processPortUpdate(NodeConnector oldPort, NodeConnector update) {
+ //TODO: Currently nothing to do here.
+ LOG.trace("ifMap: {}, dpnMap: {}", mapNcToInterfaceName, dbDpnEndpoints);
}
- public void processPortDelete(NodeConnector port) {
- String strPortId = port.getId().getValue();
+ void processPortDelete(NodeConnector port) {
+ NodeConnectorId portId = port.getId();
FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class);
- LOG.debug("PortDelete: PortId { "+strPortId+"} PortName {"+ofPort.getName()+"}");
+ LOG.debug("PortDelete: PortId { "+portId.getValue()+"} PortName {"+ofPort.getName()+"}");
+ String ifName = this.mapNcToInterfaceName.get(portId);
+ setInterfaceOperStatus(ifName, OperStatus.Down);
+ }
+
+ private void setInterfaceOperStatus(String ifName, OperStatus opStatus) {
+ if (ifName != null) {
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> id =
+ IfmUtil.buildStateInterfaceId(ifName);
+ Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> stateIf =
+ read(LogicalDatastoreType.OPERATIONAL, id);
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface;
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder =
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder();
+ if (stateIf.isPresent()) {
+ stateIface = ifaceBuilder.setOperStatus(opStatus).build();
+ LOG.trace("Setting OperStatus for {} to {} in OPERATIONAL DS", ifName, opStatus);
+ asyncUpdate(LogicalDatastoreType.OPERATIONAL, id, stateIface, DEFAULT_CALLBACK);
+ }
+ }
+ }
+
+ private Interface getInterfaceByIfName(String ifName) {
+ InstanceIdentifier<Interface> id = buildId(ifName);
+ Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
+ if(port.isPresent()) {
+ return port.get();
+ }
+ return null;
+ }
+
+ Long getPortForInterface(String ifName) {
+ Interface iface = getInterfaceByIfName(ifName);
+ return getPortNumForInterface(iface);
+ }
+
+ long getDpnForInterface(String ifName) {
+ Interface iface = getInterfaceByIfName(ifName);
+ try {
+ NodeConnector port = getNodeConnectorFromDataStore(iface);
+ //TODO: This should be an MDSAL Util method
+ return Long.parseLong(IfmUtil.getDpnFromNodeConnectorId(port.getId()));
+ } catch (NullPointerException e) {
+ LOG.error("OFPort for Interface {} not found", ifName);
+ }
+ return 0L;
+ }
+
+ String getEndpointIpForDpn(long dpnId) {
+ //TODO: This should be MDSAL Util function
+ NodeId dpnNodeId = IfmUtil.buildDpnNodeId(dpnId);
+ return dbDpnEndpoints.get(dpnNodeId);
+ }
+
+ List<MatchInfo> getInterfaceIngressRule(String ifName) {
+ Interface iface = getInterfaceByIfName(ifName);
+ List<MatchInfo> matches = new ArrayList<MatchInfo>();
+ Class<? extends InterfaceType> ifType = iface.getType();
+ long dpn = this.getDpnForInterface(ifName);
+ long portNo = this.getPortNumForInterface(iface).longValue();
+ matches.add(new MatchInfo(MatchFieldType.in_port, new long[] {dpn, portNo}));
+
+ if (ifType.isInstance(L2vlan.class)) {
+ IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class);
+ long vlanVid = vlanIface.getVlanId().longValue();
+ if (vlanVid != 0) {
+ matches.add(new MatchInfo(MatchFieldType.vlan_vid,
+ new long[] {vlanVid}));
+ LOG.trace("L2Vlan: {}",vlanIface);
+ }
+ } else if (ifType.isInstance(L3tunnel.class)) {
+ //TODO: Handle different tunnel types
+ IfL3tunnel ifL3Tunnel = iface.getAugmentation(IfL3tunnel.class);
+ Class<? extends TunnelTypeBase> tunnType = ifL3Tunnel.getTunnelType();
+ LOG.trace("L3Tunnel: {}",ifL3Tunnel);
+ } else if (ifType.isAssignableFrom(StackedVlan.class)) {
+ IfStackedVlan ifStackedVlan = iface.getAugmentation(IfStackedVlan.class);
+ LOG.trace("StackedVlan: {}",ifStackedVlan);
+ } else if (ifType.isAssignableFrom(Mpls.class)) {
+ IfMpls ifMpls = iface.getAugmentation(IfMpls.class);
+ LOG.trace("Mpls: {}",ifMpls);
+ }
+ return matches;
+ }
+
+ public List<ActionInfo> getInterfaceEgressActions(String ifName) {
+ Interface iface = getInterfaceByIfName(ifName);
+
+ List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
+ Class<? extends InterfaceType> ifType = iface.getType();
+ long dpn = this.getDpnForInterface(ifName);
+ long portNo = this.getPortNumForInterface(iface).longValue();
+
+ if (iface.isEnabled()) {
+
+ if(ifType.isAssignableFrom(L2vlan.class)) {
+ IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class);
+ long vlanVid = vlanIface.getVlanId();
+ LOG.trace("L2Vlan: {}",vlanIface);
+ if (vlanVid != 0) {
+ listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
+ listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
+ new String[] { Long.toString(vlanVid) }));
+ }
+ listActionInfo.add(new ActionInfo(ActionType.output, new String[] { Long.toString(portNo)}));
+
+ } else if (ifType.isAssignableFrom(L3tunnel.class)) {
+ //TODO: Handle different tunnel types
+ IfL3tunnel ifL3Tunnel = iface.getAugmentation(IfL3tunnel.class);
+ Class<? extends TunnelTypeBase> tunnType = ifL3Tunnel.getTunnelType();
+ LOG.trace("L3Tunnel: {}",ifL3Tunnel);
+ //TODO: check switch_type and configure accordingly
+ listActionInfo.add(new ActionInfo(ActionType.output, new String[] { Long.toString(portNo)}));
+
+ } else if (ifType.isAssignableFrom(StackedVlan.class)) {
+ IfStackedVlan ifStackedVlan = iface.getAugmentation(IfStackedVlan.class);
+ LOG.trace("StackedVlan: {}",ifStackedVlan);
+ // TODO: TBD
+ } else if (ifType.isAssignableFrom(Mpls.class)) {
+ IfMpls ifMpls = iface.getAugmentation(IfMpls.class);
+ LOG.trace("Mpls: {}",ifMpls);
+ // TODO: TBD
+ }
+ }
+ return listActionInfo;
+
+ }
+
+ private NodeId getNodeIdFromNodeConnectorId(NodeConnectorId ncId) {
+ return new NodeId(ncId.getValue().substring(0,ncId.getValue().lastIndexOf(":")));
+ }
+
+ private Long getPortNumForInterface(Interface iface) {
+ try {
+ NodeConnector port = getNodeConnectorFromDataStore(iface);
+ FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class);
+ return ofPort.getPortNumber().getUint32();
+ } catch (Exception e) {
+ LOG.error("OFPort for Interface {} not found", iface.getName());
+ }
+ return null;
}
}
*/
package org.opendaylight.vpnservice.interfacemgr;
+import java.math.BigInteger;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInputBuilder;
+import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable, IInterfaceManager {
private InterfaceManager interfaceManager;
private IfmNodeConnectorListener ifmNcListener;
+ private IdManager idManager;
@Override
public void onSessionInitiated(ProviderContext session) {
LOG.info("InterfacemgrProvider Session Initiated");
try {
final DataBroker dataBroker = session.getSALService(DataBroker.class);
- interfaceManager = new InterfaceManager(dataBroker);
+ idManager = new IdManager(dataBroker);
+ interfaceManager = new InterfaceManager(dataBroker, idManager);
ifmNcListener = new IfmNodeConnectorListener(dataBroker, interfaceManager);
+ createIdPool();
} catch (Exception e) {
LOG.error("Error initializing services", e);
}
- //TODO: Make this debug
- LOG.info("Interfacemgr services initiated");
+ }
+
+ private void createIdPool() {
+ CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
+ .setPoolName(IfmConstants.IFM_IDPOOL_NAME)
+ .setIdStart(IfmConstants.IFM_IDPOOL_START)
+ .setPoolSize(new BigInteger(IfmConstants.IFM_IDPOOL_SIZE))
+ .build();
+ //TODO: Error handling
+ Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
+ try {
+ if ((result != null) && (result.get().isSuccessful())) {
+ LOG.debug("Created IdPool for InterfaceMgr");
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Failed to create idPool for InterfaceMgr",e);
+ }
}
@Override
}
@Override
- public void testApi() {
- LOG.debug("Testing interface mgr api");
+ public Long getPortForInterface(String ifName) {
+ return interfaceManager.getPortForInterface(ifName);
+ }
+
+ @Override
+ public long getDpnForInterface(String ifName) {
+ return interfaceManager.getDpnForInterface(ifName);
+ }
+
+ @Override
+ public String getEndpointIpForDpn(long dpnId) {
+ return interfaceManager.getEndpointIpForDpn(dpnId);
+ }
+
+ @Override
+ public List<MatchInfo> getInterfaceIngressRule(String ifName) {
+ return interfaceManager.getInterfaceIngressRule(ifName);
+ }
+
+ @Override
+ public List<ActionInfo> getInterfaceEgressActions(String ifName) {
+ return interfaceManager.getInterfaceEgressActions(ifName);
}
-}
\ No newline at end of file
+}
--- /dev/null
+package org.opendaylight.vpnservice.interfacemgr.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+
+public class IfmUtilTest {
+
+ @Mock NodeConnectorId ncId;
+ MockDataChangedEvent event;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testDpnConversions() {
+ String NodeId = IfmUtil.buildDpnNodeId(101L).getValue();
+ assertEquals("openflow:101", NodeId);
+ when(ncId.getValue()).thenReturn("openflow:101:11");
+ assertEquals("101",IfmUtil.getDpnFromNodeConnectorId(ncId));
+ }
+
+}
--- /dev/null
+package org.opendaylight.vpnservice.interfacemgr.test;
+
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.idmanager.IdManager;
+import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
+import org.opendaylight.vpnservice.interfacemgr.InterfaceManager;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIdsBuilder;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+@RunWith(MockitoJUnitRunner.class)
+public class InterfaceManagerTest {
+
+ private String ifName = "dpn1-if0";
+ Map<InstanceIdentifier<?>,DataObject> written = new HashMap<>();
+ Map<InstanceIdentifier<?>,DataObject> updated = new HashMap<>();
+ Set<InstanceIdentifier<?>> removed = new HashSet<>();
+
+ @Mock DataBroker dataBroker;
+ @Mock IdManager idManager;
+ @Mock ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
+ @Mock ReadOnlyTransaction mockReadTx;
+ @Mock WriteTransaction mockWriteTx;
+
+ MockDataChangedEvent dataChangeEvent;
+ InterfaceManager imgr;
+
+ NodeConnectorId ncId;
+ NodeConnector nc;
+ Interface interf;
+ InstanceIdentifier<Interface> ifIdent;
+ InstanceIdentifier<NodeConnector> ncIdent;
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifsIdent;
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface;
+ InstanceIdentifier<IdPool> poolIdent;
+
+ @Before
+ public void setUp() throws Exception {
+ when(dataBroker.registerDataChangeListener(
+ any(LogicalDatastoreType.class),
+ any(InstanceIdentifier.class),
+ any(DataChangeListener.class),
+ any(DataChangeScope.class)))
+ .thenReturn(dataChangeListenerRegistration);
+ dataChangeEvent = new MockDataChangedEvent();
+ imgr = new InterfaceManager(dataBroker, idManager) {
+ protected <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+ /*
+ * Do nothing for now. Ideally we should capture this information
+ * and use it to verify results.
+ */
+ written.put(path, data);
+ }
+ protected <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+ updated.put(path, data);
+ }
+
+ protected <T extends DataObject> void asyncRemove(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path, FutureCallback<Void> callback) {
+ removed.add(path);
+ }
+
+ };
+ setupMocks();
+ }
+
+ private void setupMocks() {
+ ncId = new NodeConnectorId("openflow:10:111");
+ nc = buildNodeConnector(ncId);
+ interf = buildInterface(ifName, "Test Interface1", true, L2vlan.class, ncId);
+ ifIdent = IfmUtil.buildId(ifName);
+ ncIdent = getNcIdent("openflow:10",ncId);
+ ifsIdent = IfmUtil.buildStateInterfaceId(interf.getName());
+ stateIface = buildStateInterface(ifName);
+ poolIdent = IfmUtil.getPoolId("interfaces");
+
+ // Setup mocks
+ when(dataBroker.newReadOnlyTransaction()).thenReturn(mockReadTx);
+ when(dataBroker.newWriteOnlyTransaction()).thenReturn(mockWriteTx);
+ }
+
+ @Test
+ public void testAdd() {
+ Optional<Interface> expected = Optional.of(interf);
+ Optional<NodeConnector> expectedNc = Optional.of(nc);
+ doReturn(Futures.immediateCheckedFuture(expected)).when(mockReadTx).read(
+ LogicalDatastoreType.CONFIGURATION, ifIdent);
+ doReturn(Futures.immediateCheckedFuture(expectedNc)).when(mockReadTx).read(
+ LogicalDatastoreType.OPERATIONAL, ncIdent);
+ doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadTx).read(
+ LogicalDatastoreType.OPERATIONAL, ifsIdent);
+ doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadTx).read(
+ LogicalDatastoreType.OPERATIONAL, poolIdent);
+
+ dataChangeEvent.created.put(IfmUtil.buildId(ifName), interf);
+ imgr.onDataChanged(dataChangeEvent);
+ //Add some verifications
+ assertEquals(1,written.size());
+ assertEquals(0,updated.size());
+ assertEquals(0, removed.size());
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface writtenIface =
+ (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface)written.get(ifsIdent);
+ assertEquals(stateIface.getKey(), writtenIface.getKey());
+ assertEquals(65536, writtenIface.getIfIndex().intValue());
+ assertEquals(OperStatus.Up, writtenIface.getOperStatus());
+ }
+
+ @Test
+ public void testUpdate() {
+ Optional<Interface> expected = Optional.of(interf);
+ Optional<NodeConnector> expectedNc = Optional.of(nc);
+ Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> expectedStateIf = Optional.of(stateIface);
+ doReturn(Futures.immediateCheckedFuture(expected)).when(mockReadTx).read(
+ LogicalDatastoreType.CONFIGURATION, ifIdent);
+ doReturn(Futures.immediateCheckedFuture(expectedNc)).when(mockReadTx).read(
+ LogicalDatastoreType.OPERATIONAL, ncIdent);
+ doReturn(Futures.immediateCheckedFuture(expectedStateIf)).when(mockReadTx).read(
+ LogicalDatastoreType.OPERATIONAL, ifsIdent);
+ doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadTx).read(
+ LogicalDatastoreType.OPERATIONAL, poolIdent);
+ dataChangeEvent.original.put(IfmUtil.buildId(ifName), interf);
+ dataChangeEvent.updated.put(IfmUtil.buildId(ifName), interf);
+ imgr.onDataChanged(dataChangeEvent);
+ //Add some verifications
+
+ assertEquals(0,written.size());
+ assertEquals(1,updated.size());
+ assertEquals(0, removed.size());
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface updatedIface =
+ (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface)updated.get(ifsIdent);
+ assertNotEquals(stateIface.getKey(),updatedIface.getKey());
+ assertNull(updatedIface.getIfIndex());
+ assertEquals(OperStatus.Up, updatedIface.getOperStatus());
+ }
+
+ private org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface buildStateInterface(
+ String ifName) {
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder =
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder();
+ ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName));
+ return ifaceBuilder.build();
+ }
+
+ private InstanceIdentifier<NodeConnector> getNcIdent(String nodeKey, NodeConnectorId ncId) {
+ return InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class, new NodeKey(new NodeId(nodeKey)))
+ .child(NodeConnector.class, new NodeConnectorKey(ncId))
+ .build();
+ }
+
+ private Interface buildInterface(String ifName, String desc, boolean enabled, Class<? extends InterfaceType> ifType, NodeConnectorId ncId) {
+ InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(ifName)).setName(ifName)
+ .setDescription(desc).setEnabled(enabled).setType(ifType);
+
+ BaseIds baseId = new BaseIdsBuilder().setOfPortId(ncId).build();
+ builder.addAugmentation(BaseIds.class, baseId);
+ return builder.build();
+ }
+
+ private NodeConnector buildNodeConnector(NodeConnectorId ncId) {
+ NodeConnectorBuilder ncBuilder = new NodeConnectorBuilder()
+ .setId(ncId)
+ .setKey(new NodeConnectorKey(ncId));
+ return ncBuilder.build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.vpnservice.interfacemgr.test;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+class MockDataChangedEvent implements AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> {
+ Map<InstanceIdentifier<?>,DataObject> created = new HashMap<>();
+ Map<InstanceIdentifier<?>,DataObject> updated = new HashMap<>();
+ Map<InstanceIdentifier<?>,DataObject> original = new HashMap<>();
+ Set<InstanceIdentifier<?>> removed = new HashSet<>();
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getCreatedData() {
+ return created;
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getUpdatedData() {
+ return updated;
+ }
+
+ @Override
+ public Set<InstanceIdentifier<?>> getRemovedPaths() {
+ return removed;
+ }
+
+ @Override
+ public Map<InstanceIdentifier<?>, DataObject> getOriginalData() {
+ return original;
+ }
+
+ @Override
+ public DataObject getOriginalSubtree() {
+ throw new UnsupportedOperationException("Not implemented by mock");
+ }
+
+ @Override
+ public DataObject getUpdatedSubtree() {
+ throw new UnsupportedOperationException("Not implemented by mock");
+ }
+}
<artifactId>model-flow-service</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
- <!--<dependency>
- <groupId>org.opendaylight.controller.model</groupId>
- <artifactId>model-flow-management</artifactId>
- </dependency>-->
- <!-- Commenting due to missing constraint error
- <dependency>
- <groupId>org.opendaylight.controller.model</groupId>
- <artifactId>model-inventory</artifactId>
- </dependency>
- -->
- <!--<dependency>
- <groupId>org.eclipse.xtend</groupId>
- <artifactId>org.eclipse.xtend.lib</artifactId>
- <version>${xtend.version}</version>
- </dependency>-->
- <!--<dependency>
- <groupId>equinoxSDK381</groupId>
- <artifactId>org.eclipse.osgi</artifactId>
- </dependency>-->
- <dependency>
+ <!-- TEST Dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-module-junit4</artifactId>
+ <version>1.5.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito</artifactId>
+ <version>1.5.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-broker-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-broker-impl</artifactId>
+ <version>${mdsal.version}</version>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
- <dependency>
+ <dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mdsalutil-api</artifactId>
<version>${project.version}</version>
<manifestLocation>${project.basedir}/META-INF</manifestLocation>
</configuration>
</plugin>
- <!--<plugin>
- <groupId>org.eclipse.xtend</groupId>
- <artifactId>xtend-maven-plugin</artifactId>
- <version>${xtend.version}</version>
- <executions>
- <execution>
- <goals>
- <goal>compile</goal>
- </goals>
- <configuration>
- <outputDirectory>${basedir}/src/main/xtend-gen</outputDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>-->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>${maven.clean.plugin.version}</version>
</filesets>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <argLine>-XX:-UseSplitVerifier</argLine>
+ </configuration>
+ </plugin>
+
</plugins>
</build>
</project>
import java.math.BigInteger;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-//import org.opendaylight.controller.md.sal.common.api.data.DataModification;
import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
import org.opendaylight.vpnservice.mdsalutil.ActionType;
-import org.opendaylight.vpnservice.mdsalutil.BucketInfo;
import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
import org.opendaylight.vpnservice.mdsalutil.GroupEntity;
-import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
-import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
-import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
-import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
-import org.opendaylight.vpnservice.mdsalutil.InstructionType;
import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
-import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
-import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
-// Missing constraint
-//import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-//import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.OpendaylightInventoryService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
-import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-public class MDSALManager implements IMdsalApiManager,BindingAwareConsumer, AutoCloseable {
+public class MDSALManager implements IMdsalApiManager, AutoCloseable {
private static final Logger s_logger = LoggerFactory.getLogger(MDSALManager.class);
private DataBroker m_dataBroker;
- private ConsumerContext m_consumerContext = null;
-
private PacketProcessingService m_packetProcessingService;
-
+
private final AtomicInteger m_atomicInteger = new AtomicInteger();
//TODO : IF ID MANAGER IS RQD
-
- @Override
- public void onSessionInitialized(ConsumerContext session) {
-
- s_logger.info( " Session Initiated for MD SAL Manager") ;
-
- m_consumerContext = session;
-
- m_dataBroker = session.getSALService(DataBroker.class);
-
- // TODO - Verify this.
- m_packetProcessingService = session.getRpcService(PacketProcessingService.class);
-
+
+ /**
+ * Writes the flows and Groups to the MD SAL DataStore
+ * which will be sent to the openflowplugin for installing flows/groups on the switch.
+ * Other modules of VPN service that wants to install flows / groups on the switch
+ * uses this utility
+ *
+ * @param db - dataBroker reference
+ * @param PacketProcessingService for sending the packet outs
+ */
+ public MDSALManager(final DataBroker db, PacketProcessingService pktProcService) {
+ m_dataBroker = db;
+ m_packetProcessingService = pktProcService;
+
}
-
-
+
+
@Override
public void close() throws Exception {
- s_logger.info("MDSAL Manager Closed");
+ s_logger.info("MDSAL Manager Closed");
}
-
+
@Override
public void printTest() {
-
- s_logger.info(" INTER MODULECOMMUNICATION IS WORKING!!!!");
+
+ s_logger.info(" INTER MODULECOMMUNICATION IS WORKING!!!!");
}
@Override
public void installFlow(FlowEntity flowEntity) {
+
try {
- s_logger.info("within installFlowX {}", flowEntity.getDpnId());
- System.out.println( " Insie installFlow -- ") ;
+ s_logger.info("within installFlow {}", flowEntity.getDpnId());
if (flowEntity.getCookie() == null) {
- s_logger.info("Helium_sync: Cookie is null");
+ // s_logger.info("Helium_sync: Cookie is null");
flowEntity.setCookie(new BigInteger("0110000", 16));
}
- Flow flow = flowEntity.getFlowBuilder().build();
+ FlowKey flowKey = new FlowKey( new FlowId(flowEntity.getFlowId()) );
+
+ FlowBuilder flowbld = flowEntity.getFlowBuilder();
+
+ Flow flow = flowbld.build() ;
Node nodeDpn = buildDpnNode(flowEntity.getDpnId());
InstanceIdentifier<Node> nodeInstanceId = InstanceIdentifier.builder(Nodes.class)
.child(Node.class, nodeDpn.getKey()).build();
+
InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class)
.child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
- .child(Table.class, new TableKey(flow.getTableId())).child(Flow.class, flow.getKey()).build();
+ .child(Table.class, new TableKey(flowEntity.getTableId())).child(Flow.class,flowKey).build();
String sTransactionUri = generateTransactionUri();
- // Helium Way
-
+
+ TableKey tableKey = new TableKey(flowEntity.getTableId() );
+ InstanceIdentifier<Table> tableInstanceId = InstanceIdentifier.create(Nodes.class).child(Node.class, nodeDpn.getKey())
+ .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
+ Table table = new TableBuilder().setKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
+
WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction();
-
- modification.put(LogicalDatastoreType.CONFIGURATION, nodeInstanceId, nodeDpn, true);
-
- modification.put(LogicalDatastoreType.CONFIGURATION, flowInstanceId, flow);
-
- ListenableFuture<RpcResult<TransactionStatus>> commitFuture = modification.commit();
-
- Futures.addCallback(commitFuture, new FutureCallback<RpcResult<TransactionStatus>>() {
+
+ //CHECK IF RQD
+ // modification.put(LogicalDatastoreType.CONFIGURATION, nodeInstanceId, nodeDpn, true);
+
+
+ modification.put(LogicalDatastoreType.CONFIGURATION, tableInstanceId, table);
+
+ modification.put(LogicalDatastoreType.CONFIGURATION, flowInstanceId, flowbld.build());
+
+ CheckedFuture<Void,TransactionCommitFailedException> submitFuture = modification.submit();
+
+ Futures.addCallback(submitFuture, new FutureCallback<Void>() {
+
@Override
- public void onSuccess(RpcResult<TransactionStatus> result) {
- if( result.getResult() != TransactionStatus.COMMITED ) {
- s_logger.debug("Failed to commit the Flow Data " + result.getErrors());
-
- }
-
+ public void onSuccess(final Void result) {
+ // Commited successfully
+ s_logger.info( "Install Flow -- Committedsuccessfully ") ;
}
@Override
- public void onFailure(Throwable throwable) {
- s_logger.error(throwable.getMessage(), throwable);
- s_logger.debug(String.format("Status of Flow Data Loaded Transaction : failure. Reason : %s", throwable));
-
+ public void onFailure(final Throwable t) {
+ // Transaction failed
+
+ if(t instanceof OptimisticLockFailedException) {
+ // Failed because of concurrent transaction modifying same data
+ s_logger.error( "Install Flow -- Failed because of concurrent transaction modifying same data ") ;
+ } else {
+ // Some other type of TransactionCommitFailedException
+ s_logger.error( "Install Flow -- Some other type of TransactionCommitFailedException " + t) ;
+ }
}
});
} catch (Exception e) {
s_logger.error("Could not install flow: {}, exception: {}", flowEntity, e.getMessage());
}
-
}
+
@Override
public void installGroup(GroupEntity groupEntity) {
try {
.child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
.child(Group.class, new GroupKey(new GroupId(groupEntity.getGroupId()))).build();
-
- // Helium
WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction();
-
- modification.put(LogicalDatastoreType.CONFIGURATION, nodeInstanceId, nodeDpn);
+
+ //CHECK IF RQD
+ // modification.put(LogicalDatastoreType.CONFIGURATION, nodeInstanceId, nodeDpn);
modification.put(LogicalDatastoreType.CONFIGURATION, groupInstanceId, group);
-
- ListenableFuture<RpcResult<TransactionStatus>> commitFuture = modification.commit();
-
- Futures.addCallback(commitFuture, new FutureCallback<RpcResult<TransactionStatus>>() {
+
+ CheckedFuture<Void,TransactionCommitFailedException> submitFuture = modification.submit();
+
+ Futures.addCallback(submitFuture, new FutureCallback<Void>() {
@Override
- public void onSuccess(RpcResult<TransactionStatus> result) {
- if( result.getResult() != TransactionStatus.COMMITED ) {
- s_logger.debug("Failed to commit the group Data " + result.getErrors());
-
- }
-
+ public void onSuccess(final Void result) {
+ // Commited successfully
+ s_logger.info( "Install Group -- Committedsuccessfully ") ;
}
@Override
- public void onFailure(Throwable throwable) {
- s_logger.error(throwable.getMessage(), throwable);
- s_logger.debug(String.format("Status of Group Data Loaded Transaction : failure. Reason : %s", throwable));
-
+ public void onFailure(final Throwable t) {
+ // Transaction failed
+
+ if(t instanceof OptimisticLockFailedException) {
+ // Failed because of concurrent transaction modifying same data
+ s_logger.error( "Install Group -- Failed because of concurrent transaction modifying same data ") ;
+ } else {
+ // Some other type of TransactionCommitFailedException
+ s_logger.error( "Install Group -- Some other type of TransactionCommitFailedException " + t) ;
+ }
}
- });
-
- } catch (Exception e) {
+ });
+ } catch (Exception e) {
s_logger.error("Could not install Group: {}, exception: {}", groupEntity, e.getMessage());
throw e;
}
WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction();
modification.delete(LogicalDatastoreType.CONFIGURATION,flowInstanceId );
- ListenableFuture<RpcResult<TransactionStatus>> commitFuture = modification.commit();
-
- Futures.addCallback(commitFuture, new FutureCallback<RpcResult<TransactionStatus>>() {
+ CheckedFuture<Void,TransactionCommitFailedException> submitFuture = modification.submit();
+
+ Futures.addCallback(submitFuture, new FutureCallback<Void>() {
@Override
- public void onSuccess(RpcResult<TransactionStatus> result) {
- if( result.getResult() != TransactionStatus.COMMITED ) {
- s_logger.debug("Failed to remove the Flow Data " + result.getErrors());
-
- }
-
+ public void onSuccess(final Void result) {
+ // Commited successfully
+ s_logger.info( "Delete Flow -- Committedsuccessfully ") ;
}
@Override
- public void onFailure(Throwable throwable) {
- s_logger.error(throwable.getMessage(), throwable);
- s_logger.debug(String.format("Status of Flow Data remove Transaction : failure. Reason : %s", throwable));
-
+ public void onFailure(final Throwable t) {
+ // Transaction failed
+ if(t instanceof OptimisticLockFailedException) {
+ // Failed because of concurrent transaction modifying same data
+ s_logger.error( "Delete Flow -- Failed because of concurrent transaction modifying same data ") ;
+ } else {
+ // Some other type of TransactionCommitFailedException
+ s_logger.error( "Delete Flow -- Some other type of TransactionCommitFailedException " + t) ;
+ }
}
+
});
} catch (Exception e) {
s_logger.error("Could not remove Flow: {}, exception: {}", flowEntity, e.getMessage());
.child(Node.class, nodeDpn.getKey()).augmentation(FlowCapableNode.class)
.child(Group.class, new GroupKey(new GroupId(groupEntity.getGroupId()))).build();
-
WriteTransaction modification = m_dataBroker.newWriteOnlyTransaction();
-
+
modification.delete(LogicalDatastoreType.CONFIGURATION,groupInstanceId );
- ListenableFuture<RpcResult<TransactionStatus>> commitFuture = modification.commit();
-
- Futures.addCallback(commitFuture, new FutureCallback<RpcResult<TransactionStatus>>() {
+ CheckedFuture<Void,TransactionCommitFailedException> submitFuture = modification.submit();
+
+ Futures.addCallback(submitFuture, new FutureCallback<Void>() {
@Override
- public void onSuccess(RpcResult<TransactionStatus> result) {
- if( result.getResult() != TransactionStatus.COMMITED ) {
- s_logger.debug("Failed to remove the group Data " + result.getErrors());
-
- }
-
+ public void onSuccess(final Void result) {
+ // Commited successfully
+ s_logger.info( "Install Group -- Committedsuccessfully ") ;
}
@Override
- public void onFailure(Throwable throwable) {
- s_logger.error(throwable.getMessage(), throwable);
- s_logger.debug(String.format("Status of group Data remove Transaction : failure. Reason : %s", throwable));
-
+ public void onFailure(final Throwable t) {
+ // Transaction failed
+ if(t instanceof OptimisticLockFailedException) {
+ // Failed because of concurrent transaction modifying same data
+ s_logger.error( "Install Group -- Failed because of concurrent transaction modifying same data ") ;
+ } else {
+ // Some other type of TransactionCommitFailedException
+ s_logger.error( "Install Group -- Some other type of TransactionCommitFailedException " + t) ;
+ }
}
});
-
-
-
} catch (Exception e) {
s_logger.error("Could not remove Group: {}, exception: {}", groupEntity, e.getMessage());
}
+ Long.toString(nTransactionId);
}
*/
-
+
@Override
public void sendPacketOut(long lDpnId, int groupId, byte[] payload) {
return nodeDpn;
}
+
}
--- /dev/null
+package org.opendaylight.vpnservice.mdsalutil.internal;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MDSALUtilProvider implements BindingAwareConsumer, AutoCloseable {
+
+ private static final Logger s_logger = LoggerFactory.getLogger(MDSALUtilProvider.class);
+ private MDSALManager mdSalMgr;
+
+ @Override
+ public void onSessionInitialized(ConsumerContext session) {
+
+ s_logger.info( " Session Initiated for MD SAL Util Provider") ;
+
+ try {
+ final DataBroker dataBroker;
+ final PacketProcessingService packetProcessingService;
+ dataBroker = session.getSALService(DataBroker.class);
+ // TODO - Verify this.
+ packetProcessingService = session.getRpcService(PacketProcessingService.class);
+ mdSalMgr = new MDSALManager( dataBroker, packetProcessingService) ;
+ }catch( Exception e) {
+ s_logger.error( "Error initializing MD SAL Util Services " + e );
+ }
+ }
+
+
+ @Override
+ public void close() throws Exception {
+ mdSalMgr.close();
+ s_logger.info("MDSAL Manager Closed");
+ }
+
+}
package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsalutil.impl.rev150403;
-import org.opendaylight.vpnservice.mdsalutil.internal.MDSALManager;
+import org.opendaylight.vpnservice.mdsalutil.internal.MDSALUtilProvider;
public class MdsaluttilimplModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsalutil.impl.rev150403.AbstractMdsaluttilimplModule {
public MdsaluttilimplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
// TODO:implement
// Can use the following to get a handle to data broker
- MDSALManager mdsalUtilMgr = new MDSALManager();
- getBrokerDependency().registerConsumer(mdsalUtilMgr);
+ MDSALUtilProvider mdsalUtilProvider = new MDSALUtilProvider();
+ getBrokerDependency().registerConsumer(mdsalUtilProvider);
//DataBroker dataBrokerService = getDataBrokerDependency();
//mdsalUtilMgr.setDataProvider(dataBrokerService);
- return mdsalUtilMgr ;
+ return mdsalUtilProvider ;
}
}
--- /dev/null
+package org.opendaylight.vpnservice.test;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.base.Preconditions;
+
+public abstract class AbstractMockForwardingRulesManager<D extends DataObject> implements DataTreeChangeListener<D> {
+
+ public AbstractMockForwardingRulesManager() {
+ // Do Nothing
+ }
+
+
+ public void onDataTreeChanged(Collection<DataTreeModification<D>> changes) {
+ // TODO Auto-generated method stub
+ }
+
+}
--- /dev/null
+package org.opendaylight.vpnservice.test;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Collections;
+import java.util.concurrent.ExecutionException;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+import org.mockito.runners.MockitoJUnitRunner;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
+import org.opendaylight.vpnservice.mdsalutil.ActionType;
+import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
+import org.opendaylight.vpnservice.mdsalutil.GroupEntity;
+import org.opendaylight.vpnservice.mdsalutil.BucketInfo;
+import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
+import org.opendaylight.vpnservice.mdsalutil.InstructionType;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.vpnservice.mdsalutil.internal.MDSALManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(MockitoJUnitRunner.class)
+//@RunWith(PowerMockRunner.class)
+@PrepareForTest(MDSALUtil.class)
+public class MdSalUtilTest extends AbstractDataBrokerTest {
+ DataBroker dataBroker;
+ @Mock PacketProcessingService ppS ;
+ MDSALManager mdSalMgr = null ;
+ MockFlowForwarder flowFwder = null ;
+ MockGroupForwarder grpFwder = null ;
+
+ @Before
+ public void setUp() throws Exception {
+ dataBroker = getDataBroker() ;
+ mdSalMgr = new MDSALManager( dataBroker, ppS);
+ flowFwder = new MockFlowForwarder( dataBroker );
+ grpFwder = new MockGroupForwarder( dataBroker ) ;
+
+ PowerMockito.mockStatic(MDSALUtil.class) ;
+
+ NodeKey s1Key = new NodeKey(new NodeId("openflow:1"));
+ addFlowCapableNode(s1Key);
+ }
+
+ @Test
+ public void testInstallFlow() {
+ String dpnId = "openflow:1";
+ String tableId1 = "12";
+
+ //Install Flow 1
+ FlowEntity testFlow1 = createFlowEntity(dpnId, tableId1) ;
+ mdSalMgr.installFlow(testFlow1);
+ assertEquals(1, flowFwder.getDataChgCount());
+
+ // Install FLow 2
+ String tableId2 = "13" ;
+ FlowEntity testFlow2 = createFlowEntity(dpnId, tableId2) ;
+ mdSalMgr.installFlow(testFlow2);
+ assertEquals(2, flowFwder.getDataChgCount());
+ }
+
+ @Test
+ public void testRemoveFlow() {
+ String dpnId = "openflow:1";
+ String tableId = "13" ;
+ FlowEntity testFlow = createFlowEntity(dpnId, tableId) ;
+
+ // To test RemoveFlow add and then delete Flows
+ mdSalMgr.installFlow(testFlow) ;
+ assertEquals(1, flowFwder.getDataChgCount());
+ mdSalMgr.removeFlow(testFlow);
+ assertEquals(0, flowFwder.getDataChgCount());
+ }
+
+ @Test
+ public void testInstallGroup() {
+ // Install Group 1
+ String Nodeid = "1";
+ String inport = "2" ;
+ int vlanid = 100 ;
+ GroupEntity grpEntity1 = createGroupEntity(Nodeid, inport, vlanid) ;
+
+ mdSalMgr.installGroup(grpEntity1);
+ assertEquals(1, grpFwder.getDataChgCount());
+
+ // Install Group 2
+ Nodeid = "1";
+ inport = "3" ;
+ vlanid = 100 ;
+ GroupEntity grpEntity2 = createGroupEntity(Nodeid, inport, vlanid) ;
+ mdSalMgr.installGroup(grpEntity2);
+ assertEquals(2, grpFwder.getDataChgCount());
+ }
+
+ @Test
+ public void testRemoveGroup() {
+ String Nodeid = "1";
+ String inport = "2" ;
+ int vlanid = 100 ;
+ GroupEntity grpEntity = createGroupEntity(Nodeid, inport, vlanid) ;
+ // To test RemoveGroup add and then delete Group
+ mdSalMgr.installGroup(grpEntity);
+ assertEquals(1, grpFwder.getDataChgCount());
+ mdSalMgr.removeGroup(grpEntity);
+ assertEquals(0, grpFwder.getDataChgCount());
+ }
+
+ public void addFlowCapableNode(NodeKey nodeKey) throws ExecutionException, InterruptedException {
+ Nodes nodes = new NodesBuilder().setNode(Collections.<Node>emptyList()).build();
+ InstanceIdentifier<Node> flowNodeIdentifier = InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, nodeKey);
+
+ FlowCapableNodeBuilder fcnBuilder = new FlowCapableNodeBuilder();
+ NodeBuilder nodeBuilder = new NodeBuilder();
+ nodeBuilder.setKey(nodeKey);
+ nodeBuilder.addAugmentation(FlowCapableNode.class, fcnBuilder.build());
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class), nodes);
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, flowNodeIdentifier, nodeBuilder.build());
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Nodes.class), nodes);
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, flowNodeIdentifier, nodeBuilder.build());
+ assertCommit(writeTx.submit());
+ }
+
+ // Methods to test the install Flow and Group
+
+ public FlowEntity createFlowEntity(String dpnId, String tableId) {
+
+ long dpId;
+ int SERVICE_ID = 0;
+ FlowEntity terminatingServiceTableFlowEntity = null;
+
+ List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
+ listActionInfo.add(new ActionInfo(ActionType.punt_to_controller,
+ new String[] {}));
+
+ try {
+ dpId = Long.parseLong(dpnId.split(":")[1]);
+
+ List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+ BigInteger COOKIE = new BigInteger("9000000", 16);
+
+ short s_tableId = Short.parseShort(tableId) ;
+
+ mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
+ new BigInteger("0000000000000000", 16) }));
+
+ List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
+ mkInstructions.add(new InstructionInfo(InstructionType.write_actions,
+ listActionInfo));
+
+ terminatingServiceTableFlowEntity = MDSALUtil
+ .buildFlowEntity(
+ dpId,
+ s_tableId,
+ getFlowRef(s_tableId,
+ SERVICE_ID), 5, "Terminating Service Flow Entry: " + SERVICE_ID,
+ 0, 0, COOKIE
+ .add(BigInteger.valueOf(SERVICE_ID)),
+ null, null);
+ } catch (Exception e) {
+ //throw new Exception(e) ;
+ }
+
+ return terminatingServiceTableFlowEntity;
+ }
+
+ private String getFlowRef(short termSvcTable, int svcId) {
+ return new StringBuffer().append(termSvcTable).append(svcId).toString();
+ }
+
+ public GroupEntity createGroupEntity(String Nodeid, String inport, int vlanid) {
+ GroupEntity groupEntity;
+ long id = getUniqueValue(Nodeid, inport);
+ List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
+ List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
+ if (vlanid > 0) {
+ listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] { null }));
+ listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid, new String[] { String.valueOf(vlanid) }));
+ }
+ listActionInfo.add(new ActionInfo(ActionType.output, new String[] { inport, "65535" }));
+ listBucketInfo.add(new BucketInfo(listActionInfo));
+
+ String groupName = "Test Group";
+ groupEntity = MDSALUtil.buildGroupEntity(Long.valueOf(Nodeid), id, groupName, GroupTypes.GroupIndirect,
+ listBucketInfo);
+
+ return groupEntity;
+ }
+
+ private static long getUniqueValue(String nodeId, String inport) {
+
+ Long nodeIdL = Long.valueOf(nodeId);
+ Long inportL = Long.valueOf(inport);
+ long sd_set;
+ sd_set = nodeIdL * 10 + inportL;
+
+ return sd_set;
+ }
+
+}
--- /dev/null
+package org.opendaylight.vpnservice.test;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class MockFlowForwarder extends AbstractMockForwardingRulesManager<Flow> {
+
+ private int nFlowCount = 0;
+
+ private ListenerRegistration<MockFlowForwarder> listenerRegistration;
+
+ public MockFlowForwarder( final DataBroker db) {
+ super() ;
+ registerListener(db) ;
+ }
+
+ private void registerListener(final DataBroker db) {
+ final DataTreeIdentifier<Flow> treeId = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, getWildCardPath());
+ try {
+ listenerRegistration = db.registerDataTreeChangeListener(treeId, MockFlowForwarder.this);
+ } catch (final Exception e) {
+ throw new IllegalStateException("FlowForwarder registration Listener fail! System needs restart.", e);
+ }
+ }
+
+ private InstanceIdentifier<Flow> getWildCardPath() {
+ return InstanceIdentifier.create(Nodes.class).child(Node.class)
+ .augmentation(FlowCapableNode.class).child(Table.class).child(Flow.class);
+ }
+
+ @Override
+ public void onDataTreeChanged(Collection<DataTreeModification<Flow>> changes) {
+ for (DataTreeModification<Flow> change : changes) {
+ final InstanceIdentifier<Flow> key = change.getRootPath().getRootIdentifier();
+ final DataObjectModification<Flow> mod = change.getRootNode();
+
+ switch (mod.getModificationType()) {
+ case DELETE:
+ nFlowCount -= 1;
+ break;
+ case SUBTREE_MODIFIED:
+ // CHECK IF RQD
+ break;
+ case WRITE:
+ if (mod.getDataBefore() == null) {
+ nFlowCount += 1;
+ } else {
+ // UPDATE COUNT UNCHANGED
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
+ }
+ }
+ }
+
+ public int getDataChgCount() {
+ return nFlowCount;
+ }
+}
--- /dev/null
+package org.opendaylight.vpnservice.test;
+
+import java.util.Collection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+
+public class MockGroupForwarder extends AbstractMockForwardingRulesManager<Group>{
+
+ private int nGroupCount = 0;
+ private ListenerRegistration<MockGroupForwarder> listenerRegistration ;
+
+ public MockGroupForwarder( final DataBroker db) {
+ super() ;
+ registerListener(db) ;
+ }
+
+ private void registerListener(final DataBroker db) {
+ final DataTreeIdentifier<Group> treeId = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, getWildCardPath());
+ try {
+ listenerRegistration = db.registerDataTreeChangeListener(treeId, MockGroupForwarder.this);
+ } catch (final Exception e) {
+ throw new IllegalStateException("GroupForwarder registration Listener fail! System needs restart.", e);
+ }
+ }
+
+ private InstanceIdentifier<Group> getWildCardPath() {
+ return InstanceIdentifier.create(Nodes.class).child(Node.class).
+ augmentation(FlowCapableNode.class).child(Group.class);
+ }
+
+ @Override
+ public void onDataTreeChanged(Collection<DataTreeModification<Group>> changes) {
+ for (DataTreeModification<Group> change : changes) {
+ final InstanceIdentifier<Group> key = change.getRootPath().getRootIdentifier();
+ final DataObjectModification<Group> mod = change.getRootNode();
+
+ switch (mod.getModificationType()) {
+ case DELETE:
+ nGroupCount -= 1;
+ break;
+ case SUBTREE_MODIFIED:
+ // CHECK IF RQD
+ break;
+ case WRITE:
+ if (mod.getDataBefore() == null) {
+ nGroupCount += 1;
+ } else {
+ // UPDATE COUNT UNCHANGED
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
+ }
+ }
+ }
+
+ public int getDataChgCount() {
+ return nGroupCount;
+ }
+}
<groupId>org.opendaylight.odlparent</groupId>
<artifactId>odlparent</artifactId>
<version>1.5.0-SNAPSHOT</version>
- <relativePath/>
+ <relativePath/>
</parent>
<groupId>org.opendaylight.vpnservice</groupId>
<artifactId>interfacemgr-api</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.vpnservice</groupId>
+ <artifactId>idmanager-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.vpnservice</groupId>
+ <artifactId>idmanager-impl</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nexthopmgr-api</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>mdsalutil-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<!-- Testing Dependencies -->
<dependency>
<required-capabilities>
<capability>urn:opendaylight:params:xml:ns:yang:nexthopmgr:impl?module=nexthopmgr-impl&revision=2015-03-25</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:mdsalutil:api?module=odl-mdsalutil&revision=2015-04-10</capability>
+ <capability>urn:opendaylight:vpnservice:interfacemgr?module=odl-interface&revision=2015-03-31</capability>
</required-capabilities>
<configuration>
<type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
<name>binding-osgi-broker</name>
</broker>
+ <mdsalutil>
+ <type xmlns:mdsalutil="urn:opendaylight:params:xml:ns:yang:mdsalutil:api">mdsalutil:odl-mdsalutil</type>
+ <name>mdsalutil-service</name>
+ </mdsalutil>
+ <odlinterface>
+ <type xmlns:odlif="urn:opendaylight:vpnservice:interfacemgr">odlif:odl-interface</type>
+ <name>interfacemgr-service</name>
+ </odlinterface>
</module>
</modules>
</data>
package org.opendaylight.vpnservice.nexthopmgr;
-import com.google.common.base.Optional;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.Future;
+
+import com.google.common.base.Optional;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.FutureCallback;
+
+//import org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc.Rpcs;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
import org.opendaylight.yangtools.yang.common.RpcResult;
-
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstance1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.*;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.l3nexthop.*;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.l3nexthop.tunnelnexthops.*;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.l3nexthop.vpnnexthops.*;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
+import org.opendaylight.vpnservice.mdsalutil.ActionType;
+import org.opendaylight.vpnservice.mdsalutil.BucketInfo;
+import org.opendaylight.vpnservice.mdsalutil.GroupEntity;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.idmanager.IdManager;
+
+import java.util.concurrent.ExecutionException;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class NexthopManager implements L3nexthopService, AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(NexthopManager.class);
private final DataBroker broker;
+ private IMdsalApiManager mdsalManager;
+ private IInterfaceManager interfaceManager;
+ private IdManager idManager;
private static final FutureCallback<Void> DEFAULT_CALLBACK =
new FutureCallback<Void>() {
* @param db - dataBroker reference
*/
public NexthopManager(final DataBroker db) {
- // create nexhhop ID pool
- // getIdManager.createIdPool("nextHopGroupIdPool", 10000, 100000);
broker = db;
+ createNexthopPointerPool();
}
-
@Override
public void close() throws Exception {
LOG.info("NextHop Manager Closed");
}
+ public void setInterfaceManager(IInterfaceManager ifManager) {
+ this.interfaceManager = ifManager;
+ }
- public void createLocalNextHop(String ifName, String vpnName, String ipAddress)
- {
- String nhKey = new String("nexthop." + vpnName + ipAddress);
- int groupId = 1;//getIdManager().getUniqueId("nextHopGroupIdPool", nhKey);
+ public void setMdsalManager(IMdsalApiManager mdsalManager) {
+ this.mdsalManager = mdsalManager;
+ }
- long vpnId = getVpnId(vpnName);
- VpnNexthop nexthop = getVpnNexthop(vpnId, ipAddress);
- if (nexthop == null) {
+ public void setIdManager(IdManager idManager) {
+ this.idManager = idManager;
+ }
- /* List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
- List<ActionInfo> listActionInfo = interfacemgr.getEgressGroupActions(ifName);
- BucketInfo bucket = new BucketInfo(listActionInfo);
- // MAC re-write??
- listBucketInfo.add(bucket);
- GroupEntity groupEntity = MDSALUtil.buildGroupEntity
- (dpId, groupId, IPAddress, GroupTypes.GroupIndirect, listBucketInfo);
- getMdsalApiManager().installGroup(groupEntity, objTransaction???);
- */
+ private void createNexthopPointerPool() {
+ CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
+ .setPoolName("nextHopPointerPool")
+ .setIdStart(1L)
+ .setPoolSize(new BigInteger("65535"))
+ .build();
+ //TODO: Error handling
+ Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
+// try {
+// LOG.info("Result2: {}",result.get());
+// } catch (InterruptedException | ExecutionException e) {
+// // TODO Auto-generated catch block
+// LOG.error("Error in result.get");
+// }
- //update MD-SAL DS
- addVpnNexthopToDS(vpnId, ipAddress, groupId);
- } else {
- //check update
- }
}
+
private long getVpnId(String vpnName) {
InstanceIdentifierBuilder<VpnInstance> idBuilder = InstanceIdentifier.builder(VpnInstances.class)
.child(VpnInstance.class, new VpnInstanceKey(vpnName));
InstanceIdentifier<VpnInstance1> idx = id.augmentation(VpnInstance1.class);
Optional<VpnInstance1> vpn = read(LogicalDatastoreType.CONFIGURATION, idx);
- if (vpn.isPresent()) return vpn.get().getVpnId();
- else return 0;
+ if (vpn.isPresent()) {
+ return vpn.get().getVpnId();
+ } else {
+ return 0;
+ }
}
private long getDpnId(String ifName) {
- return 1;
+ String[] fields = ifName.split(":");
+ long dpn = Integer.parseInt(fields[1]);
+ return dpn;
}
- public void createRemoteNextHop(String ifName, String ipAddress)
- {
+ private int createNextHopPointer(String nexthopKey) {
+ GetUniqueIdInput getIdInput = new GetUniqueIdInputBuilder()
+ .setPoolName("nextHopPointerPool").setIdKey(nexthopKey)
+ .build();
+ //TODO: Proper error handling once IdManager code is complete
+ try {
+ Future<RpcResult<GetUniqueIdOutput>> result = idManager.getUniqueId(getIdInput);
+ RpcResult<GetUniqueIdOutput> rpcResult = result.get();
+ return rpcResult.getResult().getIdValue().intValue();
+ } catch (NullPointerException | InterruptedException | ExecutionException e) {
+ LOG.trace("",e);
+ }
+ return 0;
+ }
+
+ public void createLocalNextHop(String ifName, String vpnName, String ipAddress, String macAddress) {
+ String nhKey = new String("nexthop." + vpnName + ipAddress);
+ int groupId = createNextHopPointer(nhKey);
+
+ long vpnId = getVpnId(vpnName);
+ long dpnId = interfaceManager.getDpnForInterface(ifName);
+ VpnNexthop nexthop = getVpnNexthop(vpnId, ipAddress);
+ if (nexthop == null) {
+ List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
+ List<ActionInfo> listActionInfo = interfaceManager.getInterfaceEgressActions(ifName);
+ BucketInfo bucket = new BucketInfo(listActionInfo);
+ // MAC re-write
+ if (macAddress != null) {
+ listActionInfo.add(new ActionInfo(ActionType.set_field_eth_dest, new String[]{macAddress}));
+ } else {
+ //FIXME: Log message here.
+ }
+ listBucketInfo.add(bucket);
+ GroupEntity groupEntity = MDSALUtil.buildGroupEntity(
+ dpnId, groupId, ipAddress, GroupTypes.GroupIndirect, listBucketInfo);
+
+ // install Group
+ mdsalManager.installGroup(groupEntity);
+
+ //update MD-SAL DS
+ addVpnNexthopToDS(vpnId, ipAddress, groupId);
+ } else {
+ //check update
+ }
+ }
+
+ public void createRemoteNextHop(String ifName, String ofPortId, String ipAddress) {
String nhKey = new String("nexthop." + ifName + ipAddress);
- int groupId = 1;//getIdManager().getUniqueId("nextHopGroupIdPool", nhKey);
+ int groupId = createNextHopPointer(nhKey);
- long dpnId = getDpnId(ifName);
+ long dpnId = getDpnId(ofPortId);
TunnelNexthop nexthop = getTunnelNexthop(dpnId, ipAddress);
if (nexthop == null) {
- /* List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
- List<ActionInfo> listActionInfo = interfacemgr.getEgressGroupActions(ifName);
+ List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
+ List<ActionInfo> listActionInfo = interfaceManager.getInterfaceEgressActions(ifName);
BucketInfo bucket = new BucketInfo(listActionInfo);
- // MAC re-write??
+ // MAC re-write??
listBucketInfo.add(bucket);
- GroupEntity groupEntity = MDSALUtil.buildGroupEntity
- (dpId, groupId, IPAddress, GroupTypes.GroupIndirect, listBucketInfo);
- getMdsalApiManager().installGroup(groupEntity, objTransaction???);
- */
+ GroupEntity groupEntity = MDSALUtil.buildGroupEntity(
+ dpnId, groupId, ipAddress, GroupTypes.GroupIndirect, listBucketInfo);
+ mdsalManager.installGroup(groupEntity);
//update MD-SAL DS
addTunnelNexthopToDS(dpnId, ipAddress, groupId);
}
}
- private void addVpnNexthopToDS(long vpnId, String ipPrefix, long egressPointer){
-
+ private void addVpnNexthopToDS(long vpnId, String ipPrefix, long egressPointer) {
InstanceIdentifierBuilder<VpnNexthops> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
.child(VpnNexthops.class, new VpnNexthopsKey(vpnId));
}
- private void addTunnelNexthopToDS(long dpnId, String ipPrefix, long egressPointer){
+ private void addTunnelNexthopToDS(long dpnId, String ipPrefix, long egressPointer) {
InstanceIdentifierBuilder<TunnelNexthops> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
.child(TunnelNexthops.class, new TunnelNexthopsKey(dpnId));
Optional<TunnelNexthops> nexthops = read(LogicalDatastoreType.CONFIGURATION, id);
if (!nexthops.isPresent()) {
// create a new node
- TunnelNexthops node = new TunnelNexthopsBuilder().setKey(new TunnelNexthopsKey(dpnId)).setDpnId(dpnId).build();
+ TunnelNexthops node = new TunnelNexthopsBuilder()
+ .setKey(new TunnelNexthopsKey(dpnId))
+ .setDpnId(dpnId)
+ .build();
asyncWrite(LogicalDatastoreType.OPERATIONAL, id, node, DEFAULT_CALLBACK);
}
private VpnNexthop getVpnNexthop(long vpnId, String ipAddress) {
- InstanceIdentifierBuilder<VpnNexthop> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
- .child(VpnNexthops.class, new VpnNexthopsKey(vpnId))
- .child(VpnNexthop.class, new VpnNexthopKey(ipAddress));
- InstanceIdentifier<VpnNexthop> id = idBuilder.build();
- Optional<VpnNexthop> nextHop = read(LogicalDatastoreType.CONFIGURATION, id);
-
- if(nextHop.isPresent()) return nextHop.get();
- else return null;
+ // check if vpn node is there
+ InstanceIdentifierBuilder<VpnNexthops> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
+ .child(VpnNexthops.class, new VpnNexthopsKey(vpnId));
+ InstanceIdentifier<VpnNexthops> id = idBuilder.build();
+ Optional<VpnNexthops> vpnNexthops = read(LogicalDatastoreType.CONFIGURATION, id);
+ if (!vpnNexthops.isPresent()) {
+
+ // get nexthops list for vpn
+ List<VpnNexthop> nexthops = vpnNexthops.get().getVpnNexthop();
+ for (VpnNexthop nexthop : nexthops) {
+ if (nexthop.getIpAddress().equals(ipAddress)) {
+ // return nexthop
+ return nexthop;
+ }
+ }
+ }
+ //return null if not found
+ return null;
}
private TunnelNexthop getTunnelNexthop(long dpnId, String ipAddress) {
- InstanceIdentifierBuilder<TunnelNexthop> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
- .child(TunnelNexthops.class, new TunnelNexthopsKey(dpnId))
- .child(TunnelNexthop.class, new TunnelNexthopKey(ipAddress));
- InstanceIdentifier<TunnelNexthop> id = idBuilder.build();
- Optional<TunnelNexthop> nextHop = read(LogicalDatastoreType.CONFIGURATION, id);
+
+ InstanceIdentifierBuilder<TunnelNexthops> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
+ .child(TunnelNexthops.class, new TunnelNexthopsKey(dpnId));
- if(nextHop.isPresent()) return nextHop.get();
- else return null;
+ // check if vpn node is there
+ InstanceIdentifier<TunnelNexthops> id = idBuilder.build();
+ Optional<TunnelNexthops> dpnNexthops = read(LogicalDatastoreType.CONFIGURATION, id);
+ if (!dpnNexthops.isPresent()) {
+ List<TunnelNexthop> nexthops = dpnNexthops.get().getTunnelNexthop();
+ for (TunnelNexthop nexthop : nexthops) {
+ if (nexthop.getIpAddress().equals(ipAddress)) {
+ return nexthop;
+ }
+ }
+ }
+ return null;
}
public long getNextHopPointer(long dpnId, long vpnId, String prefixIp, String nextHopIp) {
- String endpointIp = "10.10.10.1";//interfaceManager.getLocalEndpointIp(dpnId);
+ String endpointIp = interfaceManager.getEndpointIpForDpn(dpnId);
if (nextHopIp.equals(endpointIp)) {
VpnNexthop vpnNextHop = getVpnNexthop(vpnId, prefixIp);
return vpnNextHop.getEgressPointer();
}
}
- public void removeRemoteNextHop(String ifname, String IpAddress)
- {
- String nhKey = new String("nexthop" + ifname + IpAddress);
- int groupId = 1;//getIdManager().getUniqueId(L3Constants.L3NEXTHOP_GROUPID_POOL, nhKey);
+ private void removeTunnelNexthopFromDS(long dpnId, String ipPrefix) {
-/* if (getNextHop(groupId) != Null){
- List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
- List<ActionInfo> listActionInfo = null;//nextHop.getActions({output to port});
- BucketInfo bucket = new BucketInfo(listActionInfo);
- listBucketInfo.add(bucket);
- //GroupEntity groupEntity = MDSALUtil.buildGroupEntity
- (dpId, groupId, IPAddress, GroupTypes.GroupIndirect, listBucketInfo);
- //getMdsalApiManager().removeGroup(groupEntity, objTransaction???);
+ InstanceIdentifierBuilder<TunnelNexthop> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
+ .child(TunnelNexthops.class, new TunnelNexthopsKey(dpnId))
+ .child(TunnelNexthop.class, new TunnelNexthopKey(ipPrefix));
+ InstanceIdentifier<TunnelNexthop> id = idBuilder.build();
+ // remove from DS
+ delete(LogicalDatastoreType.OPERATIONAL, id);
+ }
+
+ private void removeVpnNexthopFromDS(long vpnId, String ipPrefix) {
+
+ InstanceIdentifierBuilder<VpnNexthop> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
+ .child(VpnNexthops.class, new VpnNexthopsKey(vpnId))
+ .child(VpnNexthop.class, new VpnNexthopKey(ipPrefix));
+ InstanceIdentifier<VpnNexthop> id = idBuilder.build();
+ // remove from DS
+ delete(LogicalDatastoreType.OPERATIONAL, id);
+ }
+
+
+ public void removeLocalNextHop(String vpnName, String ipAddress) {
+ long vpnId = getVpnId(vpnName);
+
+ VpnNexthop nh = getVpnNexthop(vpnId, ipAddress);
+ if (nh != null) {
+ // how to inform and remove dependent FIB entries??
+ // we need to do it before the group is removed
+
+ // remove Group ...
+
//update MD-SAL DS
- removeNextHopFromDS(dpId, vpn, ipAddress);
- }else{
- //check update
- }*/
+ removeVpnNexthopFromDS(vpnId, ipAddress);
+ } else {
+ //throw error
+ }
+
+ }
+
+ public void removeRemoteNextHop(long dpnId, String ipAddress) {
+
+ TunnelNexthop nh = getTunnelNexthop(dpnId, ipAddress);
+ if (nh != null) {
+ // how to inform and remove dependent FIB entries??
+ // we need to do it before the group is removed
+
+ // remove Group ...
+ //update MD-SAL DS
+ removeTunnelNexthopFromDS(dpnId, ipAddress);
+ } else {
+ //throw error
+ }
+
+ }
+
+ @Override
+ public Future<RpcResult<GetEgressPointerOutput>> getEgressPointer(
+ GetEgressPointerInput input) {
+ long egressGroupId =
+ getNextHopPointer(input.getDpnId(), input.getVpnId(), input.getIpPrefix(), input.getNexthopIp());
+
+ GetEgressPointerOutputBuilder output = new GetEgressPointerOutputBuilder();
+ output.setEgressPointer(egressGroupId);
+
+ RpcResult<GetEgressPointerOutput> result = null;
+ //Rpcs.<GetEgressPointerOutput> getRpcResult(false, output.build());
+ return Futures.immediateFuture(result);
}
private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
}
- @Override
- public Future<RpcResult<GetEgressPointerOutput>> getEgressPointer(
- GetEgressPointerInput input) {
- long egressGroupId =
- getNextHopPointer(input.getDpnId(), input.getVpnId(), input.getIpPrefix(), input.getNexthopIp());
-
- GetEgressPointerOutputBuilder output = new GetEgressPointerOutputBuilder();
- output.setEgressPointer(egressGroupId);
-
- /*RpcResult<GetEgressPointerOutput> result = Rpcs.<GetEgressPointerOutput> getRpcResult(false, output.build());
- return Futures.immediateFuture(result);*/
- return null;
+ private <T extends DataObject> void delete(LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.delete(datastoreType, path);
+ Futures.addCallback(tx.submit(), DEFAULT_CALLBACK);
}
}
\ No newline at end of file
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
import org.opendaylight.vpnservice.nexthopmgr.NexthopManager;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.idmanager.IdManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private VpnInterfaceChangeListener vpnIfListener;
private OdlInterfaceChangeListener odlIfListener;
private NexthopManager nhManager;
+ private IMdsalApiManager mdsalManager;
+ private IInterfaceManager interfaceManager;
+ private IdManager idManager;
@Override
public void onSessionInitiated(ProviderContext session) {
final DataBroker dbx = session.getSALService(DataBroker.class);
nhManager = new NexthopManager(dbx);
vpnIfListener = new VpnInterfaceChangeListener(dbx, nhManager);
- odlIfListener = new OdlInterfaceChangeListener(dbx, nhManager);
+ odlIfListener = new OdlInterfaceChangeListener(dbx, nhManager, interfaceManager);
+ idManager = new IdManager(dbx);
+ nhManager.setMdsalManager(mdsalManager);
+ nhManager.setInterfaceManager(interfaceManager);
+ nhManager.setIdManager(idManager);
LOG.info("NexthopmgrProvider Session Initiated");
}
+ public void setMdsalManager(IMdsalApiManager mdsalManager) {
+ this.mdsalManager = mdsalManager;
+ }
+
+ public void setInterfaceManager(IInterfaceManager interfaceManager) {
+ this.interfaceManager = interfaceManager;
+ }
+
@Override
public void close() throws Exception {
vpnIfListener.close();
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.L3tunnel;
import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL3tunnel;
-
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
import org.opendaylight.vpnservice.nexthopmgr.AbstractDataChangeListener;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private ListenerRegistration<DataChangeListener> listenerRegistration;
private final DataBroker broker;
private NexthopManager nexthopManager;
+ private IInterfaceManager interfaceManager;
+
- public OdlInterfaceChangeListener(final DataBroker db, NexthopManager nhm) {
+ public OdlInterfaceChangeListener(final DataBroker db, NexthopManager nhm, IInterfaceManager ifManager) {
super(Interface.class);
broker = db;
nexthopManager = nhm;
+ interfaceManager = ifManager;
registerListener(db);
}
throw new IllegalStateException("Nexthop Manager registration Listener failed.", e);
}
}
-
+
@Override
-
- protected void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
+ protected void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
LOG.info("key: " + identifier + ", value=" + intrf );
if (intrf.getType().equals(L3tunnel.class)) {
- IfL3tunnel intfData = intrf.getAugmentation(IfL3tunnel.class);
+ IfL3tunnel intfData = intrf.getAugmentation(IfL3tunnel.class);
String gwIp = intfData.getGatewayIp().toString();
String remoteIp = intfData.getRemoteIp().toString();
if (gwIp != null) {
remoteIp = gwIp;
}
- nexthopManager.createRemoteNextHop(intrf.getName(), remoteIp);
+ NodeConnectorId ofPort = intrf.getAugmentation(BaseIds.class).getOfPortId();
+ nexthopManager.createRemoteNextHop(intrf.getName(), ofPort.toString(), remoteIp);
}
}
-
+
private InstanceIdentifier<Interface> getWildCardPath() {
return InstanceIdentifier.create(Interfaces.class).child(Interface.class);
}
protected void remove(InstanceIdentifier<Interface> identifier,
Interface intrf) {
if (intrf.getType().equals(L3tunnel.class)) {
+ long dpnId = interfaceManager.getDpnForInterface(intrf.getName());
IfL3tunnel intfData = intrf.getAugmentation(IfL3tunnel.class);
String gwIp = intfData.getGatewayIp().toString();
String remoteIp = intfData.getRemoteIp().toString();
if (gwIp != null) {
remoteIp = gwIp;
}
- nexthopManager.removeRemoteNextHop(intrf.getName(), remoteIp);
+ nexthopManager.removeRemoteNextHop(dpnId, remoteIp);
}
}
package org.opendaylight.vpnservice.nexthopmgr;
import java.util.List;
-import java.util.ArrayList;
-
import com.google.common.base.Optional;
-
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
-import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
import org.opendaylight.vpnservice.nexthopmgr.AbstractDataChangeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class VpnInterfaceChangeListener extends AbstractDataChangeListener<VpnInterface> implements AutoCloseable {
+public class VpnInterfaceChangeListener extends AbstractDataChangeListener<Adjacencies> implements AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceChangeListener.class);
private ListenerRegistration<DataChangeListener> listenerRegistration;
private NexthopManager nexthopManager;
public VpnInterfaceChangeListener(final DataBroker db, NexthopManager nhm) {
- super(VpnInterface.class);
+ super(Adjacencies.class);
broker = db;
nexthopManager = nhm;
registerListener(db);
}
@Override
- protected void add(InstanceIdentifier<VpnInterface> identifier,
- VpnInterface vpnIf) {
- LOG.info("key: " + identifier + ", value=" + vpnIf );
-
- String vpnName = vpnIf.getVpnInstanceName();
- final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
- String interfaceName = key.getName();
- InstanceIdentifierBuilder<Interface> idBuilder =
- InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName));
- InstanceIdentifier<Interface> id = idBuilder.build();
- Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
- if (port.isPresent()) {
- //Interface interf = port.get();
-
- //Read NextHops
- InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
- Optional<Adjacencies> adjacencies = read(LogicalDatastoreType.CONFIGURATION, path);
-
- if (adjacencies.isPresent()) {
- List<Adjacency> nextHops = adjacencies.get().getAdjacency();
- List<Adjacency> value = new ArrayList<>();
-
- if (!nextHops.isEmpty()) {
- LOG.info("NextHops are " + nextHops);
- for (Adjacency nextHop : nextHops) {
- nexthopManager.createLocalNextHop(interfaceName, vpnName, nextHop.getIpAddress());
- }
- }
- }
+ protected void add(InstanceIdentifier<Adjacencies> identifier,
+ Adjacencies adjs) {
+
+ InstanceIdentifier<VpnInterface> vpnIfId = identifier.firstIdentifierOf(VpnInterface.class);
+ Optional<VpnInterface> vpnIf = read(LogicalDatastoreType.CONFIGURATION, vpnIfId);
+ VpnInterface vpnIfData = vpnIf.get();
+
+ List<Adjacency> adjList = adjs.getAdjacency();
+ for (Adjacency adjacency : adjList) {
+ nexthopManager.createLocalNextHop(
+ vpnIfData.getName(),
+ vpnIfData.getVpnInstanceName(),
+ adjacency.getIpAddress(),
+ adjacency.getMacAddress());
}
+ }
+
+
+ @Override
+ protected void remove(InstanceIdentifier<Adjacencies> identifier,
+ Adjacencies adjs) {
+ InstanceIdentifier<VpnInterface> vpnIfId = identifier.firstIdentifierOf(VpnInterface.class);
+ Optional<VpnInterface> vpnIf = read(LogicalDatastoreType.CONFIGURATION, vpnIfId);
+ VpnInterface vpnIfData = vpnIf.get();
+
+ List<Adjacency> adjList = adjs.getAdjacency();
+ for (Adjacency adjacency : adjList) {
+ nexthopManager.removeLocalNextHop(vpnIfData.getVpnInstanceName(), adjacency.getIpAddress());
+ }
+
+ }
+ @Override
+ protected void update(InstanceIdentifier<Adjacencies> identifier,
+ Adjacencies original, Adjacencies update) {
+ // TODO Auto-generated method stub
}
+
private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
InstanceIdentifier<T> path) {
return result;
}
- private InstanceIdentifier<VpnInterface> getWildCardPath() {
- return InstanceIdentifier.create(VpnInterfaces.class).child(VpnInterface.class);
+ private InstanceIdentifier<Adjacencies> getWildCardPath() {
+ return InstanceIdentifier.create(VpnInterfaces.class).child(VpnInterface.class).augmentation(Adjacencies.class);
}
- @Override
- protected void remove(InstanceIdentifier<VpnInterface> identifier,
- VpnInterface del) {
- // TODO Auto-generated method stub
- }
-
- @Override
- protected void update(InstanceIdentifier<VpnInterface> identifier,
- VpnInterface original, VpnInterface update) {
- // TODO Auto-generated method stub
-
- }
}
\ No newline at end of file
@Override
public java.lang.AutoCloseable createInstance() {
NexthopmgrProvider provider = new NexthopmgrProvider();
+ provider.setMdsalManager(getMdsalutilDependency());
+ provider.setInterfaceManager(getOdlinterfaceDependency());
+
getBrokerDependency().registerProvider(provider);
return provider;
}
import config { prefix config; revision-date 2013-04-05; }
import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
+ import odl-mdsalutil { prefix odl-mdsal; revision-date 2015-04-10;}
+ import odl-interface {prefix odlif; revision-date 2015-03-31;}
description
"Service definition for nexthopmgr project";
}
}
}
+ container mdsalutil {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity odl-mdsal:odl-mdsalutil;
+ }
+ }
+ }
+ container odlinterface {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity odlif:odl-interface;
+ }
+ }
+ }
}
}
}
<artifactId>bgpmanager-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
- <!-- TEST Dependencies -->
+ <dependency>
+ <groupId>org.opendaylight.vpnservice</groupId>
+ <artifactId>fibmanager-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>mdsalutil-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>interfacemgr-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <!-- TEST Dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<capability>urn:opendaylight:params:xml:ns:yang:vpnservice:impl?module=vpnservice-impl&revision=2015-02-16</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28</capability>
<capability>urn:opendaylight:params:xml:ns:yang:bgpmanager:api?module=bgpmanager-api&revision=2015-04-20</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:mdsalutil:api?module=odl-mdsalutil&revision=2015-04-10</capability>
+ <capability>urn:opendaylight:vpnservice:interfacemgr?module=odl-interface&revision=2015-03-31</capability>
</required-capabilities>
<configuration>
<type xmlns:bgpmanager="urn:opendaylight:params:xml:ns:yang:bgpmanager:api">bgpmanager:bgpmanager-api</type>
<name>bgpmanager</name>
</bgpmanager>
+ <mdsalutil>
+ <type xmlns:mdsalutil="urn:opendaylight:params:xml:ns:yang:mdsalutil:api">mdsalutil:odl-mdsalutil</type>
+ <name>mdsalutil-service</name>
+ </mdsalutil>
+ <odlinterface>
+ <type xmlns:odlif="urn:opendaylight:vpnservice:interfacemgr">odlif:odl-interface</type>
+ <name>interfacemgr-service</name>
+ </odlinterface>
</module>
</modules>
</data>
*/
package org.opendaylight.vpnservice;
+import java.math.BigInteger;
import java.util.List;
import java.util.ArrayList;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.FutureCallback;
+import org.opendaylight.bgpmanager.api.IBgpManager;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
+import org.opendaylight.vpnservice.mdsalutil.InstructionInfo;
+import org.opendaylight.vpnservice.mdsalutil.InstructionType;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.AdjacencyList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.Adjacency;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstance1;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.Adjacencies;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
private static final Logger LOG = LoggerFactory.getLogger(VpnInterfaceManager.class);
private ListenerRegistration<DataChangeListener> listenerRegistration;
private final DataBroker broker;
+ private final IBgpManager bgpManager;
+ private IMdsalApiManager mdsalManager;
+ private IInterfaceManager interfaceManager;
private static final FutureCallback<Void> DEFAULT_CALLBACK =
new FutureCallback<Void>() {
public void onSuccess(Void result) {
- LOG.info("Success in Datastore operation");
+ LOG.debug("Success in Datastore operation");
}
public void onFailure(Throwable error) {
*
* @param db - dataBroker service reference
*/
- public VpnInterfaceManager(final DataBroker db) {
+ public VpnInterfaceManager(final DataBroker db, final IBgpManager bgpManager) {
super(VpnInterface.class);
broker = db;
+ this.bgpManager = bgpManager;
registerListener(db);
}
+ public void setMdsalManager(IMdsalApiManager mdsalManager) {
+ this.mdsalManager = mdsalManager;
+ }
+
@Override
public void close() throws Exception {
if (listenerRegistration != null) {
@Override
protected void add(final InstanceIdentifier<VpnInterface> identifier,
final VpnInterface vpnInterface) {
- LOG.info("key: " + identifier + ", value=" + vpnInterface );
+ LOG.info("key: {} , value: {}", identifier, vpnInterface );
addInterface(identifier, vpnInterface);
}
Optional<Interface> port = read(LogicalDatastoreType.CONFIGURATION, id);
if (port.isPresent()) {
Interface interf = port.get();
- bindServiceOnInterface(interf);
+ bindServiceOnInterface(interf, getVpnId(vpnInterface.getVpnInstanceName()));
updateNextHops(identifier, vpnInterface);
}
}
List<Adjacency> nextHops = adjacencies.get().getAdjacency();
List<Adjacency> value = new ArrayList<>();
+ //Get the rd of the vpn instance
+ String rd = getRouteDistinguisher(intf.getVpnInstanceName());
+ //TODO: Get the endpoint IP from interface manager
+ String nextHopIp = "10.0.0.1";
+
if (!nextHops.isEmpty()) {
- LOG.info("NextHops are " + nextHops);
+ LOG.info("NextHops are {}", nextHops);
for (Adjacency nextHop : nextHops) {
//TODO: Generate label for the prefix and store it in the next hop model
long label = 200;
//TODO: Update BGP
- updatePrefixToBGP(nextHop);
+ updatePrefixToBGP(rd, nextHop, nextHopIp);
value.add(new AdjacencyBuilder(nextHop).setLabel(label).build());
}
}
}
}
- private void bindServiceOnInterface(Interface intf) {
+ private long getVpnId(String vpnName) {
+ InstanceIdentifier<VpnInstance1> id = InstanceIdentifier.builder(VpnInstances.class)
+ .child(VpnInstance.class, new VpnInstanceKey(vpnName)).augmentation(VpnInstance1.class).build();
+ Optional<VpnInstance1> vpnInstance = read(LogicalDatastoreType.CONFIGURATION, id);
+ long vpnId = -1;
+ if(vpnInstance.isPresent()) {
+ vpnId = vpnInstance.get().getVpnId();
+ }
+ return vpnId;
+ }
+
+ private String getRouteDistinguisher(String vpnName) {
+ InstanceIdentifier<VpnInstance> id = InstanceIdentifier.builder(VpnInstances.class)
+ .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
+ Optional<VpnInstance> vpnInstance = read(LogicalDatastoreType.CONFIGURATION, id);
+ String rd = "";
+ if(vpnInstance.isPresent()) {
+ VpnInstance instance = vpnInstance.get();
+ VpnAfConfig config = instance.getIpv4Family();
+ rd = config.getRouteDistinguisher();
+ }
+ return rd;
+ }
+
+ private void bindServiceOnInterface(Interface intf, long vpnId) {
+ LOG.info("Bind service on interface {} for VPN: {}", intf, vpnId);
//TODO: Create Ingress flow on the interface to bind the VPN service
+ //TODO: Get dpn ID from the interface manager
+ long dpId = 1;
+ short LPORT_INGRESS_TABLE = 0;
+ //TODO: Get the port no from interface manager
+ int portNo = 1;
+ String flowRef = getL3InterfaceFlowRef(dpId, LPORT_INGRESS_TABLE, vpnId, portNo);
+
+ String flowName = intf.getName();
+ BigInteger COOKIE_VM_INGRESS_TABLE = new BigInteger("8000001", 16);
+
+ int priority = 10; //L3Constants.DEFAULT_L3_FLOW_PRIORITY;
+ short gotoTableId = 21; //L3Constants.L3_FIB_TABLE;
+
+ List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
+ mkInstructions.add(new InstructionInfo(InstructionType.write_metadata, new BigInteger[] {
+ BigInteger.valueOf(vpnId), MetaDataUtil.METADATA_MASK_VRFID }));
+
+ mkInstructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { gotoTableId }));
+
+ List<MatchInfo> matches = new ArrayList<MatchInfo>();
+ matches.add(new MatchInfo(MatchFieldType.in_port, new long[] {
+ dpId, portNo }));
+
+ FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, LPORT_INGRESS_TABLE, flowRef,
+ priority, flowName, 0, 0, COOKIE_VM_INGRESS_TABLE, matches, mkInstructions);
+
+ mdsalManager.installFlow(flowEntity);
+ }
+
+ private String getL3InterfaceFlowRef(long dpId, short tableId,
+ long vpnId, int portNo) {
+ return new StringBuilder().append(dpId).append(tableId).append(vpnId).append(portNo).toString();
}
- private void updatePrefixToBGP(Adjacency nextHop) {
+ private void updatePrefixToBGP(String rd, Adjacency nextHop, String nextHopIp) {
//TODO: Update the Prefix to BGP
+ //public void addPrefix(String rd, String prefix, String nextHop, int vpnLabel)
+ int label = nextHop.getLabel().intValue();
+ try {
+ bgpManager.addPrefix(rd, nextHop.getIpAddress(), nextHopIp, label);
+ } catch(Exception e) {
+ LOG.error("Add prefix failed", e);
+ }
}
private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
*/
package org.opendaylight.vpnservice;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.opendaylight.bgpmanager.api.IBgpManager;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstance1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstance1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.FibEntries;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTablesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.vrfentries.VrfEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+
public class VpnManager extends AbstractDataChangeListener<VpnInstance> implements AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(VpnManager.class);
- private ListenerRegistration<DataChangeListener> listenerRegistration;
+ private ListenerRegistration<DataChangeListener> listenerRegistration, fibListenerRegistration;
private final DataBroker broker;
+ private final IBgpManager bgpManager;
+ private final FibEntriesListener fibListener;
+
+ private static final FutureCallback<Void> DEFAULT_CALLBACK =
+ new FutureCallback<Void>() {
+ public void onSuccess(Void result) {
+ LOG.debug("Success in Datastore operation");
+ }
+
+ public void onFailure(Throwable error) {
+ LOG.error("Error in Datastore operation", error);
+ };
+ };
/**
* Listens for data change related to VPN Instance
*
* @param db - dataBroker reference
*/
- public VpnManager(final DataBroker db) {
+ public VpnManager(final DataBroker db, final IBgpManager bgpManager) {
super(VpnInstance.class);
broker = db;
+ this.bgpManager = bgpManager;
+ this.fibListener = new FibEntriesListener();
registerListener(db);
}
try {
listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
getWildCardPath(), VpnManager.this, DataChangeScope.SUBTREE);
+ fibListenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+ getFibEntryListenerPath(), fibListener, DataChangeScope.BASE);
} catch (final Exception e) {
LOG.error("VPN Service DataChange listener registration fail!", e);
throw new IllegalStateException("VPN Service registration Listener failed.", e);
@Override
protected void add(InstanceIdentifier<VpnInstance> identifier,
VpnInstance value) {
- LOG.info("key: " + identifier + ", value=" + value);
+ LOG.info("key: {}, value: {}" +identifier, value);
//TODO: Generate VPN ID for this instance, where to store in model ... ?
+ long vpnId = 1000;
+ InstanceIdentifier<VpnInstance1> augId = identifier.augmentation(VpnInstance1.class);
+ Optional<VpnInstance1> vpnAugmenation = read(LogicalDatastoreType.CONFIGURATION, augId);
+ if(vpnAugmenation.isPresent()) {
+ VpnInstance1 vpn = vpnAugmenation.get();
+ vpnId = vpn.getVpnId();
+ LOG.info("VPN ID is {}", vpnId);
+ }
+
+ VpnInstance opValue = new VpnInstanceBuilder(value).
+ addAugmentation(VpnInstance1.class, new VpnInstance1Builder().setVpnId(vpnId).build()).build();
+
+ asyncWrite(LogicalDatastoreType.OPERATIONAL, identifier, opValue, DEFAULT_CALLBACK);
//TODO: Add VRF to BGP
+ //public void addVrf(String rd, Collection<String> importRts, Collection<String> exportRts)
+ VpnAfConfig config = value.getIpv4Family();
+ String rd = config.getRouteDistinguisher();
+ List<String> importRts = Arrays.asList(config.getImportRoutePolicy().split(","));
+ List<String> exportRts = Arrays.asList(config.getExportRoutePolicy().split(","));
+ try {
+ bgpManager.addVrf(rd, importRts, exportRts);
+ } catch(Exception e) {
+ LOG.error("Exception when adding VRF to BGP", e);
+ }
}
private InstanceIdentifier<?> getWildCardPath() {
return InstanceIdentifier.create(VpnInstances.class).child(VpnInstance.class);
}
+ private InstanceIdentifier<?> getFibEntryListenerPath() {
+ return InstanceIdentifier.create(FibEntries.class).child(VrfTables.class)
+ .child(VrfEntry.class);
+ }
+
@Override
public void close() throws Exception {
if (listenerRegistration != null) {
try {
listenerRegistration.close();
} catch (final Exception e) {
- LOG.error("Error when cleaning up DataChangeListener.", e);
+ LOG.error("Error when cleaning up Vpn DataChangeListener.", e);
}
listenerRegistration = null;
}
- LOG.info("VPN Manager Closed");
+ if (fibListenerRegistration != null) {
+ try {
+ fibListenerRegistration.close();
+ } catch (final Exception e) {
+ LOG.error("Error when cleaning up Fib entries DataChangeListener.", e);
+ }
+ fibListenerRegistration = null;
+ }
+ LOG.trace("VPN Manager Closed");
+ }
+
+ private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path) {
+
+ ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
+
+ Optional<T> result = Optional.absent();
+ try {
+ result = tx.read(datastoreType, path).get();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return result;
+ }
+
+ private <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.put(datastoreType, path, data, true);
+ Futures.addCallback(tx.submit(), callback);
+ }
+
+ private VpnInstance getVpnForRD(String rd) {
+ InstanceIdentifier<VpnInstances> id = InstanceIdentifier.create(VpnInstances.class);
+ Optional<VpnInstances> vpnInstances = read(LogicalDatastoreType.OPERATIONAL, id);
+ if(vpnInstances.isPresent()) {
+ List<VpnInstance> vpns = vpnInstances.get().getVpnInstance();
+ for(VpnInstance vpn : vpns) {
+ if(vpn.getIpv4Family().getRouteDistinguisher().equals(rd)) {
+ return vpn;
+ }
+ }
+ }
+ return null;
+ }
+
+ private class FibEntriesListener extends AbstractDataChangeListener<VrfEntry> {
+
+ public FibEntriesListener() {
+ super(VrfEntry.class);
+ }
+
+ @Override
+ protected void remove(InstanceIdentifier<VrfEntry> identifier,
+ VrfEntry del) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected void update(InstanceIdentifier<VrfEntry> identifier,
+ VrfEntry original, VrfEntry update) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected void add(InstanceIdentifier<VrfEntry> identifier,
+ VrfEntry add) {
+ LOG.info("Key : " + identifier + " value : " + add);
+ final VrfTablesKey key = identifier.firstKeyOf(VrfTables.class, VrfTablesKey.class);
+ String rd = key.getRouteDistinguisher();
+ Long label = add.getLabel();
+ VpnInstance vpn = getVpnForRD(rd);
+ if(vpn != null) {
+ InstanceIdentifier<VpnInstance> id = VpnUtil.getVpnInstanceIdentifier(vpn.getVpnInstanceName());
+ InstanceIdentifier<VpnInstance1> augId = id.augmentation(VpnInstance1.class);
+ Optional<VpnInstance1> vpnAugmenation = read(LogicalDatastoreType.OPERATIONAL, augId);
+ if(vpnAugmenation.isPresent()) {
+ VpnInstance1 vpnAug = vpnAugmenation.get();
+ List<Long> routeIds = vpnAug.getRouteEntryId();
+ if(routeIds == null) {
+ routeIds = new ArrayList<>();
+ }
+ LOG.info("Adding label to vpn info " + label);
+ routeIds.add(label);
+ asyncWrite(LogicalDatastoreType.OPERATIONAL, augId,
+ new VpnInstance1Builder(vpnAug).setRouteEntryId(routeIds).build(), DEFAULT_CALLBACK);
+ } else {
+ LOG.info("VPN Augmentation not found");
+ }
+ } else {
+ LOG.warn("No VPN Instance found for RD: {}", rd);
+ }
+ }
}
}
import java.util.List;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
.child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
}
+ static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
+ return InstanceIdentifier.builder(VpnInstances.class)
+ .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
+ }
+
static VpnInterface getVpnInterface(String intfName, String vpnName, Adjacencies aug) {
return new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(intfName)).setVpnInstanceName(vpnName)
.addAugmentation(Adjacencies.class, aug).build();
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private VpnInterfaceManager vpnInterfaceManager;
private VpnManager vpnManager;
private IBgpManager bgpManager;
+ private IMdsalApiManager mdsalManager;
+ private IInterfaceManager interfaceManager;
@Override
public void onSessionInitiated(ProviderContext session) {
LOG.info("VpnserviceProvider Session Initiated");
try {
final DataBroker dataBroker = session.getSALService(DataBroker.class);
- vpnManager = new VpnManager(dataBroker);
- vpnInterfaceManager = new VpnInterfaceManager(dataBroker);
+ vpnManager = new VpnManager(dataBroker, bgpManager);
+ vpnInterfaceManager = new VpnInterfaceManager(dataBroker, bgpManager);
+ vpnInterfaceManager.setMdsalManager(mdsalManager);
} catch (Exception e) {
LOG.error("Error initializing services", e);
}
this.bgpManager = bgpManager;
}
+ public void setMdsalManager(IMdsalApiManager mdsalManager) {
+ this.mdsalManager = mdsalManager;
+ }
+
+ public void setInterfaceManager(IInterfaceManager interfaceManager) {
+ this.interfaceManager = interfaceManager;
+ }
+
@Override
public void close() throws Exception {
vpnManager.close();
@Override
public java.lang.AutoCloseable createInstance() {
VpnserviceProvider provider = new VpnserviceProvider();
- getBrokerDependency().registerProvider(provider);
provider.setBgpManager(getBgpmanagerDependency());
+ provider.setMdsalManager(getMdsalutilDependency());
+ provider.setInterfaceManager(getOdlinterfaceDependency());
+ getBrokerDependency().registerProvider(provider);
return provider;
}
}
import config { prefix config; revision-date 2013-04-05; }
import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
import bgpmanager-api { prefix bgpmgr-api; revision-date 2015-04-20;}
+ import odl-mdsalutil { prefix odl-mdsal; revision-date 2015-04-10;}
+ import odl-interface {prefix odlif; revision-date 2015-03-31;}
description
"Service definition for vpnservice project";
}
}
}
+ container mdsalutil {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity odl-mdsal:odl-mdsalutil;
+ }
+ }
+ }
+ container odlinterface {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity odlif:odl-interface;
+ }
+ }
+ }
}
}
}
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
-
import org.opendaylight.vpnservice.VpnManager;
+import org.opendaylight.bgpmanager.api.IBgpManager;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
@RunWith(MockitoJUnitRunner.class)
public class VpnServiceTest {
@Mock DataBroker dataBroker;
+ @Mock IBgpManager bgpManager;
@Mock ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
MockDataChangedEvent event;
setExportRoutePolicy("100:1").setApplyLabel(new ApplyLabelBuilder().setApplyLabelMode(
new PerRouteBuilder().setApplyLabelPerRoute(true).build()).build()).build());
VpnInstance instance = builder.build();
- VpnManager vpnManager = new VpnManager(dataBroker);
+ VpnManager vpnManager = new VpnManager(dataBroker, bgpManager);
event.created.put(createVpnId("Vpn1"), instance);
- vpnManager.onDataChanged(event);
+ //TODO: Need to enhance the test case to handle ds read/write ops
+ //vpnManager.onDataChanged(event);
}
private InstanceIdentifier<VpnInstance> createVpnId(String name) {