Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

export HERE_API=YOUR API KEY
export NOMINATIM_URL=https://nominatim.openstreetmap.org
export ZENFLOWS_URL="http://fcos.interfacer.dyne.org:9000"
export PORT=8080
export INBOX=INBOX URL
118 changes: 56 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
A unifying HTTP proxy for services used by
[the interfacer-gui project](https://github.com/interfacerproject/interfacer-gui)


## Services

The front-end project,
Expand All @@ -31,90 +30,86 @@ implemented for the Interfacer Project.

At the moment, the services implemented are:

* Zenflows - a [zenflows](https://github.com/interfacerproject/zenflows)
instance. It's the main back-end service.;
* Inbox - a [zenflows-inbox](https://github.com/interfacerproject/zenflows-inbox)
instance. It provides notifications and implements a subset of ActivityPub.
* Wallet - a [zenflows-wallet](https://github.com/interfacerproject/zenflows-wallet)
instance. It powers the economic model behind the Interfacer
project. It is an interface between interfacer-gui and planetmint.
* Location Autocomplition - provided by
[Here API](https://autocomplete.search.hereapi.com/v1/autocomplete)
- Zenflows - a [zenflows](https://github.com/interfacerproject/zenflows)
instance. It's the main back-end service.;
- Inbox - a [zenflows-inbox](https://github.com/interfacerproject/zenflows-inbox)
instance. It provides notifications and implements a subset of ActivityPub.
- Wallet - a [zenflows-wallet](https://github.com/interfacerproject/zenflows-wallet)
instance. It powers the economic model behind the Interfacer
project. It is an interface between interfacer-gui and planetmint.
- Location Autocomplition - provided by
[Nominatim](https://nominatim.openstreetmap.org/search)
to autocomplete location/place names on the map;
* Location Lookup - provided by
[Here API](https://lookup.search.hereapi.com/v1/lookup) to lookup
- Location Lookup - provided by
[Nominatim](https://nominatim.openstreetmap.org/lookup) to lookup
location/place names on the map;


## Bulding and executing

You may either choose to build from source, build and use the Docker
image, or just use the pre-built Docker image on
https://ghcr.io/interfacerproject/interfacer-gateway. A set of
https://ghcr.io/interfacerproject/interfacer-gateway. A set of
Ansible scripts are also provided, which could be used as well.

Building from source with Go might be a bit work due to the
dependencies. Building from source with Docker or using Ansible
dependencies. Building from source with Docker or using Ansible
is recommended, as they will be easier to get started.

Each option is detailed in the following sections.


### Building from source with Go

Bulding with Go from the source requires Go version 1.18 or later.
If you have the Go toolchain and a POSIX-compliant make(1)
implementation installed (GNU make(1) works), you can just run:

make
make

which builds a the service as the executable named `interfacer-gateway`.


### Building from source with Docker

Building with Docker requires nothing but the Docker tooling. The
Building with Docker requires nothing but the Docker tooling. The
image produced will have all the dependencies needed to run this
service.

To build the image, you can run:

docker build -t interfacer-gateway:latest .
docker build -t interfacer-gateway:latest .

which will name the image "interfacer-gateway". Then, you can run:
which will name the image "interfacer-gateway". Then, you can run:

docker run --rm -p PORT:8080 \
-e ZENFLOWS_URL=http://url-to-zenflows-instance \
docker run --rm -p PORT:8080 \
-e ZENFLOWS_URL=http://url-to-zenflows-instance \
-e INTERFACER_DPP_URL=http://url-to-interfacer-dpp-instance \
-e INBOX_URL=http://url-to-inbox-instance \
-e WALLET_URL=http://url-to-wallet-instance \
-e OSH_URL=http://url-to-osh-instance \
-e HERE_KEY=api-key-for-here-dot-com \
zenflows-osh

to start the service on port `PORT`. The service will require you
to provide the environment variables listed above. The variables
-e INBOX_URL=http://url-to-inbox-instance \
-e WALLET_URL=http://url-to-wallet-instance \
-e OSH_URL=http://url-to-osh-instance \
-e NOMINATIM_URL=https://nominatim.openstreetmap.org \
zenflows-osh

to start the service on port `PORT`. The service will require you
to provide the environment variables listed above. The variables
are descriped on the section "Configuration".


### Using the pre-built image

You may choose to just use the pre-built image, which is found at
https://ghcr.io/interfacerproject/interfacer-gateway.

To use that image, you can run:

docker run --rm -p PORT:8080 \
-e ZENFLOWS_URL=http://url-to-zenflows-instance \
docker run --rm -p PORT:8080 \
-e ZENFLOWS_URL=http://url-to-zenflows-instance \
-e INTERFACER_DPP_URL=http://url-to-interfacer-dpp-instance \
-e INBOX_URL=http://url-to-inbox-instance \
-e WALLET_URL=http://url-to-wallet-instance \
-e OSH_URL=http://url-to-osh-instance \
-e HERE_KEY=api-key-for-here-dot-com \
ghcr.io/interfacerproject/interfacer-gateway
-e INBOX_URL=http://url-to-inbox-instance \
-e WALLET_URL=http://url-to-wallet-instance \
-e OSH_URL=http://url-to-osh-instance \
-e NOMINATIM_URL=https://nominatim.openstreetmap.org \
ghcr.io/interfacerproject/interfacer-gateway

which will start the service on port `PORT`. The service will require
you to provide the environment variables listed above. The variables
you to provide the environment variables listed above. The variables
are descriped on the section "Configuration".

You may optionally use a docker-compose.yml template like this as well:
Expand All @@ -135,7 +130,7 @@ services:
INBOX_URL: http://url-to-inbox-instance
WALLET_URL: http://url-to-wallet-instance
OSH_URL: http://url-to-osh-instance
HERE_KEY: api-key-for-here-dot-com
NOMINATIM_URL: https://nominatim.openstreetmap.org
stdin_open: true
tty: true
```
Expand All @@ -150,43 +145,43 @@ The deployment use docker-compose with a template that groups all the services r
It can be started writing the `hosts.yaml` and running `make install` inside the `devops` directory.

In the `hosts.yaml` one has to provide:
- `domain_name`: the FQDN of the server
- `zenflows`: URL for the zenflows instanc3
- `ifacer_log`: directory in which we want to save the logs
- `port`: port for proxy on `localhost`
- `here_api`: URL for the API of here.com
- `inbox_port`: port for inbox on `localhost`
- `wallet_port`: port for wallet on `localhost`
- `zenflows_sk`: secret key for a user in zenflows
- `zenflows_user`: username of the same user in zenflows

Warning: currently we are deploying in a LAN with private address, so you may need to modify `docker-compose.yaml.j2`
- `domain_name`: the FQDN of the server
- `zenflows`: URL for the zenflows instanc3
- `ifacer_log`: directory in which we want to save the logs
- `port`: port for proxy on `localhost`
- `nominatim_url`: base URL for the Nominatim instance (optional, defaults to https://nominatim.openstreetmap.org)
- `inbox_port`: port for inbox on `localhost`
- `wallet_port`: port for wallet on `localhost`
- `zenflows_sk`: secret key for a user in zenflows
- `zenflows_user`: username of the same user in zenflows

Warning: currently we are deploying in a LAN with private address, so you may need to modify `docker-compose.yaml.j2`

## Configuration

The configuration is done by providing environment variables.

Here is the list of them:

* `ZENFLOWS_URL` - the URL of
- `ZENFLOWS_URL` - the URL of
[the zenflows instance](https://github.com/interfacerproject/zenflows)
to which the requests will be proxied;
* `INTERFACER_DPP_URL` - the URL of
- `INTERFACER_DPP_URL` - the URL of
[the interfacer-dpp instance](https://github.com/interfacerproject/interfacer-dpp)
to which the requests will be proxied;
* `INBOX_URL` - the URL of
- `INBOX_URL` - the URL of
[the zenflows-inbox instance](https://github.com/interfacerproject/zenflows-inbox)
to which the requests should be proxied;
* `WALLET_URL` - the URL of
- `WALLET_URL` - the URL of
[the zenflows-wallet instance](https://github.com/interfacerproject/zenflows-wallet)
to which the requests should be proxied;
* `OSH_URL` - the URL of
- `OSH_URL` - the URL of
[the zenflows-osh instance](https://github.com/interfacerproject/zenflows-osh)
to which the requests should be proxied;
* `HERE_KEY` - the API key required by the Here API. More on that
at: https://developer.here.com/documentation.

- `NOMINATIM_URL` - the base URL of the Nominatim geocoding service.
Defaults to `https://nominatim.openstreetmap.org` if not set.
Set this to a self-hosted instance if needed.

## Usage

Expand All @@ -196,12 +191,11 @@ service with the identifier of the service.

For instance, let's assume that "/foo/and/whatnot" is supposed to be
sent to the "BAR" service, and the identifier of the service "BAR"
is "bar". Then, the clients of the gateway sends the request to
is "bar". Then, the clients of the gateway sends the request to
the gateway with the url "/bar/foo/andwhatnot", assuming that
everything will be sent to the service "BAR". As such, the provided
everything will be sent to the service "BAR". As such, the provided
HTTP methods and headers will be forwarded to the service "BAR".


## Examples

See the subdirectory `examples/`.
21 changes: 15 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,11 @@ type Config struct {
// https://github.com/interfacerproject/zenflows-osh
OSHURL *url.URL

// The opaque API key of here.com. More on that at:
// https://developer.here.com/documentation
HereKey string
// NominatimURL is the base URL of the Nominatim instance used
// for location search and lookup. Defaults to the public
// instance at https://nominatim.openstreetmap.org when
// NOMINATIM_URL is not set.
NominatimURL *url.URL
}

// NewEnv() fetches configuration options from the environment. If
Expand Down Expand Up @@ -106,11 +108,18 @@ func NewEnv() (*Config, error) {
}
c.OSHURL = u

s = os.Getenv("HERE_KEY")
s = os.Getenv("NOMINATIM_URL")
if s == "" {
return nil, errors.New(`"HERE_KEY" must be provided`)
s = "https://nominatim.openstreetmap.org"
}
c.HereKey = s
u, err = url.Parse(s)
if err != nil || u.Scheme == "" || u.Host == "" {
return nil, errors.New(`"NOMINATIM_URL" is malformed`)
}
if u.Scheme != "http" && u.Scheme != "https" {
return nil, errors.New(`"NOMINATIM_URL" is malformed: invalid scheme; must be http(s)`)
}
c.NominatimURL = &url.URL{Scheme: u.Scheme, Host: u.Host, Path: "/"}

return c, nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ services:
- "{{ port }}:80"
environment:
ZENFLOWS_URL: "{{ zenflows }}"
HERE_KEY: "{{ here_api }}"
NOMINATIM_URL: "{{ nominatim_url | default('https://nominatim.openstreetmap.org') }}"
ADDR: :80
INBOX_URL: "http://inbox"
WALLET_URL: "http://wallet"
Expand Down
19 changes: 8 additions & 11 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ import (
"bytes"
"errors"
"fmt"
"github.com/interfacerproject/interfacer-gateway/config"
"github.com/interfacerproject/interfacer-gateway/logger"
"github.com/sirupsen/logrus"
"io"
"net"
"net/http"
"net/url"
"os"
"time"

"github.com/interfacerproject/interfacer-gateway/config"
"github.com/interfacerproject/interfacer-gateway/logger"
"github.com/sirupsen/logrus"
)

var conf *config.Config
Expand Down Expand Up @@ -82,20 +83,16 @@ var proxiedHosts = []ProxiedHost{
ProxiedHost{
name: "location-autocomplete",
buildUrl: func(u *url.URL) *url.URL {
values := u.Query()
values.Add("apiKey", conf.HereKey)
currentUrl, _ := url.Parse("https://autocomplete.search.hereapi.com/v1/autocomplete")
currentUrl.RawQuery = values.Encode()
currentUrl := conf.NominatimURL.JoinPath("/search")
currentUrl.RawQuery = u.RawQuery
return currentUrl
},
},
ProxiedHost{
name: "location-lookup",
buildUrl: func(u *url.URL) *url.URL {
values := u.Query()
values.Add("apiKey", conf.HereKey)
currentUrl, _ := url.Parse("https://lookup.search.hereapi.com/v1/lookup")
currentUrl.RawQuery = values.Encode()
currentUrl := conf.NominatimURL.JoinPath("/lookup")
currentUrl.RawQuery = u.RawQuery
return currentUrl
},
},
Expand Down