Changeset - a71462650e8f
[Not reviewed]
0 2 2
Jan Kaluza - 9 years ago 2016-01-18 14:43:37
jkaluza@redhat.com
manager: /api/v1/instances returns the list of instances
4 files changed with 191 insertions and 28 deletions:
0 comments (0 inline, 0 general)
spectrum_manager/src/APIServer.cpp
Show inline comments
 
new file 100644
 
#include "APIServer.h"
 
#include "methods.h"
 

	
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <assert.h>
 
#include <string.h>
 
#include <time.h>
 
#include <stdarg.h>
 
#include <pthread.h>
 
#include <fstream>
 
#include <string>
 
#include <cerrno>
 

	
 
static std::string get_http_var(const struct http_message *hm, const char *name) {
 
	char data[4096];
 
	data[0] = '\0';
 

	
 
	mg_get_http_var(&hm->body, name, data, sizeof(data));
 
	if (data[0] != '\0') {
 
		return data;
 
	}
 

	
 
	mg_get_http_var(&hm->query_string, name, data, sizeof(data));
 
	if (data[0] != '\0') {
 
		return data;
 
	}
 

	
 
	return "";
 
}
 

	
 
APIServer::APIServer(ManagerConfig *config, StorageBackend *storage) {
 
	m_config = config;
 
	m_storage = storage;
 
}
 

	
 
APIServer::~APIServer() {
 
}
 

	
 
void APIServer::send_json(struct mg_connection *conn, const std::string &json) {
 
	mg_printf(conn,
 
			"HTTP/1.1 200 OK\r\n"
 
			"Content-Type: text/json\r\n"
 
			"Content-Length: %d\r\n"
 
			"\r\n"
 
			"%s",
 
			(int) json.size(), json.c_str());
 
}
 

	
 
void APIServer::serve_instances(Server *server, Server::session *session, struct mg_connection *conn, struct http_message *hm) {
 
// 	std::string jid = get_http_var(hm, "jid");
 
// 	if (!jid.empty()) {
 
// 		serve_instance(conn, hm, jid);
 
// 		return;
 
// 	}
 

	
 
	std::vector<std::string> list = show_list(m_config, false);
 

	
 
	std::string json = "{\"error\":0, \"instances\": [";
 

	
 
	BOOST_FOREACH(std::string &instance, list) {
 
		json += "{";
 
		json += "\"id\":\"" + instance + "\",";
 
		json += "\"name\":\"" + instance + "\",";
 

	
 
		std::string status = server->send_command(instance, "status");
 
		if (status.empty()) {
 
			status = "Cannot get the instance status.";
 
		}
 
		else if (*(status.end() - 1) == '\n') {
 
			status.erase(status.end() - 1);
 
		}
 
		json += "\"status\":\"" + status + "\"";
 
		json += "},";
 
	}
 
	json.erase(json.end() - 1);
 

	
 
	json += "]}";
 
	send_json(conn, json);
 
}
 

	
 
void APIServer::handleRequest(Server *server, Server::session *sess, struct mg_connection *conn, struct http_message *hm) {
 
	if (mg_vcmp(&hm->uri, "/api/v1/instances") == 0) {
 
		serve_instances(server, sess, conn, hm);
 
	}
 
}
 

	
 

	
 

	
 

	
 

	
 

	
spectrum_manager/src/APIServer.h
Show inline comments
 
new file 100644
 
/**
 
 * libtransport -- C++ library for easy XMPP Transports development
 
 *
 
 * Copyright (C) 2016, Jan Kaluza <hanzz.k@gmail.com>
 
 *
 
 * This program is free software; you can redistribute it and/or modify
 
 * it under the terms of the GNU General Public License as published by
 
 * the Free Software Foundation; either version 2 of the License, or
 
 * (at your option) any later version.
 
 *
 
 * This program is distributed in the hope that it will be useful,
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 * GNU General Public License for more details.
 
 *
 
 * You should have received a copy of the GNU General Public License
 
 * along with this program; if not, write to the Free Software
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
 
 */
 

	
 
#pragma once
 

	
 
#include <boost/program_options.hpp>
 
#include <boost/foreach.hpp>
 
