Skip to content
Merged
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
13 changes: 7 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ stages:
- name: sourcedocs
if: branch = master AND type != pull_request

.elixir-env: &elixir-env
language: elixir
elixir: "1.9"
otp_release: "22.0"

jobs:
include:
- stage: unittest
language: elixir
elixir: "1.7"
otp_release: "21.0"
<<: *elixir-env
env:
- MIX_ENV=test
script:
Expand Down Expand Up @@ -53,9 +56,7 @@ jobs:
- echo "machine github.com login ${GH_NAME} password ${GH_TOKEN}" > ~/.netrc
- cd website && yarn install && GIT_USER="${GH_NAME}" yarn run publish-gh-pages
- stage: sourcedocs
language: elixir
elixir: "1.7"
otp_release: "21.0"
<<: *elixir-env
script:
- git config --global user.name "${GH_NAME}"
- git config --global user.email "${GH_EMAIL}"
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Technical Improvements

- Upgrade the Elixir and Erlang versions for source code and Docker images.
- Automated UI-tests using Cypress make sure that all examples work and that code changes do not introduce any unintended API changes.
[#227](https://github.com/Accenture/reactive-interaction-gateway/issues/227)
- Refactor JWT related code in favor of `RIG.JWT`.
Expand Down
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM elixir:1.7-alpine as build
FROM elixir:1.9-alpine as build

# Install Elixir & Erlang environment dependencies
RUN mix local.hex --force
Expand Down Expand Up @@ -63,9 +63,9 @@ COPY apps/rig_metrics/lib /opt/sites/rig/apps/rig_metrics/lib

# Compile and release application production code
RUN mix compile
RUN mix release
RUN mix distillery.release

FROM erlang:21-alpine
FROM erlang:22-alpine

LABEL org.label-schema.name="Reactive Interaction Gateway"
LABEL org.label-schema.description="Reactive API Gateway and Event Hub"
Expand Down
13 changes: 9 additions & 4 deletions apps/rig/lib/rig/event_filter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -269,16 +269,21 @@ defmodule Rig.EventFilter do
process group to find them.

"""
@callback refresh_subscriptions([Subscription.t()], [Subscription.t()]) :: :ok
@spec refresh_subscriptions([Subscription.t()], [Subscription.t()]) :: :ok
def refresh_subscriptions(subscriptions, prev_subscriptions) do
@type done_callback :: (() -> nil)

@callback refresh_subscriptions([Subscription.t()], [Subscription.t()], done_callback) ::
:ok
def refresh_subscriptions(subscriptions, prev_subscriptions, done_callback \\ nil) do
# There is one Filter Supervisor per node. Each of those supervisors forwards the
# subscriptions to the right Filter processes on the node they're located on.

subscriber = self()

for pid <- FilterSup.processes() do
GenServer.cast(pid, {:refresh_subscriptions, subscriber, subscriptions, prev_subscriptions})
GenServer.cast(
pid,
{:refresh_subscriptions, subscriber, subscriptions, prev_subscriptions, done_callback}
)
end

:ok
Expand Down
5 changes: 4 additions & 1 deletion apps/rig/lib/rig/event_filter/server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ defmodule Rig.EventFilter.Server do

@impl GenServer
def handle_cast(
{:refresh_subscriptions, subscriber_pid, subscriptions},
{:refresh_subscriptions, subscriber_pid, subscriptions, done},
%{
event_type: event_type,
subscription_table: subscription_table,
Expand All @@ -119,6 +119,9 @@ defmodule Rig.EventFilter.Server do
ttl_s
)

# Call the subscriber's callback, if present:
if done, do: done.()

{:noreply, state}
end

Expand Down
29 changes: 19 additions & 10 deletions apps/rig/lib/rig/event_filter/server_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,20 @@ defmodule Rig.EventFilter.ServerTest do
alias Rig.Subscription
alias RigCloudEvents.CloudEvent

defp register_subscription_with_event_filter(subscription) do
test_pid = self()

# Set up the subscription:
EventFilter.refresh_subscriptions([subscription], [], fn ->
send(test_pid, :subscriptions_refreshed)
end)

# wait for it..
assert_receive :subscriptions_refreshed, 1_000

# Should be active now!
end

test "subscribe & receive an event" do
event_type = "test.event"
field_config = %{}
Expand All @@ -24,9 +38,7 @@ defmodule Rig.EventFilter.ServerTest do
opts = [debug?: true, subscription_ttl_s: 0]
{:ok, filter_pid} = Server.start_link(event_type, field_config, opts)

EventFilter.refresh_subscriptions([subscription], [])
# wait for genserver cast
:sys.get_state(filter_pid)
register_subscription_with_event_filter(subscription)
EventFilter.forward_event(event)
EventFilter.forward_event(event)

Expand Down Expand Up @@ -107,9 +119,8 @@ defmodule Rig.EventFilter.ServerTest do

for {subscription, event, match_expectation} <- specs do
{:ok, filter_pid} = Server.start_link(event_type, field_config)
EventFilter.refresh_subscriptions([subscription], [])
# wait for genserver cast
:sys.get_state(filter_pid)

register_subscription_with_event_filter(subscription)
EventFilter.forward_event(event)

case match_expectation do
Expand Down Expand Up @@ -141,9 +152,7 @@ defmodule Rig.EventFilter.ServerTest do
greetings_to_joe_subscription =
Subscription.new!(%{event_type: event_type, constraints: [name_is_joe]})

EventFilter.refresh_subscriptions([greetings_to_joe_subscription], [])
# wait for genserver cast
:sys.get_state(filter_pid)
register_subscription_with_event_filter(greetings_to_joe_subscription)

base_event = %{"specversion" => "0.2", "type" => event_type, "source" => "test"}

Expand All @@ -165,7 +174,7 @@ defmodule Rig.EventFilter.ServerTest do
assert_receive ^greeting_to_sam

# But after refreshing the subscriptions, a greeting to Sam is no longer forwarded:
EventFilter.refresh_subscriptions([greetings_to_joe_subscription], [])
register_subscription_with_event_filter(greetings_to_joe_subscription)
# wait for genserver cast
:sys.get_state(filter_pid)
EventFilter.forward_event(greeting_to_sam)
Expand Down
11 changes: 7 additions & 4 deletions apps/rig/lib/rig/event_filter/sup.ex
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ defmodule Rig.EventFilter.Sup do

@impl GenServer
def handle_cast(
{:refresh_subscriptions, subscriber_pid, subscriptions, prev_subscriptions},
{:refresh_subscriptions, subscriber_pid, subscriptions, prev_subscriptions, done},
%{extractor_map: extractor_map} = state
)
when is_list(subscriptions) and is_list(prev_subscriptions) do
Expand All @@ -61,7 +61,7 @@ defmodule Rig.EventFilter.Sup do
for {event_type, subs} <- subs_by_eventtype do
filter_config = Config.for_event_type(extractor_map, event_type)
filter = find_or_start_filter_process(event_type, filter_config)
GenServer.cast(filter, {:refresh_subscriptions, subscriber_pid, subs})
GenServer.cast(filter, {:refresh_subscriptions, subscriber_pid, subs, done})
end

# If a subscription for an event type has been removed completely, the respective
Expand All @@ -76,8 +76,11 @@ defmodule Rig.EventFilter.Sup do
# If we can find a filter for this type, we ask it to clear all subscriptions for
# the subscriber:
case get_filter_pid(event_type) do
nil -> :ignore
filter -> GenServer.cast(filter, {:refresh_subscriptions, subscriber_pid, _subs = []})
nil ->
:ignore

filter ->
GenServer.cast(filter, {:refresh_subscriptions, subscriber_pid, _subs = [], done})
end
end)

Expand Down
2 changes: 1 addition & 1 deletion apps/rig/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ defmodule Rig.MixProject do
# Apache Kafka Erlang client library:
{:brod, "~> 3.3"},
# For distributed_set:
{:timex, "~> 3.4"},
{:timex, "~> 3.6"},
{:ex2ms, "~> 1.5"},
{:uuid, "~> 1.1"},
# For doing HTTP requests, e.g., in kafka_as_http:
Expand Down
2 changes: 1 addition & 1 deletion apps/rig_auth/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ defmodule RigAuth.Mixfile do
{:plug, "~> 1.4"},
{:poison, "~> 3.0 or ~> 4.0"},
{:stubr, "~> 1.5.0", only: :test},
{:timex, "~> 3.4"},
{:timex, "~> 3.6"},
# JSON Pointer (RFC 6901) implementation for extracting the session name from JWTs:
{:odgn_json_pointer, "~> 2.3"},
# A library for defining structs with a type without writing boilerplate code:
Expand Down
12 changes: 10 additions & 2 deletions apps/rig_common/mix.exs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
defmodule RigCommon.MixProject do
@moduledoc false
use Mix.Project

def project do
%{rig: rig_version, elixir: elixir_version} = versions()

[
app: :rig_common,
version: "0.1.0",
version: rig_version,
build_path: "../../_build",
config_path: "../../config/config.exs",
deps_path: "../../deps",
lockfile: "../../mix.lock",
elixir: "~> 1.7",
elixir: elixir_version,
start_permanent: Mix.env() == :prod,
deps: deps(),
test_coverage: [tool: ExCoveralls]
Expand All @@ -23,6 +26,11 @@ defmodule RigCommon.MixProject do
]
end

defp versions do
{map, []} = Code.eval_file("version", "../..")
map
end

# Run "mix help deps" to learn about dependencies.
defp deps do
[]
Expand Down
2 changes: 1 addition & 1 deletion apps/rig_inbound_gateway/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ defmodule RigInboundGateway.Mixfile do
{:poison, "~> 3.0 or ~> 4.0"},
{:jason, "~> 1.1"},
# Date and time handling:
{:timex, "~> 3.4"},
{:timex, "~> 3.6"},
# Helper to make writing stubs and mocks easier:
{:stubr, "~> 1.5.0", only: :test},
# Elixir-compatible :ets.fun2ms/1
Expand Down
11 changes: 9 additions & 2 deletions apps/rig_tests/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ defmodule RigTests.MixProject do
use Mix.Project

def project do
%{rig: rig_version, elixir: elixir_version} = versions()

[
app: :rig_tests,
version: "0.1.0",
version: rig_version,
build_path: "../../_build",
config_path: "../../config/config.exs",
deps_path: "../../deps",
lockfile: "../../mix.lock",
elixir: "~> 1.7",
elixir: elixir_version,
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
deps: deps(),
Expand All @@ -24,6 +26,11 @@ defmodule RigTests.MixProject do
]
end

defp versions do
{map, []} = Code.eval_file("version", "../..")
map
end

defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]

Expand Down
6 changes: 3 additions & 3 deletions aws.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ WORKDIR /opt/sites/rig/kinesis-client
# Compile AWS Kinesis Java application
RUN mvn package

FROM elixir:1.7-alpine as elixir-build
FROM elixir:1.9-alpine as elixir-build

# Install Elixir & Erlang environment dependencies
RUN mix local.hex --force
Expand Down Expand Up @@ -72,9 +72,9 @@ COPY apps/rig_metrics/lib /opt/sites/rig/apps/rig_metrics/lib

# Compile and release application production code
RUN mix compile
RUN mix release
RUN mix distillery.release

FROM erlang:21-alpine
FROM erlang:22-alpine

RUN apk add --no-cache bash

Expand Down
6 changes: 3 additions & 3 deletions docs/rig-dev-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ Then go through the following:

To have the project use a newer Elixir version, make sure to change the following locations:

- `.travis.yml`
- `Dockerfile` (the `FROM` image tag)
- `version`
- `.travis.yml`: Update the Elixir and OTP versions in the `.elixir-env` section.
- `Dockerfile`: Make sure to change the `FROM` image tag for both the build image (elixir:...-alpine) as well as the runtime image (erlang:...-alpine). If the Erlang runtime (ERTS) in the runtime image doesn't match the ERTS version in the build image, chances are the built image won't work due to missing libraries. Because of this, it's best to use the most recent versions for both images when upgrading - they should always be compatible.
- `version`: Again, make sure both the Elixir and the OTP versions match what you have used in the previous steps.

## Releasing a new version

Expand Down
5 changes: 0 additions & 5 deletions examples/channels-example/app.docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
version: "3"
services:
zookeeper:
container_name: zookeeper
image: wurstmeister/zookeeper:3.4.6
ports:
- 2181:2181

kafka:
container_name: kafka
image: wurstmeister/kafka:0.10.0.1-2
environment:
- KAFKA_ADVERTISED_HOST_NAME=kafka
Expand All @@ -22,7 +20,6 @@ services:
- zookeeper

rig:
container_name: rig
image: accenture/reactive-interaction-gateway
environment:
- JWT_SECRET_KEY=mysecret
Expand All @@ -39,15 +36,13 @@ services:
- kafka

channels-external-service:
container_name: channels-external-service
image: channels-external-service
environment:
- KAFKA_HOSTS=kafka:9092
ports:
- 8000:8000

channels-ui:
container_name: channels-ui
image: channels-ui
ports:
- 3000:80
Expand Down
Loading