Commit b8a5654a authored by Matt Strum's avatar Matt Strum
Browse files

Added support to list component managers using the clearinghouse

parent 87a4bcb2
......@@ -38,7 +38,9 @@
public var console:ConsoleWindow;
public var rspecView:XmlWindow;
[Bindable]
public var comHandler:ProtoGeniHandler;
public var mapHandler:ProtoGeniMapHandler;
public var main:Main;
......@@ -88,7 +90,13 @@
map.clearOverlays();
// Get a fresh dataset
comHandler.startCredential();
if(comHandler.credential != null && comHandler.credential.base != null) {
comHandler.AfterCall = null;
comHandler.startResourceLookup();
} else {
comHandler.AfterCall = comHandler.startResourceLookup;
comHandler.startCredential();
}
}
//------------------------------------------
......
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
title="Component Manager"
title="Choose Component Manager"
showCloseButton="true"
borderAlpha=".9" borderColor="#D2E1F0" width="400"
borderAlpha=".9" borderColor="#D2E1F0" width="320"
defaultButton="{okButton}"
close="close()"
creationComplete="okButton.setFocus()">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.CloseEvent;
import mx.managers.PopUpManager;
[Bindable]
public var main:pgmap;
public function success():void {
main.comHandler.ComponentManagerURL = urlInput.text;
main.comHandler.ComponentManagerURL = listManagers.selectedItem.url;
main.refresh();
close();
}
......@@ -27,14 +29,48 @@
public function open():void {
PopUpManager.addPopUp(this, main, true);
PopUpManager.centerPopUp(this);
urlInput.text = main.comHandler.ComponentManagerURL;
if(main.comHandler.Components == null || main.comHandler.Components.length == 0) {
startRefreshList();
}
//urlInput.text = main.comHandler.ComponentManagerURL;
}
public function startRefreshList():void {
progressLabel.text = "Updating list...";
waitingIcon.visible = true;
if(main.comHandler.credential == null || main.comHandler.credential.base == null) {
main.console.appendText("Getting credential...\n");
main.comHandler.AfterCall = afterCredential;
main.comHandler.startCredential();
} else
afterCredential();
}
public function afterCredential():void {
main.console.appendText("After credential...\n");
main.comHandler.AfterCall = refreshList;
main.comHandler.startListComponents();
}
public function refreshList():void {
main.comHandler.AfterCall = null;
progressLabel.text = "List updated";
waitingIcon.visible = false;
}
]]>
</mx:Script>
<mx:Label text="Please input the URL to the Component Manager"/>
<mx:TextInput id="urlInput" width="100%" text=""/>
<mx:HBox width="100%" verticalAlign="middle">
<mx:Button id="refreshButton" label="Refresh" icon="@Embed('../images/server.png')"/>
<mx:ComboBox editable="false" width="100%" id="listManagers" dataProvider="{main.comHandler.Components}" labelField="hrn"></mx:ComboBox>
</mx:HBox>
<mx:HBox width="100%" horizontalAlign="right">
<mx:Label id="progressLabel" fontStyle="normal" fontWeight="bold"/>
<mx:SWFLoader id="waitingIcon" source="@Embed('../../images/waiting.swf')" visible="false"/>
<mx:Spacer width="100%"/>
<mx:Button id="cancelButton" label="Cancel" icon="@Embed('../images/cross.png')" click="close();"/>
<mx:Button id="okButton" label="Go" icon="@Embed('../images/tick.png')" click="success();"/>
</mx:HBox>
......
......@@ -5,5 +5,17 @@ package pgmap
public static var successColor:String = "#0E8219";
public static var failColor:String = "#FE0000";
public static var waitColor:String = "#FF7F00";
public static function kbsToString(bandwidth:Number):String {
var bw:String = "";
if(bandwidth < 1000) {
return bandwidth + " Kb\\s"
} else if(bandwidth < 1000000) {
return bandwidth / 1000 + " Mb\\s"
} else if(bandwidth < 1000000000) {
return bandwidth / 1000000 + " Gb\\s"
}
return bw;
}
}
}
\ No newline at end of file
......@@ -23,19 +23,29 @@
public var main:pgmap;
public function loadGroup(group:LinkGroup):void {
links = new ArrayCollection();
public function loadCollection(group:ArrayCollection):void {
links = group;
for each(var n:Link in group.collection) {
links.addItem(n);
if(links.length > 1) {
listLinks.selectedIndex = 0;
} else {
listLinks.visible = false;
listLinks.includeInLayout = false;
nodeInfoHolder.percentWidth = 100;
title = "Link Information";
}
listLinks.selectedIndex = 0;
loadLink(group.collection[0]);
loadLink(links[0]);
}
public function loadGroup(group:LinkGroup):void {
loadCollection(group.collection);
}
public function loadLink(l:Link):void {
link = l;
txtBandwidth.text = Common.kbsToString(l.bandwidth);
}
public function viewRspec():void {
......@@ -63,7 +73,7 @@
<mx:GridRow width="100%">
<mx:GridItem width="100%">
<mx:Label text="Bandwidth" fontWeight="bold"/>
<mx:Label text="{link.bandwidth}"/>
<mx:Label id="txtBandwidth"/>
<mx:VRule height="16"/>
<mx:Label text="Latency" fontWeight="bold"/>
<mx:Label text="{link.latency}"/>
......@@ -90,23 +100,23 @@
</mx:GridRow>
<mx:GridRow width="100%">
<mx:GridItem>
<mx:Label text="Interface 1" fontWeight="bold"/>
<mx:Label text="Connects" fontWeight="bold"/>
</mx:GridItem>
<mx:GridItem width="100%">
<mx:VBox width="100%">
<mx:Label text="{link.interface1.id}"/>
<mx:Label text="on {link.interface1.owner.name}"/>
<mx:Label text="{link.interface1.owner.name}"/>
<mx:Label text="on {link.interface1.id}"/>
</mx:VBox>
</mx:GridItem>
</mx:GridRow>
<mx:GridRow width="100%">
<mx:GridItem>
<mx:Label text="Interface 2" fontWeight="bold"/>
<mx:Label text="to" fontWeight="bold"/>
</mx:GridItem>
<mx:GridItem width="100%">
<mx:VBox width="100%">
<mx:Label text="{link.interface2.id}"/>
<mx:Label text="on {link.interface2.owner.name}"/>
<mx:Label text="{link.interface2.owner.name}"/>
<mx:Label text="on {link.interface2.id}"/>
</mx:VBox>
</mx:GridItem>
</mx:GridRow>
......
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
width="140" height="120" horizontalAlign="center" verticalGap="0">
<mx:Script>
<![CDATA[
[Bindable]
public var linkCount:String = "0";
[Bindable]
public var totalBandwidth:String = "";
[Bindable]
public var averageBandwidth:String = "";
public var group:LinkGroup = null;
public var main:pgmap = null;
public function Load(lg:LinkGroup, pg:pgmap):void
{
linkCount = lg.collection.length.toString();
totalBandwidth = lg.TotalBandwidth().toString();
averageBandwidth = lg.AverageBandwidth().toString();
group = lg;
main = pg;
}
]]>
</mx:Script>
<mx:Label text="{linkCount} Link(s)" fontWeight="normal"/>
<mx:Label text="Total Bandwidth" fontStyle="italic"/>
<mx:Label text="{totalBandwidth}" id="txtTotalBw"/>
<mx:Label text="Average Bandwidth" fontStyle="italic"/>
<mx:Label text="{averageBandwidth}" id="txtAvgBw"/>
<mx:Button label="More Info" click="main.mapHandler.viewLinkGroup(group)"/>
</mx:VBox>
......@@ -22,21 +22,30 @@
public var node:Node = null;
[Bindable]
public var links:ArrayCollection = new ArrayCollection();
public var linkedNodes:ArrayCollection = new ArrayCollection();
public var main:pgmap;
public function loadGroup(group:NodeGroup):void {
if(group.city.length > 0)
title = group.city + " Node Group";
nodes = new ArrayCollection();
public function loadCollection(group:ArrayCollection):void {
nodes = group;
for each(var n:Node in group.collection) {
nodes.addItem(n);
if(nodes.length > 1) {
listNodes.selectedIndex = 0;
title += " Group";
} else {
listNodes.visible = false;
listNodes.includeInLayout = false;
nodeInfoHolder.percentWidth = 100;
title = "Node Information";
}
listNodes.selectedIndex = 0;
loadNode(group.collection[0]);
loadNode(nodes[0]);
}
public function loadGroup(group:NodeGroup):void {
if(group.city.length > 0)
title = group.city + " Node";
loadCollection(group.collection);
}
public function loadNode(n:Node):void {
......@@ -45,7 +54,43 @@
imgAvailable.source = assignIcon(n.available);
imgExclusive.source = assignIcon(n.exclusive);
links = n.GetLinks();
linkedNodes = new ArrayCollection();
for each(var i:NodeInterface in n.interfaces.collection) {
for each(var l:Link in i.links) {
var ns:String;
var ins:String;
if(l.interface1 == i) {
ns = l.interface2.owner.name;
ins = l.interface1.id;
} else {
ns = l.interface1.owner.name;
ins = l.interface2.id;
}
linkedNodes.addItem({name: ns + " on " + ins, link: l});
}
}
}
public function viewLink(l:Link):void {
var lgWindow:LinkGroupAdvancedWindow = new LinkGroupAdvancedWindow();
lgWindow.main = main;
PopUpManager.addPopUp(lgWindow, main, false);
PopUpManager.centerPopUp(lgWindow);
var ac:ArrayCollection = new ArrayCollection();
ac.addItem(l);
lgWindow.loadCollection(ac);
lgWindow.title = node.name + "'s Links";
}
public function viewLinks():void {
var lgWindow:LinkGroupAdvancedWindow = new LinkGroupAdvancedWindow();
lgWindow.main = main;
PopUpManager.addPopUp(lgWindow, main, false);
PopUpManager.centerPopUp(lgWindow);
lgWindow.loadCollection(node.GetLinks());
}
public function viewRspec():void {
......@@ -131,18 +176,13 @@
</mx:GridRow>
<mx:GridRow width="100%" height="100%">
<mx:GridItem>
<mx:Label text="Interfaces" fontWeight="bold"/>
</mx:GridItem>
<mx:GridItem width="100%">
<mx:List width="100%" height="100%" id="listInterfaces" dataProvider="{node.interfaces.collection}" labelField="id"></mx:List>
</mx:GridItem>
</mx:GridRow>
<mx:GridRow width="100%" height="100%">
<mx:GridItem>
<mx:Label text="Links" fontWeight="bold"/>
<mx:VBox horizontalAlign="right">
<mx:Label text="Links to" fontWeight="bold"/>
<mx:Button label="All" click="viewLinks();" width="100%"/>
</mx:VBox>
</mx:GridItem>
<mx:GridItem width="100%">
<mx:List width="100%" height="100%" id="listLinks" dataProvider="{links}" labelField="name"></mx:List>
<mx:List width="100%" height="100%" id="listInterfaces" dataProvider="{linkedNodes}" labelField="name" change="viewLink(listInterfaces.selectedItem.link);"></mx:List>
</mx:GridItem>
</mx:GridRow>
</mx:Grid>
......
......@@ -30,9 +30,14 @@
public var Rspec:XML = null;
[Bindable]
public var Components:Array = null;
public var Nodes:NodeGroupCollection = new NodeGroupCollection();
public var Links:LinkGroupCollection = new LinkGroupCollection();
public var AfterCall:Function;
public function ProtoGeniHandler()
{
op = new Operation(null);
......@@ -41,7 +46,13 @@
credential = new Credential();
}
public function clear() : void
public function clearAll() : void
{
clearResources();
Components = null;
}
public function clearResources() : void
{
Nodes = new NodeGroupCollection();
Links = new LinkGroupCollection();
......@@ -51,9 +62,7 @@
public function startCredential() : void
{
main.console.clear();
clear();
opName = "Acquiring credential";
main.setProgress(opName, Common.waitColor);
main.startWaiting();
......@@ -69,12 +78,21 @@
if (code == 0)
{
credential.base = String(response.value);
startSshLookup();
}
else
{
codeFailure();
}
postCall();
}
public function postCall() : void {
main.console.appendText("Seeing if there are any other method to call...\n");
if(AfterCall != null) {
main.console.appendText("Doing a post call...\n");
AfterCall();
}
}
public function failure(event : ErrorEvent, fault : MethodFault) : void
......@@ -136,19 +154,21 @@
if (code == 0)
{
credential.ssh = response.value;
startResourceLookup();
// startUserLookup();
}
else
{
codeFailure();
}
postCall();
}
public function startResourceLookup() : void
{
clearResources();
opName = "Looking up resources";
main.setProgress(opName, Common.waitColor);
main.startWaiting();
main.console.appendText(opName + "...\n");
op.reset(Geni.discoverResources);
op.addField("credential", credential.base);
......@@ -161,6 +181,7 @@
main.setProgress("Done", Common.successColor);
main.stopWaiting();
main.console.appendText("Resource lookup complete...\n");
if (code == 0)
{
Rspec = new XML(response.value);
......@@ -171,6 +192,37 @@
codeFailure();
main.console.appendText(op.getResponseXml());
}
postCall();
}
public function startListComponents() : void
{
opName = "Looking up components";
main.setProgress(opName, Common.waitColor);
main.startWaiting();
main.console.appendText(opName + "...\n");
op.reset(Geni.listComponents);
op.addField("credential", credential.base);
op.setUrl("https://boss.emulab.net:443/protogeni/xmlrpc/ch");
op.call(completeListComponents, failure);
}
public function completeListComponents(code : Number, response : Object) : void
{
main.setProgress("Done", Common.successColor);
main.stopWaiting();
main.console.appendText("List Components complete...\n");
if (code == 0)
{
Components = response.value;
main.console.appendText(op.getResponseXml());
}
else
{
codeFailure();
main.console.appendText(op.getResponseXml());
}
postCall();
}
private function processRspec():void {
......
......@@ -14,8 +14,10 @@ package pgmap
import com.google.maps.styles.StrokeStyle;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import mx.controls.Alert;
import mx.managers.PopUpManager;
public class ProtoGeniMapHandler
......@@ -92,32 +94,16 @@ package pgmap
main.map.addOverlay(polyline);
// Add marker
var m:Marker = new Marker(
new LatLng((lg.latitude1 + lg.latitude2)/2, (lg.longitude1 + lg.longitude2)/2),
new MarkerOptions({
strokeStyle: new StrokeStyle({color: 0xFF00FF}),
fillStyle: new FillStyle({color: 0xFFCFD1, alpha: 1}),
radius: 10,
hasShadow: true,
//tooltip: g.country,
label: lg.collection.length.toString()
}));
var linkInfo:LinkGroupInfo = new LinkGroupInfo();
linkInfo.Load(lg, main);
m.addEventListener(MapMouseEvent.CLICK, function(e:Event):void {
m.openInfoWindow(
new InfoWindowOptions({
customContent: linkInfo,
customoffset: new Point(0, 10),
width:140,
height:120,
drawDefaultFrame:true}));
// Add link marker
var ll:LatLng = new LatLng((lg.latitude1 + lg.latitude2)/2, (lg.longitude1 + lg.longitude2)/2);
var t:TooltipOverlay = new TooltipOverlay(ll, Common.kbsToString(lg.TotalBandwidth()));
t.addEventListener(MouseEvent.CLICK, function(e:Event):void {
e.stopImmediatePropagation();
main.mapHandler.viewLinkGroup(lg)
});
main.map.addOverlay(m);
main.map.addOverlay(t);
}
public function drawMap():void {
......@@ -152,6 +138,7 @@ package pgmap
PopUpManager.addPopUp(lgWindow, main, false);
PopUpManager.centerPopUp(lgWindow);
lgWindow.loadGroup(group);
}
}
}
\ No newline at end of file
/*
* Licensed under the Apache License, Version 2.0 (the "License"):
* http://www.apache.org/licenses/LICENSE-2.0
*/
package pgmap {
import com.google.maps.LatLng;
import com.google.maps.MapEvent;
import com.google.maps.PaneId;
import com.google.maps.interfaces.IMap;
import com.google.maps.interfaces.IPane;
import com.google.maps.overlays.OverlayBase;
import flash.display.Sprite;
import flash.filters.DropShadowFilter;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
public class TooltipOverlay extends OverlayBase {
private var latLng:LatLng;
private var label:String;
private var textField:TextField;
private var dropShadow:Sprite;
private var button:Sprite;
public function TooltipOverlay(latLng:LatLng, label:String) {
super();
this.latLng = latLng;
this.label = label;
this.addEventListener(MapEvent.OVERLAY_ADDED, onOverlayAdded);
this.addEventListener(MapEvent.OVERLAY_REMOVED, onOverlayRemoved);
}
public override function getDefaultPane(map:IMap):IPane {
return map.getPaneManager().getPaneById(PaneId.PANE_FLOAT);
}
private function onOverlayAdded(event:MapEvent):void {
this.textField = new TextField();
this.textField.text = this.label;
this.textField.selectable = false;
this.textField.border = true;
this.textField.borderColor = 0xFF00FF;
this.textField.background = true;