|
| 1 | +# Plank |
| 2 | + |
| 3 | +## What is Plank? |
| 4 | +Plank is just enough of a platform to build whatever you want on top. It is a small yet powerful Golang server that can serve |
| 5 | +static contents, single page applications, create and expose microservices over REST endpoints or WebSocket via a built-in |
| 6 | +STOMP broker, or even interact directly with other message brokers such as RabbitMQ. All this is done in a consistent |
| 7 | +and easy to follow manner powered by Transport Event Bus. |
| 8 | + |
| 9 | +Writing a service for a Plank server is in a way similar to writing a Spring Boot `Component` or `Service`, because a lot of tedious |
| 10 | +plumbing work is already done for you such as creating an instance of a service and wiring it up with HTTP endpoints using routers etc. |
| 11 | +Just by following the API you can easily stand up a service, apply any kinds of middleware your application logic calls for, and do all these |
| 12 | +dynamically while in runtime, meaning you can conditionally apply a filter for certain REST endpoints, stand up a new service on demand, or |
| 13 | +even spawn yet another whole new instance of Plank at a different endpoint. |
| 14 | + |
| 15 | +All features are cleanly exposed as public API and modules and, combined with the power of Golang's concurrency model using channels, |
| 16 | +the Transport Event Bus allows creating a clean application architecture, with straightforward and easy to follow logic. |
| 17 | + |
| 18 | +Detailed tutorials and examples are currently in progress and will be made public on the [Transport GitHub page](https://vmware.github.io/transport/). |
| 19 | +Some topics that will initially be covered are: |
| 20 | + |
| 21 | +- Writing a simple service and interacting with it over REST and WebSocket |
| 22 | +- Service lifecycle hooks |
| 23 | +- Middleware management (for REST bridged services) |
| 24 | +- Concept of local bus channel and galactic bus channel |
| 25 | +- Communicating between Plank instances using the built-in STOMP broker |
| 26 | +- Securing your REST and WebSocket endpoints using Auth Provider Manager |
| 27 | + |
| 28 | +## Hello world |
| 29 | +### How to build Plank |
| 30 | +First things first, you'll need the latest Golang version. Plank was first written in Golang 1.13 and it still works with it, but it's advised |
| 31 | +to use the latest Golang (especially 1.16 and forward) because of some nice new packages such as `embed` that we may later employ as part of Plank codebase. |
| 32 | +Once you have the latest Golang ready, follow the commands below: |
| 33 | + |
| 34 | +```bash |
| 35 | +# get all dependencies |
| 36 | +go get ./... |
| 37 | + |
| 38 | +# To build against your operating system |
| 39 | +go run build.go |
| 40 | + |
| 41 | +# or, to build against a specific operating system |
| 42 | +BUILD_OS=darwin|linux|windows go run build.go |
| 43 | +``` |
| 44 | + |
| 45 | +Once successfully built, `plank` binary will be ready under `build/`. |
| 46 | + |
| 47 | +> NOTE: we acknowledge there's a lack of build script for Windows Powershell, We'll add it soon! |
| 48 | +
|
| 49 | +### Generate a self signed certificate |
| 50 | +Plank can run in non-HTTPS mode but it's generally a good idea to always do development in a similar environment where you'll be serving your |
| 51 | +audience in public internet (or even intranet). Plank repository comes with a handy utility script that can generate a pair of server certificate |
| 52 | +and its matching private key at `scripts/create-selfsigned-cert.sh`. Simply run it in a POSIX shell like below. (requires `openssl` library |
| 53 | +to be available): |
| 54 | + |
| 55 | +```bash |
| 56 | +# generate a pair of x509 certificate and private key files |
| 57 | +./scripts/generate-selfsigned-cert.sh |
| 58 | + |
| 59 | +# cert/fullchain.pem is your certificate and cert/server.key its matching private key |
| 60 | +ls -la cert/ |
| 61 | +``` |
| 62 | + |
| 63 | +### The real Hello World part |
| 64 | +Now we're ready to start the application. To kick off the server using the demo app you have built above, type the following and you'll see something like this: |
| 65 | + |
| 66 | +```bash |
| 67 | +./build/plank start-server --config-file config.json |
| 68 | + |
| 69 | + ______ __ ______ __ __ __ __ |
| 70 | +/\ == /\ \ /\ __ \/\ "-.\ \/\ \/ / |
| 71 | +\ \ _-\ \ \___\ \ __ \ \ \-. \ \ _"-. |
| 72 | + \ \_\ \ \_____\ \_\ \_\ \_\\"\_\ \_\ \_\ |
| 73 | + \/_/ \/_____/\/_/\/_/\/_/ \/_/\/_/\/_/ |
| 74 | + |
| 75 | +Host localhost |
| 76 | +Port 30080 |
| 77 | +Fabric endpoint /ws |
| 78 | +SPA endpoint /public |
| 79 | +SPA static assets /assets |
| 80 | +Health endpoint /health |
| 81 | +Prometheus endpoint /prometheus |
| 82 | +... |
| 83 | +time="2021-08-05T21:32:50-07:00" level=info msg="Starting HTTP server at localhost:30080 with TLS" fileName=server.go goroutine=28 package=server |
| 84 | +``` |
| 85 | +
|
| 86 | +Open your browser and navigate to https://localhost:30080, accept the self-signed certificate warning and you'll be greeted with a 404! |
| 87 | +This is an expected behavior, as the demo app does not serve anything at root `/`, but we will consider changing the default 404 screen to |
| 88 | +something that looks more informational or more appealing at least. |
| 89 | +
|
| 90 | +## All supported flags and usages |
| 91 | +
|
| 92 | +|Long flag|Short flag|Default value|Required|Description| |
| 93 | +|----|----|----|----|----| |
| 94 | +|--hostname|-n|localhost|false|Hostname where Plank is to be served. Also reads from `$PLANK_SERVER_HOSTNAME` environment variable| |
| 95 | +|--port|-p|30080|false|Port where Plank is to be served. Also reads from `$PLANK_SERVER_PORT` environment variable| |
| 96 | +|--rootdir|-r|<current directory>|false|Root directory for the server. Also reads from `$PLANK_SERVER_ROOTDIR` environment variable| |
| 97 | +|--static|-s|-|false|Path to a location where static files will be served. Can be used multiple times| |
| 98 | +|--no-fabric-broker|-|false|false|Do not start Fabric broker| |
| 99 | +|--fabric-endpoint|-|/fabric|false|Fabric broker endpoint (ignored if --no-fabric-broker is present)| |
| 100 | +|--topic-prefix|-|/topic|false|Topic prefix for Fabric broker (ignored if --no-fabric-broker is present)| |
| 101 | +|--queue-prefix|-|/queue|false|Queue prefix for Fabric broker (ignored if --no-fabric-broker is present)| |
| 102 | +|--request-prefix|-|/pub|false|Application request prefix for Fabric broker (ignored if --no-fabric-broker is present)| |
| 103 | +|--request-queue-prefix|-|/pub/queue|false|Application request queue prefix for Fabric broker (ignored if --no-fabric-broker is present)| |
| 104 | +|--shutdown-timeout|-|5|false|Graceful server shutdown timeout in minutes| |
| 105 | +|--output-log|-l|stdout|false|File to output platform logs to| |
| 106 | +|--access-log|-l|stdout|false|File to output HTTP server access logs to| |
| 107 | +|--error-log|-l|stderr|false|File to output HTTP server error logs to| |
| 108 | +|--debug|-d|false|false|Debug mode| |
| 109 | +|--no-banner|-b|false|false|Do not print Plank banner at startup| |
| 110 | +|--prometheus|-|false|false|Enable Prometheus at /prometheus for metrics| |
| 111 | +|--rest-bridge-timeout|-|1|false|Time in minutes before a REST endpoint for a service request to timeout| |
| 112 | +
|
| 113 | +Examples are as follows: |
| 114 | +```bash |
| 115 | +# Start a server with all options set to default values |
| 116 | +./plank start-server |
| 117 | +
|
| 118 | +# Start a server with a custom hostname and at port 8080 without Fabric (WebSocket) broker |
| 119 | +./plank start-server --no-fabric-broker --hostname my-app.io --port 8080 |
| 120 | +
|
| 121 | +# Start a server with a 10 minute graceful shutdown timeout |
| 122 | +# NOTE: this is useful when you run a service that takes a significant amount of time or might even hang while shutting down |
| 123 | +./plank start-server --shutdown-timeout 10 |
| 124 | +
|
| 125 | +# Start a server with platform server logs printing to stdout and access/error logs to their respective files |
| 126 | +./plank start-server --access-log server-access-$(date +%m%d%y).log --error-log server-error-$(date +%m%d%y).log |
| 127 | +
|
| 128 | +# Start a server with debug outputs enabled |
| 129 | +./plank start-server -d |
| 130 | +
|
| 131 | +# Start a server without splash banner |
| 132 | +./plank start-server --no-banner |
| 133 | +
|
| 134 | +# Start a server with Prometheus enabled at /prometheus |
| 135 | +./plank start-server --prometheus |
| 136 | +
|
| 137 | +# Start a server with static path served at `/static` for folder `static` |
| 138 | +./plank start-server --static static |
| 139 | +
|
| 140 | +# Start a server with static paths served at `/static` for folder `static` and |
| 141 | +# at `/public` for folder `public-contents` |
| 142 | +./plank start-server --static static --static public-contents:/public |
| 143 | +
|
| 144 | +# Start a server with a JSON configuration file |
| 145 | +./plank start-server --config-file config.json |
| 146 | +``` |
| 147 | +
|
| 148 | +## Advanced topics (WIP. Coming soon) |
| 149 | +### OAuth2 Client |
| 150 | +Plank supports seamless out of the box OAuth 2.0 client that support a few OAuth flows. such as authorization |
| 151 | +code grant for web applications and client credentials grant for server-to-server applications. |
| 152 | +See below for a detailed guide for each flow. |
| 153 | +
|
| 154 | +#### Authorization Code flow |
| 155 | +You'll choose this authentication flow when the Plank server acts as an intermediary that exchanges |
| 156 | +the authorization code returned from the authorization server for an access token. During this process you will be |
| 157 | +redirected to the identity provider's page like Google where you are asked to confirm the type of 3rd party application and |
| 158 | +its scope of actions it will perform on your behalf and will be taken back to the application after successful authorization. |
| 159 | +
|
| 160 | +#### Client Credentials flow |
| 161 | +You'll choose this authentication flow when the Plank server needs to directly communicate with another backend service. |
| 162 | +This will not require user's consent like you would be redirected to Google's page where you confirm the type of application |
| 163 | +requesting your consent for the scope of actions it will perform on your behalf. not requiring any interactions from the user. You will need to |
| 164 | +create an OAuth 2.0 Client with `client_credentials` grant before following the steps below to implement the |
| 165 | +authentication flow. |
0 commit comments