Adds explicit channels between FSMs to add in tracing message flows.

* Adds channels between FSMs
* Adds FSMTrace model
* Adds FSMTrace storage and download

Channels between FSMs make the processing pipeline delegation explicit
and allow for better instrumentation to trace the state of the entire
pipeline including FSM state transitions and message flow through
the pipeline.  This feature is not turned on by default and is
only necessary for debugging or certain kinds of testing.
This commit is contained in:
Ben Thomasson
2017-12-12 13:38:56 -05:00
parent a1f639bc8f
commit f6eecad25e
42 changed files with 718 additions and 215 deletions

View File

@@ -1,4 +1,3 @@
# Copyright (c) 2017 Red Hat, Inc
from django.contrib import admin
from awx.network_ui.models import Device
@@ -33,6 +32,8 @@ from awx.network_ui.models import Toolbox
from awx.network_ui.models import ToolboxItem
from awx.network_ui.models import FSMTrace
class DeviceAdmin(admin.ModelAdmin):
fields = ('topology', 'name', 'x', 'y', 'id', 'type', 'interface_id_seq', 'process_id_seq',)
@@ -160,3 +161,11 @@ class ToolboxItemAdmin(admin.ModelAdmin):
admin.site.register(ToolboxItem, ToolboxItemAdmin)
class FSMTraceAdmin(admin.ModelAdmin):
fields = ('fsm_name', 'from_state', 'to_state', 'message_type', 'client', 'trace_session_id', 'order',)
raw_id_fields = ('client',)
admin.site.register(FSMTrace, FSMTraceAdmin)

View File

@@ -8,6 +8,7 @@ from awx.network_ui.models import GroupDevice as GroupDeviceMap
from awx.network_ui.models import DataSheet, DataBinding, DataType
from awx.network_ui.models import Process, Stream
from awx.network_ui.models import Toolbox, ToolboxItem
from awx.network_ui.models import FSMTrace
from awx.network_ui.serializers import yaml_serialize_topology
from awx.network_ui.messages import MultipleMessage, InterfaceCreate, LinkCreate, to_dict
import urlparse
@@ -262,12 +263,16 @@ class _Persistence(object):
print "no sender"
return
if isinstance(data[1], dict) and client_id != data[1].get('sender'):
logger.error("client_id mismatch expected:", client_id, "actual:", data[1].get('sender'))
logger.error("client_id mismatch expected: %s actual %s", client_id, data[1].get('sender'))
logger.error(pformat(data))
return
message_type = data[0]
message_value = data[1]
message_type_id = MessageType.objects.get_or_create(name=message_type)[0].pk
try:
message_type_id = MessageType.objects.get(name=message_type).pk
except ObjectDoesNotExist, e:
logger.warning("Unsupported message %s", message_type)
return
TopologyHistory(topology_id=topology_id,
client_id=client_id,
message_type_id=message_type_id,
@@ -510,6 +515,15 @@ class _Persistence(object):
if new_entries:
GroupDeviceMap.objects.bulk_create(new_entries)
def onFSMTrace(self, message_value, diagram_id, client_id):
FSMTrace(trace_session_id=message_value['trace_id'],
fsm_name=message_value['fsm_name'],
from_state=message_value['from_state'],
to_state=message_value['to_state'],
order=message_value['order'],
client_id=client_id,
message_type=message_value['recv_message_type'] or "none").save()
persistence = _Persistence()

View File

@@ -99,8 +99,8 @@ models:
pk: true
type: AutoField
name: Client
x: -455
y: 109
x: -510
y: 141
- fields:
- name: topology_history_id
pk: true
@@ -136,8 +136,8 @@ models:
name: name
type: CharField
name: MessageType
x: -509
y: 383
x: -501
y: 428
- display: name
fields:
- name: interface_id
@@ -305,8 +305,8 @@ models:
name: name
type: CharField
name: Toolbox
x: -222
y: 627
x: 179
y: 644
- fields:
- name: toolbox_item_id
pk: true
@@ -318,8 +318,37 @@ models:
- name: data
type: TextField
name: ToolboxItem
x: 54
y: 664
x: 391
y: 645
- fields:
- name: fsm_trace_id
pk: true
type: AutoField
- len: 200
name: fsm_name
type: CharField
- len: 200
name: from_state
type: CharField
- len: 200
name: to_state
type: CharField
- len: 200
name: message_type
type: CharField
- name: client
ref: Client
ref_field: client_id
type: ForeignKey
- default: 0
name: trace_session_id
type: IntegerField
- default: 0
name: order
type: IntegerField
name: FSMTrace
x: -872
y: 507
modules: []
view:
panX: 213.72955551921206

View File

@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('network_ui', '0021_toolbox_toolboxitem'),
]
operations = [
migrations.CreateModel(
name='FSMTrace',
fields=[
('fsm_trace_id', models.AutoField(serialize=False, primary_key=True)),
('fsm_name', models.CharField(max_length=200)),
('from_state', models.CharField(max_length=200)),
('to_state', models.CharField(max_length=200)),
('message_type', models.CharField(max_length=200)),
('trace_session_id', models.IntegerField(default=0)),
('order', models.IntegerField(default=0)),
('client', models.ForeignKey(to='network_ui.Client')),
],
),
]

View File

@@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
import yaml
messages = yaml.load('''
messages:
- {msg_type: DeviceMove, fields: [msg_type, sender, id, x, y, previous_x, previous_y]}
- {msg_type: DeviceCreate, fields: [msg_type, sender, id, x, y, name, type]}
- {msg_type: DeviceDestroy, fields: [msg_type, sender, id, previous_x, previous_y, previous_name, previous_type]}
- {msg_type: DeviceLabelEdit, fields: [msg_type, sender, id, name, previous_name]}
- {msg_type: DeviceSelected, fields: [msg_type, sender, id]}
- {msg_type: DeviceUnSelected, fields: [msg_type, sender, id]}
- {msg_type: InterfaceCreate, fields: [msg_type, sender, device_id, id, name]}
- {msg_type: InterfaceLabelEdit, fields: [msg_type, sender, id, device_id, name, previous_name]}
- {msg_type: LinkLabelEdit, fields: [msg_type, sender, id, name, previous_name]}
- {msg_type: LinkCreate, fields: [msg_type, id, sender, name, from_device_id, to_device_id, from_interface_id, to_interface_id]}
- {msg_type: LinkDestroy, fields: [msg_type, id, sender, name, from_device_id, to_device_id, from_interface_id, to_interface_id]}
- {msg_type: LinkSelected, fields: [msg_type, sender, id]}
- {msg_type: LinkUnSelected, fields: [msg_type, sender, id]}
- {msg_type: Undo, fields: [msg_type, sender, original_message]}
- {msg_type: Redo, fields: [msg_type, sender, original_message]}
- {msg_type: Deploy, fields: [msg_type, sender]}
- {msg_type: Destroy, fields: [msg_type, sender]}
- {msg_type: Discover, fields: [msg_type, sender]}
- {msg_type: Layout, fields: [msg_type, sender]}
- {msg_type: MultipleMessage, fields: [msg_type, sender, messages]}
- {msg_type: Coverage, fields: [msg_type, sender, coverage]}
- {msg_type: MouseEvent, fields: [msg_type, sender, x, y, type]}
- {msg_type: MouseWheelEvent, fields: [msg_type, sender, delta, deltaX, deltaY, type, originalEvent]}
- {msg_type: KeyEvent, fields: [msg_type, sender, key, keyCode, type, altKey, shiftKey, ctrlKey, metaKey]}
- {msg_type: TouchEvent, fields: [msg_type, sender, type, touches]}
- {msg_type: StartRecording, fields: [msg_type, sender]}
- {msg_type: StopRecording, fields: [msg_type, sender]}
- {msg_type: ViewPort, fields: [msg_type, sender, scale, panX, panY]}
- {msg_type: CopySite, fields: [msg_type, site]}
- {msg_type: GroupMove, fields: [msg_type, sender, id, x1, y1, x2, y2, previous_x1, previous_y1, previous_x2, previous_y2]}
- {msg_type: GroupCreate, fields: [msg_type, sender, id, x1, y1, x2, y2, name, type]}
- {msg_type: GroupDestroy, fields: [msg_type, sender, id, previous_x1, previous_y1, previous_x2, previous_y2, previous_name, previous_type]}
- {msg_type: GroupLabelEdit, fields: [msg_type, sender, id, name, previous_name]}
- {msg_type: GroupSelected, fields: [msg_type, sender, id]}
- {msg_type: GroupUnSelected, fields: [msg_type, sender, id]}
- {msg_type: GroupMembership, fields: [msg_type, sender, id, members]}
- {msg_type: TableCellEdit, fields: [msg_type, sender, sheet, col, row, old_value, new_value]}
- {msg_type: ProcessCreate, fields: [msg_type, id, name, type, device_id, x, y]}
- {msg_type: StreamCreate, fields: [msg_type, sender, id, from_id, to_id, label]}
- {msg_type: StreamDestroy, fields: [msg_type, sender, id, from_id, to_id, label]}
- {msg_type: StreamLabelEdit, fields: [msg_type, sender, id, label, previous_label]}
- {msg_type: StreamSelected, fields: [msg_type, sender, id]}
- {msg_type: StreamUnSelected, fields: [msg_type, sender, id]}
''')
def populate_message_types(apps, schema_editor):
MessageType = apps.get_model('network_ui', 'MessageType')
for message in messages['messages']:
MessageType.objects.get_or_create(name=message['msg_type'])
class Migration(migrations.Migration):
dependencies = [
('network_ui', '0022_fsmtrace'),
]
operations = [
migrations.RunPython(
code=populate_message_types,
),
]

View File

