package net.onrc.onos.apps.sdnip.web; import java.util.Iterator; import net.onrc.onos.apps.sdnip.ISdnIpService; import net.onrc.onos.apps.sdnip.Prefix; import net.onrc.onos.apps.sdnip.RestClient; import net.onrc.onos.apps.sdnip.RibEntry; import net.onrc.onos.apps.sdnip.RibUpdate; import net.onrc.onos.apps.sdnip.RibUpdate.Operation; import org.restlet.resource.Delete; import org.restlet.resource.Get; import org.restlet.resource.Post; import org.restlet.resource.ServerResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.googlecode.concurrenttrees.common.KeyValuePair; import com.googlecode.concurrenttrees.radix.RadixTree; /** * REST resource that handles REST calls from BGPd. This is the interface BGPd * uses to push RIB entries (routes) to SDN-IP. */ public class IncomingRequestResource extends ServerResource { private static final Logger log = LoggerFactory.getLogger(IncomingRequestResource.class); /** * Gets the contents of SDN-IP's route table. * * @return the contents of SDN-IP's route table formatted as JSON */ @Get public String handleGetMethod() { String dest = (String) getRequestAttributes().get("dest"); StringBuilder output = new StringBuilder(80); ISdnIpService sdnIp = (ISdnIpService) getContext() .getAttributes(). get(ISdnIpService.class.getCanonicalName()); if (dest == null) { RadixTree<RibEntry> radixTree = sdnIp.getPtree(); output.append("{\n \"rib\": [\n"); boolean printed = false; Iterator<KeyValuePair<RibEntry>> it = radixTree.getKeyValuePairsForKeysStartingWith("").iterator(); while (it.hasNext()) { KeyValuePair<RibEntry> entry = it.next(); if (printed) { output.append(",\n"); } output.append(" {\"prefix\": \""); output.append(Prefix.fromBinaryString(entry.getKey().toString())); output.append("\", \"nexthop\": \""); output.append(entry.getValue().getNextHop().getHostAddress()); output.append("\"}"); printed = true; } output.append("\n ]\n}\n"); } else { // TODO Needs to be changed to use the new RestClient.get(). // the dest here refers to router-id // bgpdRestIp includes port number, such as 1.1.1.1:8080 String bgpdRestIp = sdnIp.getBgpdRestIp(); String url = "http://" + bgpdRestIp + "/wm/bgp/" + dest; // Doesn't actually do anything with the response RestClient.get(url); output.append("Get rib from bgpd finished!\n"); } return output.toString(); } /** * Handler to receive a new RIB entry. The details of the RIB entry are * given as part of the URL. * * @return a String describing the result of the action */ @Post public String handlePostMethod() { ISdnIpService sdnIp = (ISdnIpService) getContext() .getAttributes(). get(ISdnIpService.class.getCanonicalName()); String strSysuptime = (String) getRequestAttributes().get("sysuptime"); String strSequence = (String) getRequestAttributes().get("sequence"); String routerId = (String) getRequestAttributes().get("routerid"); String prefix = (String) getRequestAttributes().get("prefix"); String mask = (String) getRequestAttributes().get("mask"); String nexthop = (String) getRequestAttributes().get("nexthop"); String capability = (String) getRequestAttributes().get("capability"); log.debug("sysuptime: {}", strSysuptime); log.debug("sequence: {}", strSequence); String reply = ""; if (capability == null) { // this is a prefix add Prefix p; long sysUpTime, sequenceNum; try { p = new Prefix(prefix, Integer.parseInt(mask)); sysUpTime = Long.parseLong(strSysuptime); sequenceNum = Long.parseLong(strSequence); } catch (NumberFormatException e) { reply = "[POST: mask format is wrong]"; log.info(reply); return reply + "\n"; } catch (IllegalArgumentException e1) { reply = "[POST: prefix format is wrong]"; log.info(reply); return reply + "\n"; } RibEntry rib = new RibEntry(routerId, nexthop, sysUpTime, sequenceNum); sdnIp.newRibUpdate(new RibUpdate(Operation.UPDATE, p, rib)); reply = "[POST: " + prefix + "/" + mask + ":" + nexthop + "]"; log.info(reply); } else { reply = "[POST-capability: " + capability + "]\n"; log.info(reply); // to store the number in the top node of the Ptree } /*else if ("1".equals(capability)) { reply = "[POST-capability: " + capability + "]\n"; log.info(reply); // to store the number in the top node of the Ptree }*/ return reply + "\n"; } /** * Handler to remove a RIB entry from ONOS's route table. The details of * the route to remove are passed as part of the URL. * * @return a String describing the result of the action */ @Delete public String handleDeleteMethod() { ISdnIpService sdnIp = (ISdnIpService) getContext() .getAttributes(). get(ISdnIpService.class.getCanonicalName()); String strSysuptime = (String) getRequestAttributes().get("sysuptime"); String strSequence = (String) getRequestAttributes().get("sequence"); String routerId = (String) getRequestAttributes().get("routerid"); String prefix = (String) getRequestAttributes().get("prefix"); String mask = (String) getRequestAttributes().get("mask"); String nextHop = (String) getRequestAttributes().get("nexthop"); String capability = (String) getRequestAttributes().get("capability"); log.debug("sysuptime: {}", strSysuptime); log.debug("sequence: {}", strSequence); //String reply = ""; StringBuilder replyStringBuilder = new StringBuilder(80); if (capability == null) { // this is a prefix delete Prefix p; long sysUpTime, sequenceNum; try { p = new Prefix(prefix, Integer.parseInt(mask)); sysUpTime = Long.parseLong(strSysuptime); sequenceNum = Long.parseLong(strSequence); } catch (NumberFormatException e) { String reply = "[DELE: mask format is wrong]"; log.info(reply); return reply + "\n"; } catch (IllegalArgumentException e1) { String reply = "[DELE: prefix format is wrong]"; log.info(reply); return reply + "\n"; } RibEntry r = new RibEntry(routerId, nextHop, sysUpTime, sequenceNum); sdnIp.newRibUpdate(new RibUpdate(Operation.DELETE, p, r)); replyStringBuilder.append("[DELE: ") .append(prefix) .append('/') .append(mask) .append(':') .append(nextHop) .append(']'); } else { // clear the local rib: Ptree sdnIp.clearPtree(); replyStringBuilder.append("[DELE-capability: ") .append(capability) .append("; The local RibEntry is cleared!]\n"); // to store the number in the top node of the Ptree } log.info(replyStringBuilder.toString()); replyStringBuilder.append('\n'); return replyStringBuilder.toString(); } }