Commit 82868958 authored by Luciano Orsini's avatar Luciano Orsini
Browse files

references #259: restful support package

parent b5a6f822
# $Id$
#########################################################################
# XDAQ Components for Distributed Data Acquisition #
# Copyright (C) 2000-2019, CERN. #
# All rights reserved. #
# Authors: J. Gutleber, L. Orsini and D. Simelevicius #
# #
# For the licensing terms see LICENSE. #
# For the list of contributors see CREDITS. #
#########################################################################
##
#
# This is the cmsos/worksuite/extern/libhttpserver
#
##
#
# Packages to be built
#
BUILD_HOME:=$(shell pwd)/../..
BUILD_SUPPORT=build
PROJECT_NAME=worksuite
include $(XDAQ_ROOT)/$(BUILD_SUPPORT)/mfAutoconf.rules
include $(XDAQ_ROOT)/$(BUILD_SUPPORT)/mfDefs.$(XDAQ_OS)
Project=$(PROJECT_NAME)
Package=extern/libhttpserver
PackageName=libhttpserver
PACKAGE_VER_MAJOR=0
PACKAGE_VER_MINOR=18
PACKAGE_VER_PATCH=2
Summary=libhttpserver is a C++ library for building high performance RESTful web servers
Description=libhttpserver is built upon libmicrohttpd to provide a simple API for developers to create HTTP services in C++
Link=https://github.com/etr/libhttpserver
export CC
export CXX
LD:=$(LDD)
export LD
build: _buildall
_buildall: all
_all: all
default: all
$(PACKING_DIR)/configure:
-rm -rf $(XDAQ_PLATFORM)
tar -xvf 0.18.2.tar.gz
rm -rf $(PACKING_DIR)
mv libhttpserver-0.18.2 $(PACKING_DIR)
all: $(PACKING_DIR)/configure
cd $(PACKING_DIR); ./bootstrap; mkdir build; cd build; \
../configure --enable-debug --prefix=$(BUILD_HOME)/$(Package)/$(XDAQ_PLATFORM) --exec-prefix=$(BUILD_HOME)/$(Package)/$(XDAQ_PLATFORM); \
make; make install
_installall: install
install: $(PACKING_DIR)/configure
cd $(PACKING_DIR); ./bootstrap; mkdir build; cd build; \
./configure --enable-debug --prefix=$(INSTALL_PREFIX)/$(XDAQ_PLATFORM) --exec-prefix=$(INSTALL_PREFIX)/$(XDAQ_PLATFORM); \
make; make install
_cleanall: clean
clean:
-rm -rf $(XDAQ_PLATFORM)
-rm -rf $(PACKING_DIR)
include $(XDAQ_ROOT)/$(BUILD_SUPPORT)/mfExternRPM.rules
#Required packages
libtool
libhttpdmicro-devel
BUILD_HOME:=$(shell pwd)/..
BUILD_SUPPORT=build
PROJECT_NAME=worksuite
include $(XDAQ_ROOT)/$(BUILD_SUPPORT)/mfAutoconf.rules
include $(XDAQ_ROOT)/$(BUILD_SUPPORT)/mfDefs.$(XDAQ_OS)
include $(BUILD_HOME)/mfDefs.$(PROJECT_NAME)
#
# Package to be built
#
Project=$(PROJECT_NAME)
Package=restate
#
# Source files
#
Sources=$(wildcard src/common/*.cc)
#
# Include directories
#
IncludeDirs = \
/usr/include/tirpc
DependentLibraryDirs = $(DIP_LIB_PREFIX)
DependentLibraries = microhttpd httpserver
LibraryDirs =
UserSourcePath =
UserCFlags =
UserCCFlags =
UserDynamicLinkFlags =
UserStaticLinkFlags =
UserExecutableLinkFlags =
# These libraries can be platform specific and
# potentially need conditional processing
#
Libraries =
ExternalObjects =
#
# Compile the source files and create a shared library
#
DynamicLibrary=restate
StaticLibrary=
TestLibraryDirs = $(XDAQ_ROOT)/lib $(XDAQ_ROOT)/lib64
include $(XDAQ_ROOT)/$(BUILD_SUPPORT)/Makefile.rules
include $(XDAQ_ROOT)/$(BUILD_SUPPORT)/mfRPM.rules
Run example
# To run these co-existing with hyperdaq , shall remove fake soap
/opt/xdaq/bin/xdaq.exe -e /nfshome0/lorsini/devel/localbus/worksuite/restate/xml/restate.profile -c /nfshome0/lorsini/devel/localbus/worksuite/restate/xml/service.configuration
/opt/xdaq/bin/xdaq.exe -c /nfshome0/lorsini/devel/localbus/worksuite/restate/xml/restate.configuration
# XDAQ restate approach (no hyperdaq, no soap, no configuration, no cgi )
/opt/xdaq/bin/xdaq.exe -e /nfshome0/lorsini/devel/localbus/worksuite/restate/xml/service.profile -l DEBUG
Example of restful paramater get that return json value
path
/api
path
/api/application/{lid|[0-9]+}/{parameter}
curl -v "http://xdaqdev1.cms:8080/api/application/1/readiness"
curl -v "http://xdaqdev1.cms:8080/api/application/1/documentRoot"
curl -v "http://xdaqdev1.cms:8080/api/application/1/descriptor"
path
/api/service/{name}/{parameter}
curl -v "http://xdaqdev1.cms:8080/api/service/pthttp/responseTimeout"
curl -v "http://xdaqdev1.cms:8080/api/service/executive/liveness"
Generic rest path for user application
https://riptutorial.com/cplusplus/example/7541/std--function-used-with-std--bind
// $Id$
/*************************************************************************
* XDAQ Components for Distributed Data Acquisition *
* Copyright (C) 2000-2021, CERN. *
* All rights reserved. *
* Authors: L. Orsini, D. Simelevicius *
* *
* For the licensing terms see LICENSE. *
* For the list of contributors see CREDITS. *
*************************************************************************/
#ifndef _restate_Address_h
#define _restate_Address_h
#include "pt/Address.h"
#include "toolbox/net/URL.h"
#include <netinet/in.h>
#include "pt/exception/InvalidAddress.h"
namespace restate
{
class Address: public pt::Address
{
public:
//! Create address from url
Address (const std::string& url, const std::string & service) ;
virtual ~Address ();
//! Get the URL protocol, e.g. http
std::string getProtocol();
//! Get the URL service if it exists, e.g. SyncSOAP
std::string getService();
//! Get additional parameters at the end of the URL
std::string getServiceParameters();
//! Return the URL in string form
std::string toString();
//! Get the host part of the url
std::string getHost();
//! Get the port number of the url if it exists
std::string getPort();
//! Get the url provided in the constructor
std::string getURL();
//! Get the path
std::string getPath();
//! Get the IP representation of the hostname/port address combination
struct sockaddr_in getSocketAddress() ;
//! Compare with another address
bool equals( pt::Address::Reference address );
protected:
toolbox::net::URL * url_;
std::string service_;
};
}
#endif
// $Id$
/*************************************************************************
* XDAQ Components for Distributed Data Acquisition *
* Copyright (C) 2000-2021, CERN. *
* All rights reserved. *
* Authors: L. Orsini, D. Simelevicius *
* *
* For the licensing terms see LICENSE. *
* For the list of contributors see CREDITS. *
*************************************************************************/
#ifndef _restate_Application_h_
#define _restate_Application_h_
#include "xdaq/Application.h"
#include "xdata/ActionListener.h"
#include "xdata/UnsignedInteger.h"
#include "toolbox/ActionListener.h"
#include "restate/api.h"
#include "pt/PeerTransportSender.h"
#include "pt/PeerTransportReceiver.h"
namespace restate
{
class Application: public xdaq::Application, public xdata::ActionListener, public toolbox::ActionListener, public pt::PeerTransportReceiver
{
public:
XDAQ_INSTANTIATOR();
Application(xdaq::ApplicationStub* s);
~Application();
void actionPerformed(xdata::Event& e);
void actionPerformed(toolbox::Event& event);
// pt support
pt::TransportType getType ();
pt::Address::Reference createAddress (const std::string& url, const std::string& service) ;
pt::Address::Reference createAddress (std::map<std::string, std::string, std::less<std::string> > & address) ;
std::string getProtocol ();
std::vector<std::string> getSupportedServices ();
bool isServiceSupported (const std::string & service);
void addServiceListener (pt::Listener * listener) ;
void removeServiceListener (pt::Listener * listener) ;
void removeAllServiceListeners ();
void config (pt::Address::Reference address) ;
protected:
std::list<httpserver::webserver *> servers_;
};
}
#endif
// $Id$
/*************************************************************************
* XDAQ Components for Distributed Data Acquisition *
* Copyright (C) 2000-2021, CERN. *
* All rights reserved. *
* Authors: L. Orsini, D. Simelevicius *
* *
* For the licensing terms see LICENSE. *
* For the list of contributors see CREDITS. *
*************************************************************************/
#ifndef _restate_Service_h_
#define _restate_Service_h_
#include "xdaq/Application.h"
#include "restate/api.h"
namespace restate
{
class Service: public xdaq::Application
{
public:
XDAQ_INSTANTIATOR();
Service(xdaq::ApplicationStub* s);
~Service();
const std::shared_ptr<restate::response> render(const restate::request&);
};
}
#endif
// $Id$
/*************************************************************************
* XDAQ Components for Distributed Data Acquisition *
* Copyright (C) 2000-2021, CERN. *
* All rights reserved. *
* Authors: L. Orsini, D. Simelevicius *
* *
* For the licensing terms see LICENSE. *
* For the list of contributors see CREDITS. *
*************************************************************************/
#ifndef _restate_api_h_
#define _restate_api_h_
#include <httpserver.hpp>
namespace restate
{
//typedef httpserver::http_resource resource;
//typedef httpserver::http_request request;
//typedef httpserver::http_response response;
//typedef httpserver::string_response string;
using resource = httpserver::http_resource;
using request = httpserver::http_request;
using response = httpserver::http_response;
using string = httpserver::string_response;
void register_resource(const std::string & path, const std::function<std::shared_ptr<restate::response>(const restate::request&)> & r);
}
#endif
// $Id$
/*************************************************************************
* XDAQ Components for Distributed Data Acquisition *
* Copyright (C) 2000-2021, CERN. *
* All rights reserved. *
* Authors: L. Orsini, D. Simelevicius *
* *
* For the licensing terms see LICENSE. *
* For the list of contributors see CREDITS. *
*************************************************************************/
#ifndef _restate_version_h_
#define _restate_version_h_
#include "config/PackageInfo.h"
// !!! Edit this line to reflect the latest package version !!!
#define WORKSUITE_RESTATE_VERSION_MAJOR 1
#define WORKSUITE_RESTATE_VERSION_MINOR 0
#define WORKSUITE_RESTATE_VERSION_PATCH 0
// If any previous versions available E.g. #define ESOURCE_PREVIOUS_VERSIONS "3.8.0,3.8.1"
#undef WORKSUITE_RESTATE_PREVIOUS_VERSIONS
//
// Template macros
//
#define WORKSUITE_RESTATE_VERSION_CODE PACKAGE_VERSION_CODE(WORKSUITE_RESTATE_VERSION_MAJOR,WORKSUITE_RESTATE_VERSION_MINOR,WORKSUITE_RESTATE_VERSION_PATCH)
#ifndef WORKSUITE_RESTATE_PREVIOUS_VERSIONS
#define WORKSUITE_RESTATE_FULL_VERSION_LIST PACKAGE_VERSION_STRING(WORKSUITE_RESTATE_VERSION_MAJOR,WORKSUITE_RESTATE_VERSION_MINOR,WORKSUITE_RESTATE_VERSION_PATCH)
#else
#define WORKSUITE_RESTATE_FULL_VERSION_LIST WORKSUITE_RESTATE_PREVIOUS_VERSIONS "," PACKAGE_VERSION_STRING(WORKSUITE_RESTATE_VERSION_MAJOR,WORKSUITE_RESTATE_VERSION_MINOR,WORKSUITE_RESTATE_VERSION_PATCH)
#endif
namespace restate
{
const std::string project = "worksuite";
const std::string package = "restate";
const std::string versions = WORKSUITE_RESTATE_FULL_VERSION_LIST;
const std::string summary = "XDAQ restate";
const std::string description = "restate";
const std::string authors = " ";
const std::string link = "http://xdaq.web.cern.ch";
config::PackageInfo getPackageInfo ();
void checkPackageDependencies ();
std::set<std::string, std::less<std::string> > getPackageDependencies ();
}
#endif
// $Id$
/*************************************************************************
* XDAQ Components for Distributed Data Acquisition *
* Copyright (C) 2000-2021, CERN. *
* All rights reserved. *
* Authors: L. Orsini, D. Simelevicius *
* *
* For the licensing terms see LICENSE. *
* For the list of contributors see CREDITS. *
*************************************************************************/
#include <iostream>
#include <sstream>
#include "restate/Address.h"
#include "toolbox/net/URL.h"
#include "toolbox/net/Utils.h"
#include "toolbox/exception/Exception.h"
#include "toolbox/net/exception/MalformedURL.h"
// only for debugging inet_ntoa
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
restate::Address::Address(const std::string& url, const std::string & service)
{
try
{
url_ = new toolbox::net::URL(url);
} catch (toolbox::net::exception::MalformedURL& mfu)
{
XCEPT_RETHROW (pt::exception::InvalidAddress, "Cannot create http address", mfu);
}
if ((url_->getProtocol()) != "http")
{
std::string msg = "Cannot create pt::http address from url ";
msg += url;
msg += ", unsupported protocol";
XCEPT_RAISE (pt::exception::InvalidAddress, msg.c_str());
}
if ( ( service != "restful" ) && ( service != "soap" ) )
{
std::string msg = "Cannot create pt::http address from url ";
msg += url;
msg += ", unsupported service ";
msg += service;
XCEPT_RAISE (pt::exception::InvalidAddress, msg.c_str());
}
service_ = service;
}
restate::Address::~Address()
{
delete url_;
}
struct sockaddr_in restate::Address::getSocketAddress()
{
struct sockaddr_in writeAddr;
try
{
writeAddr = toolbox::net::getSocketAddressByName (url_->getHost(), url_->getPort());
//cout << "port number " << writeAddr.sin_port << endl;
//cout << "IP addressin host format: " << inet_ntoa(writeAddr.sin_addr) << endl;
} catch (toolbox::exception::Exception& e)
{
XCEPT_RETHROW (pt::exception::InvalidAddress, "Cannot retrieve socket address from http address", e);
}
return writeAddr;
}
std::string restate::Address::getService()
{
return service_;
}
std::string restate::Address::getProtocol()
{
return url_->getProtocol();
}
std::string restate::Address::toString()
{
return url_->toString();
}
std::string restate::Address::getURL()
{
return url_->toString();
}
std::string restate::Address::getHost()
{
return url_->getHost();
}
std::string restate::Address::getPort()
{
std::ostringstream o;
if(url_->getPort() > 0)
o << url_->getPort();
return o.str();
}
std::string restate::Address::getPath()
{
std::string path = url_->getPath();
if ( path.empty() ) {
return "/";
}
else
{
if ( path[0] == '/' )
{
return path;
}
else
{
path.insert(0,"/");
return path;
}
}
}
std::string restate::Address::getServiceParameters()
{
return url_->getPath();
}
bool restate::Address::equals( pt::Address::Reference address )
{
return (( this->toString() == address->toString()) && ( this->getService() == address->getService()));
}
<
// $Id$
/*
*************************************************************************
* XDAQ Components for Distributed Data Acquisition *
* Copyright (C) 2000-2021, CERN. *
* All rights reserved. *
* Authors: L. Orsini, D. Simelevicius *
* *
* For the licensing terms see LICENSE. *
* For the list of contributors see CREDITS. *
*************************************************************************
*/
#include "xcept/tools.h"
#include "cgicc/CgiDefs.h"
#include "cgicc/Cgicc.h"
#include "cgicc/HTTPHTMLHeader.h"
#include "cgicc/HTMLClasses.h"
#include "xgi/framework/UIManager.h"
#include "xgi/framework/Method.h"
#include "restate/Application.h"
#include "httpserver.hpp"
#include <nlohmann/json.hpp>
#include "xdata/json/Serializer.h"
#include "xdaq/ApplicationRegistry.h"
#include "restate/Address.h"
#include "pt/PeerTransportAgent.h"
class root_resource : public httpserver::http_resource {
public:
root_resource(restate::Application & a): application(a){}
const std::shared_ptr<httpserver::http_response> render(const httpserver::http_request& r)
{
if ( r.get_path() == "/" )
{
std::stringstream page;
page << "<!DOCTYPE html>" << "<html><head><title>Restate application</title></head>";
page << "<link rel=\"shortcut icon\" href=\"data:image/x-icon;,\" type=\"image/x-icon\">";
page << "<body>/api to show all paths available</body></html>";