@@ -0,0 +1,76 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
import yaml
messages = yaml.load('''
messages:
- {msg_type: DeviceMove, fields: [msg_type, sender, id, x, y, previous_x, previous_y]}
- {msg_type: DeviceCreate, fields: [msg_type, sender, id, x, y, name, type]}
- {msg_type: DeviceDestroy, fields: [msg_type, sender, id, previous_x, previous_y, previous_name, previous_type]}
- {msg_type: DeviceLabelEdit, fields: [msg_type, sender, id, name, previous_name]}
- {msg_type: DeviceSelected, fields: [msg_type, sender, id]}
- {msg_type: DeviceUnSelected, fields: [msg_type, sender, id]}
- {msg_type: InterfaceCreate, fields: [msg_type, sender, device_id, id, name]}
- {msg_type: InterfaceLabelEdit, fields: [msg_type, sender, id, device_id, name, previous_name]}
- {msg_type: LinkLabelEdit, fields: [msg_type, sender, id, name, previous_name]}
- {msg_type: LinkCreate, fields: [msg_type, id, sender, name, from_device_id, to_device_id, from_interface_id, to_interface_id]}
- {msg_type: LinkDestroy, fields: [msg_type, id, sender, name, from_device_id, to_device_id, from_interface_id, to_interface_id]}
- {msg_type: LinkSelected, fields: [msg_type, sender, id]}
- {msg_type: LinkUnSelected, fields: [msg_type, sender, id]}
- {msg_type: Undo, fields: [msg_type, sender, original_message]}
- {msg_type: Redo, fields: [msg_type, sender, original_message]}
- {msg_type: Deploy, fields: [msg_type, sender]}
- {msg_type: Destroy, fields: [msg_type, sender]}
- {msg_type: Discover, fields: [msg_type, sender]}
- {msg_type: Layout, fields: [msg_type, sender]}
- {msg_type: MultipleMessage, fields: [msg_type, sender, messages]}
- {msg_type: Coverage, fields: [msg_type, sender, coverage]}
- {msg_type: MouseEvent, fields: [msg_type, sender, x, y, type]}
- {msg_type: MouseWheelEvent, fields: [msg_type, sender, delta, deltaX, deltaY, type, originalEvent]}
- {msg_type: KeyEvent, fields: [msg_type, sender, key, keyCode, type, altKey, shiftKey, ctrlKey, metaKey]}
- {msg_type: TouchEvent, fields: [msg_type, sender, type, touches]}
- {msg_type: StartRecording, fields: [msg_type, sender]}
- {msg_type: StopRecording, fields: [msg_type, sender]}
- {msg_type: ViewPort, fields: [msg_type, sender, scale, panX, panY]}
- {msg_type: CopySite, fields: [msg_type, site]}
- {msg_type: GroupMove, fields: [msg_type, sender, id, x1, y1, x2, y2, previous_x1, previous_y1, previous_x2, previous_y2]}
- {msg_type: GroupCreate, fields: [msg_type, sender, id, x1, y1, x2, y2, name, type]}
- {msg_type: GroupDestroy, fields: [msg_type, sender, id, previous_x1, previous_y1, previous_x2, previous_y2, previous_name, previous_type]}
- {msg_type: GroupLabelEdit, fields: [msg_type, sender, id, name, previous_name]}
- {msg_type: GroupSelected, fields: [msg_type, sender, id]}
- {msg_type: GroupUnSelected, fields: [msg_type, sender, id]}
- {msg_type: GroupMembership, fields: [msg_type, sender, id, members]}
- {msg_type: TableCellEdit, fields: [msg_type, sender, sheet, col, row, old_value, new_value]}
- {msg_type: ProcessCreate, fields: [msg_type, id, name, type, device_id, x, y]}
- {msg_type: StreamCreate, fields: [msg_type, sender, id, from_id, to_id, label]}
- {msg_type: StreamDestroy, fields: [msg_type, sender, id, from_id, to_id, label]}
- {msg_type: StreamLabelEdit, fields: [msg_type, sender, id, label, previous_label]}
- {msg_type: StreamSelected, fields: [msg_type, sender, id]}
- {msg_type: StreamUnSelected, fields: [msg_type, sender, id]}
- {msg_type: FSMTrace, fields: [msg_type, order, sender, trace_id, fsm_name, from_state, to_state, recv_message_type]}
- {msg_type: ChannelTrace, fields: [msg_type, sender, trace_id, from_fsm, to_fsm, sent_message_type]}
''')
def populate_message_types(apps, schema_editor):
MessageType = apps.get_model('network_ui', 'MessageType')
for message in messages['messages']:
MessageType.objects.get_or_create(name=message['msg_type'])
class Migration(migrations.Migration):
dependencies = [
('network_ui', '0023_auto_20171213_1623'),
]
operations = [
migrations.RunPython(
code=populate_message_types,
),
]

View File

@@ -156,3 +156,15 @@ class ToolboxItem(models.Model):
toolbox_item_id = models.AutoField(primary_key=True,)
toolbox = models.ForeignKey('Toolbox',)
data = models.TextField()
class FSMTrace(models.Model):
fsm_trace_id = models.AutoField(primary_key=True,)
fsm_name = models.CharField(max_length=200,)
from_state = models.CharField(max_length=200,)
to_state = models.CharField(max_length=200,)
message_type = models.CharField(max_length=200,)
client = models.ForeignKey('Client',)
trace_session_id = models.IntegerField(default=0)
order = models.IntegerField(default=0)

View File

@@ -571,11 +571,11 @@ The messages defined are [src/messages.js](src/messages.js):
**Message Passing**
Messages are passed along channels between FSMs and over the websocket to and from the
server. Messages from the server over the web socket and user input events from the web
browser are passed to the `first_controller` where they are handled and discarded or
passed along the chain of FSMControllers until they reach the end with `null_controller`
or they are handled and the models are updated.
Messages are passed along channels between FSMs and over the websocket to and
from the server. Messages from the server over the web socket and user input
events from the web browser are passed to the `first_channel` where they are
passed along the chain of FSMControllers until they reach the end with
`NullChannel` or they are handled and the models are updated.
* See: [src/network.ui.controller.js](src/network.ui.controller.js#L115)

View File

@@ -29,7 +29,7 @@ istanbul: main
simple-server: lint main lessc
python -m SimpleHTTPServer 8081
python -m SimpleHTTPServer 8082
deploy: main

View File

@@ -1,4 +1,4 @@
app: button
app: button_fsm
panX: 53
panY: -52
scaleXY: 1

View File

@@ -1,4 +1,4 @@
app: buttons
app: buttons_fsm
panX: 133
panY: 41
scaleXY: 1

View File

@@ -1,5 +1,5 @@
finite_state_machine_id: 131
name: fsm
name: device_detail_fsm
states:
- id: 2
label: Ready

View File

@@ -1,57 +1,57 @@
finite_state_machine_id: 6
name: fsm
diagram_id: 38
name: group_fsm
states:
- id: 11
- id: 1
label: Disable
x: 497
y: 84
- id: 1
- id: 2
label: Resize
x: 571
y: 911
- id: 2
- id: 3
label: Start
x: 744
y: 69
- id: 3
label: CornerSelected
x: 359
y: 682
- id: 4
- id: 5
label: Selected1
x: 839
y: 640
- id: 5
- id: 6
label: Selected3
x: 1528
y: 360
- id: 6
- id: 7
label: Move
x: 1297
y: 786
- id: 9
- id: 8
label: Selected2
x: 1179
y: 435
- id: 10
label: Placing
x: 410
y: 295
- id: 7
label: Ready
x: 733
y: 304
- id: 8
- id: 11
label: EditLabel
x: 1130
y: 112
- id: 4
label: CornerSelected
x: 526
y: 554
- id: 9
label: Placing
x: 299
y: 300
transitions:
- from_state: CornerSelected
label: onMouseMove
to_state: Resize
- from_state: Placing
label: onMouseDown
to_state: CornerSelected
to_state: Resize
- from_state: Ready
label: onMouseDown
to_state: CornerSelected

View File

@@ -1,5 +1,5 @@
finite_state_machine_id: 113
name: hotkeys
name: hotkeys_fsm
states:
- id: 2
label: Enabled

View File

@@ -1,5 +1,5 @@
finite_state_machine_id: 10
name: src/link
name: link_fsm
states:
- id: 5
label: Selecting

View File

@@ -42,4 +42,6 @@ messages:
- {msg_type: StreamLabelEdit, fields: [msg_type, sender, id, label, previous_label]}
- {msg_type: StreamSelected, fields: [msg_type, sender, id]}
- {msg_type: StreamUnSelected, fields: [msg_type, sender, id]}
- {msg_type: FSMTrace, fields: [msg_type, order, sender, trace_id, fsm_name, from_state, to_state, recv_message_type]}
- {msg_type: ChannelTrace, fields: [msg_type, sender, trace_id, from_fsm, to_fsm, sent_message_type]}

View File

@@ -1,5 +1,5 @@
finite_state_machine_id: 130
name: mode
name: mode_fsm
states:
- id: 1
label: Start

View File

@@ -1,5 +1,5 @@
finite_state_machine_id: 13
name: move
name: move_fsm
states:
- id: 9
label: Disable

View File

@@ -1,5 +1,5 @@
finite_state_machine_id: 114
name: fsm
name: null_fsm
states:
- id: 1
label: Start

View File

@@ -1,5 +1,5 @@
finite_state_machine_id: 131
name: fsm
name: rack_fsm
states:
- id: 5
label: Selected2

View File

@@ -1,5 +1,5 @@
finite_state_machine_id: 131
name: fsm
name: site_fsm
states:
- id: 5
label: Selected2

View File

@@ -1,5 +1,5 @@
finite_state_machine_id: 82
name: src/transition
name: stream_fsm
states:
- id: 4
label: Connecting

View File

@@ -1,5 +1,5 @@
finite_state_machine_id: 11
name: src/time
name: time_fsm
states:
- id: 1
label: Present

View File

@@ -1,5 +1,5 @@
finite_state_machine_id: 24
name: toolbox
finite_state_machine_id: 14
name: toolbox_fsm
states:
- id: 9
label: Disabled

View File

@@ -1,5 +1,5 @@
finite_state_machine_id: 15
name: view
name: view_fsm
states:
- id: 1
label: Start

View File

@@ -46,7 +46,7 @@ _Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
button = null;
}
if (button === null) {
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
}
};
@@ -70,7 +70,7 @@ _Ready.prototype.onMouseMove = function (controller, msg_type, $event) {
}
}
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
};

