Commit 30b50e5c authored by Luca Lamorte's avatar Luca Lamorte

Feature: Change Message Data; UI: Improved with templates

parent bded237b
{"exchange": "default", "orchestrator": "http://locahost:50001", "version": "0.0.1", "connected": false, "url": "amqp://luca:luca@finterop1/session1", "component": "gui_tt"}
\ No newline at end of file
{"connected": false, "exchange": "default", "orchestrator": "http://locahost:50001", "url": "amqp://luca:luca@finterop1/session1", "component": "gui_tt", "version": "0.0.1"}
\ No newline at end of file
......@@ -19,9 +19,6 @@ from testing_tool_gui.gui.render_html import create_device_table
from werkzeug.utils import secure_filename
my_channel = None
amqp_listener = None
thread = None
......@@ -60,13 +57,45 @@ def allowed_file(filename):
@socketio.on('send_amqp_msg', namespace=NAMESPACE)
def test_message(message):
global app_cfg
logger.info("SEND MESSAGE %s" % message["msg"])
logger.info("Received message %s" %message)
try:
json_msg = json.loads(message)
if app_cfg.is_connected:
msg = message_types_dict[message["msg"]]()
msg = message_types_dict[json_msg["routing_key"]]()
del json_msg["routing_key"]
msg = msg.from_json(json.dumps(json_msg))
publish_message(app_cfg.get_channel(), msg)
logger.debug("MSG Sent!")
logger.debug("MSG %s SEND!" %repr(message))
else:
socketio.emit("info",
"warning#Connection with RabbitMQ is not available. Please try later or change settings!.",
namespace=NAMESPACE)
except Exception as ex:
logger.error("EXCEPTION %s!" %ex)
socketio.emit("info",
"danger# Exception while sending message: %s" %ex,
namespace=NAMESPACE)
@socketio.on('send_amqp_simple', namespace=NAMESPACE)
def send_message(message):
global app_cfg
logger.info("Received message %s" %message)
try:
if app_cfg.is_connected:
msg = message_types_dict[message]()
publish_message(app_cfg.get_channel(), msg)
logger.debug("MSG %s SEND!" %repr(message))
else:
socketio.emit("info",
"warning#Connection with RabbitMQ is not available. Please try later or change settings!.",
......@@ -141,7 +170,8 @@ def get_html_template(template):
def amqp_msg():
list_of_msg = list(message_types_dict.keys())
list_of_msg = sorted(list_of_msg)
filtered = [v for v in list_of_msg if not v.endswith('.reply')]
list_of_msg = sorted(filtered)
response = app.response_class(
response=json.dumps(list_of_msg),
status=200,
......@@ -150,6 +180,29 @@ def amqp_msg():
return response
@app.route('/message/<msg_type>')
def get_message_type(msg_type):
logger.info("Get %s structure ..." %msg_type)
my_msg = message_types_dict[msg_type]()
# full_data = dict()
# full_data["header"] = dict()
# full_data["body"] = dict()
# full_data["header"] = dict(my_msg.get_properties())
# full_data["body"] = my_msg.to_dict()
# print (full_data)
response = app.response_class(
response= my_msg.to_json(),
status=200,
mimetype='application/json'
)
return response
@app.route('/configuration', methods=['GET', 'POST'])
def configuration():
if request.method == 'POST':
......
......@@ -50,12 +50,14 @@ $(document).ready(function() {
});
$('#filter_rk').keyup(function() {
filterByRoutingKey()
});
$.get('/amqp_msg_list', function(data){
read_message_list(data)
read_message_list(data, "utils_msg_list")
});
$.get('/configuration', function(data){
......@@ -74,8 +76,20 @@ $(document).ready(function() {
});
load_last_page()
});
function load_last_page(){
var menu = Cookies.get('menu')
if (menu) {
console.log("Cookie menu = "+menu)
showDetails(menu)
}
}
/*******************************************************************
*
* PRIVACY SECTION - FUNCTION FOR PRIVACY
......@@ -119,7 +133,6 @@ function checkPrivacyMessage(msg){
function show_verdict(){
$.get( "verdict/html", function( data ) {
$( "#info").html( data );
......@@ -127,31 +140,50 @@ function show_verdict(){
}
function addTestCase(testcase){
Cookies.set('testcase', testcase);
$.get( "html/" + testcase, function( data ) {
$( "#p_tc").html( data );
console.log(testcase+ " added.")
});
}
function showDetails(value){
var html = ""
Cookies.set('menu', value);
$.get( "html/"+value , function( data ) {
$("#add_page_here").html(data )
})
$('#myNavbar li').each(function(){
$(this).removeClass('active')
});
$("#"+value).addClass("active")
if (value === 'privacy'){
// Default is gui
html = ['<h1> Privacy Testing Tool - v.1.0.0 </h1>',
'<p>Lorem ipsum dolor sit amet, consectetur adipisci elit, sed eiusmod tempor incidunt ut ' +
'labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrum exercitationem ullam ' +
'corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur. Quis aute iure ' +
'reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur ' +
'sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim ' +
'id est laborum.</p>',
'<div class="raw" id="p_tc"></div>']
var testcase = Cookies.get('testcase')
if (testcase){
addTestCase(testcase)
}
}
else {
// Default is gui
html = ['<h1>Demo GUI!</h1>',
'<p>This is a a simple GUI to play with <a href-="http://www.finterop.eu">F-Interop</a> ' +
'APIs and Testing Tools (TT) . It includes a Event Bus (RabbitMQ) console ' +
'and the AMQP Messages Utils. Use it as a starting point to test your component.</p>',
]
else if (value === "message"){
$.get('/amqp_msg_list', function(data){
read_message_list(data, "message_rk_list")
});
console.log("Message Insert into $(#message_rk_list)")
console.log("BUTTON ROUTING KEY has messages")
}
$("#info").html(html);
}
......@@ -167,12 +199,59 @@ function change_cfg(){
}
function send_amqp_message(message){
function send_amqp_msg(){
if ( $("#routing_key_input").val() === ""){
send_alert("RK Missing", "Please select the Routing Key", "danger")
}
else {
var sendData = {};
$('#message_body tr').each(function (i, el) {
var key = $.trim($(this).find('td:eq(0)').text()),
val = $.trim($(this).find('td:eq(1)').find('input').val());
sendData[key] = val;
});
sendData["routing_key"] = $("#routing_key_input").val()
console.log(JSON.stringify(sendData))
socket.emit("send_amqp_msg", JSON.stringify(sendData))
}
}
function send_simple_message(routing_key){
socket.emit("send_amqp_simple", routing_key)
}
function show_amqp_message(message){
console.log("Send message "+ message)
socket.emit('send_amqp_msg', { 'msg' : message });
//socket.emit('send_var routing_key
$("#routing_key_input").val(message)
$("#message_body").append("")
$.get( "message/"+message , function( data ) {
for (var key in data) {
console.log("key:"+key + " value:"+data[key])
var key_elm = $("<td>").html(key).addClass("body_key")
var input_elm = $("<input>").val(data[key])
input_elm.addClass("form-control").addClass("body_value")
var value_elm = $("<td>").append(input_elm)
var line = $("<tr>").append(key_elm).append(value_elm)
$("#message_body").append(line)
}
});
}
function read_configuration(cfg){
//console.log(data)
// var cfg = JSON.parse(data)
......@@ -189,27 +268,29 @@ function read_configuration(cfg){
}
}
function read_message_list(data){
function read_message_list(data, id_to_place){
var old_topic = ""
$("#utils_msg_list").html("")
//$("#"+id_to_place).html("")
var submenu = $("<ul>").addClass("dropdown-submenu")
for (var i in data){
var topic = data[i].split(".")[0];
if (topic !== old_topic ){
var serparator = $("<li>").addClass("divider").attr("role", "separator")
$("#utils_msg_list").append(serparator);
$("#"+id_to_place).append(serparator);
old_topic = topic;
console.log("change topic")
}
var item = $("<li>")
var aaaa = $("<a>").attr("href", "javascript:send_amqp_message('"+data[i]+"')").html(data[i])
var aaaa = $("<a>").attr("href", "javascript:show_amqp_message('"+data[i]+"')").html(data[i])
aaaa.addClass("amqp_message")
item.append(aaaa)
$("#utils_msg_list").append(item)
$("#"+id_to_place).append(item)
}
console.log("Message Insert into $(#"+id_to_place+')')
}
function uniqueid(){
......@@ -381,7 +462,7 @@ function amqpToHtml(data_str){
p_collapse.append(p_body)
p_collapse.append(p_foot)
var p_group = $("<div>").addClass("panel-group").attr("id", msg_id).attr("rk", routing_key)
var p_group = $("<div>").addClass("panel-group").attr("id", msg_id).attr("rk", routing_key).addClass("amqp_msg")
var p_def = $("<div>").addClass("panel panel-default")
p_group.append(p_def)
p_def.append(p_head)
......
/*!
* JavaScript Cookie v2.1.4
* https://github.com/js-cookie/js-cookie
*
* Copyright 2006, 2015 Klaus Hartl & Fagner Brack
* Released under the MIT license
*/
;(function (factory) {
var registeredInModuleLoader = false;
if (typeof define === 'function' && define.amd) {
define(factory);
registeredInModuleLoader = true;
}
if (typeof exports === 'object') {
module.exports = factory();
registeredInModuleLoader = true;
}
if (!registeredInModuleLoader) {
var OldCookies = window.Cookies;
var api = window.Cookies = factory();
api.noConflict = function () {
window.Cookies = OldCookies;
return api;
};
}
}(function () {
function extend () {
var i = 0;
var result = {};
for (; i < arguments.length; i++) {
var attributes = arguments[ i ];
for (var key in attributes) {
result[key] = attributes[key];
}
}
return result;
}
function init (converter) {
function api (key, value, attributes) {
var result;
if (typeof document === 'undefined') {
return;
}
// Write
if (arguments.length > 1) {
attributes = extend({
path: '/'
}, api.defaults, attributes);
if (typeof attributes.expires === 'number') {
var expires = new Date();
expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
attributes.expires = expires;
}
// We're using "expires" because "max-age" is not supported by IE
attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';
try {
result = JSON.stringify(value);
if (/^[\{\[]/.test(result)) {
value = result;
}
} catch (e) {}
if (!converter.write) {
value = encodeURIComponent(String(value))
.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
} else {
value = converter.write(value, key);
}
key = encodeURIComponent(String(key));
key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
key = key.replace(/[\(\)]/g, escape);
var stringifiedAttributes = '';
for (var attributeName in attributes) {
if (!attributes[attributeName]) {
continue;
}
stringifiedAttributes += '; ' + attributeName;
if (attributes[attributeName] === true) {
continue;
}
stringifiedAttributes += '=' + attributes[attributeName];
}
return (document.cookie = key + '=' + value + stringifiedAttributes);
}
// Read
if (!key) {
result = {};
}
// To prevent the for loop in the first place assign an empty array
// in case there are no cookies at all. Also prevents odd result when
// calling "get()"
var cookies = document.cookie ? document.cookie.split('; ') : [];
var rdecode = /(%[0-9A-Z]{2})+/g;
var i = 0;
for (; i < cookies.length; i++) {
var parts = cookies[i].split('=');
var cookie = parts.slice(1).join('=');
if (cookie.charAt(0) === '"') {
cookie = cookie.slice(1, -1);
}
try {
var name = parts[0].replace(rdecode, decodeURIComponent);
cookie = converter.read ?
converter.read(cookie, name) : converter(cookie, name) ||
cookie.replace(rdecode, decodeURIComponent);
if (this.json) {
try {
cookie = JSON.parse(cookie);
} catch (e) {}
}
if (key === name) {
result = cookie;
break;
}
if (!key) {
result[name] = cookie;
}
} catch (e) {}
}
return result;
}
api.set = api;
api.get = function (key) {
return api.call(api, key);
};
api.getJSON = function () {
return api.apply({
json: true
}, [].slice.call(arguments));
};
api.defaults = {};
api.remove = function (key, attributes) {
api(key, '', extend(attributes, {
expires: -1
}));
};
api.withConverter = init;
return api;
}
return init(function () {});
}));
......@@ -8,12 +8,6 @@
* @param testcase
*/
// $('#pcap_form').submit(function(e){
// send_alert("ATTENZIONE", "ENTRATO")
// e.preventDefault();
// send_alert("NO REDIRECT", "ci sono riuscito")
// });
$(document).on('change', "#pcap_file", function(e){
if ($("#pcap_file").val() !== "")
$("#send_file_amqp").removeClass("fade");
......@@ -58,64 +52,5 @@ $(document).on('click', "#send_file_amqp", function(e) {
});
function addTestCase(testcase){
// var index = parseInt(testcase)
// var title = ["Test Case1", "Test Case 2"]
// var descr = ["User MUST provide the PCAP file of IUTs Conversation to check if there is any privacy issue.",
// "The simplest topology to test this test case is a CoAP Client and Server running on two different" +
// " machines, connected each other with the FI-AGENT. All the traffic will be routed through the " +
// "EventBUS. When the setup is completed user must confirm it by sending Start Test Suite. " +
// "At this stage the Privacy Testing tools will enable the agent and the sniffer to capture " +
// "the conversation between the client and the server. When done, press Test Case Finished and the " +
// "PCAP file generated will be analyzed and a report will be send back to the GUI. " +
// "To check the current status of the Testing tools please use the GetStatus button."]
//
// var cmds = [
// '<div class="col-md-11">' +
// '<p style="color: #000088">'+ descr[index]+'</p>' +
// '<div class="row">' +
// '<div class="col-md-3">' +
// '<form enctype="multipart/form-data">' +
// '<span> Analyze IUT Conversation (CoAP) </span>' +
// '<span class="glyphicon glyphicon-phone" aria-hidden="true"></span>' +
// '<div style="position:relative;">' +
// '<a class="btn btn-primary" href="javascript:;">Choose File...' +
// '<input type="file" id="pcap_file" name="file_source" size="40" onchange="select_pcap()"></a>' +
// '<span class="label label-info" id="upload-file-info"></span>' +
// '</form></div> </div>' +
// '<progress></progress>'+
// '<div class="col-md-9 " id="cmq_area"></div>'+
// '</div>',
//
// // SECOND TEST CASE
// '<div class="col-md-11">'+
// '<p style="color: #000088">'+ descr[index]+'</p>' +
// '<div class="row">' +
// '<button type="button" class="btn btn-default" onclick="send_amqp_message(testcoordination.testsuite.start)">Start TestCase</button> '+
// '<button type="button" class="btn btn-primary" onclick="send_amqp_message(testcoordination.testsuite.finish)">Finish TestCase</button> '+
// '<button type="button" class="btn btn-success" onclick="send_amqp_message(privacy.geststatus)">Get Status</button> '+
// '</div>'+
// '</div>'
// ]
//
//
// var html = ['<hr>',
// '<div class="col-md-1 ">' +
// '<span class="label label-primary">' + title[index] + '</span>' +
// '</div>',
// cmds[index]
// ]
//
//
// console.log("Add testcase "+index)
//
// $("#p_tc").html(html)
$.get( "html/" + testcase, function( data ) {
$( "#p_tc").html( data );
console.log(testcase+ " added.")
});
}
......@@ -29,23 +29,28 @@
.console{
border: dotted 1px black;
background: #000000;
height: 300px;
padding:2%;
overflow-y:auto;
}
/*#alerts{*/
/*margin: 20px;*/
/*}*/
.amqp_msg{
padding-left: 2%;
padding-right: 2%;
}
footer {
padding: 25px;
padding: 10px;
bottom: 0;
width: 100%;
/* Set the fixed height of the footer here */
color: darkgrey;
background-color: black;
}
......@@ -99,7 +104,13 @@ footer {
}
.table-striped > tbody > tr:nth-child(2n+1) > td, .table-striped > tbody > tr:nth-child(2n+1) > th {
background-color: cadetblue;
}
.yellow
{
color:#f0ad4e !important;
}
\ No newline at end of file
}
<div class="jumbotron">
<div class="container">
<h1> Privacy Testing Tool - v.1.0.0 </h1>
<p> Lorem ipsum dolor sit amet, consectetur adipisci elit, sed eiusmod tempor incidunt ut
abore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrum exercitationem ullam
corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur. Quis aute iure
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim
id est laborum.
</p>
</div>
</div>
<div class="row" id="center-block">
</div> <!-- END ROW-->
\ No newline at end of file
......@@ -8,7 +8,8 @@
<link rel="stylesheet" href="{{ url_for('static', filename='style.css')}}">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js.cookie.js')}}"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.3/socket.io.js"></script>
<script type="text/javascript" src="{{ url_for('static', filename='gui.js')}}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='privacy.js')}}"></script>
......@@ -18,7 +19,7 @@
</script>
</head>
<body>
<body >
<nav class="navbar navbar-inverse">
<div class="container-fluid">
......@@ -32,9 +33,9 @@
</div>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li class="dropdown">
<li class="dropdown multi-level" id="message">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Messages <span class="caret"></span></a>
aria-expanded="false" onclick="showDetails('message')">Messages <span class="caret"></span></a>
<!--<ul class="dropdown-menu" id="utils_msg_list">-->
<ul class="dropdown-menu scrollable-menu"
role="menu"
......@@ -44,9 +45,11 @@
</ul>
</li>
<li class="dropdown">
<li class="dropdown" id="privacy">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false" onclick="showDetails('privacy')">Privacy TT <span class="caret"></span></a>
aria-expanded="false" onclick="showDetails('privacy')" >
Privacy TT <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="#" onclick="addTestCase('privacy_tc1')">Test Case 1</a></li>
<li><a href="#" onclick="addTestCase('privacy_tc2')">Test Case 2</a></li>
......@@ -58,7 +61,7 @@
<li><a href="#">Get Status</a></li>
</ul>
</li>
<li><a href="#">Orchestrator API</a></li>
<li id="orchestrator"><a href="#" onclick="showDetails('orchestrator')">Orchestrator API</a></li>
<li><a href="http://doc.f-interop.eu/">Docs</a></li>
</ul>
......@@ -109,8 +112,10 @@
</div>
</div>
</nav>
<div id="alerts"> </div>
<div class="jumbotron">
<div id="add_page_here" style="overflow: scroll">
<div class="container" id="info">
<h1>Demo GUI!</h1>
......@@ -121,17 +126,13 @@
</div>
</div>
<!--</div>-->
<div class="raw force-to-bottom">
<div class="navbar-fixed-bottom" >
<div<