| 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(); |
| } |
| } |