View File

@@ -1,38 +1,89 @@
/* Copyright (c) 2017 Red Hat, Inc. */
function FSMController (scope, initial_state, next_controller, name) {
var messages = require('./messages.js');
function Channel(from_controller, to_controller, tracer) {
this.tracer = tracer;
this.from_controller = from_controller;
this.to_controller = to_controller;
this.trace = false;
}
exports.Channel = Channel;
Channel.prototype.send = function(msg_type, message) {
if (this.trace && this.from_controller !== null) {
this.tracer.send_trace_message(new messages.ChannelTrace(this.from_controller.name,
this.to_controller.name,
msg_type));
}
this.to_controller.handle_message(msg_type, message);
};
function NullChannel(from_controller, tracer) {
this.tracer = tracer;
this.from_controller = from_controller;
this.trace = false;
}
NullChannel.prototype.send = function(msg_type) {
if (this.trace) {
this.tracer.send_trace_message(new messages.ChannelTrace(this.from_controller.name,
'null',
msg_type));
}
};
function FSMController (scope, name, initial_state, tracer) {
this.scope = scope;
this.state = initial_state;
this.next_controller = next_controller;
this.name = name;
this.debug = false;
this.state = initial_state;
this.delegate_channel = new NullChannel(this, tracer);
this.tracer = tracer;
this.trace = true;
this.handling_message_type = 'start';
this.state.start(this);
this.handling_message_type = null;
}
exports.FSMController = FSMController;
FSMController.prototype.changeState = function (state) {
var old_handling_message_type;
if(this.state !== null) {
old_handling_message_type = this.handling_message_type;
this.handling_message_type = 'end';
this.state.end(this);
this.handling_message_type = old_handling_message_type;
}
if (this.trace) {
this.tracer.send_trace_message(new messages.FSMTrace(this.tracer.trace_order_seq(),
this.name,
this.state.name,
state.name,
this.handling_message_type));
}
this.state = state;
if(state !== null) {
old_handling_message_type = this.handling_message_type;
this.handling_message_type = 'start';
state.start(this);
this.handling_message_type = old_handling_message_type;
}
};
FSMController.prototype.handle_message = function(msg_type, message) {
var old_handling_message_type = this.handling_message_type;
this.handling_message_type = msg_type;
var handler_name = 'on' + msg_type;
if (typeof(this.state[handler_name]) !== "undefined") {
this.state[handler_name](this, msg_type, message);
} else {
this.default_handler(msg_type, message);
}
this.handling_message_type = old_handling_message_type;
};
FSMController.prototype.default_handler = function(msg_type, message) {
if (this.next_controller !== null) {
this.next_controller.handle_message(msg_type, message);
}
this.delegate_channel.send(msg_type, message);
};
function _State () {

View File

@@ -91,7 +91,7 @@ exports.Placing = Placing;
_State.prototype.onUnselectAll = function (controller, msg_type, $event) {
controller.changeState(Ready);
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
};
_Resize.prototype.onMouseUp = function (controller, msg_type, $event) {
@@ -343,7 +343,7 @@ _Move.prototype.end = function (controller) {
_Ready.prototype.onMouseMove = function (controller, msg_type, $event) {
if (controller.scope.hide_groups) {
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
return;
}
@@ -353,14 +353,14 @@ _Ready.prototype.onMouseMove = function (controller, msg_type, $event) {
controller.scope.groups[i].update_hightlighted(controller.scope.scaledX, controller.scope.scaledY);
}
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
};
_Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
if (controller.scope.hide_groups) {
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
return;
}
@@ -402,7 +402,7 @@ _Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
}
}
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
};
_Ready.prototype.onMouseDown.transitions = ['Selected1', 'CornerSelected'];
@@ -564,7 +564,7 @@ _Selected2.prototype.onKeyDown = function (controller, msg_type, $event) {
groups[i].name));
}
} else {
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
}
};
_Selected2.prototype.onKeyDown.transitions = ['Ready'];
@@ -610,5 +610,5 @@ _Placing.prototype.onMouseDown = function (controller) {
controller.changeState(Resize);
};
_Placing.prototype.onMouseDown.transitions = ['CornerSelected'];
_Placing.prototype.onMouseDown.transitions = ['Resize'];

View File

@@ -45,16 +45,16 @@ _Enabled.prototype.onKeyDown = function(controller, msg_type, $event) {
var scope = controller.scope;
if ($event.key === 'c' && ($event.ctrlKey || $event.metaKey)) {
scope.first_controller.handle_message("CopySelected", $event);
scope.first_channel.send("CopySelected", $event);
}
if ($event.key === 'l') {
scope.first_controller.handle_message("NewLink", $event);
scope.first_channel.send("NewLink", $event);
return;
}
if ($event.key === 'm') {
scope.first_controller.handle_message("NewStream", $event);
scope.first_channel.send("NewStream", $event);
}
if ($event.key === 'd') {
@@ -75,27 +75,27 @@ _Enabled.prototype.onKeyDown = function(controller, msg_type, $event) {
}
if ($event.key === 'r') {
scope.first_controller.handle_message("NewDevice", new messages.NewDevice("router"));
scope.first_channel.send("NewDevice", new messages.NewDevice("router"));
return;
}
else if ($event.key === 's') {
scope.first_controller.handle_message("NewDevice", new messages.NewDevice("switch"));
scope.first_channel.send("NewDevice", new messages.NewDevice("switch"));
return;
}
else if ($event.key === 'a') {
scope.first_controller.handle_message("NewGroup", new messages.NewGroup("rack"));
scope.first_channel.send("NewGroup", new messages.NewGroup("rack"));
return;
}
else if ($event.key === 'h') {
scope.first_controller.handle_message("NewDevice", new messages.NewDevice("host"));
scope.first_channel.send("NewDevice", new messages.NewDevice("host"));
return;
}
else if ($event.key === 'g') {
scope.first_controller.handle_message("NewGroup", new messages.NewGroup("group"));
scope.first_channel.send("NewGroup", new messages.NewGroup("group"));
return;
}
else if ($event.key === 'e') {
scope.first_controller.handle_message("NewGroup", new messages.NewGroup("site"));
scope.first_channel.send("NewGroup", new messages.NewGroup("site"));
return;
}
else if ($event.key === '0') {
@@ -106,7 +106,7 @@ _Enabled.prototype.onKeyDown = function(controller, msg_type, $event) {
scope.updatePanAndScale();
}
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
};
_Start.prototype.start = function (controller) {

View File

@@ -51,7 +51,7 @@ _Ready.prototype.onNewLink = function (controller, msg_type, message) {
controller.scope.clear_selections();
controller.changeState(Selecting);
controller.next_controller.handle_message(msg_type, message);
controller.delegate_channel.send(msg_type, message);
};
_Ready.prototype.onNewLink.transitions = ['Selecting'];

View File

@@ -422,3 +422,25 @@ function StreamUnSelected(sender, id) {
this.id = id;
}
exports.StreamUnSelected = StreamUnSelected;
function FSMTrace(order, fsm_name, from_state, to_state, recv_message_type) {
this.msg_type = 'FSMTrace';
this.order = order;
this.sender = 0;
this.trace_id = 0;
this.fsm_name = fsm_name;
this.from_state = from_state;
this.to_state = to_state;
this.recv_message_type = recv_message_type;
}
exports.FSMTrace = FSMTrace;
function ChannelTrace(from_fsm, to_fsm, sent_message_type) {
this.msg_type = 'ChannelTrace';
this.sender = 0;
this.trace_id = 0;
this.from_fsm = from_fsm;
this.to_fsm = to_fsm;
this.sent_message_type = sent_message_type;
}
exports.ChannelTrace = ChannelTrace;

View File

@@ -83,7 +83,7 @@ _Interface.prototype.onMouseWheel = function (controller, msg_type, $event) {
//controller.changeState(Device);
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
};
_Interface.prototype.onMouseWheel.transitions = ['Device'];
@@ -110,7 +110,7 @@ _Site.prototype.onMouseWheel = function (controller, msg_type, $event) {
controller.changeState(Rack);
}
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
};
_Site.prototype.onMouseWheel.transitions = ['MultiSite', 'Rack'];
@@ -119,7 +119,7 @@ _Site.prototype.onMouseWheel.transitions = ['MultiSite', 'Rack'];
_Process.prototype.onMouseWheel = function (controller, msg_type, $event) {
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
//controller.changeState(Device);
@@ -145,7 +145,7 @@ _MultiSite.prototype.onMouseWheel = function (controller, msg_type, $event) {
controller.changeState(Site);
}
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
};
_MultiSite.prototype.onMouseWheel.transitions = ['Site'];
@@ -171,7 +171,7 @@ _Device.prototype.onMouseWheel = function (controller, msg_type, $event) {
controller.changeState(Rack);
}
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
};
_Device.prototype.onMouseWheel.transitions = ['Process', 'Interface', 'Rack'];
@@ -200,6 +200,6 @@ _Rack.prototype.onMouseWheel = function (controller, msg_type, $event) {
controller.changeState(Device);
}
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
};
_Rack.prototype.onMouseWheel.transitions = ['Site', 'Device'];

