eclipse-thingweb / eclipse-thingweb/node-wot
HTTP PORT and BASE_URL deployment issues
- Dominant language
- TypeScript
- Stars
- 192
- Forks
- 100
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 6
Description
> FYI The wot library has a lot of depth to it, it was neat to see the event subscription using the plain http binding just work out of the box. It's really more than a reference implementation. kudos.
I wrote an example exposed thing that is hosted in a NodeJS application, using express for the browser UI, and wot for the exposed thing, which is controlled by browserified node-wot. When deploying it in the cloud, I ran in to issues with HTTP PORT mapping and the BASE URL for the TD URLs, which required changes to the http-binding to get it working.
If there's consensus on how to address these, I'm happy to create a PR.
# HTTP PORT
With the thing embedded in NodsJS, there's two http listeners i a single process. This all worked fine on my development system, 3000 (express) and 8081 (wot)
In the cloud, I use Dokku, which is a docker based "heroku in a box" that you can run on your own ec2 instance. It is heroku compatible and uses the heroku build-packs. https://github.com/dokku/dokku
My first deploy got me this:
````
> lightbar@0.0.0 start /app
> node ./bin/www
HttpServer starting on port 8081
Port 5000 is already in use
npm ERR! code ELIFECYCLE
npm ERR! errno 1
````
(The full heroku buildpack output is here: https://gist.github.com/joshco/e5fbf2b7167504fbc66b6ffc83b447cc)
Port 5000 is the port the build-pack sets in an environment variable that the application will use. (this is the same as the rails and other build-packs) When I did a curl to port 5000, i got back the wot servient response, where I expected the Node Express app to be.
8081 is the port I specified in the WOT http config, and where I expected the WOT to be. When I did a curl to 8081, it wouldn't connect.
After troubleshooting, it turns out that WOT is fooling us. In the start method of http-server, it's logging that it is going to use the port specified in the http config (8081), but later in the code, in line 121 it gives preference to the PORT env variable if it is present. So it's actually bound to 5000, wining the race, leaving express to get the error.
To make my project work, I changed the code from
`(+process.env.PORT || this.port, this.address);`
To
`+process.env.WOT_PORT || +process.env.PORT || _this.port;`
In http-server.ts
https://github.com/eclipse/thingweb.node-wot/blob/b9d0a3d85448d2d0652dcd3cfe5980ad5c12fd39/packages/binding-http/src/http-server.ts#L100-L123
I added a WOT_PORT so the preference is WOT_PORT (wot specific) | PORT (heroku style generic) | _this.port (wot http config)
# Base URL
The other challenge, which I think many will run into when using docker or other heroku type systems, is making the servient provide the right URLs in the TD et al.
```
`"forms":[{"href":"http://192.168.1.111:8081/WOT/properties/color","contentType":"application/json."`
```
The servient in the container can only work with the network interfaces on the container. So that means a domain name or IP that maps to one of the local interfaces, which is not the internet facing interface, or domain name. Attempting to use an external domain name in the server.address field or STATIC env var of the CLI gets EADDRNOTAVAIL
To fix this, I modified the expose method in http-server.ts where it defines the `base` variable it uses to create URL strings:
From
````
let base: string = this.scheme + "://" + address + ":" + this.getPort() + "/" + encodeURIComponent(title);
let href = base + "/" + this.ALL_DIR + "/" + encodeURIComponent( this.ALL_PROPERTIES);
````
To
````
var domain_url = (process.env.WOT_URL_BASE|| (this.scheme + "://" + address + ":" + this.getPort()));
var base = domain_url + "/" + encodeURIComponent(title);
````
https://github.com/eclipse/thingweb.node-wot/blob/b9d0a3d85448d2d0652dcd3cfe5980ad5c12fd39/packages/binding-http/src/http-server.ts#L190-L193
PS: If you want to see the thing: http://thingpatrol.dev.joshco.org
Contributor guide
Assessment
This issue has not been assessed yet.