diff options
Diffstat (limited to 'docs/usecases/webapp.md')
-rw-r--r-- | docs/usecases/webapp.md | 274 |
1 files changed, 0 insertions, 274 deletions
diff --git a/docs/usecases/webapp.md b/docs/usecases/webapp.md deleted file mode 100644 index 3b1a3b7b5b7..00000000000 --- a/docs/usecases/webapp.md +++ /dev/null @@ -1,274 +0,0 @@ -Building VPP web applications -============================= - -Vpp includes a versatile http/https "static" server plugin. We quote -the word static in the previous sentence because the server is easily -extended. This note describes how to build a Hugo site which includes -both monitoring and control functions. - -Let's assume that we have a vpp data-plane plugin which needs a -monitoring and control web application. Here's how to build one. - -Step 1: Add URL handlers ------------------------- - -Individual URL handlers are pretty straightforward. You can -return just about anything you like, but as we work through -the example you'll see why returning data in .json format -tends to work out pretty well. - -``` - static int - handle_get_status (http_builtin_method_type_t reqtype, - u8 * request, http_session_t * hs) - { - my_main_t *mm = &my_main; - u8 *s = 0; - - /* Construct a .json reply */ - s = format (s, "{\"status\": {"); - s = format (s, " \"thing1\": \"%s\",", mm->thing1_value_string); - s = format (s, " \"thing2\": \"%s\",", mm->thing2_value_string); - /* ... etc ... */ - s = format (s, " \"lastthing\": \"%s\"", mm->last_value_string); - s = format (s, "}}"); - - /* And tell the static server plugin how to send the results */ - hs->data = s; - hs->data_offset = 0; - hs->cache_pool_index = ~0; - hs->free_data = 1; /* free s when done with it, in the framework */ - return 0; - } -``` - -Words to the Wise: Chrome has a very nice set of debugging -tools. Select "More Tools -> Developer Tools". Right-hand sidebar -appears with html source code, a javascript debugger, network results -including .json objects, and so on. - -Note: .json object format is **intolerant** of both missing and extra -commas, missing and extra curly-braces. It's easy to waste a -considerable amount of time debugging .json bugs. - -Step 2: Register URL handlers with the server ---------------------------------------------- - -Call http_static_server_register_builtin_handler() as shown. It's -likely but not guaranteed that the static server plugin will be -available. - - -``` - int - plugin_url_init (vlib_main_t * vm) - { - void (*fp) (void *, char *, int); - - /* Look up the builtin URL registration handler */ - fp = vlib_get_plugin_symbol ("http_static_plugin.so", - "http_static_server_register_builtin_handler"); - - if (fp == 0) - { - clib_warning ("http_static_plugin.so not loaded..."); - return -1; - } - - (*fp) (handle_get_status, "status.json", HTTP_BUILTIN_METHOD_GET); - (*fp) (handle_get_run, "run.json", HTTP_BUILTIN_METHOD_GET); - (*fp) (handle_get_reset, "reset.json", HTTP_BUILTIN_METHOD_GET); - (*fp) (handle_get_stop, "stop.json", HTTP_BUILTIN_METHOD_GET); - return 0; - } -``` - -Make sure to start the http static server **before** calling -plugin_url_init(...), or the registrations will disappear. - -Step 3: Install Hugo, pick a theme, and create a site ------------------------------------------------------ - -Please refer to the Hugo documentation. - -See [the Hugo Quick Start -Page](https://gohugo.io/getting-started/quick-start). Prebuilt binary -artifacts for many different environments are available on -[the Hugo release page](https://github.com/gohugoio/hugo/releases). - -To pick a theme, visit [the Hugo Theme -site](https://themes.gohugo.io). Decide what you need your site to -look like. Stay away from complex themes unless you're prepared to -spend considerable time tweaking and tuning. - -The "Introduction" theme is a good choice for a simple site, YMMV. - -Step 4: Create a "rawhtml" shortcode ------------------------------------- - -Once you've initialized your new site, create the directory -<site-root>/layouts/shortcodes. Create the file "rawhtml.html" in that -directory, with the following contents: - -``` - <!-- raw html --> - {{.Inner}} -``` -This is a key trick which allows a static Hugo site to include -javascript code. - -Step 5: create Hugo content which interacts with vpp ----------------------------------------------------- - -Now it's time to do some web front-end coding in javascript. Of -course, you can create static text, images, etc. as described in the -Hugo documentation. Nothing changes in that respect. - -To include dynamically-generated data in your Hugo pages, splat down -some <div> HTML tags, and define a few buttons: - -``` - {{< rawhtml >}} - <div id="Thing1"></div> - <div id="Thing2"></div> - <div id="Lastthing"></div> - <input type="button" value="Run" onclick="runButtonClick()"> - <input type="button" value="Reset" onclick="resetButtonClick()"> - <input type="button" value="Stop" onclick="stopButtonClick()"> - <div id="Message"></div> - {{< /rawhtml >}} -``` - -Time for some javascript code to interact with vpp: - - {{< rawhtml >}} - <script> - async function getStatusJson() { - pump_url = location.href + "status.json"; - const json = await fetch(pump_url, { - method: 'GET', - mode: 'no-cors', - cache: 'no-cache', - headers: { - 'Content-Type': 'application/json', - }, - }) - .then((response) => response.json()) - .catch(function(error) { - console.log(error); - }); - - return json.status; - }; - - async function sendButton(which) { - my_url = location.href + which + ".json"; - const json = await fetch(my_url, { - method: 'GET', - mode: 'no-cors', - cache: 'no-cache', - headers: { - 'Content-Type': 'application/json', - }, - }) - .then((response) => response.json()) - .catch(function(error) { - console.log(error); - }); - return json.message; - }; - - async function getStatus() { - const status = await getStatusJson(); - - document.getElementById("Thing1").innerHTML = status.thing1; - document.getElementById("Thing2").innerHTML = status.thing2; - document.getElementById("Lastthing").innerHTML = status.lastthing; - }; - - async function runButtonClick() { - const json = await sendButton("run"); - document.getElementById("Message").innerHTML = json.Message; - } - - async function resetButtonClick() { - const json = await sendButton("reset"); - document.getElementById("Message").innerHTML = json.Message; - } - async function stopButtonClick() { - const json = await sendButton("stop"); - document.getElementById("Message").innerHTML = json.Message; - } - - getStatus(); - - </script> - {{< /rawhtml >}} - -At this level, javascript coding is pretty simple. Unless you know -exactly what you're doing, please follow the async function / await -pattern shown above. - -Step 6: compile the website ---------------------------- - -At the top of the website workspace, simply type "hugo". The compiled -website lands in the "public" subdirectory. - -You can use the Hugo static server - with suitable stub javascript -code - to see what your site will eventually look like. To start the -hugo static server, type "hugo server". Browse to -"http://localhost:1313". - -Step 7: configure vpp ---------------------- - -In terms of command-line args: you may wish to use poll-sleep-usec 100 -to keep the load average low. Totally appropriate if vpp won't be -processing a lot of packets or handling high-rate http/https traffic. - -``` - unix { - ... - poll-sleep-usec 100 - startup-config ... see below ... - ... - } -``` - -If you wish to provide an https site, configure tls. The simplest tls -configuration uses a built-in test certificate - which will annoy -Chrome / Firefox - but it's sufficient for testing: - -``` - tls { - use-test-cert-in-ca - } -``` - - - - -### vpp startup configuration - -Enable the vpp static server by way of the startup config mentioned above: - -``` - http static server www-root /myhugosite/public uri tcp://0.0.0.0/2345 cache-size 5m fifo-size 8192 -``` - -The www-root must be specified, and must correctly name the compiled -hugo site root. If your Hugo site is located at /myhugosite, specify -"www-root /myhugosite/public" in the "http static server" stanza. The -uri shown above binds to TCP port 2345. - -If you're using https, use a uri like "tls://0.0.0.0/443" instead of -the uri shown above. - -You may want to add a Linux host interface to view the full-up site locally: - -``` - create tap host-if-name lstack host-ip4-addr 192.168.10.2/24 - set int ip address tap0 192.168.10.1/24 - set int state tap0 up -``` |