View File

@@ -289,7 +289,7 @@ Link.prototype.plength = function (x, y) {
return util.pDistance(x, y, x1, y1, x2, y2);
};
function ActionIcon(name, x, y, r, callback, enabled) {
function ActionIcon(name, x, y, r, callback, enabled, tracer) {
this.name = name;
this.x = x;
this.y = y;
@@ -298,7 +298,7 @@ function ActionIcon(name, x, y, r, callback, enabled) {
this.is_pressed = false;
this.mouse_over = false;
this.enabled = enabled;
this.fsm = new fsm.FSMController(this, enabled ? button.Start : button.Disabled, null, name+'button_fsm');
this.fsm = new fsm.FSMController(this, "button_fsm", enabled ? button.Start : button.Disabled, tracer);
}
exports.ActionIcon = ActionIcon;
@@ -311,7 +311,7 @@ ActionIcon.prototype.is_selected = function (x, y) {
};
function Button(name, x, y, width, height, callback) {
function Button(name, x, y, width, height, callback, tracer) {
this.name = name;
this.x = x;
this.y = y;
@@ -321,7 +321,7 @@ function Button(name, x, y, width, height, callback) {
this.is_pressed = false;
this.mouse_over = false;
this.enabled = true;
this.fsm = new fsm.FSMController(this, button.Start, null, name+'button_fsm');
this.fsm = new fsm.FSMController(this, "button_fsm", button.Start, tracer);
}
exports.Button = Button;
@@ -336,7 +336,7 @@ Button.prototype.is_selected = function (x, y) {
};
function ToggleButton(name, x, y, width, height, toggle_callback, untoggle_callback, default_toggled) {
function ToggleButton(name, x, y, width, height, toggle_callback, untoggle_callback, default_toggled, tracer) {
this.name = name;
this.x = x;
this.y = y;
@@ -349,7 +349,7 @@ function ToggleButton(name, x, y, width, height, toggle_callback, untoggle_callb
this.untoggle_callback = untoggle_callback;
this.mouse_over = false;
this.enabled = true;
this.fsm = new fsm.FSMController(this, button.Start, null, name+'toggle_button_fsm');
this.fsm = new fsm.FSMController(this, "button_fsm", button.Start, tracer);
}
inherits(ToggleButton, Button);
exports.ToggleButton = ToggleButton;
@@ -365,7 +365,7 @@ ToggleButton.prototype.toggle = function () {
}
};
function ContextMenu(name, x, y, width, height, callback, enabled, buttons) {
function ContextMenu(name, x, y, width, height, callback, enabled, buttons, tracer) {
this.name = name;
this.x = x;
this.y = y;
@@ -376,7 +376,7 @@ function ContextMenu(name, x, y, width, height, callback, enabled, buttons) {
this.mouse_over = false;
this.enabled = enabled;
this.buttons = buttons;
this.fsm = new fsm.FSMController(this, button.Start, null, name+'button_fsm');
this.fsm = new fsm.FSMController(this, "button_fsm", button.Start, tracer);
}
exports.ContextMenu = ContextMenu;
@@ -390,7 +390,7 @@ ContextMenu.prototype.is_selected = function (x, y) {
};
function ContextMenuButton(name, x, y, width, height, callback) {
function ContextMenuButton(name, x, y, width, height, callback, tracer) {
this.name = name;
this.x = x;
this.y = y;
@@ -400,7 +400,7 @@ function ContextMenuButton(name, x, y, width, height, callback) {
this.is_pressed = false;
this.mouse_over = false;
this.enabled = true;
this.fsm = new fsm.FSMController(this, button.Start, null, name+'button_fsm');
this.fsm = new fsm.FSMController(this, "button_fsm", button.Start, tracer);
}
exports.ContextMenuButton = ContextMenuButton;

View File

@@ -79,7 +79,7 @@ exports.Placing = Placing;
_State.prototype.onUnselectAll = function (controller, msg_type, $event) {
controller.changeState(Ready);
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
};
_Ready.prototype.onNewDevice = function (controller, msg_type, message) {
@@ -209,7 +209,7 @@ _Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
} else if (last_selected.last_selected_interface !== null) {
controller.changeState(Selected1);
} else {
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
}
};
_Ready.prototype.onMouseDown.transitions = ['Selected1'];
@@ -345,7 +345,7 @@ _Selected2.prototype.onKeyDown = function (controller, msg_type, $event) {
}
}
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
};
_Selected2.prototype.onKeyDown.transitions = ['Ready'];

View File

@@ -1,5 +1,4 @@
/* Copyright (c) 2017 Red Hat, Inc. */
// var _ = require('lodash');
var angular = require('angular');
var fsm = require('./fsm.js');
var null_fsm = require('./null.fsm.js');
@@ -30,13 +29,14 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.http = $http;
$scope.api_token = '';
$scope.disconnected = true;
$scope.disconnected = false;
$scope.topology_id = $location.search().topology_id || 0;
// Create a web socket to connect to the backend server
//
$scope.inventory_id = $location.search().inventory_id || 1;
$scope.initial_messages = [];
if (!$scope.disconnected) {
$scope.control_socket = new ReconnectingWebSocket("wss://" + window.location.host + "/network_ui/topology?topology_id=" + $scope.topology_id,
null,
@@ -112,19 +112,43 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
'y': 0,
'width': 0,
'height': 0};
$scope.trace_id_seq = util.natural_numbers(0);
$scope.trace_order_seq = util.natural_numbers(0);
$scope.trace_id = $scope.trace_id_seq();
$scope.send_trace_message = function (message) {
console.log(message);
message.sender = $scope.client_id;
message.trace_id = $scope.trace_id;
message.message_id = $scope.message_id_seq();
var data = messages.serialize(message);
if (!$scope.disconnected) {
try {
$scope.control_socket.send(data);
}
catch(err) {
$scope.initial_messages.push(message);
}
} else {
console.log(data);
}
};
//Define the FSMs
$scope.null_controller = new fsm.FSMController($scope, "null_fsm", null_fsm.Start, $scope);
$scope.hotkeys_controller = new fsm.FSMController($scope, "hotkeys_fsm", hotkeys.Start, $scope);
$scope.view_controller = new fsm.FSMController($scope, "view_fsm", view.Start, $scope);
$scope.device_detail_controller = new fsm.FSMController($scope, "device_detail_fsm", device_detail_fsm.Start, $scope);
$scope.move_controller = new fsm.FSMController($scope, "move_fsm", move.Start, $scope);
$scope.link_controller = new fsm.FSMController($scope, "link_fsm", link.Start, $scope);
$scope.stream_controller = new fsm.FSMController($scope, "stream_fsm", stream_fsm.Start, $scope);
$scope.group_controller = new fsm.FSMController($scope, "group_fsm", group.Start, $scope);
$scope.rack_controller = new fsm.FSMController($scope, "rack_fsm", rack_fsm.Disable, $scope);
$scope.site_controller = new fsm.FSMController($scope, "site_fsm", site_fsm.Disable, $scope);
$scope.buttons_controller = new fsm.FSMController($scope, "buttons_fsm", buttons.Start, $scope);
$scope.time_controller = new fsm.FSMController($scope, "time_fsm", time.Start, $scope);
$scope.app_toolbox_controller = new fsm.FSMController($scope, "toolbox_fsm", toolbox_fsm.Start, $scope);
$scope.null_controller = new fsm.FSMController($scope, null_fsm.Start, null, 'null_fsm');
$scope.hotkeys_controller = new fsm.FSMController($scope, hotkeys.Start, $scope.null_controller, 'hotkeys_fsm');
$scope.view_controller = new fsm.FSMController($scope, view.Start, $scope.hotkeys_controller, 'null_fsm');
$scope.device_detail_controller = new fsm.FSMController($scope, device_detail_fsm.Start, $scope.view_controller, 'device_detail_fsm');
$scope.move_controller = new fsm.FSMController($scope, move.Start, $scope.device_detail_controller, 'move_fsm');
$scope.link_controller = new fsm.FSMController($scope, link.Start, $scope.move_controller, 'link_fsm');
$scope.stream_controller = new fsm.FSMController($scope, stream_fsm.Start, $scope.link_controller, 'stream_fsm');
$scope.group_controller = new fsm.FSMController($scope, group.Start, $scope.stream_controller, 'group_fsm');
$scope.rack_controller = new fsm.FSMController($scope, rack_fsm.Disable, $scope.group_controller, 'rack_fsm');
$scope.site_controller = new fsm.FSMController($scope, site_fsm.Disable, $scope.rack_controller, 'site_fsm');
$scope.time_controller = new fsm.FSMController($scope, time.Start, $scope.site_controller, 'time_fsm');
$scope.app_toolbox_controller = new fsm.FSMController($scope, toolbox_fsm.Disabled, $scope.time_controller, 'toolbox_fsm');
//App Toolbox Setup
$scope.app_toolbox = new models.ToolBox(0, 'Process', 'app', 0, 40, 200, $scope.graph.height - 40);
$scope.app_toolbox.title_coordinates = {x: 70, y: 70};
@@ -133,7 +157,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.app_toolbox_controller.toolbox = $scope.app_toolbox;
$scope.app_toolbox_controller.debug = true;
$scope.app_toolbox_controller.dropped_action = function (selected_item) {
$scope.first_controller.handle_message("PasteProcess", new messages.PasteProcess(selected_item));
$scope.first_channel.send("PasteProcess", new messages.PasteProcess(selected_item));
};
$scope.app_toolbox.items.push(new models.Process(0, 'BGP', 'process', 0, 0));
@@ -145,19 +169,19 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.app_toolbox.items[i].icon = true;
}
$scope.inventory_toolbox_controller = new fsm.FSMController($scope, toolbox_fsm.Start, $scope.app_toolbox_controller, 'inventory_toolbox_fsm');
$scope.inventory_toolbox_controller = new fsm.FSMController($scope, "toolbox_fsm", toolbox_fsm.Start, $scope);
function add_host (host) {
console.log(host);
var device = new models.Device(0, host.data.name, 0, 0, host.data.type);
device.icon = true;
$scope.inventory_toolbox.items.push(device);
}
//Inventory Toolbox Setup
$scope.inventory_toolbox = new models.ToolBox(0, 'Inventory', 'device', 0, 40, 200, $scope.graph.height - 40);
if (!$scope.disconnected) {
console.log($location.protocol() + "://" + $location.host() + ':' + $location.port());
console.log($scope.my_location);
var add_host = function(host) {
console.log(host);
var device = new models.Device(0, host.data.name, 0, 0, host.data.type);
device.icon = true;
$scope.inventory_toolbox.items.push(device);
};
$http.get('/api/v2/inventories/' + $scope.inventory_id + '/hosts/?format=json')
.then(function(inventory) {
console.log(inventory);
@@ -191,11 +215,11 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.inventory_toolbox_controller.remove_on_drop = true;
$scope.inventory_toolbox_controller.debug = true;
$scope.inventory_toolbox_controller.dropped_action = function (selected_item) {
$scope.first_controller.handle_message("PasteDevice", new messages.PasteDevice(selected_item));
$scope.first_channel.send("PasteDevice", new messages.PasteDevice(selected_item));
};
//End Inventory Toolbox Setup
$scope.rack_toolbox_controller = new fsm.FSMController($scope, toolbox_fsm.Start, $scope.inventory_toolbox_controller, 'rack_toolbox_fsm');
$scope.rack_toolbox_controller = new fsm.FSMController($scope, "toolbox_fsm", toolbox_fsm.Start, $scope);
//Rack Toolbox Setup
$scope.rack_toolbox = new models.ToolBox(0, 'Rack', 'rack', 0, 40, 200, $scope.graph.height - 40);
$scope.rack_toolbox.title_coordinates = {x: 80, y: 70};
@@ -205,14 +229,14 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.rack_toolbox_controller.toolbox = $scope.rack_toolbox;
$scope.rack_toolbox_controller.debug = true;
$scope.rack_toolbox_controller.dropped_action = function (selected_item) {
$scope.first_controller.handle_message("PasteRack", new messages.PasteRack(selected_item));
$scope.first_channel.send("PasteRack", new messages.PasteRack(selected_item));
};
for(i = 0; i < $scope.rack_toolbox.items.length; i++) {
$scope.rack_toolbox.items[i].icon = true;
$scope.rack_toolbox.items[i].selected = false;
}
//End Rack Toolbox Setup
$scope.site_toolbox_controller = new fsm.FSMController($scope, toolbox_fsm.Start, $scope.rack_toolbox_controller, 'site_toolbox_fsm');
$scope.site_toolbox_controller = new fsm.FSMController($scope, "toolbox_fsm", toolbox_fsm.Start, $scope);
//Site Toolbox Setup
$scope.site_toolbox = new models.ToolBox(0, 'Sites', 'sites', 0, 40, 200, $scope.graph.height - 40);
$scope.site_toolbox.title_coordinates = {x: 80, y: 70};
@@ -222,16 +246,67 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.site_toolbox_controller.toolbox = $scope.site_toolbox;
$scope.site_toolbox_controller.debug = true;
$scope.site_toolbox_controller.dropped_action = function (selected_item) {
$scope.first_controller.handle_message("PasteSite", new messages.PasteSite(selected_item));
$scope.first_channel.send("PasteSite", new messages.PasteSite(selected_item));
};
for(i = 0; i < $scope.site_toolbox.items.length; i++) {
$scope.site_toolbox.items[i].icon = true;
$scope.site_toolbox.items[i].selected = false;
}
//End Site Toolbox Setup
$scope.buttons_controller = new fsm.FSMController($scope, buttons.Start, $scope.site_toolbox_controller, 'buttons_fsm');
$scope.mode_controller = new fsm.FSMController($scope, mode_fsm.Start, $scope.buttons_controller, 'mode_fsm');
$scope.first_controller = $scope.mode_controller;
$scope.mode_controller = new fsm.FSMController($scope, "mode_fsm", mode_fsm.Start, $scope);
//Wire up the FSMs
$scope.view_controller.delegate_channel = new fsm.Channel($scope.view_controller,
$scope.hotkeys_controller,
$scope);
$scope.device_detail_controller.delegate_channel = new fsm.Channel($scope.device_detail_controller,
$scope.view_controller,
$scope);
$scope.move_controller.delegate_channel = new fsm.Channel($scope.move_controller,
$scope.device_detail_controller,
$scope);
$scope.link_controller.delegate_channel = new fsm.Channel($scope.link_controller,
$scope.move_controller,
$scope);
$scope.stream_controller.delegate_channel = new fsm.Channel($scope.stream_controller,
$scope.link_controller,
$scope);
$scope.group_controller.delegate_channel = new fsm.Channel($scope.group_controller,
$scope.stream_controller,
$scope);
$scope.rack_controller.delegate_channel = new fsm.Channel($scope.rack_controller,
$scope.group_controller,
$scope);
$scope.site_controller.delegate_channel = new fsm.Channel($scope.site_controller,
$scope.rack_controller,
$scope);
$scope.app_toolbox_controller.delegate_channel = new fsm.Channel($scope.app_toolbox_controller,
$scope.site_controller,
$scope);
$scope.inventory_toolbox_controller.delegate_channel = new fsm.Channel($scope.inventory_toolbox_controller,
$scope.app_toolbox_controller,
$scope);
$scope.rack_toolbox_controller.delegate_channel = new fsm.Channel($scope.rack_toolbox_controller,
$scope.inventory_toolbox_controller,
$scope);
$scope.site_toolbox_controller.delegate_channel = new fsm.Channel($scope.site_toolbox_controller,
$scope.rack_toolbox_controller,
$scope);
$scope.buttons_controller.delegate_channel = new fsm.Channel($scope.buttons_controller,
$scope.site_toolbox_controller,
$scope);
$scope.time_controller.delegate_channel = new fsm.Channel($scope.time_controller,
$scope.buttons_controller,
$scope);
$scope.mode_controller.delegate_channel = new fsm.Channel($scope.mode_controller,
$scope.time_controller,
$scope);
$scope.first_channel = new fsm.Channel(null,
$scope.mode_controller,
$scope);
var getMouseEventResult = function (mouseEvent) {
return "(" + mouseEvent.x + ", " + mouseEvent.y + ")";
};
@@ -406,7 +481,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.send_control_message(new messages.MouseEvent($scope.client_id, $event.x, $event.y, $event.type));
}
$scope.last_event = $event;
$scope.first_controller.handle_message('MouseDown', $event);
$scope.first_channel.send('MouseDown', $event);
$scope.onMouseDownResult = getMouseEventResult($event);
$event.preventDefault();
};
@@ -417,7 +492,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.send_control_message(new messages.MouseEvent($scope.client_id, $event.x, $event.y, $event.type));
}
$scope.last_event = $event;
$scope.first_controller.handle_message('MouseUp', $event);
$scope.first_channel.send('MouseUp', $event);
$scope.onMouseUpResult = getMouseEventResult($event);
$event.preventDefault();
};
@@ -444,7 +519,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.mouseX = $event.x;
$scope.mouseY = $event.y;
$scope.updateScaledXY();
$scope.first_controller.handle_message('MouseMove', $event);
$scope.first_channel.send('MouseMove', $event);
$scope.onMouseMoveResult = getMouseEventResult($event);
$event.preventDefault();
};
@@ -471,7 +546,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.send_control_message(new messages.MouseWheelEvent($scope.client_id, delta, deltaX, deltaY, $event.type, $event.originalEvent.metaKey));
}
$scope.last_event = $event;
$scope.first_controller.handle_message('MouseWheel', [$event, delta, deltaX, deltaY]);
$scope.first_channel.send('MouseWheel', [$event, delta, deltaX, deltaY]);
event.preventDefault();
};
@@ -489,7 +564,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.last_event = $event;
$scope.last_key = $event.key;
$scope.last_key_code = $event.keyCode;
$scope.first_controller.handle_message('KeyDown', $event);
$scope.first_channel.send('KeyDown', $event);
$scope.$apply();
$event.preventDefault();
};
@@ -518,7 +593,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.mouseY = $event.touches[0].screenY;
$scope.updateScaledXY();
}
$scope.first_controller.handle_message('TouchStart', $event);
$scope.first_channel.send('TouchStart', $event);
$scope.onTouchStartEvent = $event;
$event.preventDefault();
};
@@ -533,7 +608,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
if ($scope.recording) {
$scope.send_control_message(new messages.TouchEvent($scope.client_id, "touchend", touches));
}
$scope.first_controller.handle_message('TouchEnd', $event);
$scope.first_channel.send('TouchEnd', $event);
$scope.onTouchEndEvent = $event;
$event.preventDefault();
};
@@ -558,7 +633,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.updateScaledXY();
}
$scope.first_controller.handle_message('TouchMove', $event);
$scope.first_channel.send('TouchMove', $event);
$scope.onTouchMoveEvent = $event;
$event.preventDefault();
};
@@ -586,7 +661,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
//
$scope.onToggleToolboxButtonLeft = function (button) {
console.log(button.name);
$scope.first_controller.handle_message("ToggleToolbox", {});
$scope.first_channel.send("ToggleToolbox", {});
$scope.action_icons[0].fsm.handle_message("Disable", {});
$scope.action_icons[1].fsm.handle_message("Enable", {});
$scope.overall_toolbox_collapsed = !$scope.overall_toolbox_collapsed;
@@ -594,7 +669,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.onToggleToolboxButtonRight = function (button) {
console.log(button.name);
$scope.first_controller.handle_message("ToggleToolbox", {});
$scope.first_channel.send("ToggleToolbox", {});
$scope.action_icons[0].fsm.handle_message("Enable", {});
$scope.action_icons[1].fsm.handle_message("Disable", {});
$scope.overall_toolbox_collapsed = !$scope.overall_toolbox_collapsed;
@@ -696,54 +771,61 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
// Context Menu Buttons
$scope.context_menu_buttons = [
new models.ContextMenuButton("Edit", 210, 200, 160, 26, $scope.onDetailsContextButton),
new models.ContextMenuButton("Details", 236, 231, 160, 26, $scope.onDetailsContextButton)
new models.ContextMenuButton("Edit", 210, 200, 160, 26, $scope.onDetailsContextButton, $scope),
new models.ContextMenuButton("Details", 236, 231, 160, 26, $scope.onDetailsContextButton, $scope)
];
// Context Menus
$scope.context_menus = [
new models.ContextMenu('HOST', 210, 200, 160, 64, $scope.contextMenuCallback, true, $scope.context_menu_buttons)
new models.ContextMenu('HOST', 210, 200, 160, 64, $scope.contextMenuCallback, true, $scope.context_menu_buttons, $scope)
];
// Icons
$scope.action_icons = [
new models.ActionIcon("chevron-left", 170, $scope.graph.height/2, 16, $scope.onToggleToolboxButtonLeft, true),
new models.ActionIcon("chevron-right", 15, $scope.graph.height/2, 16, $scope.onToggleToolboxButtonRight, false)
new models.ActionIcon("chevron-left", 170, $scope.graph.height/2, 16, $scope.onToggleToolboxButtonLeft, true, $scope),
new models.ActionIcon("chevron-right", 15, $scope.graph.height/2, 16, $scope.onToggleToolboxButtonRight, false, $scope)
];
$scope.onDownloadTraceButton = function (button) {
console.log(button.label);
window.open("/network_ui/download_trace?topology_id=" + $scope.topology_id + "&trace_id=" + $scope.trace_id + "&client_id=" + $scope.client_id);
};
// Buttons
var button_offset = 200;
$scope.buttons = [
new models.Button("DEPLOY", button_offset + 10, 48, 70, 30, $scope.onDeployButton),
new models.Button("DESTROY", button_offset + 90, 48, 80, 30, $scope.onDestroyButton),
new models.Button("RECORD", button_offset + 180, 48, 80, 30, $scope.onRecordButton),
new models.Button("EXPORT", button_offset + 270, 48, 70, 30, $scope.onExportButton),
new models.Button("DISCOVER", button_offset + 350, 48, 80, 30, $scope.onDiscoverButton),
new models.Button("LAYOUT", button_offset + 440, 48, 70, 30, $scope.onLayoutButton),
new models.Button("CONFIGURE", button_offset + 520, 48, 90, 30, $scope.onConfigureButton),
new models.Button("EXPORT YAML", button_offset + 620, 48, 120, 30, $scope.onExportYamlButton),
new models.Button("DEPLOY", button_offset + 10, 48, 70, 30, $scope.onDeployButton, $scope),
new models.Button("DESTROY", button_offset + 90, 48, 80, 30, $scope.onDestroyButton, $scope),
new models.Button("RECORD", button_offset + 180, 48, 80, 30, $scope.onRecordButton, $scope),
new models.Button("EXPORT", button_offset + 270, 48, 70, 30, $scope.onExportButton, $scope),
new models.Button("DISCOVER", button_offset + 350, 48, 80, 30, $scope.onDiscoverButton, $scope),
new models.Button("LAYOUT", button_offset + 440, 48, 70, 30, $scope.onLayoutButton, $scope),
new models.Button("CONFIGURE", button_offset + 520, 48, 90, 30, $scope.onConfigureButton, $scope),
new models.Button("EXPORT YAML", button_offset + 620, 48, 120, 30, $scope.onExportYamlButton, $scope),
new models.Button("DOWNLOAD TRACE", button_offset + 750, 48, 150, 30, $scope.onDownloadTraceButton, $scope),
];
var LAYERS_X = 160;
$scope.layers = [
new models.ToggleButton("APPLICATION", $scope.graph.width - LAYERS_X, 10, 120, 30, util.noop, util.noop, true),
new models.ToggleButton("PRESENTATION", $scope.graph.width - LAYERS_X, 50, 120, 30, util.noop, util.noop, true),
new models.ToggleButton("SESSION", $scope.graph.width - LAYERS_X, 90, 120, 30, util.noop, util.noop, true),
new models.ToggleButton("TRANSPORT", $scope.graph.width - LAYERS_X, 130, 120, 30, util.noop, util.noop, true),
new models.ToggleButton("NETWORK", $scope.graph.width - LAYERS_X, 170, 120, 30, util.noop, util.noop, true),
new models.ToggleButton("DATA-LINK", $scope.graph.width - LAYERS_X, 210, 120, 30, util.noop, util.noop, true),
new models.ToggleButton("APPLICATION", $scope.graph.width - LAYERS_X, 10, 120, 30, util.noop, util.noop, true, $scope),
new models.ToggleButton("PRESENTATION", $scope.graph.width - LAYERS_X, 50, 120, 30, util.noop, util.noop, true, $scope),
new models.ToggleButton("SESSION", $scope.graph.width - LAYERS_X, 90, 120, 30, util.noop, util.noop, true, $scope),
new models.ToggleButton("TRANSPORT", $scope.graph.width - LAYERS_X, 130, 120, 30, util.noop, util.noop, true, $scope),
new models.ToggleButton("NETWORK", $scope.graph.width - LAYERS_X, 170, 120, 30, util.noop, util.noop, true, $scope),
new models.ToggleButton("DATA-LINK", $scope.graph.width - LAYERS_X, 210, 120, 30, util.noop, util.noop, true, $scope),
new models.ToggleButton("PHYSICAL",
$scope.graph.width - LAYERS_X, 250, 120, 30,
$scope.onTogglePhysical,
$scope.onUnTogglePhysical,
true),
true,
$scope),
new models.ToggleButton("GROUP",
$scope.graph.width - LAYERS_X, 290, 120, 30,
$scope.onToggleGroup,
$scope.onUnToggleGroup,
true)
true,
$scope)
];
$scope.layers = [];
@@ -1213,6 +1295,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.onClientId = function(data) {
$scope.client_id = data;
$scope.send_initial_messages();
};
$scope.onTopology = function(data) {
@@ -1559,12 +1642,26 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.control_socket.onmessage = function(message) {
$scope.first_controller.handle_message('Message', message);
$scope.first_channel.send('Message', message);
$scope.$apply();
};
$scope.control_socket.onopen = function() {
//Ignore
//ignore
};
$scope.send_initial_messages = function() {
var i = 0;
var messages_to_send = $scope.initial_messages;
var message = null;
var data = null;
$scope.initial_messages = [];
for(i = 0; i < messages_to_send.length; i++) {
message = messages_to_send[i];
message.sender = $scope.client_id;
data = messages.serialize(message);
$scope.control_socket.send(data);
}
};
// Call onopen directly if $scope.control_socket is already open

View File

@@ -32,7 +32,8 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.topology_id = 0;
$scope.control_socket = {
on_message: util.noop
on_message: util.noop,
send: util.noop
};
$scope.history = [];
$scope.client_id = 1;
@@ -98,27 +99,45 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
'y': 0,
'width': 0,
'height': 0};
$scope.trace_id_seq = util.natural_numbers(0);
$scope.trace_order_seq = util.natural_numbers(0);
$scope.trace_id = $scope.trace_id_seq();
$scope.send_trace_message = function (message) {
console.log(message);
message.sender = $scope.client_id;
message.trace_id = $scope.trace_id;
message.message_id = $scope.message_id_seq();
var data = messages.serialize(message);
if (!$scope.disconnected) {
$scope.control_socket.send(data);
} else {
console.log(data);
}
};
//Define the FSMs
$scope.null_controller = new fsm.FSMController($scope, "null_fsm", null_fsm.Start, $scope);
$scope.hotkeys_controller = new fsm.FSMController($scope, "hotkeys_fsm", hotkeys.Start, $scope);
$scope.view_controller = new fsm.FSMController($scope, "view_fsm", view.Start, $scope);
$scope.device_detail_controller = new fsm.FSMController($scope, "device_detail_fsm", device_detail_fsm.Start, $scope);
$scope.move_controller = new fsm.FSMController($scope, "move_fsm", move.Start, $scope);
$scope.link_controller = new fsm.FSMController($scope, "link_fsm", link.Start, $scope);
$scope.stream_controller = new fsm.FSMController($scope, "stream_fsm", stream_fsm.Start, $scope);
$scope.group_controller = new fsm.FSMController($scope, "group_fsm", group.Start, $scope);
$scope.rack_controller = new fsm.FSMController($scope, "rack_fsm", rack_fsm.Disable, $scope);
$scope.site_controller = new fsm.FSMController($scope, "site_fsm", site_fsm.Disable, $scope);
$scope.buttons_controller = new fsm.FSMController($scope, "buttons_fsm", buttons.Start, $scope);
$scope.time_controller = new fsm.FSMController($scope, "time_fsm", time.Start, $scope);
$scope.app_toolbox_controller = new fsm.FSMController($scope, "toolbox_fsm", toolbox_fsm.Start, $scope);
$scope.null_controller = new fsm.FSMController($scope, null_fsm.Start, null);
$scope.hotkeys_controller = new fsm.FSMController($scope, hotkeys.Start, $scope.null_controller);
$scope.view_controller = new fsm.FSMController($scope, view.Start, $scope.hotkeys_controller);
$scope.device_detail_controller = new fsm.FSMController($scope, device_detail_fsm.Start, $scope.view_controller);
$scope.move_controller = new fsm.FSMController($scope, move.Start, $scope.device_detail_controller);
$scope.link_controller = new fsm.FSMController($scope, link.Start, $scope.move_controller);
$scope.stream_controller = new fsm.FSMController($scope, stream_fsm.Start, $scope.link_controller);
$scope.group_controller = new fsm.FSMController($scope, group.Start, $scope.stream_controller);
$scope.rack_controller = new fsm.FSMController($scope, rack_fsm.Disable, $scope.group_controller);
$scope.site_controller = new fsm.FSMController($scope, site_fsm.Disable, $scope.rack_controller);
$scope.buttons_controller = new fsm.FSMController($scope, buttons.Start, $scope.site_controller);
$scope.time_controller = new fsm.FSMController($scope, time.Start, $scope.buttons_controller);
$scope.app_toolbox_controller = new fsm.FSMController($scope, toolbox_fsm.Start, $scope.time_controller);
//App Toolbox Setup
$scope.app_toolbox = new models.ToolBox(0, 'Process', 'app', 10, 200, 150, $scope.graph.height - 200 - 100);
$scope.app_toolbox.spacing = 150;
$scope.app_toolbox.enabled = false;
$scope.app_toolbox_controller.toolbox = $scope.app_toolbox;
$scope.app_toolbox_controller.dropped_action = function (selected_item) {
$scope.first_controller.handle_message("PasteProcess", new messages.PasteProcess(selected_item));
$scope.first_channel.send("PasteProcess", new messages.PasteProcess(selected_item));
};
$scope.app_toolbox.items.push(new models.Process(0, 'BGP', 'process', 0, 0));
$scope.app_toolbox.items.push(new models.Process(0, 'OSPF', 'process', 0, 0));
@@ -129,7 +148,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.app_toolbox.items[i].icon = true;
}
$scope.inventory_toolbox_controller = new fsm.FSMController($scope, toolbox_fsm.Start, $scope.app_toolbox_controller);
$scope.inventory_toolbox_controller = new fsm.FSMController($scope, "toolbox_fsm", toolbox_fsm.Start, $scope);
//Inventory Toolbox Setup
$scope.inventory_toolbox = new models.ToolBox(0, 'Inventory', 'device', 10, 200, 150, $scope.graph.height - 200 - 100);
@@ -151,14 +170,14 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.inventory_toolbox_controller.toolbox = $scope.inventory_toolbox;
$scope.inventory_toolbox_controller.remove_on_drop = true;
$scope.inventory_toolbox_controller.dropped_action = function (selected_item) {
$scope.first_controller.handle_message("PasteDevice", new messages.PasteDevice(selected_item));
$scope.first_channel.send("PasteDevice", new messages.PasteDevice(selected_item));
};
for(i = 0; i < $scope.inventory_toolbox.items.length; i++) {
$scope.inventory_toolbox.items[i].icon = true;
}
//End Inventory Toolbox Setup
$scope.rack_toolbox_controller = new fsm.FSMController($scope, toolbox_fsm.Start, $scope.inventory_toolbox_controller);
$scope.rack_toolbox_controller = new fsm.FSMController($scope, "toolbox_fsm", toolbox_fsm.Start, $scope);
//Rack Toolbox Setup
$scope.rack_toolbox = new models.ToolBox(0, 'Rack', 'rack', 10, 200, 150, $scope.graph.height - 200 - 100);
$scope.rack_toolbox.items.push(new models.Group(0, 'Rack3', 'rack', 0, 0, 200, 1000, 'false'));
@@ -167,14 +186,14 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.rack_toolbox_controller.remove_on_drop = false;
$scope.rack_toolbox_controller.toolbox = $scope.rack_toolbox;
$scope.rack_toolbox_controller.dropped_action = function (selected_item) {
$scope.first_controller.handle_message("PasteRack", new messages.PasteRack(selected_item));
$scope.first_channel.send("PasteRack", new messages.PasteRack(selected_item));
};
for(i = 0; i < $scope.rack_toolbox.items.length; i++) {
$scope.rack_toolbox.items[i].icon = true;
$scope.rack_toolbox.items[i].selected = false;
}
//End Rack Toolbox Setup
$scope.site_toolbox_controller = new fsm.FSMController($scope, toolbox_fsm.Start, $scope.rack_toolbox_controller);
$scope.site_toolbox_controller = new fsm.FSMController($scope, "toolbox_fsm", toolbox_fsm.Start, $scope);
//Site Toolbox Setup
$scope.site_toolbox = new models.ToolBox(0, 'Sites', 'sites', 10, 200, 150, $scope.graph.height - 200 - 100);
$scope.site_toolbox.items.push(new models.Group(0, 'Site3', 'site', 0, 0, 1000, 1000, 'false'));
@@ -183,7 +202,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.site_toolbox_controller.remove_on_drop = false;
$scope.site_toolbox_controller.toolbox = $scope.site_toolbox;
$scope.site_toolbox_controller.dropped_action = function (selected_item) {
$scope.first_controller.handle_message("PasteSite", new messages.PasteSite(selected_item));
$scope.first_channel.send("PasteSite", new messages.PasteSite(selected_item));
};
for(i = 0; i < $scope.site_toolbox.items.length; i++) {
$scope.site_toolbox.items[i].icon = true;
@@ -191,8 +210,58 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
}
//End Site Toolbox Setup
$scope.mode_controller = new fsm.FSMController($scope, mode_fsm.Start, $scope.site_toolbox_controller);
$scope.first_controller = $scope.mode_controller;
$scope.mode_controller = new fsm.FSMController($scope, "mode_fsm", mode_fsm.Start, $scope);
//Wire up the FSMs
$scope.view_controller.delegate_channel = new fsm.Channel($scope.view_controller,
$scope.hotkeys_controller,
$scope);
$scope.device_detail_controller.delegate_channel = new fsm.Channel($scope.device_detail_controller,
$scope.view_controller,
$scope);
$scope.move_controller.delegate_channel = new fsm.Channel($scope.move_controller,
$scope.device_detail_controller,
$scope);
$scope.link_controller.delegate_channel = new fsm.Channel($scope.link_controller,
$scope.move_controller,
$scope);
$scope.stream_controller.delegate_channel = new fsm.Channel($scope.stream_controller,
$scope.link_controller,
$scope);
$scope.group_controller.delegate_channel = new fsm.Channel($scope.group_controller,
$scope.stream_controller,
$scope);
$scope.rack_controller.delegate_channel = new fsm.Channel($scope.rack_controller,
$scope.group_controller,
$scope);
$scope.site_controller.delegate_channel = new fsm.Channel($scope.site_controller,
$scope.rack_controller,
$scope);
$scope.buttons_controller.delegate_channel = new fsm.Channel($scope.buttons_controller,
$scope.site_controller,
$scope);
$scope.time_controller.delegate_channel = new fsm.Channel($scope.time_controller,
$scope.buttons_controller,
$scope);
$scope.app_toolbox_controller.delegate_channel = new fsm.Channel($scope.app_toolbox_controller,
$scope.time_controller,
$scope);
$scope.inventory_toolbox_controller.delegate_channel = new fsm.Channel($scope.inventory_toolbox_controller,
$scope.app_toolbox_controller,
$scope);
$scope.rack_toolbox_controller.delegate_channel = new fsm.Channel($scope.rack_toolbox_controller,
$scope.inventory_toolbox_controller,
$scope);
$scope.site_toolbox_controller.delegate_channel = new fsm.Channel($scope.site_toolbox_controller,
$scope.rack_toolbox_controller,
$scope);
$scope.mode_controller.delegate_channel = new fsm.Channel($scope.mode_controller,
$scope.site_toolbox_controller,
$scope);
$scope.first_channel = new fsm.Channel(null,
$scope.mode_controller,
$scope);
var dids = $scope.device_id_seq;
var mids = $scope.message_id_seq;
@@ -401,7 +470,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.send_control_message(new messages.MouseEvent($scope.client_id, $event.offsetX, $event.offsetY, $event.type));
}
$scope.last_event = $event;
$scope.first_controller.handle_message('MouseDown', $event);
$scope.first_channel.send('MouseDown', $event);
$scope.onMouseDownResult = getMouseEventResult($event);
$event.preventDefault();
};
@@ -411,7 +480,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.send_control_message(new messages.MouseEvent($scope.client_id, $event.offsetX, $event.offsetY, $event.type));
}
$scope.last_event = $event;
$scope.first_controller.handle_message('MouseUp', $event);
$scope.first_channel.send('MouseUp', $event);
$scope.onMouseUpResult = getMouseEventResult($event);
$event.preventDefault();
};
@@ -436,7 +505,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.mouseX = $event.offsetX;
$scope.mouseY = $event.offsetY;
$scope.updateScaledXY();
$scope.first_controller.handle_message('MouseMove', $event);
$scope.first_channel.send('MouseMove', $event);
$scope.onMouseMoveResult = getMouseEventResult($event);
$event.preventDefault();
};
@@ -457,7 +526,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.send_control_message(new messages.MouseWheelEvent($scope.client_id, delta, deltaX, deltaY, $event.type, $event.originalEvent.metaKey));
}
$scope.last_event = $event;
$scope.first_controller.handle_message('MouseWheel', [$event, delta, deltaX, deltaY]);
$scope.first_channel.send('MouseWheel', [$event, delta, deltaX, deltaY]);
event.preventDefault();
};
@@ -475,7 +544,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.last_event = $event;
$scope.last_key = $event.key;
$scope.last_key_code = $event.keyCode;
$scope.first_controller.handle_message('KeyDown', $event);
$scope.first_channel.send('KeyDown', $event);
$scope.$apply();
$event.preventDefault();
};
@@ -504,7 +573,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.mouseY = $event.touches[0].screenY;
$scope.updateScaledXY();
}
$scope.first_controller.handle_message('TouchStart', $event);
$scope.first_channel.send('TouchStart', $event);
$scope.onTouchStartEvent = $event;
$event.preventDefault();
};
@@ -519,7 +588,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
if ($scope.recording) {
$scope.send_control_message(new messages.TouchEvent($scope.client_id, "touchend", touches));
}
$scope.first_controller.handle_message('TouchEnd', $event);
$scope.first_channel.send('TouchEnd', $event);
$scope.onTouchEndEvent = $event;
$event.preventDefault();
};
@@ -544,7 +613,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.updateScaledXY();
}
$scope.first_controller.handle_message('TouchMove', $event);
$scope.first_channel.send('TouchMove', $event);
$scope.onTouchMoveEvent = $event;
$event.preventDefault();
};
@@ -636,15 +705,15 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
// Buttons
$scope.buttons = [
new models.Button("BUTTON1", 10, 10, 90, 30, util.noop),
new models.Button("BUTTON1", 110, 10, 90, 30, util.noop),
new models.Button("BUTTON1", 10, 10, 90, 30, util.noop, $scope),
new models.Button("BUTTON1", 110, 10, 90, 30, util.noop, $scope),
];
var LAYERS_X = 160;
$scope.layers = [
new models.ToggleButton("TOGGLEBUTTON1", $scope.graph.width - LAYERS_X, 10, 150, 30, util.noop, util.noop, true),
new models.ToggleButton("TOGGLEBUTTON2", $scope.graph.width - LAYERS_X, 50, 150, 30, util.noop, util.noop, true),
new models.ToggleButton("TOGGLEBUTTON1", $scope.graph.width - LAYERS_X, 10, 150, 30, util.noop, util.noop, true, $scope),
new models.ToggleButton("TOGGLEBUTTON2", $scope.graph.width - LAYERS_X, 50, 150, 30, util.noop, util.noop, true, $scope),
];
var STENCIL_X = 10;
@@ -652,8 +721,8 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
var STENCIL_SPACING = 40;
$scope.stencils = [
new models.Button("BUTTON3", STENCIL_X, STENCIL_Y + STENCIL_SPACING * 0, 90, 30, util.noop),
new models.Button("BUTTON4", STENCIL_X, STENCIL_Y + STENCIL_SPACING * 1, 90, 30, util.noop),
new models.Button("BUTTON3", STENCIL_X, STENCIL_Y + STENCIL_SPACING * 0, 90, 30, util.noop, $scope),
new models.Button("BUTTON4", STENCIL_X, STENCIL_Y + STENCIL_SPACING * 1, 90, 30, util.noop, $scope),
];
$scope.all_buttons = [];
@@ -1326,7 +1395,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.control_socket.onmessage = function(message) {
$scope.first_controller.handle_message('Message', message);
$scope.first_channel.send('Message', message);
$scope.$apply();
};
@@ -1391,7 +1460,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
for (i =0; i < $scope.initial_messages.length; i++) {
console.log(['Inital message', $scope.initial_messages[i]]);
$scope.first_controller.handle_message($scope.initial_messages[i][0], $scope.initial_messages[i][1]);
$scope.first_channel.send($scope.initial_messages[i][0], $scope.initial_messages[i][1]);
}
$scope.updateScaledXY();