#include <boost/format.hpp>
 
#include <boost/algorithm/string.hpp>
 
#include <boost/assign.hpp>
 
#include <boost/bind.hpp>
 
#include <boost/signal.hpp>
 

	
 
#include "mongoose.h"
 
#include "managerconfig.h"
 
#include "server.h"
 

	
 
#include "transport/Config.h"
 
#include "transport/SQLite3Backend.h"
 
#include "transport/MySQLBackend.h"
 
#include "transport/PQXXBackend.h"
 
#include "transport/StorageBackend.h"
 

	
 
using namespace Transport;
 

	
 
class APIServer {
 
	public:
 
		APIServer(ManagerConfig *config, StorageBackend *storage);
 

	
 
		virtual ~APIServer();
 

	
 
		void handleRequest(Server *server, Server::session *sess, struct mg_connection *conn, struct http_message *hm);
 

	
 
	private:
 
		void serve_instances(Server *server, Server::session *sess, struct mg_connection *conn, struct http_message *hm);
 
		void send_json(struct mg_connection *conn, const std::string &json);
 

	
 
	private:
 
		ManagerConfig *m_config;
 
		StorageBackend *m_storage;
 
};
spectrum_manager/src/server.cpp
Show inline comments
 
#include "APIServer.h"
 
#include "server.h"
 
#include "methods.h"
 

	
 
@@ -99,9 +100,13 @@ Server::Server(ManagerConfig *config, const std::string &config_file) {
 
		m_storage = NULL;
 
		std::cerr << "Can't connect to database!\n";
 
	}
 

	
 
	m_apiServer = new APIServer(config, m_storage);
 
}
 

	
 
