refactoring to rest app, fixed removal of simple update state logic that was causing a loop for CoreClient

This commit is contained in:
Blake J. Harnden 2018-09-12 21:32:40 -07:00
parent 46730ce216
commit 2593d97cab
5 changed files with 77 additions and 162 deletions

View file

@ -20,6 +20,8 @@ public interface ICoreClient {
boolean start() throws IOException; boolean start() throws IOException;
void updateState(SessionState state);
boolean setState(SessionState state) throws IOException; boolean setState(SessionState state) throws IOException;
GetServices getServices() throws IOException; GetServices getServices() throws IOException;

View file

@ -158,6 +158,10 @@ public class CoreRestClient implements ICoreClient {
return setState(SessionState.INSTANTIATION); return setState(SessionState.INSTANTIATION);
} }
@Override
public void updateState(SessionState state) {
sessionState = state;
}
@Override @Override
public boolean setState(SessionState state) throws IOException { public boolean setState(SessionState state) throws IOException {

View file

@ -46,7 +46,7 @@ public class CoreWebSocket {
SessionState state = SessionState.get(event.getEventType().getValue()); SessionState state = SessionState.get(event.getEventType().getValue());
if (state != null) { if (state != null) {
logger.info("event updating session state: {}", state); logger.info("event updating session state: {}", state);
controller.getCoreClient().setState(state); controller.getCoreClient().updateState(state);
} }
} catch (IOException ex) { } catch (IOException ex) {
logger.error("error getting core event", ex); logger.error("error getting core event", ex);

View file

@ -3,6 +3,7 @@ import tempfile
from functools import wraps from functools import wraps
from threading import Lock from threading import Lock
from bottle import HTTPError
from flask import Flask from flask import Flask
from flask import jsonify from flask import jsonify
from flask import render_template from flask import render_template
@ -11,6 +12,7 @@ from flask import send_file
from flask_socketio import SocketIO from flask_socketio import SocketIO
from flask_socketio import emit from flask_socketio import emit
import core_utils
import mobility_routes import mobility_routes
from core import logger from core import logger
from core.emulator.coreemu import CoreEmu from core.emulator.coreemu import CoreEmu
@ -261,10 +263,7 @@ def delete_session(session_id):
@app.route("/sessions/<int:session_id>/options") @app.route("/sessions/<int:session_id>/options")
def get_session_options(session_id): def get_session_options(session_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session:
return jsonify(error="session does not exist"), 404
config = session.options.get_configs() config = session.options.get_configs()
config_options = [] config_options = []
@ -293,10 +292,7 @@ def get_session_options(session_id):
@app.route("/sessions/<int:session_id>/options", methods=["PUT"]) @app.route("/sessions/<int:session_id>/options", methods=["PUT"])
@synchronized @synchronized
def set_session_options(session_id): def set_session_options(session_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session:
return jsonify(error="session does not exist"), 404
data = request.get_json() or {} data = request.get_json() or {}
values = data["values"] values = data["values"]
config = {x["name"]: x["value"] for x in values} config = {x["name"]: x["value"] for x in values}
@ -306,9 +302,7 @@ def set_session_options(session_id):
@app.route("/sessions/<int:session_id>") @app.route("/sessions/<int:session_id>")
def get_session(session_id): def get_session(session_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session:
return jsonify(error="session does not exist"), 404
nodes = [] nodes = []
links = [] links = []
@ -347,10 +341,7 @@ def get_session(session_id):
@app.route("/sessions/<int:session_id>/hooks", methods=["POST"]) @app.route("/sessions/<int:session_id>/hooks", methods=["POST"])
def add_hook(session_id): def add_hook(session_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session:
return jsonify(error="session does not exist"), 404
data = request.get_json() or {} data = request.get_json() or {}
state = data["state"] state = data["state"]
file_name = data["file"] file_name = data["file"]
@ -361,9 +352,7 @@ def add_hook(session_id):
@app.route("/sessions/<int:session_id>/hooks") @app.route("/sessions/<int:session_id>/hooks")
def get_hooks(session_id): def get_hooks(session_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session:
return jsonify(error="session does not exist"), 404
hooks = [] hooks = []
for state, state_hooks in session._hooks.iteritems(): for state, state_hooks in session._hooks.iteritems():
@ -379,26 +368,16 @@ def get_hooks(session_id):
@app.route("/sessions/<int:session_id>/nodes/<node_id>/wlan") @app.route("/sessions/<int:session_id>/nodes/<node_id>/wlan")
def get_wlan_config(session_id, node_id): def get_wlan_config(session_id, node_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session: node_id = core_utils.get_node_id(node_id)
return jsonify(error="session does not exist"), 404
if node_id.isdigit():
node_id = int(node_id)
config = session.mobility.get_model_config(node_id, BasicRangeModel.name) config = session.mobility.get_model_config(node_id, BasicRangeModel.name)
return jsonify(config) return jsonify(config)
@app.route("/sessions/<int:session_id>/nodes/<node_id>/wlan", methods=["PUT"]) @app.route("/sessions/<int:session_id>/nodes/<node_id>/wlan", methods=["PUT"])
def set_wlan_config(session_id, node_id): def set_wlan_config(session_id, node_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session: node_id = core_utils.get_node_id(node_id)
return jsonify(error="session does not exist"), 404
if node_id.isdigit():
node_id = int(node_id)
config = request.get_json() or {} config = request.get_json() or {}
session.mobility.set_model_config(node_id, BasicRangeModel.name, config) session.mobility.set_model_config(node_id, BasicRangeModel.name, config)
return jsonify() return jsonify()
@ -407,12 +386,8 @@ def set_wlan_config(session_id, node_id):
@app.route("/sessions/<int:session_id>/emane/config", methods=["PUT"]) @app.route("/sessions/<int:session_id>/emane/config", methods=["PUT"])
@synchronized @synchronized
def set_emane_config(session_id): def set_emane_config(session_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session:
return jsonify(error="session does not exist"), 404
data = request.get_json() or {} data = request.get_json() or {}
node_id = data.get("node")
values = data["values"] values = data["values"]
config = {x["name"]: x["value"] for x in values} config = {x["name"]: x["value"] for x in values}
session.emane.set_configs(config) session.emane.set_configs(config)
@ -422,10 +397,7 @@ def set_emane_config(session_id):
@app.route("/sessions/<int:session_id>/emane/model/config", methods=["PUT"]) @app.route("/sessions/<int:session_id>/emane/model/config", methods=["PUT"])
@synchronized @synchronized
def set_emane_model_config(session_id): def set_emane_model_config(session_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session:
return jsonify(error="session does not exist"), 404
data = request.get_json() or {} data = request.get_json() or {}
model_name = data["name"] model_name = data["name"]
node_id = data.get("node") node_id = data.get("node")
@ -437,13 +409,7 @@ def set_emane_model_config(session_id):
@app.route("/sessions/<int:session_id>/emane/config") @app.route("/sessions/<int:session_id>/emane/config")
def get_emane_config(session_id): def get_emane_config(session_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session:
return jsonify(error="session does not exist"), 404
node_id = request.args.get("node")
if node_id.isdigit():
node_id = int(node_id)
config = session.emane.get_configs() config = session.emane.get_configs()
@ -472,13 +438,8 @@ def get_emane_config(session_id):
@app.route("/sessions/<int:session_id>/emane/model/config") @app.route("/sessions/<int:session_id>/emane/model/config")
def get_emane_model_config(session_id): def get_emane_model_config(session_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session: node_id = core_utils.get_node_id(request.args.get("node"))
return jsonify(error="session does not exist"), 404
node_id = request.args.get("node")
if node_id.isdigit():
node_id = int(node_id)
model_name = request.args["name"] model_name = request.args["name"]
model = session.emane.models[model_name] model = session.emane.models[model_name]
@ -509,9 +470,7 @@ def get_emane_model_config(session_id):
@app.route("/sessions/<int:session_id>/emane/models") @app.route("/sessions/<int:session_id>/emane/models")
def get_emane_models(session_id): def get_emane_models(session_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session:
return jsonify(error="session does not exist"), 404
models = [] models = []
for model in session.emane.models.keys(): for model in session.emane.models.keys():
@ -525,9 +484,7 @@ def get_emane_models(session_id):
@app.route("/sessions/<int:session_id>/nodes", methods=["POST"]) @app.route("/sessions/<int:session_id>/nodes", methods=["POST"])
@synchronized @synchronized
def create_node(session_id): def create_node(session_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session:
return jsonify(error="session does not exist"), 404
data = request.get_json() or {} data = request.get_json() or {}
node_id = data.get("id") node_id = data.get("id")
@ -561,15 +518,8 @@ def create_node(session_id):
@app.route("/sessions/<int:session_id>/nodes/<node_id>", methods=["PUT"]) @app.route("/sessions/<int:session_id>/nodes/<node_id>", methods=["PUT"])
@synchronized @synchronized
def edit_node(session_id, node_id): def edit_node(session_id, node_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session: node_id = core_utils.get_node_id(node_id)
return jsonify(error="session does not exist"), 404
if node_id.isdigit():
node_id = int(node_id)
node = session.objects.get(node_id)
if not node:
return jsonify(error="node does not exist"), 404
data = request.get_json() or {} data = request.get_json() or {}
@ -591,15 +541,8 @@ def edit_node(session_id, node_id):
@app.route("/sessions/<int:session_id>/nodes/<node_id>") @app.route("/sessions/<int:session_id>/nodes/<node_id>")
def get_node(session_id, node_id): def get_node(session_id, node_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session: node = core_utils.get_node(session, node_id)
return jsonify(error="session does not exist"), 404
if node_id.isdigit():
node_id = int(node_id)
node = session.objects.get(node_id)
if not node:
return jsonify(error="node does not exist"), 404
interfaces = [] interfaces = []
for interface_id, interface in node._netif.iteritems(): for interface_id, interface in node._netif.iteritems():
@ -635,34 +578,17 @@ def get_node(session_id, node_id):
@app.route("/sessions/<int:session_id>/nodes/<node_id>/terminal") @app.route("/sessions/<int:session_id>/nodes/<node_id>/terminal")
def node_terminal(session_id, node_id): def node_terminal(session_id, node_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session: node = core_utils.get_node(session, node_id)
return jsonify(error="session does not exist"), 404
if node_id.isdigit():
node_id = int(node_id)
node = session.objects.get(node_id)
if not node:
return jsonify(error="node does not exist"), 404
terminal_command = node.termcmdstring("/bin/bash") terminal_command = node.termcmdstring("/bin/bash")
return jsonify(terminal_command) return jsonify(terminal_command)
@app.route("/sessions/<int:session_id>/nodes/<node_id>", methods=["DELETE"]) @app.route("/sessions/<int:session_id>/nodes/<node_id>", methods=["DELETE"])
@synchronized @synchronized
def delete_node(session_id, node_id): def delete_node(session_id, node_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session: node_id = core_utils.get_node_id(node_id)
return jsonify(error="session does not exist"), 404
if node_id.isdigit():
node_id = int(node_id)
node = session.objects.get(node_id)
if not node:
return jsonify(error="node does not exist"), 404
result = session.delete_node(node_id) result = session.delete_node(node_id)
if result: if result:
return jsonify() return jsonify()
@ -673,12 +599,8 @@ def delete_node(session_id, node_id):
# TODO: this should just be a general service query # TODO: this should just be a general service query
@app.route("/sessions/<int:session_id>/nodes/<node_id>/services") @app.route("/sessions/<int:session_id>/nodes/<node_id>/services")
def get_node_services(session_id, node_id): def get_node_services(session_id, node_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session: node_id = core_utils.get_node_id(node_id)
return jsonify(error="session does not exist"), 404
if node_id.isdigit():
node_id = int(node_id)
services = {} services = {}
for service in ServiceManager.services.itervalues(): for service in ServiceManager.services.itervalues():
@ -690,12 +612,8 @@ def get_node_services(session_id, node_id):
@app.route("/sessions/<int:session_id>/nodes/<node_id>/services/<service_name>") @app.route("/sessions/<int:session_id>/nodes/<node_id>/services/<service_name>")
def get_node_service(session_id, node_id, service_name): def get_node_service(session_id, node_id, service_name):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session: node_id = core_utils.get_node_id(node_id)
return jsonify(error="session does not exist"), 404
if node_id.isdigit():
node_id = int(node_id)
service = session.services.get_service(node_id, service_name, default_service=True) service = session.services.get_service(node_id, service_name, default_service=True)
service_config = { service_config = {
@ -715,15 +633,8 @@ def get_node_service(session_id, node_id, service_name):
@app.route("/sessions/<int:session_id>/nodes/<node_id>/services/<service_name>", methods=["PUT"]) @app.route("/sessions/<int:session_id>/nodes/<node_id>/services/<service_name>", methods=["PUT"])
def set_node_service(session_id, node_id, service_name): def set_node_service(session_id, node_id, service_name):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session: node_id = core_utils.get_node_id(node_id)
return jsonify(error="session does not exist"), 404
if node_id.isdigit():
node_id = int(node_id)
node = session.objects.get(node_id)
if not node:
return jsonify(error="node does not exist"), 404
data = request.get_json() or {} data = request.get_json() or {}
@ -742,15 +653,8 @@ def set_node_service(session_id, node_id, service_name):
@app.route("/sessions/<int:session_id>/nodes/<node_id>/services/<service_name>/file") @app.route("/sessions/<int:session_id>/nodes/<node_id>/services/<service_name>/file")
def get_node_service_file(session_id, node_id, service_name): def get_node_service_file(session_id, node_id, service_name):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session: node = core_utils.get_node(session, node_id)
return jsonify(error="session does not exist"), 404
if node_id.isdigit():
node_id = int(node_id)
node = session.objects.get(node_id)
if not node:
return jsonify(error="node does not exist"), 404
# get custom service file or default # get custom service file or default
service_file = request.args["file"] service_file = request.args["file"]
@ -760,15 +664,8 @@ def get_node_service_file(session_id, node_id, service_name):
@app.route("/sessions/<int:session_id>/nodes/<node_id>/services/<service>/file", methods=["PUT"]) @app.route("/sessions/<int:session_id>/nodes/<node_id>/services/<service>/file", methods=["PUT"])
def set_node_service_file(session_id, node_id, service): def set_node_service_file(session_id, node_id, service):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session: node_id = core_utils.get_node_id(node_id)
return jsonify(error="session does not exist"), 404
if node_id.isdigit():
node_id = int(node_id)
node = session.objects.get(node_id)
if not node:
return jsonify(error="node does not exist"), 404
data = request.get_json() or {} data = request.get_json() or {}
file_name = data["name"] file_name = data["name"]
@ -780,9 +677,7 @@ def set_node_service_file(session_id, node_id, service):
@app.route("/sessions/<int:session_id>/state", methods=["PUT"]) @app.route("/sessions/<int:session_id>/state", methods=["PUT"])
@synchronized @synchronized
def set_session_state(session_id): def set_session_state(session_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session:
return jsonify(error="session does not exist"), 404
data = request.get_json() data = request.get_json()
try: try:
@ -809,9 +704,7 @@ def set_session_state(session_id):
@app.route("/sessions/<int:session_id>/links", methods=["POST"]) @app.route("/sessions/<int:session_id>/links", methods=["POST"])
@synchronized @synchronized
def add_link(session_id): def add_link(session_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session:
return jsonify(error="session does not exist"), 404
data = request.get_json() data = request.get_json()
logger.info("adding link: %s", data) logger.info("adding link: %s", data)
@ -873,9 +766,7 @@ def add_link(session_id):
@app.route("/sessions/<int:session_id>/links", methods=["PUT"]) @app.route("/sessions/<int:session_id>/links", methods=["PUT"])
@synchronized @synchronized
def edit_link(session_id): def edit_link(session_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session:
return jsonify(error="session does not exist"), 404
data = request.get_json() data = request.get_json()
@ -907,10 +798,7 @@ def edit_link(session_id):
@app.route("/sessions/<int:session_id>/links", methods=["DELETE"]) @app.route("/sessions/<int:session_id>/links", methods=["DELETE"])
@synchronized @synchronized
def delete_link(session_id): def delete_link(session_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session:
return jsonify(error="session does not exist"), 404
data = request.get_json() data = request.get_json()
node_one = data.get("node_one") node_one = data.get("node_one")
node_two = data.get("node_two") node_two = data.get("node_two")
@ -922,15 +810,8 @@ def delete_link(session_id):
@app.route("/sessions/<int:session_id>/nodes/<node_id>/links") @app.route("/sessions/<int:session_id>/nodes/<node_id>/links")
def get_node_links(session_id, node_id): def get_node_links(session_id, node_id):
session = coreemu.sessions.get(session_id) session = core_utils.get_session(coreemu, session_id)
if not session: node = core_utils.get_node(session, node_id)
return jsonify(error="session does not exist"), 404
if node_id.isdigit():
node_id = int(node_id)
node = session.objects.get(node_id)
if not node:
return jsonify(error="node does not exist"), 404
links_data = node.all_link_data(0) links_data = node.all_link_data(0)
links = [] links = []
@ -948,5 +829,10 @@ def get_node_links(session_id, node_id):
return jsonify(links=links) return jsonify(links=links)
@app.errorhandler(HTTPError)
def handle_error(e):
return jsonify(message=e.body, status=e.status_code), e.status_code
if __name__ == "__main__": if __name__ == "__main__":
socketio.run(app, host="0.0.0.0", debug=True) socketio.run(app, host="0.0.0.0", debug=True)

23
webapp/core_utils.py Normal file
View file

@ -0,0 +1,23 @@
from bottle import abort
def get_session(coreemu, session_id):
session = coreemu.sessions.get(session_id)
if not session:
abort(404, "session does not exist")
return session
def get_node(session, node_id):
if node_id.isdigit():
node_id = int(node_id)
node = session.objects.get(node_id)
if not node:
abort(404, "node does not exist")
return node
def get_node_id(node_id):
if node_id.isdigit():
node_id = int(node_id)
return node_id