View File

@@ -284,7 +284,7 @@ _Selected2.prototype.onCopySelected = function (controller) {
_Selected2.prototype.onKeyDown = function (controller, msg_type, $event) {
//controller.changeState(Ready);
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
};
_Selected2.prototype.onKeyDown.transitions = ['Ready'];
@@ -407,7 +407,7 @@ _Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
if (selected) {
controller.changeState(Selected1);
} else {
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
}
};
_Ready.prototype.onMouseDown.transitions = ['Selected1'];

View File

@@ -367,7 +367,7 @@ _Selected2.prototype.onCopySelected = function (controller) {
_Selected2.prototype.onKeyDown = function (controller, msg_type, $event) {
//controller.changeState(Ready);
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
};
_Selected2.prototype.onKeyDown.transitions = ['Ready'];
@@ -490,7 +490,7 @@ _Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
if (selected) {
controller.changeState(Selected1);
} else {
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
}
};
_Ready.prototype.onMouseDown.transitions = ['Selected1'];

View File

@@ -195,7 +195,7 @@ _Past.prototype.onMouseWheel = function (controller, msg_type, message) {
this.redo(controller);
}
} else {
controller.next_controller.handle_message(msg_type, message);
controller.delegate_channel.send(msg_type, message);
}
};
@@ -218,7 +218,7 @@ _Past.prototype.onKeyDown = function(controller, msg_type, $event) {
this.redo(controller);
return;
} else {
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
}
};
_Past.prototype.onKeyDown.transitions = ['Present'];
@@ -504,7 +504,7 @@ _Present.prototype.onMouseWheel = function (controller, msg_type, message) {
this.undo(controller);
}
} else {
controller.next_controller.handle_message(msg_type, message);
controller.delegate_channel.send(msg_type, message);
}
};
@@ -521,7 +521,7 @@ _Present.prototype.onKeyDown = function(controller, msg_type, $event) {
this.undo(controller);
return;
} else {
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
}
};
_Present.prototype.onKeyDown.transitions = ['Past'];