Server::~Server() {
 
	delete m_apiServer;
 

	
 
	mg_mgr_free(&m_mgr);
 
	if (m_storage) {
 
		delete m_storage;
 
@@ -173,9 +178,10 @@ void Server::authorize(struct mg_connection *conn, struct http_message *hm) {
 
		mg_printf(conn, "HTTP/1.1 302 Found\r\n"
 
			"Set-Cookie: session=%s; max-age=3600; http-only\r\n"  // Session ID
 
			"Set-Cookie: user=%s\r\n"  // Set user, needed by Javascript code
 
			"Set-Cookie: admin=%s\r\n"  // Set user, needed by Javascript code
 
			"Set-Cookie: original_url=/; max-age=0\r\n"  // Delete original_url
 
			"Location: /\r\n\r\n",
 
			session->session_id, session->user);
 
			session->session_id, session->user, session->admin ? "1" : "0");
 
	} else {
 
		// Authentication failure, redirect to login.
 
		redirect_to(conn, hm, "/login");
 
@@ -312,9 +318,10 @@ void Server::serve_cmd(struct mg_connection *conn, struct http_message *hm) {
 
void Server::serve_logout(struct mg_connection *conn, struct http_message *hm) {
 
	Server:session *session = get_session(hm);
 
	mg_printf(conn, "HTTP/1.1 302 Found\r\n"
 
		"Set-Cookie: session=%s; max-age=0\r\n"  // Session ID
 
		"Set-Cookie: session=%s; max-age=0\r\n"
 
		"Set-Cookie: admin=%s; max-age=0\r\n"
 
		"Location: /\r\n\r\n",
 
		session->session_id);
 
		session->session_id, session->admin ? "1" : "0");
 

	
 
	sessions.erase(session->session_id);
 
	delete session;
 
@@ -675,32 +682,34 @@ void Server::event_handler(struct mg_connection *conn, int ev, void *p) {
 
		redirect_to(conn, hm, "/login");
 
	} else if (mg_vcmp(&hm->uri, "/authorize") == 0) {
 
		authorize(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/") == 0) {
 
		serve_instances(conn, hm);
 
// 	} else if (mg_vcmp(&hm->uri, "/") == 0) {
 
// 		serve_instances(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/logout") == 0) {
 
		serve_logout(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/instances") == 0) {
 
		serve_instances(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/onlineusers") == 0) {
 
		serve_onlineusers(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/cmd") == 0) {
 
		serve_cmd(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/instances/start") == 0) {
 
		serve_instances_start(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/instances/stop") == 0) {
 
		serve_instances_stop(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/instances/register") == 0) {
 
		serve_instances_register(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/instances/unregister") == 0) {
 
		serve_instances_unregister(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/users") == 0) {
 
		serve_users(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/users/add") == 0) {
 
		serve_users_add(conn, hm);
 
	} else if (mg_vcmp(&hm->uri, "/users/remove") == 0) {
 
		serve_users_remove(conn, hm);
 
// 	} else if (mg_vcmp(&hm->uri, "/instances") == 0) {
 
// 		serve_instances(conn, hm);
 
// 	} else if (mg_vcmp(&hm->uri, "/onlineusers") == 0) {
 
// 		serve_onlineusers(conn, hm);
 
// 	} else if (mg_vcmp(&hm->uri, "/cmd") == 0) {
 
// 		serve_cmd(conn, hm);
 
// 	} else if (mg_vcmp(&hm->uri, "/instances/start") == 0) {
 
// 		serve_instances_start(conn, hm);
 
// 	} else if (mg_vcmp(&hm->uri, "/instances/stop") == 0) {
 
// 		serve_instances_stop(conn, hm);
 
// 	} else if (mg_vcmp(&hm->uri, "/instances/register") == 0) {
 
// 		serve_instances_register(conn, hm);
 
// 	} else if (mg_vcmp(&hm->uri, "/instances/unregister") == 0) {
 
// 		serve_instances_unregister(conn, hm);
 
// 	} else if (mg_vcmp(&hm->uri, "/users") == 0) {
 
// 		serve_users(conn, hm);
 
// 	} else if (mg_vcmp(&hm->uri, "/users/add") == 0) {
 
// 		serve_users_add(conn, hm);
 
// 	} else if (mg_vcmp(&hm->uri, "/users/remove") == 0) {
 
// 		serve_users_remove(conn, hm);
 
	} else if (has_prefix(&hm->uri, "/oauth2")) {
 
		serve_oauth2(conn, hm);
 
	} else if (has_prefix(&hm->uri, "/api/v1/")) {
 
		m_apiServer->handleRequest(this, get_session(hm), conn, hm);
 
	} else {
 
		mg_serve_http(conn, hm, s_http_server_opts);
 
	}
spectrum_manager/src/server.h
Show inline comments
 
@@ -39,6 +39,8 @@
 

	
 
using namespace Transport;
 

	
 
class APIServer;
 

	
 
class Server {
 
	public:
 
		struct session {
 
@@ -59,6 +61,10 @@ class Server {
 

	
 
		void event_handler(struct mg_connection *nc, int ev, void *p);
 

	
 
		void redirect_to(struct mg_connection *conn, struct http_message *hm, const char *where);
 

	
 
		std::string send_command(const std::string &jid, const std::string &cmd);
 

	
 
	private:
 
		void serve_instance(struct mg_connection *conn, struct http_message *hm, const std::string &jid);
 
		void serve_instances(struct mg_connection *conn, struct http_message *hm);
 
@@ -74,7 +80,6 @@ class Server {
 
		void serve_cmd(struct mg_connection *conn, struct http_message *hm);
 
		void serve_oauth2(struct mg_connection *conn, struct http_message *hm);
 
		void print_html(struct mg_connection *conn, struct http_message *hm, const std::string &html);
 
		std::string send_command(const std::string &jid, const std::string &cmd);
 

	
 
	private:
 
		bool check_password(const std::string &user, const std::string &password);
 
@@ -85,8 +90,6 @@ class Server {
 

	
 
		bool is_authorized(const struct mg_connection *conn, struct http_message *hm);
 

	
 
		void redirect_to(struct mg_connection *conn, struct http_message *hm, const char *where);
 

	
 
	private:
 
		struct mg_mgr m_mgr;
 
		struct mg_connection *m_nc;
 
@@ -99,4 +102,5 @@ class Server {
 
		std::string m_footer;
 
		Config *m_storageCfg;
 
		StorageBackend *m_storage;
 
		APIServer *m_apiServer;
 
};
0 comments (0 inline, 0 general)