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 django.contrib import admin
from awx.network_ui.models import Device 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 ToolboxItem
from awx.network_ui.models import FSMTrace
class DeviceAdmin(admin.ModelAdmin): class DeviceAdmin(admin.ModelAdmin):
fields = ('topology', 'name', 'x', 'y', 'id', 'type', 'interface_id_seq', 'process_id_seq',) 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) 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 DataSheet, DataBinding, DataType
from awx.network_ui.models import Process, Stream from awx.network_ui.models import Process, Stream
from awx.network_ui.models import Toolbox, ToolboxItem 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.serializers import yaml_serialize_topology
from awx.network_ui.messages import MultipleMessage, InterfaceCreate, LinkCreate, to_dict from awx.network_ui.messages import MultipleMessage, InterfaceCreate, LinkCreate, to_dict
import urlparse import urlparse
@@ -262,12 +263,16 @@ class _Persistence(object):
print "no sender" print "no sender"
return return
if isinstance(data[1], dict) and client_id != data[1].get('sender'): 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)) logger.error(pformat(data))
return return
message_type = data[0] message_type = data[0]
message_value = data[1] 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, TopologyHistory(topology_id=topology_id,
client_id=client_id, client_id=client_id,
message_type_id=message_type_id, message_type_id=message_type_id,
@@ -510,6 +515,15 @@ class _Persistence(object):
if new_entries: if new_entries:
GroupDeviceMap.objects.bulk_create(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() persistence = _Persistence()

View File

@@ -99,8 +99,8 @@ models:
pk: true pk: true
type: AutoField type: AutoField
name: Client name: Client
x: -455 x: -510
y: 109 y: 141
- fields: - fields:
- name: topology_history_id - name: topology_history_id
pk: true pk: true
@@ -136,8 +136,8 @@ models:
name: name name: name
type: CharField type: CharField
name: MessageType name: MessageType
x: -509 x: -501
y: 383 y: 428
- display: name - display: name
fields: fields:
- name: interface_id - name: interface_id
@@ -305,8 +305,8 @@ models:
name: name name: name
type: CharField type: CharField
name: Toolbox name: Toolbox
x: -222 x: 179
y: 627 y: 644
- fields: - fields:
- name: toolbox_item_id - name: toolbox_item_id
pk: true pk: true
@@ -318,8 +318,37 @@ models:
- name: data - name: data
type: TextField type: TextField
name: ToolboxItem name: ToolboxItem
x: 54 x: 391
y: 664 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: [] modules: []
view: view:
panX: 213.72955551921206 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_item_id = models.AutoField(primary_key=True,)
toolbox = models.ForeignKey('Toolbox',) toolbox = models.ForeignKey('Toolbox',)
data = models.TextField() 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** **Message Passing**
Messages are passed along channels between FSMs and over the websocket to and from the Messages are passed along channels between FSMs and over the websocket to and
server. Messages from the server over the web socket and user input events from the web from the server. Messages from the server over the web socket and user input
browser are passed to the `first_controller` where they are handled and discarded or 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 `null_controller` passed along the chain of FSMControllers until they reach the end with
or they are handled and the models are updated. `NullChannel` or they are handled and the models are updated.
* See: [src/network.ui.controller.js](src/network.ui.controller.js#L115) * 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 simple-server: lint main lessc
python -m SimpleHTTPServer 8081 python -m SimpleHTTPServer 8082
deploy: main deploy: main

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -42,4 +42,6 @@ messages:
- {msg_type: StreamLabelEdit, fields: [msg_type, sender, id, label, previous_label]} - {msg_type: StreamLabelEdit, fields: [msg_type, sender, id, label, previous_label]}
- {msg_type: StreamSelected, fields: [msg_type, sender, id]} - {msg_type: StreamSelected, fields: [msg_type, sender, id]}
- {msg_type: StreamUnSelected, 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 finite_state_machine_id: 130
name: mode name: mode_fsm
states: states:
- id: 1 - id: 1
label: Start label: Start

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -46,7 +46,7 @@ _Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
button = null; button = null;
} }
if (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. */ /* 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.scope = scope;
this.state = initial_state;
this.next_controller = next_controller;
this.name = name; 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.state.start(this);
this.handling_message_type = null;
} }
exports.FSMController = FSMController; exports.FSMController = FSMController;
FSMController.prototype.changeState = function (state) { FSMController.prototype.changeState = function (state) {
var old_handling_message_type;
if(this.state !== null) { if(this.state !== null) {
old_handling_message_type = this.handling_message_type;
this.handling_message_type = 'end';
this.state.end(this); 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; this.state = state;
if(state !== null) { if(state !== null) {
old_handling_message_type = this.handling_message_type;
this.handling_message_type = 'start';
state.start(this); state.start(this);
this.handling_message_type = old_handling_message_type;
} }
}; };
FSMController.prototype.handle_message = function(msg_type, message) { 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; var handler_name = 'on' + msg_type;
if (typeof(this.state[handler_name]) !== "undefined") { if (typeof(this.state[handler_name]) !== "undefined") {
this.state[handler_name](this, msg_type, message); this.state[handler_name](this, msg_type, message);
} else { } else {
this.default_handler(msg_type, message); this.default_handler(msg_type, message);
} }
this.handling_message_type = old_handling_message_type;
}; };
FSMController.prototype.default_handler = function(msg_type, message) { FSMController.prototype.default_handler = function(msg_type, message) {
if (this.next_controller !== null) { this.delegate_channel.send(msg_type, message);
this.next_controller.handle_message(msg_type, message);
}
}; };
function _State () { function _State () {

View File

@@ -91,7 +91,7 @@ exports.Placing = Placing;
_State.prototype.onUnselectAll = function (controller, msg_type, $event) { _State.prototype.onUnselectAll = function (controller, msg_type, $event) {
controller.changeState(Ready); 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) { _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) { _Ready.prototype.onMouseMove = function (controller, msg_type, $event) {
if (controller.scope.hide_groups) { if (controller.scope.hide_groups) {
controller.next_controller.handle_message(msg_type, $event); controller.delegate_channel.send(msg_type, $event);
return; 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.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) { _Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
if (controller.scope.hide_groups) { if (controller.scope.hide_groups) {
controller.next_controller.handle_message(msg_type, $event); controller.delegate_channel.send(msg_type, $event);
return; 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']; _Ready.prototype.onMouseDown.transitions = ['Selected1', 'CornerSelected'];
@@ -564,7 +564,7 @@ _Selected2.prototype.onKeyDown = function (controller, msg_type, $event) {
groups[i].name)); groups[i].name));
} }
} else { } else {
controller.next_controller.handle_message(msg_type, $event); controller.delegate_channel.send(msg_type, $event);
} }
}; };
_Selected2.prototype.onKeyDown.transitions = ['Ready']; _Selected2.prototype.onKeyDown.transitions = ['Ready'];
@@ -610,5 +610,5 @@ _Placing.prototype.onMouseDown = function (controller) {
controller.changeState(Resize); 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; var scope = controller.scope;
if ($event.key === 'c' && ($event.ctrlKey || $event.metaKey)) { 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') { if ($event.key === 'l') {
scope.first_controller.handle_message("NewLink", $event); scope.first_channel.send("NewLink", $event);
return; return;
} }
if ($event.key === 'm') { if ($event.key === 'm') {
scope.first_controller.handle_message("NewStream", $event); scope.first_channel.send("NewStream", $event);
} }
if ($event.key === 'd') { if ($event.key === 'd') {
@@ -75,27 +75,27 @@ _Enabled.prototype.onKeyDown = function(controller, msg_type, $event) {
} }
if ($event.key === 'r') { if ($event.key === 'r') {
scope.first_controller.handle_message("NewDevice", new messages.NewDevice("router")); scope.first_channel.send("NewDevice", new messages.NewDevice("router"));
return; return;
} }
else if ($event.key === 's') { 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; return;
} }
else if ($event.key === 'a') { 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; return;
} }
else if ($event.key === 'h') { 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; return;
} }
else if ($event.key === 'g') { 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; return;
} }
else if ($event.key === 'e') { 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; return;
} }
else if ($event.key === '0') { else if ($event.key === '0') {
@@ -106,7 +106,7 @@ _Enabled.prototype.onKeyDown = function(controller, msg_type, $event) {
scope.updatePanAndScale(); scope.updatePanAndScale();
} }
controller.next_controller.handle_message(msg_type, $event); controller.delegate_channel.send(msg_type, $event);
}; };
_Start.prototype.start = function (controller) { _Start.prototype.start = function (controller) {

View File

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

View File

@@ -422,3 +422,25 @@ function StreamUnSelected(sender, id) {
this.id = id; this.id = id;
} }
exports.StreamUnSelected = StreamUnSelected; 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.changeState(Device);
controller.next_controller.handle_message(msg_type, $event); controller.delegate_channel.send(msg_type, $event);
}; };
_Interface.prototype.onMouseWheel.transitions = ['Device']; _Interface.prototype.onMouseWheel.transitions = ['Device'];
@@ -110,7 +110,7 @@ _Site.prototype.onMouseWheel = function (controller, msg_type, $event) {
controller.changeState(Rack); controller.changeState(Rack);
} }
controller.next_controller.handle_message(msg_type, $event); controller.delegate_channel.send(msg_type, $event);
}; };
_Site.prototype.onMouseWheel.transitions = ['MultiSite', 'Rack']; _Site.prototype.onMouseWheel.transitions = ['MultiSite', 'Rack'];
@@ -119,7 +119,7 @@ _Site.prototype.onMouseWheel.transitions = ['MultiSite', 'Rack'];
_Process.prototype.onMouseWheel = function (controller, msg_type, $event) { _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); //controller.changeState(Device);
@@ -145,7 +145,7 @@ _MultiSite.prototype.onMouseWheel = function (controller, msg_type, $event) {
controller.changeState(Site); controller.changeState(Site);
} }
controller.next_controller.handle_message(msg_type, $event); controller.delegate_channel.send(msg_type, $event);
}; };
_MultiSite.prototype.onMouseWheel.transitions = ['Site']; _MultiSite.prototype.onMouseWheel.transitions = ['Site'];
@@ -171,7 +171,7 @@ _Device.prototype.onMouseWheel = function (controller, msg_type, $event) {
controller.changeState(Rack); 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']; _Device.prototype.onMouseWheel.transitions = ['Process', 'Interface', 'Rack'];
@@ -200,6 +200,6 @@ _Rack.prototype.onMouseWheel = function (controller, msg_type, $event) {
controller.changeState(Device); controller.changeState(Device);
} }
controller.next_controller.handle_message(msg_type, $event); controller.delegate_channel.send(msg_type, $event);
}; };
_Rack.prototype.onMouseWheel.transitions = ['Site', 'Device']; _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); 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.name = name;
this.x = x; this.x = x;
this.y = y; this.y = y;
@@ -298,7 +298,7 @@ function ActionIcon(name, x, y, r, callback, enabled) {
this.is_pressed = false; this.is_pressed = false;
this.mouse_over = false; this.mouse_over = false;
this.enabled = enabled; 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; 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.name = name;
this.x = x; this.x = x;
this.y = y; this.y = y;
@@ -321,7 +321,7 @@ function Button(name, x, y, width, height, callback) {
this.is_pressed = false; this.is_pressed = false;
this.mouse_over = false; this.mouse_over = false;
this.enabled = true; 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; 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.name = name;
this.x = x; this.x = x;
this.y = y; this.y = y;
@@ -349,7 +349,7 @@ function ToggleButton(name, x, y, width, height, toggle_callback, untoggle_callb
this.untoggle_callback = untoggle_callback; this.untoggle_callback = untoggle_callback;
this.mouse_over = false; this.mouse_over = false;
this.enabled = true; 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); inherits(ToggleButton, Button);
exports.ToggleButton = ToggleButton; 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.name = name;
this.x = x; this.x = x;
this.y = y; this.y = y;
@@ -376,7 +376,7 @@ function ContextMenu(name, x, y, width, height, callback, enabled, buttons) {
this.mouse_over = false; this.mouse_over = false;
this.enabled = enabled; this.enabled = enabled;
this.buttons = buttons; 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; 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.name = name;
this.x = x; this.x = x;
this.y = y; this.y = y;
@@ -400,7 +400,7 @@ function ContextMenuButton(name, x, y, width, height, callback) {
this.is_pressed = false; this.is_pressed = false;
this.mouse_over = false; this.mouse_over = false;
this.enabled = true; 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; exports.ContextMenuButton = ContextMenuButton;

View File

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

View File

@@ -1,5 +1,4 @@
/* Copyright (c) 2017 Red Hat, Inc. */ /* Copyright (c) 2017 Red Hat, Inc. */
// var _ = require('lodash');
var angular = require('angular'); var angular = require('angular');
var fsm = require('./fsm.js'); var fsm = require('./fsm.js');
var null_fsm = require('./null.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.http = $http;
$scope.api_token = ''; $scope.api_token = '';
$scope.disconnected = true; $scope.disconnected = false;
$scope.topology_id = $location.search().topology_id || 0; $scope.topology_id = $location.search().topology_id || 0;
// Create a web socket to connect to the backend server // Create a web socket to connect to the backend server
// //
$scope.inventory_id = $location.search().inventory_id || 1; $scope.inventory_id = $location.search().inventory_id || 1;
$scope.initial_messages = [];
if (!$scope.disconnected) { if (!$scope.disconnected) {
$scope.control_socket = new ReconnectingWebSocket("wss://" + window.location.host + "/network_ui/topology?topology_id=" + $scope.topology_id, $scope.control_socket = new ReconnectingWebSocket("wss://" + window.location.host + "/network_ui/topology?topology_id=" + $scope.topology_id,
null, null,
@@ -112,19 +112,43 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
'y': 0, 'y': 0,
'width': 0, 'width': 0,
'height': 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 //App Toolbox Setup
$scope.app_toolbox = new models.ToolBox(0, 'Process', 'app', 0, 40, 200, $scope.graph.height - 40); $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}; $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.toolbox = $scope.app_toolbox;
$scope.app_toolbox_controller.debug = true; $scope.app_toolbox_controller.debug = true;
$scope.app_toolbox_controller.dropped_action = function (selected_item) { $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, 'BGP', 'process', 0, 0));
@@ -145,19 +169,19 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.app_toolbox.items[i].icon = true; $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 //Inventory Toolbox Setup
$scope.inventory_toolbox = new models.ToolBox(0, 'Inventory', 'device', 0, 40, 200, $scope.graph.height - 40); $scope.inventory_toolbox = new models.ToolBox(0, 'Inventory', 'device', 0, 40, 200, $scope.graph.height - 40);
if (!$scope.disconnected) { if (!$scope.disconnected) {
console.log($location.protocol() + "://" + $location.host() + ':' + $location.port()); console.log($location.protocol() + "://" + $location.host() + ':' + $location.port());
console.log($scope.my_location); 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') $http.get('/api/v2/inventories/' + $scope.inventory_id + '/hosts/?format=json')
.then(function(inventory) { .then(function(inventory) {
console.log(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.remove_on_drop = true;
$scope.inventory_toolbox_controller.debug = true; $scope.inventory_toolbox_controller.debug = true;
$scope.inventory_toolbox_controller.dropped_action = function (selected_item) { $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 //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 //Rack Toolbox Setup
$scope.rack_toolbox = new models.ToolBox(0, 'Rack', 'rack', 0, 40, 200, $scope.graph.height - 40); $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}; $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.toolbox = $scope.rack_toolbox;
$scope.rack_toolbox_controller.debug = true; $scope.rack_toolbox_controller.debug = true;
$scope.rack_toolbox_controller.dropped_action = function (selected_item) { $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++) { for(i = 0; i < $scope.rack_toolbox.items.length; i++) {
$scope.rack_toolbox.items[i].icon = true; $scope.rack_toolbox.items[i].icon = true;
$scope.rack_toolbox.items[i].selected = false; $scope.rack_toolbox.items[i].selected = false;
} }
//End Rack Toolbox Setup //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 //Site Toolbox Setup
$scope.site_toolbox = new models.ToolBox(0, 'Sites', 'sites', 0, 40, 200, $scope.graph.height - 40); $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}; $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.toolbox = $scope.site_toolbox;
$scope.site_toolbox_controller.debug = true; $scope.site_toolbox_controller.debug = true;
$scope.site_toolbox_controller.dropped_action = function (selected_item) { $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++) { for(i = 0; i < $scope.site_toolbox.items.length; i++) {
$scope.site_toolbox.items[i].icon = true; $scope.site_toolbox.items[i].icon = true;
$scope.site_toolbox.items[i].selected = false; $scope.site_toolbox.items[i].selected = false;
} }
//End Site Toolbox Setup //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.mode_controller = new fsm.FSMController($scope, "mode_fsm", mode_fsm.Start, $scope);
$scope.first_controller = $scope.mode_controller;
//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) { var getMouseEventResult = function (mouseEvent) {
return "(" + mouseEvent.x + ", " + mouseEvent.y + ")"; 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.send_control_message(new messages.MouseEvent($scope.client_id, $event.x, $event.y, $event.type));
} }
$scope.last_event = $event; $scope.last_event = $event;
$scope.first_controller.handle_message('MouseDown', $event); $scope.first_channel.send('MouseDown', $event);
$scope.onMouseDownResult = getMouseEventResult($event); $scope.onMouseDownResult = getMouseEventResult($event);
$event.preventDefault(); $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.send_control_message(new messages.MouseEvent($scope.client_id, $event.x, $event.y, $event.type));
} }
$scope.last_event = $event; $scope.last_event = $event;
$scope.first_controller.handle_message('MouseUp', $event); $scope.first_channel.send('MouseUp', $event);
$scope.onMouseUpResult = getMouseEventResult($event); $scope.onMouseUpResult = getMouseEventResult($event);
$event.preventDefault(); $event.preventDefault();
}; };
@@ -444,7 +519,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.mouseX = $event.x; $scope.mouseX = $event.x;
$scope.mouseY = $event.y; $scope.mouseY = $event.y;
$scope.updateScaledXY(); $scope.updateScaledXY();
$scope.first_controller.handle_message('MouseMove', $event); $scope.first_channel.send('MouseMove', $event);
$scope.onMouseMoveResult = getMouseEventResult($event); $scope.onMouseMoveResult = getMouseEventResult($event);
$event.preventDefault(); $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.send_control_message(new messages.MouseWheelEvent($scope.client_id, delta, deltaX, deltaY, $event.type, $event.originalEvent.metaKey));
} }
$scope.last_event = $event; $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(); event.preventDefault();
}; };
@@ -489,7 +564,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.last_event = $event; $scope.last_event = $event;
$scope.last_key = $event.key; $scope.last_key = $event.key;
$scope.last_key_code = $event.keyCode; $scope.last_key_code = $event.keyCode;
$scope.first_controller.handle_message('KeyDown', $event); $scope.first_channel.send('KeyDown', $event);
$scope.$apply(); $scope.$apply();
$event.preventDefault(); $event.preventDefault();
}; };
@@ -518,7 +593,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.mouseY = $event.touches[0].screenY; $scope.mouseY = $event.touches[0].screenY;
$scope.updateScaledXY(); $scope.updateScaledXY();
} }
$scope.first_controller.handle_message('TouchStart', $event); $scope.first_channel.send('TouchStart', $event);
$scope.onTouchStartEvent = $event; $scope.onTouchStartEvent = $event;
$event.preventDefault(); $event.preventDefault();
}; };
@@ -533,7 +608,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
if ($scope.recording) { if ($scope.recording) {
$scope.send_control_message(new messages.TouchEvent($scope.client_id, "touchend", touches)); $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; $scope.onTouchEndEvent = $event;
$event.preventDefault(); $event.preventDefault();
}; };
@@ -558,7 +633,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.updateScaledXY(); $scope.updateScaledXY();
} }
$scope.first_controller.handle_message('TouchMove', $event); $scope.first_channel.send('TouchMove', $event);
$scope.onTouchMoveEvent = $event; $scope.onTouchMoveEvent = $event;
$event.preventDefault(); $event.preventDefault();
}; };
@@ -586,7 +661,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
// //
$scope.onToggleToolboxButtonLeft = function (button) { $scope.onToggleToolboxButtonLeft = function (button) {
console.log(button.name); 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[0].fsm.handle_message("Disable", {});
$scope.action_icons[1].fsm.handle_message("Enable", {}); $scope.action_icons[1].fsm.handle_message("Enable", {});
$scope.overall_toolbox_collapsed = !$scope.overall_toolbox_collapsed; $scope.overall_toolbox_collapsed = !$scope.overall_toolbox_collapsed;
@@ -594,7 +669,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.onToggleToolboxButtonRight = function (button) { $scope.onToggleToolboxButtonRight = function (button) {
console.log(button.name); 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[0].fsm.handle_message("Enable", {});
$scope.action_icons[1].fsm.handle_message("Disable", {}); $scope.action_icons[1].fsm.handle_message("Disable", {});
$scope.overall_toolbox_collapsed = !$scope.overall_toolbox_collapsed; $scope.overall_toolbox_collapsed = !$scope.overall_toolbox_collapsed;
@@ -696,54 +771,61 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
// Context Menu Buttons // Context Menu Buttons
$scope.context_menu_buttons = [ $scope.context_menu_buttons = [
new models.ContextMenuButton("Edit", 210, 200, 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) new models.ContextMenuButton("Details", 236, 231, 160, 26, $scope.onDetailsContextButton, $scope)
]; ];
// Context Menus // Context Menus
$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 // Icons
$scope.action_icons = [ $scope.action_icons = [
new models.ActionIcon("chevron-left", 170, $scope.graph.height/2, 16, $scope.onToggleToolboxButtonLeft, true), 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) 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 // Buttons
var button_offset = 200; var button_offset = 200;
$scope.buttons = [ $scope.buttons = [
new models.Button("DEPLOY", button_offset + 10, 48, 70, 30, $scope.onDeployButton), 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), 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), 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), 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), 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), 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), 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), 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; var LAYERS_X = 160;
$scope.layers = [ $scope.layers = [
new models.ToggleButton("APPLICATION", $scope.graph.width - LAYERS_X, 10, 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), 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), 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), 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), 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), new models.ToggleButton("DATA-LINK", $scope.graph.width - LAYERS_X, 210, 120, 30, util.noop, util.noop, true, $scope),
new models.ToggleButton("PHYSICAL", new models.ToggleButton("PHYSICAL",
$scope.graph.width - LAYERS_X, 250, 120, 30, $scope.graph.width - LAYERS_X, 250, 120, 30,
$scope.onTogglePhysical, $scope.onTogglePhysical,
$scope.onUnTogglePhysical, $scope.onUnTogglePhysical,
true), true,
$scope),
new models.ToggleButton("GROUP", new models.ToggleButton("GROUP",
$scope.graph.width - LAYERS_X, 290, 120, 30, $scope.graph.width - LAYERS_X, 290, 120, 30,
$scope.onToggleGroup, $scope.onToggleGroup,
$scope.onUnToggleGroup, $scope.onUnToggleGroup,
true) true,
$scope)
]; ];
$scope.layers = []; $scope.layers = [];
@@ -1213,6 +1295,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.onClientId = function(data) { $scope.onClientId = function(data) {
$scope.client_id = data; $scope.client_id = data;
$scope.send_initial_messages();
}; };
$scope.onTopology = function(data) { $scope.onTopology = function(data) {
@@ -1559,12 +1642,26 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
$scope.control_socket.onmessage = function(message) { $scope.control_socket.onmessage = function(message) {
$scope.first_controller.handle_message('Message', message); $scope.first_channel.send('Message', message);
$scope.$apply(); $scope.$apply();
}; };
$scope.control_socket.onopen = function() { $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 // 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.topology_id = 0;
$scope.control_socket = { $scope.control_socket = {
on_message: util.noop on_message: util.noop,
send: util.noop
}; };
$scope.history = []; $scope.history = [];
$scope.client_id = 1; $scope.client_id = 1;
@@ -98,27 +99,45 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
'y': 0, 'y': 0,
'width': 0, 'width': 0,
'height': 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 //App Toolbox Setup
$scope.app_toolbox = new models.ToolBox(0, 'Process', 'app', 10, 200, 150, $scope.graph.height - 200 - 100); $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.spacing = 150;
$scope.app_toolbox.enabled = false; $scope.app_toolbox.enabled = false;
$scope.app_toolbox_controller.toolbox = $scope.app_toolbox; $scope.app_toolbox_controller.toolbox = $scope.app_toolbox;
$scope.app_toolbox_controller.dropped_action = function (selected_item) { $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, 'BGP', 'process', 0, 0));
$scope.app_toolbox.items.push(new models.Process(0, 'OSPF', '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.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 //Inventory Toolbox Setup
$scope.inventory_toolbox = new models.ToolBox(0, 'Inventory', 'device', 10, 200, 150, $scope.graph.height - 200 - 100); $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.toolbox = $scope.inventory_toolbox;
$scope.inventory_toolbox_controller.remove_on_drop = true; $scope.inventory_toolbox_controller.remove_on_drop = true;
$scope.inventory_toolbox_controller.dropped_action = function (selected_item) { $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++) { for(i = 0; i < $scope.inventory_toolbox.items.length; i++) {
$scope.inventory_toolbox.items[i].icon = true; $scope.inventory_toolbox.items[i].icon = true;
} }
//End Inventory Toolbox Setup //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 //Rack Toolbox Setup
$scope.rack_toolbox = new models.ToolBox(0, 'Rack', 'rack', 10, 200, 150, $scope.graph.height - 200 - 100); $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')); $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.remove_on_drop = false;
$scope.rack_toolbox_controller.toolbox = $scope.rack_toolbox; $scope.rack_toolbox_controller.toolbox = $scope.rack_toolbox;
$scope.rack_toolbox_controller.dropped_action = function (selected_item) { $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++) { for(i = 0; i < $scope.rack_toolbox.items.length; i++) {
$scope.rack_toolbox.items[i].icon = true; $scope.rack_toolbox.items[i].icon = true;
$scope.rack_toolbox.items[i].selected = false; $scope.rack_toolbox.items[i].selected = false;
} }
//End Rack Toolbox Setup //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 //Site Toolbox Setup
$scope.site_toolbox = new models.ToolBox(0, 'Sites', 'sites', 10, 200, 150, $scope.graph.height - 200 - 100); $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')); $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.remove_on_drop = false;
$scope.site_toolbox_controller.toolbox = $scope.site_toolbox; $scope.site_toolbox_controller.toolbox = $scope.site_toolbox;
$scope.site_toolbox_controller.dropped_action = function (selected_item) { $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++) { for(i = 0; i < $scope.site_toolbox.items.length; i++) {
$scope.site_toolbox.items[i].icon = true; $scope.site_toolbox.items[i].icon = true;
@@ -191,8 +210,58 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
} }
//End Site Toolbox Setup //End Site Toolbox Setup
$scope.mode_controller = new fsm.FSMController($scope, mode_fsm.Start, $scope.site_toolbox_controller); $scope.mode_controller = new fsm.FSMController($scope, "mode_fsm", mode_fsm.Start, $scope);
$scope.first_controller = $scope.mode_controller;
//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 dids = $scope.device_id_seq;
var mids = $scope.message_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.send_control_message(new messages.MouseEvent($scope.client_id, $event.offsetX, $event.offsetY, $event.type));
} }
$scope.last_event = $event; $scope.last_event = $event;
$scope.first_controller.handle_message('MouseDown', $event); $scope.first_channel.send('MouseDown', $event);
$scope.onMouseDownResult = getMouseEventResult($event); $scope.onMouseDownResult = getMouseEventResult($event);
$event.preventDefault(); $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.send_control_message(new messages.MouseEvent($scope.client_id, $event.offsetX, $event.offsetY, $event.type));
} }
$scope.last_event = $event; $scope.last_event = $event;
$scope.first_controller.handle_message('MouseUp', $event); $scope.first_channel.send('MouseUp', $event);
$scope.onMouseUpResult = getMouseEventResult($event); $scope.onMouseUpResult = getMouseEventResult($event);
$event.preventDefault(); $event.preventDefault();
}; };
@@ -436,7 +505,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.mouseX = $event.offsetX; $scope.mouseX = $event.offsetX;
$scope.mouseY = $event.offsetY; $scope.mouseY = $event.offsetY;
$scope.updateScaledXY(); $scope.updateScaledXY();
$scope.first_controller.handle_message('MouseMove', $event); $scope.first_channel.send('MouseMove', $event);
$scope.onMouseMoveResult = getMouseEventResult($event); $scope.onMouseMoveResult = getMouseEventResult($event);
$event.preventDefault(); $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.send_control_message(new messages.MouseWheelEvent($scope.client_id, delta, deltaX, deltaY, $event.type, $event.originalEvent.metaKey));
} }
$scope.last_event = $event; $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(); event.preventDefault();
}; };
@@ -475,7 +544,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.last_event = $event; $scope.last_event = $event;
$scope.last_key = $event.key; $scope.last_key = $event.key;
$scope.last_key_code = $event.keyCode; $scope.last_key_code = $event.keyCode;
$scope.first_controller.handle_message('KeyDown', $event); $scope.first_channel.send('KeyDown', $event);
$scope.$apply(); $scope.$apply();
$event.preventDefault(); $event.preventDefault();
}; };
@@ -504,7 +573,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.mouseY = $event.touches[0].screenY; $scope.mouseY = $event.touches[0].screenY;
$scope.updateScaledXY(); $scope.updateScaledXY();
} }
$scope.first_controller.handle_message('TouchStart', $event); $scope.first_channel.send('TouchStart', $event);
$scope.onTouchStartEvent = $event; $scope.onTouchStartEvent = $event;
$event.preventDefault(); $event.preventDefault();
}; };
@@ -519,7 +588,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
if ($scope.recording) { if ($scope.recording) {
$scope.send_control_message(new messages.TouchEvent($scope.client_id, "touchend", touches)); $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; $scope.onTouchEndEvent = $event;
$event.preventDefault(); $event.preventDefault();
}; };
@@ -544,7 +613,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.updateScaledXY(); $scope.updateScaledXY();
} }
$scope.first_controller.handle_message('TouchMove', $event); $scope.first_channel.send('TouchMove', $event);
$scope.onTouchMoveEvent = $event; $scope.onTouchMoveEvent = $event;
$event.preventDefault(); $event.preventDefault();
}; };
@@ -636,15 +705,15 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
// Buttons // Buttons
$scope.buttons = [ $scope.buttons = [
new models.Button("BUTTON1", 10, 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), new models.Button("BUTTON1", 110, 10, 90, 30, util.noop, $scope),
]; ];
var LAYERS_X = 160; var LAYERS_X = 160;
$scope.layers = [ $scope.layers = [
new models.ToggleButton("TOGGLEBUTTON1", $scope.graph.width - LAYERS_X, 10, 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), new models.ToggleButton("TOGGLEBUTTON2", $scope.graph.width - LAYERS_X, 50, 150, 30, util.noop, util.noop, true, $scope),
]; ];
var STENCIL_X = 10; var STENCIL_X = 10;
@@ -652,8 +721,8 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
var STENCIL_SPACING = 40; var STENCIL_SPACING = 40;
$scope.stencils = [ $scope.stencils = [
new models.Button("BUTTON3", STENCIL_X, STENCIL_Y + STENCIL_SPACING * 0, 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), new models.Button("BUTTON4", STENCIL_X, STENCIL_Y + STENCIL_SPACING * 1, 90, 30, util.noop, $scope),
]; ];
$scope.all_buttons = []; $scope.all_buttons = [];
@@ -1326,7 +1395,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
$scope.control_socket.onmessage = function(message) { $scope.control_socket.onmessage = function(message) {
$scope.first_controller.handle_message('Message', message); $scope.first_channel.send('Message', message);
$scope.$apply(); $scope.$apply();
}; };
@@ -1391,7 +1460,7 @@ var NetworkWidgetsController = function($scope, $document, $location, $window) {
for (i =0; i < $scope.initial_messages.length; i++) { for (i =0; i < $scope.initial_messages.length; i++) {
console.log(['Inital message', $scope.initial_messages[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(); $scope.updateScaledXY();

View File

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

View File

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

View File

@@ -195,7 +195,7 @@ _Past.prototype.onMouseWheel = function (controller, msg_type, message) {
this.redo(controller); this.redo(controller);
} }
} else { } 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); this.redo(controller);
return; return;
} else { } else {
controller.next_controller.handle_message(msg_type, $event); controller.delegate_channel.send(msg_type, $event);
} }
}; };
_Past.prototype.onKeyDown.transitions = ['Present']; _Past.prototype.onKeyDown.transitions = ['Present'];
@@ -504,7 +504,7 @@ _Present.prototype.onMouseWheel = function (controller, msg_type, message) {
this.undo(controller); this.undo(controller);
} }
} else { } 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); this.undo(controller);
return; return;
} else { } else {
controller.next_controller.handle_message(msg_type, $event); controller.delegate_channel.send(msg_type, $event);
} }
}; };
_Present.prototype.onKeyDown.transitions = ['Past']; _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.x = toolbox.x + toolbox.width/2;
toolbox.selected_item.y = selected_item * toolbox.spacing + toolbox.y + toolbox.scroll_offset + toolbox.spacing/2; toolbox.selected_item.y = selected_item * toolbox.spacing + toolbox.y + toolbox.scroll_offset + toolbox.spacing/2;
controller.scope.clear_selections(); controller.scope.clear_selections();
controller.scope.first_controller.handle_message("UnselectAll", {}); controller.scope.first_channel.send("UnselectAll", {});
controller.changeState(Selected); controller.changeState(Selected);
} else { } else {
toolbox.selected_item = null; toolbox.selected_item = null;
@@ -171,7 +171,7 @@ _Ready.prototype.onMouseDown = function (controller, msg_type, $event) {
controller.handle_message(msg_type, $event); controller.handle_message(msg_type, $event);
} else { } else {
controller.next_controller.handle_message(msg_type, $event); controller.delegate_channel.send(msg_type, $event);
} }
}; };
_Ready.prototype.onMouseDown.transitions = ['Selecting']; _Ready.prototype.onMouseDown.transitions = ['Selecting'];
@@ -188,7 +188,7 @@ _Ready.prototype.onMouseWheel = function (controller, msg_type, $event) {
controller.handle_message(msg_type, $event); controller.handle_message(msg_type, $event);
} else { } else {
controller.next_controller.handle_message(msg_type, $event); controller.delegate_channel.send(msg_type, $event);
} }
}; };
_Ready.prototype.onMouseWheel.transitions = ['Scrolling']; _Ready.prototype.onMouseWheel.transitions = ['Scrolling'];
@@ -196,7 +196,7 @@ _Ready.prototype.onMouseWheel.transitions = ['Scrolling'];
_Ready.prototype.onToggleToolbox = function (controller, msg_type, message) { _Ready.prototype.onToggleToolbox = function (controller, msg_type, message) {
controller.changeState(OffScreen); controller.changeState(OffScreen);
controller.next_controller.handle_message(msg_type, message); controller.delegate_channel.send(msg_type, message);
}; };
_Ready.prototype.onToggleToolbox.transitions = ['OffScreen']; _Ready.prototype.onToggleToolbox.transitions = ['OffScreen'];
@@ -256,7 +256,7 @@ _Move.prototype.onMouseMove = function (controller) {
_OffScreen.prototype.onToggleToolbox = function (controller, msg_type, message) { _OffScreen.prototype.onToggleToolbox = function (controller, msg_type, message) {
controller.changeState(Ready); controller.changeState(Ready);
controller.next_controller.handle_message(msg_type, message); controller.delegate_channel.send(msg_type, message);
}; };
_OffScreen.prototype.onToggleToolbox.transitions = ['Ready']; _OffScreen.prototype.onToggleToolbox.transitions = ['Ready'];
@@ -298,7 +298,7 @@ _OffScreen2.prototype.start = function (controller) {
_OffScreen2.prototype.onToggleToolbox = function (controller, msg_type, message) { _OffScreen2.prototype.onToggleToolbox = function (controller, msg_type, message) {
controller.changeState(Disabled); controller.changeState(Disabled);
controller.next_controller.handle_message(msg_type, message); controller.delegate_channel.send(msg_type, message);
}; };
_OffScreen2.prototype.onToggleToolbox.transitions = ['Disabled']; _OffScreen2.prototype.onToggleToolbox.transitions = ['Disabled'];
@@ -327,6 +327,6 @@ _Disabled.prototype.end = function (controller) {
_Disabled.prototype.onToggleToolbox = function (controller, msg_type, message) { _Disabled.prototype.onToggleToolbox = function (controller, msg_type, message) {
controller.changeState(OffScreen2); controller.changeState(OffScreen2);
controller.next_controller.handle_message(msg_type, message); controller.delegate_channel.send(msg_type, message);
}; };
_Disabled.prototype.onToggleToolbox.transitions = ['OffScreen2']; _Disabled.prototype.onToggleToolbox.transitions = ['OffScreen2'];

View File

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

View File

@@ -6,7 +6,7 @@ import yaml
# Create your views here. # Create your views here.
from .models import Topology from .models import Topology, FSMTrace
from .serializers import topology_data from .serializers import topology_data
@@ -35,3 +35,24 @@ def yaml_topology_data(request):
else: else:
return HttpResponseBadRequest(form.errors) 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)