View File

@@ -145,7 +145,7 @@ _Selecting.prototype.onMouseDown = function (controller) {
toolbox.selected_item.x = toolbox.x + toolbox.width/2;
toolbox.selected_item.y = selected_item * toolbox.spacing + toolbox.y + toolbox.scroll_offset + toolbox.spacing/2;
controller.scope.clear_selections();
controller.scope.first_controller.handle_message("UnselectAll", {});
controller.scope.first_channel.send("UnselectAll", {});
controller.changeState(Selected);
} else {
toolbox.selected_item = null;
@@ -171,7 +171,7 @@ _Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
controller.handle_message(msg_type, $event);
} else {
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
}
};
_Ready.prototype.onMouseDown.transitions = ['Selecting'];
@@ -188,7 +188,7 @@ _Ready.prototype.onMouseWheel = function (controller, msg_type, $event) {
controller.handle_message(msg_type, $event);
} else {
controller.next_controller.handle_message(msg_type, $event);
controller.delegate_channel.send(msg_type, $event);
}
};
_Ready.prototype.onMouseWheel.transitions = ['Scrolling'];
@@ -196,7 +196,7 @@ _Ready.prototype.onMouseWheel.transitions = ['Scrolling'];
_Ready.prototype.onToggleToolbox = function (controller, msg_type, message) {
controller.changeState(OffScreen);
controller.next_controller.handle_message(msg_type, message);
controller.delegate_channel.send(msg_type, message);
};
_Ready.prototype.onToggleToolbox.transitions = ['OffScreen'];
@@ -256,7 +256,7 @@ _Move.prototype.onMouseMove = function (controller) {
_OffScreen.prototype.onToggleToolbox = function (controller, msg_type, message) {
controller.changeState(Ready);
controller.next_controller.handle_message(msg_type, message);
controller.delegate_channel.send(msg_type, message);
};
_OffScreen.prototype.onToggleToolbox.transitions = ['Ready'];
@@ -298,7 +298,7 @@ _OffScreen2.prototype.start = function (controller) {
_OffScreen2.prototype.onToggleToolbox = function (controller, msg_type, message) {
controller.changeState(Disabled);
controller.next_controller.handle_message(msg_type, message);
controller.delegate_channel.send(msg_type, message);
};
_OffScreen2.prototype.onToggleToolbox.transitions = ['Disabled'];
@@ -327,6 +327,6 @@ _Disabled.prototype.end = function (controller) {
_Disabled.prototype.onToggleToolbox = function (controller, msg_type, message) {
controller.changeState(OffScreen2);
controller.next_controller.handle_message(msg_type, message);
controller.delegate_channel.send(msg_type, message);
};
_Disabled.prototype.onToggleToolbox.transitions = ['OffScreen2'];

View File

@@ -7,6 +7,7 @@ import awx.network_ui.routing
app_name = 'network_ui'
urlpatterns = [
url(r'^download_trace$', views.download_trace, name='download_trace'),
url(r'^topology.json$', views.json_topology_data, name='json_topology_data'),
url(r'^topology.yaml$', views.yaml_topology_data, name='json_topology_data'),
url(r'^$', views.index, name='index'),

View File

@@ -6,7 +6,7 @@ import yaml
# Create your views here.
from .models import Topology
from .models import Topology, FSMTrace
from .serializers import topology_data
@@ -35,3 +35,24 @@ def yaml_topology_data(request):
else:
return HttpResponseBadRequest(form.errors)
class FSMTraceForm(forms.Form):
topology_id = forms.IntegerField()
trace_id = forms.IntegerField()
client_id = forms.IntegerField()
def download_trace(request):
form = FSMTraceForm(request.GET)
if form.is_valid():
topology_id = form.cleaned_data['topology_id']
trace_id = form.cleaned_data['trace_id']
client_id = form.cleaned_data['client_id']
data = list(FSMTrace.objects.filter(trace_session_id=trace_id,
client_id=client_id).order_by('order').values())
response = HttpResponse(yaml.safe_dump(data, default_flow_style=False),
content_type="application/force-download")
response['Content-Disposition'] = 'attachment; filename="trace_{0}_{1}_{2}.yml"'.format(topology_id, client_id, trace_id)
return response
else:
return HttpResponse(form.errors)