You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@openwhisk.apache.org by GitBox <gi...@apache.org> on 2018/12/24 17:23:08 UTC

[GitHub] jonpspri closed pull request #285: Multi-architecture build of API Gateway.

jonpspri closed pull request #285: Multi-architecture build of API Gateway.
URL: https://github.com/apache/incubator-openwhisk-apigateway/pull/285
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index 93a444c..0000000
--- a/.dockerignore
+++ /dev/null
@@ -1,8 +0,0 @@
-doc
-.gitignore
-.travis.yml
-CONTRIBUTING.md
-Dockerfile
-LICENSE.txt
-Makefile
-README.md
diff --git a/.gitignore b/.gitignore
index a9d0ef1..e61b1c5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,12 @@ secrets.yml
 
 # npm
 npm-debug.log
+
+# Gradle
+build
+/.gradle
+
+# Some places where secrets are kept...
+docker-local.json
+*.pem
+/tls
diff --git a/.profiling.after b/.profiling.after
deleted file mode 100644
index a078925..0000000
--- a/.profiling.after
+++ /dev/null
@@ -1,7 +0,0 @@
-COPY ./api-gateway.conf.profiling /etc/api-gateway/api-gateway.conf
-RUN apt-get install -y git && mkdir -p /profiling && git clone https://github.com/openresty/stapxx.git && cd stapxx && git clone https://github.com/brendangregg/FlameGraph.git && apt-get remove -y git
-RUN apt-get install -y linux-headers-`uname -r` kbuild gcc 
-ENV LD_LIBRARY_PATH /usr/local/lib 
-WORKDIR /tmp/stapxx
-ENTRYPOINT ["/usr/local/bin/dumb-init", "--"]
-CMD ["/etc/init-container.sh"]
diff --git a/.profiling.before b/.profiling.before
deleted file mode 100644
index a17091d..0000000
--- a/.profiling.before
+++ /dev/null
@@ -1,9 +0,0 @@
-FROM ubuntu:latest
-
-RUN apt-get update && apt-get install -y gcc make g++ gettext git python zlib1g-dev bzip2 wget m4 git
-WORKDIR /tmp
-RUN wget https://sourceware.org/elfutils/ftp/0.168/elfutils-0.168.tar.bz2 && tar -jxf elfutils-0.168.tar.bz2 && cd elfutils-0.168 && ./configure && make -j4 && make install
-
-RUN wget https://sourceware.org/systemtap/ftp/releases/systemtap-3.1.tar.gz && tar -zxf systemtap-3.1.tar.gz && cd systemtap-3.1 && ./configure && make -j4 && make install
-RUN cp /proc/kallsyms /boot/System.map-`uname -r`
-RUN mkdir -p /usr/local/share/perl5/site_perl
diff --git a/.travis.yml b/.travis.yml
index 4b9d47a..d74d483 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,26 +2,11 @@
 
 sudo: required
 
-language: scala
-scala:
-   - 2.11.8
+language: java # So the runtime is available for gradle
 
 services:
   - docker
 
-notifications:
-  email: false
-  webhooks:
-    urls:
-      # travis2slack webhook to enable DMs on openwhisk-team.slack.com to PR authors with TravisCI results
-      secure: "AEc7oc14mGjxLcnvco61XgUn5icDutoj+5fjQ4SiOqvZIhtwcdlM6T3ELeeorkRUyCwghMWkH89Z5RSqF5uvNBjmn3E+z+x3q3hM2ZF9KaiMuaxHJHydTjQzHOZuYyYeMWSoK/qczoYAVY2c3+3GtAzqZ55V5L2oQa6fpBm384lqJukQpK426kk9wMO6xNaByQxiLDOz9ddDwDeroR7RwclYs1XG68O9a/J2/gBKhjVy10GHAhet5HMO9CCwOsi/VVJMw+Q6zhlErLgmVnA722JlLiqqMJZQ1z5z7MUyt9ZhZc3qhKBNfU0cobEdguEGjo5AwsJTaQq/RdgIRk3kTNxT7t34cLwyCL+e/H2h83Tm1Cv4X4F4Qsk88VSivaKWU4LEv0tJ4cx5wM2nbprZn5MBhVZUD3T4NnbbLgR593gQqB1m4QWbZD4WDPYMFYZn+zOVVYH15DxLJlBNUsoQExknmeAZfGq4Del93bYn7H/c+pQR3XG5ntOTp0xsUxSjxVfEBdMOdR9ev/HO7rN3xIE6bgUdwYZKKcpQLlKkp5EBoBDjl6oLJbEg0oFmn/0l7Da2FxKdD7oxOzEQCvymc74gOVH78Fl9HBFCh0xRJGl6R1ZN1c5mpSRIKuzFTS5oyhbuZdkDxdgyE5XNBvziNdD3Li0xXQkLzXhdxL71KnM="
-
-env:
-  global:
-    - LUA="lua=5.1"
-    - secure: "c8XNwdOryMVJUGLzWv+AzUQaS0Yt7uUmGqw+5/K7o7zmpux7Q5H7OU3jni2kOr+ZoIldsmTnnG7m1N9D8qUjD64KaAfEC0ybo04kDraezVMghUEV8LWMpSRRlAFpzQeVC8IcSiUEXM0H8E6Y09jGMnLKqyFUWAlDB60n0x2rfK/IPU+x4/h+6Y5XpYqaNtujoUf/2XVkrOeRcEhVZQJAwsRtA8HjRUy7PRB/9kepTSln9QzRZYd6v4F1qUKgZhlWNRUXWRbhrNK/z6T7jSlHjY44yvse4fBbie+EsuImtOHnDuTA4XXQlbc0gGVvD3sYYf2CBMxeeE+UTbRPLxgml+uUIviWKt/PKB5qUwQyLKP/Rzr1qv5RryrX0xWoqCrVsaCe0fkh0vUks0AYlzhm1CNK/g1If+qZ6R0GMjawVUbCunhDi1vJlP5PmniIoLpVwLa6XoMYJKtfngGm2763y00ktVGGL1gDtnm0lDuhkinIxOzieh8aRpYDBX6zZZ/n20LzDO/5l0CGErKPgzzt9vRPiQNoGxqC90jtsin+XkOxF9erk0QYt/St7/Qa1R0E+0dA2bHqxz2SWz3cjcc4Cw8/DW3SLFjaONvs6aQyHkrL2LJabARMMgGmf68P5nJrPy56c3gV8jXe7CVaV+5nClT1HYgWSEIna6oyzo8kzFk="
-    - secure: "dM0paMW2d4U4U7OwbnrTjdOqDnvo+nce9r7h+qTbYfbuJe0fpRkHCrxcB//8ESkMrPTr0EDExCxvaywY8pqeVVJbykNswdyze1SWYk6lbUvXTpSrKqp0J0a/FtVjfamc1aMv4c6KIDKh4vIcgK4xrjXj68COCS6uIcFhETNUy5bxH8T2BOJzyf/iWOF7oduXUV/VGNcWnhkPdoPh8xtpmBJ6ZTWQ01MriZ/28hvzgyh1OjJFWCJZ+OZoIDQVPb/jnfPXU4Wk/G/LEPJcBgvN4qSMr2lm3Iq29V0Ltrsx8rrYADO7trCm6qyEQK9TLKfywaYIcm/D9FJ8F4WBHtIeJ3PLY3518L3iZ+Ngd6QTnd0FI6hrG7rpoD/0dz4e//9d3tSsjbh/1BiQwXXTnPyaUjN3C92k4GyITYJTVL5f6evzsTneT6Plj1vWC0E52d1oqVOZDgrWMYZEHdYvpUJTQqclMNhu5SMIYAPqVvibqupcmAh5B+UDr6UvYT/hUAC/d3hyjfHgouRoluJ1mutND88QjDw6UWmXXjHqRSCI6OI5NDZczl/aqz7nPFyTaIe9EibTdZa5LC8fN+Am9MTRxJAv8HXt0zKe5FqHijSvFcVxYlhwlIZg7ShbPh+X2Hnh/JMjx0z/7ujkBRYfmAQW53SBy8Tv/Zv69nCz8eOFOUk="
-
 before_install:
   - ./tools/travis/setup.sh
   - pip install hererocks --user
@@ -33,19 +18,43 @@ install:
   - ./install-deps.sh
 
 script:
-  - busted --output=TAP --helper=set_paths --pattern=.lua scripts
+  - busted --output=TAP --helper=set_paths --pattern=.lua --lpath="$(pwd)/../common/etc-api-gateway/scripts/lua/?.lua" scripts
   - cd ..
   - ./tools/travis/build.sh
 
 deploy:
   # deploy latest
   - provider: script
-    script: ./tools/travis/deploy.sh openwhisk apigateway latest
+    script: ./gradlew --console=plain :core:apigateway:putManifestList -PdockerImagePrefix=openwhisk -PdockerImageTag=latest
     on:
       branch: master
   # deploy tag
   - provider: script
-    script: ./tools/travis/deploy.sh openwhisk apigateway $TRAVIS_TAG
+    script: ./gradlew --console=plain :core:apigateway:putManifestList -PdockerImagePrefix=openwhisk -PdockerImageTag=$TRAVIS_TAG
     on:
       tags: true
       all_branches: true
+
+env:
+  global:
+    - LUA="lua=5.1"
+  #  --- begin: DOCKER_REGISTRY (defaults to docker.io)
+  #      + for jonpspri/incubator-openwhisk-apigateway
+    - secure: "49ms3wjVftu9gsLRGCUZVlR6ezYD0KFoanXnGoYoSi9RjjRanPUAj9zHeIcPbeH7b/N29dX4YSTR64WdcxaOGDSjslkzqHY2kkeklQS19d7lTRn4Sa4wItYN1FMtg99wHSWZlxNjPpLI2KcfOwoVErh+PmIY1G6znHUsFOL2P/u96YKp+SPmqrc8eQEDjzFa574A5tQq40C5bSPNUXLrNJ1J+LnxMZ8Tw/z4ERnMSwtWgBcl2mU0O1XH4KSs2XNRi48xeyc8oVPnJ7DjVXPblh3qzIC1elOoZkcGYLfV7d3DvDOVWsC1Z7ZVDxeDqTJqdjDjInAed6pAB1pFoK7v/EMBhtzf+0M44qv2W6pZrwqxsLX0F9rMgVMfxG+72dQfR2sVFVZG73klJJ80miqgtUv6WEyf7uPeIeFAjDFpekxfoLI4n9817LHYfoOJOqVMJrhris8+ymFHu/l1kThkVbeoQVJlTgEesl7SRLu5fKqx5qpmwUNr123vBMaPF+EH0Aq5bHG1B/LGq9U73TxqC6zM3COAjDl0wmpGqhTopJ90IgjAZ1iTIVtMpmUfymwL7Ed2CWa6yqObdzoA4O7EjDvUEC+ysYKz3faRkxmqJ3utsuOFQH94CCYt8uFIEgfrGtconR9oc79kIaJmv7R0c/2BzeWoK2De2czQJrdYXGw="
+  #  ---
+
+  #  --- begin: DOCKER_USER and DOCKER_PASSWORD
+  #      + for apache/incubator-openwhisk-apigateway
+    - secure: "c8XNwdOryMVJUGLzWv+AzUQaS0Yt7uUmGqw+5/K7o7zmpux7Q5H7OU3jni2kOr+ZoIldsmTnnG7m1N9D8qUjD64KaAfEC0ybo04kDraezVMghUEV8LWMpSRRlAFpzQeVC8IcSiUEXM0H8E6Y09jGMnLKqyFUWAlDB60n0x2rfK/IPU+x4/h+6Y5XpYqaNtujoUf/2XVkrOeRcEhVZQJAwsRtA8HjRUy7PRB/9kepTSln9QzRZYd6v4F1qUKgZhlWNRUXWRbhrNK/z6T7jSlHjY44yvse4fBbie+EsuImtOHnDuTA4XXQlbc0gGVvD3sYYf2CBMxeeE+UTbRPLxgml+uUIviWKt/PKB5qUwQyLKP/Rzr1qv5RryrX0xWoqCrVsaCe0fkh0vUks0AYlzhm1CNK/g1If+qZ6R0GMjawVUbCunhDi1vJlP5PmniIoLpVwLa6XoMYJKtfngGm2763y00ktVGGL1gDtnm0lDuhkinIxOzieh8aRpYDBX6zZZ/n20LzDO/5l0CGErKPgzzt9vRPiQNoGxqC90jtsin+XkOxF9erk0QYt/St7/Qa1R0E+0dA2bHqxz2SWz3cjcc4Cw8/DW3SLFjaONvs6aQyHkrL2LJabARMMgGmf68P5nJrPy56c3gV8jXe7CVaV+5nClT1HYgWSEIna6oyzo8kzFk="
+    - secure: "dM0paMW2d4U4U7OwbnrTjdOqDnvo+nce9r7h+qTbYfbuJe0fpRkHCrxcB//8ESkMrPTr0EDExCxvaywY8pqeVVJbykNswdyze1SWYk6lbUvXTpSrKqp0J0a/FtVjfamc1aMv4c6KIDKh4vIcgK4xrjXj68COCS6uIcFhETNUy5bxH8T2BOJzyf/iWOF7oduXUV/VGNcWnhkPdoPh8xtpmBJ6ZTWQ01MriZ/28hvzgyh1OjJFWCJZ+OZoIDQVPb/jnfPXU4Wk/G/LEPJcBgvN4qSMr2lm3Iq29V0Ltrsx8rrYADO7trCm6qyEQK9TLKfywaYIcm/D9FJ8F4WBHtIeJ3PLY3518L3iZ+Ngd6QTnd0FI6hrG7rpoD/0dz4e//9d3tSsjbh/1BiQwXXTnPyaUjN3C92k4GyITYJTVL5f6evzsTneT6Plj1vWC0E52d1oqVOZDgrWMYZEHdYvpUJTQqclMNhu5SMIYAPqVvibqupcmAh5B+UDr6UvYT/hUAC/d3hyjfHgouRoluJ1mutND88QjDw6UWmXXjHqRSCI6OI5NDZczl/aqz7nPFyTaIe9EibTdZa5LC8fN+Am9MTRxJAv8HXt0zKe5FqHijSvFcVxYlhwlIZg7ShbPh+X2Hnh/JMjx0z/7ujkBRYfmAQW53SBy8Tv/Zv69nCz8eOFOUk="
+  #      + for jonpspri/incubator-openwhisk-apigateway
+    - secure: "q86rA9AwHBywzJkaLWu0UbA5QvKOao+23LTTrq5kpmmHRnolo1HlfHUG4cYFaRTVryqpA09ZYa0XFUCRLvI1KTxaAJkqmgzf88VXXDNulQB48QwTqhCEzU6hX3h/sgkU6WMpP3WPu5qws4Qxo/AV45Sb+sOKtRWbnyUdWqa8dqaGG8LSmiOX/hEIdaToXcnxZMMzCJ2fRSNngii9FbOxUbCPml9/HHJiuqT0xXegYQz3lgOKyApV1oj/g+Z7zkktme86NVTUJT6F9VSn4YRxTqEY8rYoFXiqYyW5wR+abNzF42RmtYFPKN+TbPPygotrzrooMGPstRcZ84c77OLK0XFNFLk92HLf/+Mau28qXW7id7/lSpkz4ogCTtbJUEotQhHkBCuivX6JEsvu1MoQjbzfzx5rJ2jybJo3bTriWkMXslgvabM1YVQOYZjXvtmhDycMUpjzC+TcT3N6lA/WE0wuTuDr2qeJC9xc8f4PAvInxZIiFUjKhRgizMbM31aRgy/ttCg7XsKUDEzj+HYmQo+OqHkMBF2AcHqtjQ6UPnZCUWTAlz1+ksYZjZZBahDh8T90bxj8sDEMSthG40zjLayWpruyUwyj/Ld/eggkaZKy6A/ANl9+gK4TTrs45lfrUVGH3OET1g2rDZIpI7rKaNPTFi2p70i6uD0Stlz2epc="
+    - secure: "jZIQ6Z1lxn/9L/CTMOKtgC+KLmO8ZRiVdYUw2bJPLKunPazTZDJLisbG6HGeVSlnHHak3RXbsMnySuoEriE1+Y2tEPAcXI0S6QXpDL4hf2hZGCcQ+Hyt5YX1y/q1vBwklajGSNkdFqplAnwgKsbAAEm+imq+aOno5NVZPlExL0mXOOtGcJmAYWteTdSHFfAJawXDyp/ORKOLdLN/RQfLr23Kte2KuAApp5xf1+GAcGvNdrAd0NhiYc/0EnqY7Bf4ngNUgC7izxKJOhJNwfzKM06Nk2mAUV9DTkRICISYfj7jb+fSWa2Q/9T0tVeferJWObLgG7jufdDpyTqDzwvwjrVrcJ3HMypGdlZmtt87zkDtTWcFduaBmbMJywgvJMnZtLb+Lhe2cKcMCNKK+fl6g4bOos56997yQXZWADRE73sNkwYlF0za8YCoZEiO829hGiAGjY5JvyFbUMNVdHRTwx6QkPu2p4YK+gV4aKnoCsBFx9hc70fNR/w/WK4aJVaCETIz4EYvwDvD/3sFNCjdy/zhdY7xIaNCWq0OargMggxdl1neqsiQoeWh2aNa6B4vdYGV6DFsoDdkqjcjQovtBLqV7gHFspxGUZm5oJfbaiLBHdd7b3D+eNfPCOSZ2NkK6AGid44TcC1kxI2wc+QDNvxLnIVySTcaeUqZQy12jXc="
+  #  ---
+
+  #  --- begin: DOCKER_EMAIL
+  #      + for apache/incubator-openwhisk-apigateway
+    - secure: "QoJIbU1brSezSNe7HzA54owOe3VRdRTj/XB94DXjpFgKevpthziAZqHisktx3JAYL9ctLGT60hBqltcou0B6+EvOerPh94zjIhTha+ZQxMGXA2MFVhFmgKUBoO+qRIn1haKKsxj+/a4lD+i2NXiFqjVvv6aIMjisCxrO89xAG9f9jx37tgBrw8WhjVIyfolL1MhUHz+e6shQu/MReByoY/4zW4QUsoe9d+Z9r6MblDQmpfGYZ5PHVe8TtAiz37IPhtDXBBwBBT84IY6Q+LbwPIe7LUGg3V0FMWTMqy5lagV7yVVJaeidPiMINhHmp74C3uaqe53Q2XmSXuZR6AxnAaBRxvQkMhCwxV9YL5QPiYZ/VvqSE8dB7DyLTZ0F5dfix2xd124k4Lbr03qrriR0Y8ybIVijIfOxMv980n+1LCn26SgY42hAEKqkG8wt0/Cs7va5nTaa55yGj5nNAuOm211EFQMGXrCY9ovrARwO+vHLugqELp7ZntPRDGde+5d/HIPPznCYKqSskA8XNw2SqvCBFvg8OL0c1cG1Sk9JMClws1LPAdq+QHH397gI1TVMOQl3ZhvJV2w5YWX1VZyTxHtIEZ+vr2GK1P0dEyecYCgYwUYrJ4H4Oo5P/N1jDDjzqnw8UMURUaOuWDDAfjDAA2XppBYOpFsoww8Oa1hDqqA="
+  #      + for jonpspri/incubator-openwhisk-apigateway
+    - secure: "iwOEWUxpmY8HWORjOgyx4SSS/Fgd25fSKHay00EB1+K5JjrbdUmT4H2d1A3LnOtOJq4/fKcW6gggaMANros8ULlSlU7BWGn6/oSO8nV+inysR93onCVlptwT9bAWKnv+HuklNS6IXsWLAcDjcPrq1/JbDVrSP9x/PJd7t6++z8NSXHsJ3/KFlCC+qlOb8qHEu2iqbJ2nKYKUOr+v3QemahnllNWm/QkaARt0BbjGYV83VGlb+3g3I2EJRZTH4IpENGVgzKf6GlpG986jn5sxxD8cK+aSkjh1u/NLxvliEghdnw54UN4AFFPf8e7MtTDthIxKDLfivcw6yvlXd5hvjJ2PTv7BmofiUp6AwqNJB1qZTOw5BFYdVBuGw4iqhbcdKjC4xBzsp6qfiVnwOUHdGokQtstjoQg5fIkKl+OzzOOaFnPKOxm9bOy0PK42k7dh0LtrSNcVMy9siNwkpdmy2rdOoCTpl5nk+JqtuwM6ieaODRM1SdTgNCB4Q4PohXfbKLuYgHWRicZeNrLK3pV6V+zu1j6IFYolwf5EZ/60Dmn75lltz67Fv+u1gQOvBifb4CurnwiapB1eVljfWTArjSefoqof0Y4yoKHDufx9gipCKSHTluCpu4pXPHjJ5T3GVmiaOtb4H2e5pMKy6cTMIfYFJb4nc1kVUobpVgUrVr0="
+  #  ---
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 148e79b..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,243 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more contributor
-# license agreements.  See the NOTICE file distributed with this work for additional
-# information regarding copyright ownership.  The ASF licenses this file to you
-# under the Apache License, Version 2.0 (the # "License"); you may not use this
-# file except in compliance with the License.  You may obtain a copy of the License
-# at:
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software distributed
-# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-# CONDITIONS OF ANY KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations under the License.
-#
-# apigateway
-#
-# VERSION               1.13.6.1
-#
-# From https://hub.docker.com/_/alpine/
-#
-FROM alpine:latest
-
-# install dependencies
-RUN apk --update add \
-    gcc tar libtool zlib jemalloc jemalloc-dev perl \
-    ca-certificates wget make musl-dev openssl-dev pcre-dev g++ zlib-dev curl python \
-    perl-test-longstring perl-list-moreutils perl-http-message geoip-dev dumb-init jq \
-    && update-ca-certificates \
-    && rm -rf /var/cache/apk/*
-
-# openresty build
-ENV OPENRESTY_VERSION=1.13.6.1 \
-    NAXSI_VERSION=0.53-2 \
-    PCRE_VERSION=8.37 \
-    TEST_NGINX_VERSION=0.24 \
-    OPM_VERSION=0.0.3 \
-    LUA_RESTY_HTTP_VERSION=0.10 \
-    LUA_RESTY_IPUTILS_VERSION=0.2.1 \
-    LUA_RESTY_STRING_VERSION=0.09 \
-    LUA_RESTY_LRUCACHE_VERSION=0.06 \
-    LUA_RESTY_CJOSE_VERSION=0.4 \
-    NETURL_LUA_VERSION=0.9-1 \
-    CJOSE_VERSION=0.5.1 \
-    LD_LIBRARY_PATH=/usr/local/lib \
-    _prefix=/usr/local \
-    _exec_prefix=/usr/local \
-    _localstatedir=/var \
-    _sysconfdir=/etc \
-    _sbindir=/usr/local/sbin
-
-RUN  if [ x`uname -m` = xs390x ]; then \
-         echo "Building LuaJIT for s390x" \
-	 && mkdir -p /tmp/luajit \
-	 && cd /tmp/luajit \
-	 && curl -k -L https://api.github.com/repos/linux-on-ibm-z/LuaJIT/tarball/v2.1 > luajit.tar.gz \
-	 && tar -zxf luajit.tar.gz \
-	 && cd linux-on-ibm-z-LuaJIT-* \
-	 && make install \
-	 && cd /tmp \
-	 && rm -rf /tmp/luajit \
-     ; fi
-
-RUN  if [ x`uname -m` = xppc64le ]; then \
-         echo "Building LuaJIT for ppc64le" \
-         && mkdir /tmp/luajit  \
-         && cd /tmp/luajit \
-         && curl -k -L https://api.github.com/repos/PPC64/LuaJIT/tarball > luajit.tar.gz \
-         && tar -zxf luajit.tar.gz \
-         && cd PPC64-LuaJIT-* \
-         && make && make install \
-         && rm -rf /tmp/luajit \
-     ; fi
-
-RUN  echo " ... adding Openresty, NGINX, NAXSI and PCRE" \
-     && mkdir -p /tmp/api-gateway \
-     && readonly NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) \
-     && echo "using up to $NPROC threads" \
-
-     && cd /tmp/api-gateway/ \
-     && curl -k -L https://github.com/nbs-system/naxsi/archive/${NAXSI_VERSION}.tar.gz -o /tmp/api-gateway/naxsi-${NAXSI_VERSION}.tar.gz \
-     && curl -k -L https://ftp.pcre.org/pub/pcre/pcre-${PCRE_VERSION}.tar.gz -o /tmp/api-gateway/pcre-${PCRE_VERSION}.tar.gz \
-     && curl -k -L https://openresty.org/download/openresty-${OPENRESTY_VERSION}.tar.gz -o /tmp/api-gateway/openresty-${OPENRESTY_VERSION}.tar.gz \
-     && tar -zxf ./openresty-${OPENRESTY_VERSION}.tar.gz \
-     && tar -zxf ./pcre-${PCRE_VERSION}.tar.gz \
-     && tar -zxf ./naxsi-${NAXSI_VERSION}.tar.gz \
-     && cd /tmp/api-gateway/openresty-${OPENRESTY_VERSION} \
-
-     && if [ x`uname -m` = xs390x ]; then \
-          luajitdir="=/usr/local/" \
-	  pcrejit="" \
-        ; elif [ x`uname -m` = xppc64le ]; then \
-          luajitdir="=/usr/local/" \
-          pcrejit="--with-pcre-jit" \
-        ; else \
-	  luajitdir="" \
-	  pcrejit="--with-pcre-jit" \
-	; fi \
-
-     && echo "        - building debugging version of the api-gateway ... " \
-     && ./configure \
-            --prefix=${_exec_prefix}/api-gateway \
-            --sbin-path=${_sbindir}/api-gateway-debug \
-            --conf-path=${_sysconfdir}/api-gateway/api-gateway.conf \
-            --error-log-path=${_localstatedir}/log/api-gateway/error.log \
-            --http-log-path=${_localstatedir}/log/api-gateway/access.log \
-            --pid-path=${_localstatedir}/run/api-gateway.pid \
-            --lock-path=${_localstatedir}/run/api-gateway.lock \
-            --add-module=../naxsi-${NAXSI_VERSION}/naxsi_src/ \
-            --with-pcre=../pcre-${PCRE_VERSION}/ ${pcrejit} \
-            --with-stream \
-            --with-stream_ssl_module \
-            --with-http_ssl_module \
-            --with-http_stub_status_module \
-            --with-http_realip_module \
-            --with-http_addition_module \
-            --with-http_sub_module \
-            --with-http_dav_module \
-            --with-http_geoip_module \
-            --with-http_gunzip_module  \
-            --with-http_gzip_static_module \
-            --with-http_auth_request_module \
-            --with-http_random_index_module \
-            --with-http_secure_link_module \
-            --with-http_degradation_module \
-            --with-http_auth_request_module  \
-            --with-http_v2_module \
-            --with-luajit${luajitdir} \
-            --without-http_ssi_module \
-            --without-http_userid_module \
-            --without-http_uwsgi_module \
-            --without-http_scgi_module \
-            --with-debug \
-            -j${NPROC} \
-    && make -j${NPROC} \
-    && make install \
-
-    && echo "        - building regular version of the api-gateway ... " \
-    && ./configure \
-            --prefix=${_exec_prefix}/api-gateway \
-            --sbin-path=${_sbindir}/api-gateway \
-            --conf-path=${_sysconfdir}/api-gateway/api-gateway.conf \
-            --error-log-path=${_localstatedir}/log/api-gateway/error.log \
-            --http-log-path=${_localstatedir}/log/api-gateway/access.log \
-            --pid-path=${_localstatedir}/run/api-gateway.pid \
-            --lock-path=${_localstatedir}/run/api-gateway.lock \
-            --add-module=../naxsi-${NAXSI_VERSION}/naxsi_src/ \
-            --with-pcre=../pcre-${PCRE_VERSION}/ ${pcrejit} \
-            --with-stream \
-            --with-stream_ssl_module \
-            --with-http_ssl_module \
-            --with-http_stub_status_module \
-            --with-http_realip_module \
-            --with-http_addition_module \
-            --with-http_sub_module \
-            --with-http_dav_module \
-            --with-http_geoip_module \
-            --with-http_gunzip_module  \
-            --with-http_gzip_static_module \
-            --with-http_auth_request_module \
-            --with-http_random_index_module \
-            --with-http_secure_link_module \
-            --with-http_degradation_module \
-            --with-http_auth_request_module  \
-            --with-http_v2_module \
-            --with-luajit${luajitdir} \
-            --without-http_ssi_module \
-            --without-http_userid_module \
-            --without-http_uwsgi_module \
-            --without-http_scgi_module \
-            -j${NPROC} \
-    && make -j${NPROC} \
-    && make install \
-
-    && echo "        - adding Nginx Test support" \
-    && curl -k -L https://github.com/openresty/test-nginx/archive/v${TEST_NGINX_VERSION}.tar.gz -o ${_prefix}/test-nginx-${TEST_NGINX_VERSION}.tar.gz \
-    && cd ${_prefix} \
-    && tar -xf ${_prefix}/test-nginx-${TEST_NGINX_VERSION}.tar.gz \
-    && rm ${_prefix}/test-nginx-${TEST_NGINX_VERSION}.tar.gz \
-    && cp -r ${_prefix}/test-nginx-0.24/inc/* /usr/local/share/perl5/site_perl/ \
-
-    && ln -s ${_sbindir}/api-gateway-debug ${_sbindir}/nginx \
-    && cp /tmp/api-gateway/openresty-${OPENRESTY_VERSION}/build/install ${_prefix}/api-gateway/bin/resty-install \
-    && apk del g++ gcc make \
-    && rm -rf /var/cache/apk/* \
-    && rm -rf /tmp/api-gateway
-
-RUN echo " ... installing opm..." \
-    && mkdir -p /tmp/api-gateway \
-    && curl -k -L https://github.com/openresty/opm/archive/v${OPM_VERSION}.tar.gz -o /tmp/api-gateway/opm-${OPM_VERSION}.tar.gz \
-    && tar -xf /tmp/api-gateway/opm-${OPM_VERSION}.tar.gz -C /tmp/api-gateway \
-    && cd /tmp/api-gateway/opm-${OPM_VERSION} \
-    && cp bin/opm ${_prefix}/api-gateway/bin \
-    && cd ${_prefix}/api-gateway \
-    && mkdir -p site/manifest site/pod \
-    && cd site \
-    && ( [ -x ../lualib ] || ln -s ../lualib ./ ) \
-    && ln -s ${_prefix}/api-gateway/bin/opm /usr/bin/opm \
-    && ln -s ${_prefix}/api-gateway/bin/resty /usr/bin/resty \
-    && rm -rf /tmp/api-gateway
-
-
-RUN echo " ... installing opm packages ... " \
-    && opm get pintsized/lua-resty-http=${LUA_RESTY_HTTP_VERSION} \
-               hamishforbes/lua-resty-iputils=${LUA_RESTY_IPUTILS_VERSION} \
-               openresty/lua-resty-string=${LUA_RESTY_STRING_VERSION} \
-               openresty/lua-resty-lrucache=${LUA_RESTY_LRUCACHE_VERSION} \
-               taylorking/lua-resty-cjose=${LUA_RESTY_CJOSE_VERSION} \
-               taylorking/lua-resty-rate-limit
-
-RUN echo " ... installing neturl.lua ... " \
-    && mkdir -p /tmp/api-gateway \
-    && curl -k -L https://github.com/golgote/neturl/archive/${NETURL_LUA_VERSION}.tar.gz -o /tmp/api-gateway/neturl.lua-${NETURL_LUA_VERSION}.tar.gz \
-    && tar -xf /tmp/api-gateway/neturl.lua-${NETURL_LUA_VERSION}.tar.gz -C /tmp/api-gateway/ \
-    && export LUA_LIB_DIR=${_prefix}/api-gateway/lualib \
-    && cd /tmp/api-gateway/neturl-${NETURL_LUA_VERSION} \
-    && cp lib/net/url.lua ${LUA_LIB_DIR} \
-    && rm -rf /tmp/api-gateway
-
-RUN echo " ... installing cjose ... " \
-    && apk update && apk add automake autoconf git gcc make jansson jansson-dev \
-    && mkdir -p /tmp/api-gateway \
-    && curl -L -k https://github.com/cisco/cjose/archive/${CJOSE_VERSION}.tar.gz -o /tmp/api-gateway/cjose-${CJOSE_VERSION}.tar.gz \
-    && tar -xf /tmp/api-gateway/cjose-${CJOSE_VERSION}.tar.gz -C /tmp/api-gateway/ \
-    && cd /tmp/api-gateway/cjose-${CJOSE_VERSION} \
-    && sh configure \
-    && make && make install \
-    && rm -rf /tmp/api-gateway
-
-ENV CONFIG_SUPERVISOR_VERSION 1.0.1-RC1
-COPY build_config_supervisor.sh /tmp/build_config_supervisor.sh 
-RUN sh +x /tmp/build_config_supervisor.sh 
-
-COPY init.sh /etc/init-container.sh
-# add the default configuration for the Gateway
-COPY . /etc/api-gateway
-RUN adduser -S nginx-api-gateway \
-    && addgroup -S nginx-api-gateway
-
-EXPOSE 80 8080 8423 9000
-
-ENTRYPOINT ["/usr/bin/dumb-init", "--"]
-CMD ["/etc/init-container.sh"]
diff --git a/Makefile b/Makefile
index 91f4517..c796fee 100644
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,7 @@ DOCKER_TAG ?= snapshot-`date +'%Y%m%d-%H%M'`
 DOCKER_REGISTRY ?= ''
 
 docker:
-	docker build -t openwhisk/apigateway .
+	docker_local_json='{"local":null}' ./gradlew core:apigateway:dockerBuildImage
 
 .PHONY: docker-ssh
 docker-ssh:
@@ -30,8 +30,7 @@ test-build:
 
 .PHONY: profile-build
 profile-build:
-	./build_profiling.sh
-	docker build -t openwhisk/apigateway-profiling -f Dockerfile.profiling .
+	./gradlew core:apigateway-profiling:dockerBuildImage
 
 .PHONY: profile-run
 profile-run: profile-build
@@ -69,7 +68,7 @@ docker-debug:
 	#Volumes directories must be under your Users directory
 	mkdir -p ${HOME}/tmp/apiplatform/apigateway
 	rm -rf ${HOME}/tmp/apiplatform/apigateway
-	cp -r `pwd` ${HOME}/tmp/apiplatform/apigateway/
+	cp -r $(pwd)/common/etc-api-gateway ${HOME}/tmp/apiplatform/apigateway/
 	docker run --name="apigateway" \
 			-p 80:80 -p 5000:5000 \
 			-e "LOG_LEVEL=info" -e "DEBUG=true" \
@@ -78,7 +77,7 @@ docker-debug:
 
 .PHONY: docker-reload
 docker-reload:
-	cp -r `pwd` ${HOME}/tmp/apiplatform/apigateway/
+	cp -r $(pwd)/common/etc-api-gateway ${HOME}/tmp/apiplatform/apigateway/
 	docker exec apigateway api-gateway -t -p /usr/local/api-gateway/ -c /etc/api-gateway/api-gateway.conf
 	docker exec apigateway api-gateway -s reload
 
diff --git a/README.md b/README.md
index bd0e3ea..8ea1f26 100644
--- a/README.md
+++ b/README.md
@@ -1,32 +1,32 @@
 <!--
 #
 # Licensed to the Apache Software Foundation (ASF) under one or more contributor
-# license agreements.  See the NOTICE file distributed with this work for additional
-# information regarding copyright ownership.  The ASF licenses this file to you
+# license agreements. See the NOTICE file distributed with this work for additional
+# information regarding copyright ownership. The ASF licenses this file to you
 # under the Apache License, Version 2.0 (the # "License"); you may not use this
-# file except in compliance with the License.  You may obtain a copy of the License
+# file except in compliance with the License. You may obtain a copy of the License
 # at:
 #
 # http://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software distributed
 # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-# CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+# CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
 #
 -->
 
-OpenWhisk API Gateway
-=============
+# OpenWhisk API Gateway
+
 [![Build Status](https://travis-ci.org/apache/incubator-openwhisk-apigateway.svg?branch=master)](https://travis-ci.org/apache/incubator-openwhisk-apigateway)
 [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0)
 
 A performant API Gateway based on Openresty and NGINX.
 
-Project status
----------------
-This project is currently considered beta stage, Large swaths of code or APIs may change.
+## Project status
 
+This project is currently considered beta stage, Large swaths of code or APIs
+may change.
 
 ## Table of Contents
 
@@ -36,7 +36,6 @@ This project is currently considered beta stage, Large swaths of code or APIs ma
   * [Running locally](#running-locally)
   * [Testing](#testing)
 
-
 ## Quick Start
 
 ```
@@ -50,8 +49,9 @@ docker run -p 80:80 -p <managedurl_port>:8080 -p 9000:9000 \
 ```
 
 ## API
-- [v2 Management Interface](https://github.com/openwhisk/openwhisk-apigateway/blob/master/doc/v2/management_interface_v2.md)
-- [v1 Management Interface](https://github.com/openwhisk/openwhisk-apigateway/blob/master/doc/v1/management_interface_v1.md)
+
+* [v2 Management Interface](https://github.com/openwhisk/openwhisk-apigateway/blob/master/doc/v2/management_interface_v2.md)
+* [v1 Management Interface](https://github.com/openwhisk/openwhisk-apigateway/blob/master/doc/v1/management_interface_v1.md)
 
 ## Syncing configuration from a remote source
 
@@ -85,24 +85,54 @@ Then make changes to any configuration file ( i.e. `api-gateway.conf` ), save it
 ### Running locally
 
  To build the docker image locally use:
+
  ```
   make docker
  ```
 
  To Run the Docker image
+
  ```
-  make docker-run PUBLIC_MANAGEDURL_HOST=<mangedurl_host> PUBLIC_MANAGEDURL_PORT=<managedurl_port> \
-    REDIS_HOST=<redis_host> REDIS_PORT=<redis_port> REDIS_PASS=<redis_pass>
+ make docker-run \
+    PUBLIC_MANAGEDURL_HOST=<mangedurl_host> \
+    PUBLIC_MANAGEDURL_PORT=<managedurl_port> \
+    REDIS_HOST=<redis_host> REDIS_PORT=<redis_port> \
+    REDIS_PASS=<redis_pass>
  ```
 
-
 ### Testing
 
  First install the necessary dependencies:
+
  ```
   make test-build
  ```
+
  Then, run the unit tests:
+
  ```
   make test-run
  ```
+
+### Multi-architecture build
+
+ The API Gateway has been converted to support multi-architecture builds for
+ the standard (non-profiling) build. As a result, all builds are now managed
+ by the Gradle build tool. For backward compatibility, the `Makefile` can be
+ used to execute the builds and runs as always.
+
+ For more information on building a multiarchitecture OpenWhisk image, see
+ [this document](https://github.com/apache/incubator-openwhisk/blob/master/docs/runtimes-multiarch.md).
+ The Gradle project for base image builds is `:core:apigateway`.
+
+### Profiling image
+
+ A Docker image build is available for profiling, utilizing
+ [SystemTap](https://sourceware.org/systemtap/). The image is intented to be
+ built and run on the same system, where monitoring will be run. During build,
+ It copies kernel headers from the local system, expecting to find them from
+ the local system, expecting to find them at
+ `/usr/src/kernel-headers-$(uname -r)`.
+
+ To build the profiling image, use `make profile-build`. To run it, use
+ `make profile-run`.
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..10b18d9
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,310 @@
+/*
+    NOTE TO MAINTAINERS:
+
+    You should not need to change this file to configure your specific
+    action image.  Image specific configurations occur in:
+
+        ./docker-local.gradle -- for secrets/configurations that should NOT
+            be uploaded to GitHub for the world to see
+        ./settings.grade -- for listing the projects (and imageNames) to build
+        ./.../build.grade -- for subproject-specific configurations
+
+    Note:  The writing is on the wall that as other project builds come into
+           play this module may need to move, perhaps to core/build.gradle or
+           to an included directory.  But we shall persevere for the time
+           being in keeping it here where it's obvious that a lot is going on.
+ */
+
+buildscript {
+    repositories {
+        jcenter()
+        mavenLocal()
+        maven {
+            url  "http://dl.bintray.com/jonpspri/gradle-plugins/"
+        }
+    }
+    dependencies {
+        classpath "cz.alenkacz:gradle-scalafmt:${gradle.scalafmt.version}"
+        classpath 'org.ajoberstar:grgit:2.1.0'
+        classpath 'com.bmuschko:gradle-docker-plugin:3.2.5'
+        classpath 'com.xanophis:gradle-fatmanifest-plugin:0.0.5'
+    }
+}
+
+import com.bmuschko.gradle.docker.DockerRegistryCredentials
+import com.bmuschko.gradle.docker.tasks.DockerInfo
+import com.bmuschko.gradle.docker.tasks.image.*
+
+//  There are some serious naming mismatchees to be dealt with in v0.0.6 of gradle-fatmanifest-plugin :(
+import com.s390x.gradle.multidocker.tasks.*
+
+/*
+    So you called a registry method without providing any registry
+    credentials?  Shame on you!  This warning (which likely needs editing) will
+    put you back on the straight and narrow.
+
+    Located here in the code so it's available within all necessary blocks.
+ */
+private def warnNoRegistryCredentials() {
+    logger.warning """
+    |You are attempting a registry task without having provided registry
+    |credentials.  Registry credentials should be provided in the
+    |'./docker-local.gradle' file.  See './docker-local.gradle.sample' for
+    |an example.  Meanwhile, this action does nothing.
+    |""".stripMargin()
+}
+
+/*
+    These two lists will hold the projects to be managed throughout the
+    remainder of the process -- the 'top-level' builds and the individual
+    architecture builds created beneath each of them.
+
+    Note:  The lists could possible be created by re-constructing the project
+    paths, which in a performance-oriented system I'd consider doing.  But
+    the findAll based approach works for now, and provides flexibility if we
+    add later capability to settings to gradle to select only certain builds
+    for certain projects (more of a matrix)
+ */
+Collection<Project> buildProjects = subprojects.findAll { subproject ->
+        gradle.dockerBuildProjects.containsKey(subproject.path)
+    }
+
+Collection<Project> individualArchProjects = buildProjects.collectMany { buildProject ->
+        buildProject.subprojects.findAll() {
+            gradle.architectures.containsKey(it.name)
+        }
+    }
+
+/*
+    Every project in ':core:* is some form of Docker build for the action image
+    and is therefore assumed to need to be able to push a Manifest List for
+    eventual publication.  This block activates the Docker and Manifest List
+    plugins and configures them from information provided in the docker-local
+    file.  Recall that the docker-local file was loaded in
+    settings.gradle and applied as extension properties to the gradle object.
+
+    The :core:* projects (parent projects) should all have been set up and
+    logged in 'grade.dockerBuildProjects' (by settings.gradle), along with the
+    image name for each.  This is where we pull that image name and configure it
+    into the project.
+
+    Why put it in a gradle extension property first?  Frankly, we don't want
+    to wait for it to be set in a project-specific build.gradle, and we want
+    to limit configuration to the project-specific build.gradle and to the
+    settings.gradle.  This (root) build.gradle should rarely have to change.
+
+    (Side note:  Maybe these need to be in a plugin or sub-file, but IMO that
+    actually makes maintenance more difficult.)
+ */
+
+configure (buildProjects) {
+    buildscript.repositories { jcenter() }
+
+    logger.info ("Configuring subproject '${path}'")
+
+    /*
+        We only configure Manifest List processing if registryCredentials exist,
+        because otherwise what's the point?
+    */
+    if (gradle?.registryCredentials) {
+        apply plugin: 'com.s390x.gradle.multidocker'
+
+        logger.debug "Applying registry credentials to ${it.path}"
+        multidocker.registry('default',gradle.registryCredentials)
+    }
+
+    /*
+        Retrieve project properties from the Map created in settings.gradle
+        and apply to the projects.  Now the properties are available during
+        configuration in the remainder of this script.
+     */
+    logger.info "Setting properties for ${path}"
+    gradle.dockerBuildProjects[path].each { k,v -> ext.set(k,v) }
+    ext.dockerRegistry = gradle.dockerRegistry
+    logger.info "Project ${path} has dockerImageName of ${dockerImageName}"
+}
+
+/*
+    Each architecture gets its own project sharing a project directory with the
+    root project.  It's EXPECTED (but not required) for the local build scripts
+    to override the build directory with architecture-specific build directories
+    as needed, which will also ease maintenance of the source tree for docker
+    builds.
+
+    Notice that in the block, we ensure that parent tasks are dependent on
+    the underlying architecture tasks.  That way, we can still
+    './gradlew core:<image>:<task>' and all architectures will be built.
+ */
+
+configure (individualArchProjects) {
+    buildscript.repositories { jcenter() }
+
+    logger.info ("Configuring subproject '${path}'")
+
+    //  Since this is an architecture-specific subproject, we can copy all the
+    //  properties from the parent project to make our code more readable
+    parent.ext.properties.each { k,v -> ext.set(k,v) }
+
+    apply plugin: 'com.bmuschko.docker-remote-api'
+    docker {
+        /*
+            Since we survived the findAll, we know this architecture exists,
+            which means fewer guard clauses.  Hooray!
+         */
+        if (gradle.architectures[name]?.url) {
+            // Don't overwrite a default if it was defined!
+            url = gradle.architectures[name].url
+        }
+        if (gradle.architectures[name]?.certPath) {
+            certPath = rootProject.file(gradle.architectures[name].certPath)
+        }
+
+        /*
+            Yet another place to check whether registryCredentials were
+            actually provided.  It could be simplified by providing meaningless
+            defaults, but it's a bit clearer this way that there's a
+            responsiblity for the runtime developer.
+         */
+        if (gradle?.registryCredentials) registryCredentials {
+            url = gradle.registryCredentials.url
+            username = gradle.registryCredentials.username
+            password = gradle.registryCredentials.password
+            email = gradle.registryCredentials.email
+        }
+    }
+
+    task dockerInfo(type: DockerInfo) {
+        onNext {
+            logger.quiet "Docker Info retreived for project ${project.name}:"
+            logger.quiet "  OSType = ${it.osType}"
+            logger.quiet "  Architecture = ${it.architecture}"
+            owner.ext.dockerInfo = it
+        }
+    }
+    (parent.tasks.find() {it.name=='dockerInfo'} ?: parent.task('dockerInfo'))\
+        .dependsOn dockerInfo
+
+    task dockerBuildImage(type: DockerBuildImage) {
+        /*
+            Recommended default for inputDir
+         */
+        inputDir = file("${project.projectDir}/build/docker/${project.name}")
+
+        /*
+            The tags list is out of hand and is doing a bang-up job of making
+            my local docker repository messy.  However, I haven't really
+            gotten a handle on what's needed and what's not.  For example,
+            the dockerRegistry tag should probably be conditional.  The
+            prefixed tag seems critical, however, to working with local-build
+            openwhisk deployments.
+         */
+
+        //  Is this an appropriate prefix?  Perhaps we should use 'whisk' as the
+        //  default local-build prefix?  Again -- not sure I have a sense of tags.
+        def prefix = findProperty('dockerImagePrefix') ?: 'openwhisk'
+        def tag = findProperty('dockerImageTag') ?: 'latest'
+
+        //  Note that project.name will be the docker engine name from settings.gradle
+        //  We could set up an option to declare suffixes in docker.gradle, but so far
+        //  this works.
+        tags = [   // Return a list of tags build from the environment
+                "${parent.dockerImageName}:${tag}",
+                "${parent.dockerImageName}:${tag}-${project.name}",
+                "${prefix}/${parent.dockerImageName}:${tag}-${project.name}"
+        ] as String[]
+
+        //  This tag is created to support uploads if there's a target registry.
+        //  Note that the script DOES NOT support multiple target registries.
+        //  As of the writing, there was no need to.
+        if (dockerRegistry) {
+            tags += new String("${dockerRegistry}/${prefix}/"+
+                "${parent.dockerImageName}:${tag}-${project.name}")
+        }
+    }
+    (parent.tasks.find() {it.name=='dockerBuildImage'} ?: parent.task('dockerBuildImage'))\
+        .dependsOn dockerBuildImage
+
+    /*
+        Pushing images and getting manifests only makes sense if registry
+        credentials were provided, we we make this block conditional.  If
+        no credentials were provided, the tasks will instead display a warning
+        and point to a tutorial on docker-local.gradle.
+     */
+    if (gradle?.registryCredentials) {
+        task dockerPushImage(type: DockerPushImage, dependsOn: dockerBuildImage) {
+            imageName = "${dockerRegistry}/" +
+                "${findProperty('dockerImagePrefix') ?: 'openwhisk'}/" +
+                "${parent.dockerImageName}"
+            tag = "${findProperty('dockerImageTag') ?: 'latest'}-${project.name}"
+        }
+        (parent.tasks.find() {it.name=='dockerPushImage'} ?: parent.task('dockerPushImage'))\
+            .dependsOn dockerPushImage
+
+        task getImageManifest(type: GetImageManifest, dependsOn: [ dockerPushImage, dockerInfo ] ) {
+
+            targetRegistry = 'default'
+
+            imageName =
+                "${findProperty('dockerImagePrefix') ?: 'openwhisk'}/${parent.dockerImageName}"
+            tag = "${findProperty('dockerImageTag') ?: 'latest'}-${project.name}"
+
+            //  Store the relevant details of the received manifest as an
+            //  extension of the task.
+            onNext {
+                logger.quiet "Manifest retreived for ${imageName}:${tag}"
+                logger.quiet "  Digest: ${it.digest}"
+                logger.quiet "  Media Type: ${it.mediaType}"
+                logger.quiet "  Size: ${it.size}"
+
+                owner.ext.manifestMap = [
+                    mediaType: it.mediaType,
+                    digest: it.digest,
+                    size: it.size,
+                    os: project.dockerInfo.dockerInfo.osType,
+                    architecture: project.dockerInfo.dockerInfo.architecture
+                ]
+            }
+        }
+        (parent.tasks.find() {it.name=='getImageManifest'} ?: parent.task('getImageManifest'))\
+            .dependsOn getImageManifest
+    } else {
+        task dockerPushImage() { warnNoRegistryCredentials() }
+        task getImageManifest() { warnNoRegistryCredentials() }
+    }
+}
+
+/*
+    And now, the Manifest List.  It's a multi-architecture manifest, so there's
+    no point to putting it in the individual architecture builds.  Instead, it
+    will collect the individual manifests from the getManifest steps.
+ */
+configure (buildProjects) {
+    if (gradle?.registryCredentials) {
+        task putManifestList(type: PutManifestList, dependsOn: 'getImageManifest') {
+
+            targetRegistry = 'default'
+
+            imageName = "${findProperty('dockerImagePrefix') ?: 'openwhisk'}/" +
+                "${project.dockerImageName}"
+            // TODO - Project property candidate to support release builds?
+            tag = "${findProperty('dockerImageTag') ?: 'latest' }"
+
+            /*
+                Collect the manifests to be built from the subprojects
+             */
+            project.subprojects.collectMany { subproject ->
+                subproject.tasks.withType(GetImageManifest)
+            }.each { task ->
+                logger.info "Adding manifest ${it.path} to Manifest List"
+                manifests << { task.manifestMap }
+            }
+        }
+    } else {
+        task putManifestList() { warnNoRegistryCredentials() }
+    }
+}
+
+subprojects {
+    apply plugin: 'scalafmt'
+    scalafmt.configFilePath = gradle.scalafmt.config
+}
diff --git a/build_profiling.sh b/build_profiling.sh
deleted file mode 100755
index 088f18d..0000000
--- a/build_profiling.sh
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/bin/bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-cp Dockerfile Dockerfile.profiling
-
-sed -i -e 's/FROM\ alpine.*//g' "Dockerfile.profiling"
-sed -i -e 's/apk\ update/apt-get\ update/g' "Dockerfile.profiling"
-sed -i -e 's/apk\ add/apt-get\ install\ -y/g' "Dockerfile.profiling"
-sed -i -e 's/apk\ del/apt-get\ remove\ -y/g' "Dockerfile.profiling"
-sed -i -e 's/pcre-dev/libpcre2-dev/g' "Dockerfile.profiling"
-sed -i -e 's/zlib/zlibc/g' "Dockerfile.profiling"
-sed -i -e 's/zlibc-dev/lua-zlib\ lua-zlib-dev/g' "Dockerfile.profiling"
-sed -i -e 's/perl-test-longstring/libtest-longstring-perl/g' "Dockerfile.profiling"
-sed -i -e 's/perl-list-moreutils/liblist-moreutils-perl/g' "Dockerfile.profiling"
-sed -i -e 's/perl-http-message/libhttp-message-perl/g' "Dockerfile.profiling"
-sed -i -e 's/geoip-dev/libgeoip-dev/g' "Dockerfile.profiling"
-sed -i -e 's/jemalloc/libjemalloc1/g' "Dockerfile.profiling"
-sed -i -e 's/libjemalloc1-dev/libjemalloc-dev/g' "Dockerfile.profiling"
-sed -i -e 's/openssl-dev/libssl-dev/g' "Dockerfile.profiling"
-sed -i -e 's/--with-debug/--with-debug\ --with-dtrace-probes/g' "Dockerfile.profiling"
-sed -i -e 's/OPENRESTY_VERSION=.*\ /OPENRESTY_VERSION=1.11.2.2\ /g' "Dockerfile.profiling"
-sed -i -e 's/adduser\ -S.*/useradd\ nginx-api-gateway/g' "Dockerfile.profiling"
-sed -i -e 's/&&\ addgroup.*//g' "Dockerfile.profiling"
-sed -i -e 's/ENTRYPOINT.*//g' "Dockerfile.profiling"
-sed -i -e 's/CMD.*//g' "Dockerfile.profiling"
-
-cp api-gateway.conf api-gateway.conf.profiling
-sed -i -e 's/worker_processes\ *auto;/worker_processes\ 1;/g' "api-gateway.conf.profiling"
-
-cat .profiling.before | cat - Dockerfile.profiling > /tmp/out && mv /tmp/out Dockerfile.profiling
-cat Dockerfile.profiling | cat - .profiling.after > /tmp/out && mv /tmp/out Dockerfile.profiling
-
-if [[ -f "Dockerfile.profiling-e" ]]; then
-	rm Dockerfile.profiling-e
-fi
diff --git a/api-gateway.conf b/common/api-gateway.conf.in
similarity index 96%
rename from api-gateway.conf
rename to common/api-gateway.conf.in
index f82e06f..9e1cdc8 100644
--- a/api-gateway.conf
+++ b/common/api-gateway.conf.in
@@ -22,7 +22,7 @@
 # */
 #user                 nginx-api-gateway;
 user                 root;
-worker_processes     auto;
+worker_processes     ${worker_processes};
 worker_rlimit_nofile 524288; # 100000
 
 env REDIS_HOST;
@@ -57,7 +57,7 @@ events {
     multi_accept on;
 }
 
-pcre_jit on;
+pcre_jit ${pcre_jit.call()};
 # error_log  /var/log/api-gateway/error.log warn;
 
 http {
diff --git a/common/build-scripts/build-openresty.sh b/common/build-scripts/build-openresty.sh
new file mode 100644
index 0000000..e49bc4d
--- /dev/null
+++ b/common/build-scripts/build-openresty.sh
@@ -0,0 +1,109 @@
+#!/bin/bash
+
+set -euo pipefail
+
+#
+#  The profiling setup will have dtrace installed, so
+#  we should use it in the configuration
+#
+if command -v dtrace; then
+    debug_options="--with-debug --with-dtrace-probes"
+else
+    debug_options="--with-debug"
+fi
+
+#
+#  The api-gateway.conf file should have been copied and will likely tell us
+#  whether to install PCRE JIT
+#
+if grep 'pcre_jit *yes' /etc/api-gateway/api-gateway.conf; then
+    with_pcre_jit="--with-pcre-jit"
+else
+    with_pcre_jit=""
+fi
+
+case "$(uname -m)" in
+    s390x)
+         echo "Building LuaJIT for s390x"
+         curl -sSL https://api.github.com/repos/linux-on-ibm-z/LuaJIT/tarball/v2.1 \
+         | tar -C /tmp -zxf -
+         (cd /tmp/linux-on-ibm-z-LuaJIT-* && make install)
+         rm -rf /tmp/luajit.tar.gz /tmp/linux-on-ibm-z-LuaJIT-*
+         luajitdir="=/usr/local/"
+         ;;
+    ppc64le)
+        echo "Building LuaJIT for ppc64le"
+        curl -sSL https://api.github.com/repos/PPC64/LuaJIT/tarball \
+        | tar -C /tmp -zxf -
+        (cd /tmp/PPC64-LuaJIT-* && make install)
+        rm -rf /tmp/luajit.tar.gz /tmp/PPC64-LuaJIT-*
+        luajitdir="=/usr/local/"
+        ;;
+    *)
+        echo "Configuring for $(uname -m)"
+        luajitdir=""
+        ;;
+esac
+
+echo " ... adding Openresty, NGINX, NAXSI and PCRE"
+mkdir -p /tmp/api-gateway
+readonly NPROC="$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1)"
+echo "using up to $NPROC threads"
+
+curl -sSL "https://github.com/nbs-system/naxsi/archive/${NAXSI_VERSION}.tar.gz" \
+    | tar -C /tmp/api-gateway -zxf -
+
+curl -sSL "https://ftp.pcre.org/pub/pcre/pcre-${PCRE_VERSION}.tar.gz" \
+    | tar -C /tmp/api-gateway -zxf -
+
+curl -sSL "https://openresty.org/download/openresty-${OPENRESTY_VERSION}.tar.gz" \
+    | tar -C /tmp/api-gateway -zxf -
+
+echo "        - building debugging version of the api-gateway ... "
+for with_debug in "$debug_options" ""; do (
+    cd "/tmp/api-gateway/openresty-${OPENRESTY_VERSION}"
+    echo "Building with debug options '$with_debug'"
+    ./configure \
+            --prefix="${_exec_prefix}/api-gateway" \
+            --sbin-path="${_sbindir}/api-gateway-debug" \
+            --conf-path="${_sysconfdir}/api-gateway/api-gateway.conf" \
+            --error-log-path="${_localstatedir}/log/api-gateway/error.log" \
+            --http-log-path="${_localstatedir}/log/api-gateway/access.log" \
+            --pid-path="${_localstatedir}/run/api-gateway.pid" \
+            --lock-path="${_localstatedir}/run/api-gateway.lock" \
+            --add-module="../naxsi-${NAXSI_VERSION}/naxsi_src/" \
+            --with-pcre="../pcre-${PCRE_VERSION}/" \
+            $with_pcre_jit \
+            --with-stream \
+            --with-stream_ssl_module \
+            --with-http_ssl_module \
+            --with-http_stub_status_module \
+            --with-http_realip_module \
+            --with-http_addition_module \
+            --with-http_sub_module \
+            --with-http_dav_module \
+            --with-http_geoip_module \
+            --with-http_gunzip_module \
+            --with-http_gzip_static_module \
+            --with-http_auth_request_module \
+            --with-http_random_index_module \
+            --with-http_secure_link_module \
+            --with-http_degradation_module \
+            --with-http_auth_request_module \
+            --with-http_v2_module \
+            "--with-luajit${luajitdir}" \
+            --without-http_ssi_module \
+            --without-http_userid_module \
+            --without-http_uwsgi_module \
+            --without-http_scgi_module \
+            $with_debug \
+            "-j$NPROC"
+    make "-j$NPROC" install
+); done
+
+mkdir -p "${_prefix}/api-gateway/bin"
+cp "/tmp/api-gateway/openresty-${OPENRESTY_VERSION}/build/install" \
+    "${_prefix}/api-gateway/bin/resty-install"
+rm -rf /tmp/api-gateway
+
+# VIM: let b:syntastic_sh_shellcheck_args = "-e SC2154"
diff --git a/build_config_supervisor.sh b/common/build_config_supervisor.sh
similarity index 100%
rename from build_config_supervisor.sh
rename to common/build_config_supervisor.sh
diff --git a/conf.d/api_gateway_init.conf b/common/etc-api-gateway/conf.d/api_gateway_init.conf
similarity index 100%
rename from conf.d/api_gateway_init.conf
rename to common/etc-api-gateway/conf.d/api_gateway_init.conf
diff --git a/conf.d/api_gateway_logging.conf b/common/etc-api-gateway/conf.d/api_gateway_logging.conf
similarity index 100%
rename from conf.d/api_gateway_logging.conf
rename to common/etc-api-gateway/conf.d/api_gateway_logging.conf
diff --git a/conf.d/blacklist.conf b/common/etc-api-gateway/conf.d/blacklist.conf
similarity index 100%
rename from conf.d/blacklist.conf
rename to common/etc-api-gateway/conf.d/blacklist.conf
diff --git a/conf.d/commons/common-headers.conf b/common/etc-api-gateway/conf.d/commons/common-headers.conf
similarity index 100%
rename from conf.d/commons/common-headers.conf
rename to common/etc-api-gateway/conf.d/commons/common-headers.conf
diff --git a/conf.d/default.conf b/common/etc-api-gateway/conf.d/default.conf
similarity index 100%
rename from conf.d/default.conf
rename to common/etc-api-gateway/conf.d/default.conf
diff --git a/conf.d/includes/analytics_endpoints.conf b/common/etc-api-gateway/conf.d/includes/analytics_endpoints.conf
similarity index 100%
rename from conf.d/includes/analytics_endpoints.conf
rename to common/etc-api-gateway/conf.d/includes/analytics_endpoints.conf
diff --git a/conf.d/includes/basic_endpoints.conf b/common/etc-api-gateway/conf.d/includes/basic_endpoints.conf
similarity index 100%
rename from conf.d/includes/basic_endpoints.conf
rename to common/etc-api-gateway/conf.d/includes/basic_endpoints.conf
diff --git a/conf.d/managed_endpoints.conf b/common/etc-api-gateway/conf.d/managed_endpoints.conf
similarity index 100%
rename from conf.d/managed_endpoints.conf
rename to common/etc-api-gateway/conf.d/managed_endpoints.conf
diff --git a/conf.d/management_apis.conf b/common/etc-api-gateway/conf.d/management_apis.conf
similarity index 100%
rename from conf.d/management_apis.conf
rename to common/etc-api-gateway/conf.d/management_apis.conf
diff --git a/html/index.html b/common/etc-api-gateway/html/index.html
similarity index 100%
rename from html/index.html
rename to common/etc-api-gateway/html/index.html
diff --git a/naxsi_core.rules b/common/etc-api-gateway/naxsi_core.rules
similarity index 100%
rename from naxsi_core.rules
rename to common/etc-api-gateway/naxsi_core.rules
diff --git a/scripts/lua/api_gateway_init.lua b/common/etc-api-gateway/scripts/lua/api_gateway_init.lua
similarity index 100%
rename from scripts/lua/api_gateway_init.lua
rename to common/etc-api-gateway/scripts/lua/api_gateway_init.lua
diff --git a/scripts/lua/cors.lua b/common/etc-api-gateway/scripts/lua/cors.lua
similarity index 100%
rename from scripts/lua/cors.lua
rename to common/etc-api-gateway/scripts/lua/cors.lua
diff --git a/scripts/lua/lib/dataStore.lua b/common/etc-api-gateway/scripts/lua/lib/dataStore.lua
similarity index 100%
rename from scripts/lua/lib/dataStore.lua
rename to common/etc-api-gateway/scripts/lua/lib/dataStore.lua
diff --git a/scripts/lua/lib/logger.lua b/common/etc-api-gateway/scripts/lua/lib/logger.lua
similarity index 100%
rename from scripts/lua/lib/logger.lua
rename to common/etc-api-gateway/scripts/lua/lib/logger.lua
diff --git a/scripts/lua/lib/redis.lua b/common/etc-api-gateway/scripts/lua/lib/redis.lua
similarity index 100%
rename from scripts/lua/lib/redis.lua
rename to common/etc-api-gateway/scripts/lua/lib/redis.lua
diff --git a/scripts/lua/lib/request.lua b/common/etc-api-gateway/scripts/lua/lib/request.lua
similarity index 100%
rename from scripts/lua/lib/request.lua
rename to common/etc-api-gateway/scripts/lua/lib/request.lua
diff --git a/scripts/lua/lib/utils.lua b/common/etc-api-gateway/scripts/lua/lib/utils.lua
similarity index 100%
rename from scripts/lua/lib/utils.lua
rename to common/etc-api-gateway/scripts/lua/lib/utils.lua
diff --git a/scripts/lua/management/lib/apis.lua b/common/etc-api-gateway/scripts/lua/management/lib/apis.lua
similarity index 100%
rename from scripts/lua/management/lib/apis.lua
rename to common/etc-api-gateway/scripts/lua/management/lib/apis.lua
diff --git a/scripts/lua/management/lib/resources.lua b/common/etc-api-gateway/scripts/lua/management/lib/resources.lua
similarity index 100%
rename from scripts/lua/management/lib/resources.lua
rename to common/etc-api-gateway/scripts/lua/management/lib/resources.lua
diff --git a/scripts/lua/management/lib/subscriptions.lua b/common/etc-api-gateway/scripts/lua/management/lib/subscriptions.lua
similarity index 100%
rename from scripts/lua/management/lib/subscriptions.lua
rename to common/etc-api-gateway/scripts/lua/management/lib/subscriptions.lua
diff --git a/scripts/lua/management/lib/swagger.lua b/common/etc-api-gateway/scripts/lua/management/lib/swagger.lua
similarity index 100%
rename from scripts/lua/management/lib/swagger.lua
rename to common/etc-api-gateway/scripts/lua/management/lib/swagger.lua
diff --git a/scripts/lua/management/lib/tenants.lua b/common/etc-api-gateway/scripts/lua/management/lib/tenants.lua
similarity index 100%
rename from scripts/lua/management/lib/tenants.lua
rename to common/etc-api-gateway/scripts/lua/management/lib/tenants.lua
diff --git a/scripts/lua/management/lib/validation.lua b/common/etc-api-gateway/scripts/lua/management/lib/validation.lua
similarity index 100%
rename from scripts/lua/management/lib/validation.lua
rename to common/etc-api-gateway/scripts/lua/management/lib/validation.lua
diff --git a/scripts/lua/management/routes/apis.lua b/common/etc-api-gateway/scripts/lua/management/routes/apis.lua
similarity index 100%
rename from scripts/lua/management/routes/apis.lua
rename to common/etc-api-gateway/scripts/lua/management/routes/apis.lua
diff --git a/scripts/lua/management/routes/subscriptions.lua b/common/etc-api-gateway/scripts/lua/management/routes/subscriptions.lua
similarity index 100%
rename from scripts/lua/management/routes/subscriptions.lua
rename to common/etc-api-gateway/scripts/lua/management/routes/subscriptions.lua
diff --git a/scripts/lua/management/routes/tenants.lua b/common/etc-api-gateway/scripts/lua/management/routes/tenants.lua
similarity index 100%
rename from scripts/lua/management/routes/tenants.lua
rename to common/etc-api-gateway/scripts/lua/management/routes/tenants.lua
diff --git a/scripts/lua/oauth/app-id.lua b/common/etc-api-gateway/scripts/lua/oauth/app-id.lua
similarity index 100%
rename from scripts/lua/oauth/app-id.lua
rename to common/etc-api-gateway/scripts/lua/oauth/app-id.lua
diff --git a/scripts/lua/oauth/facebook.lua b/common/etc-api-gateway/scripts/lua/oauth/facebook.lua
similarity index 100%
rename from scripts/lua/oauth/facebook.lua
rename to common/etc-api-gateway/scripts/lua/oauth/facebook.lua
diff --git a/scripts/lua/oauth/github.lua b/common/etc-api-gateway/scripts/lua/oauth/github.lua
similarity index 100%
rename from scripts/lua/oauth/github.lua
rename to common/etc-api-gateway/scripts/lua/oauth/github.lua
diff --git a/scripts/lua/oauth/google.lua b/common/etc-api-gateway/scripts/lua/oauth/google.lua
similarity index 100%
rename from scripts/lua/oauth/google.lua
rename to common/etc-api-gateway/scripts/lua/oauth/google.lua
diff --git a/scripts/lua/oauth/mock.lua b/common/etc-api-gateway/scripts/lua/oauth/mock.lua
similarity index 100%
rename from scripts/lua/oauth/mock.lua
rename to common/etc-api-gateway/scripts/lua/oauth/mock.lua
diff --git a/scripts/lua/policies/backendRouting.lua b/common/etc-api-gateway/scripts/lua/policies/backendRouting.lua
similarity index 100%
rename from scripts/lua/policies/backendRouting.lua
rename to common/etc-api-gateway/scripts/lua/policies/backendRouting.lua
diff --git a/scripts/lua/policies/mapping.lua b/common/etc-api-gateway/scripts/lua/policies/mapping.lua
similarity index 100%
rename from scripts/lua/policies/mapping.lua
rename to common/etc-api-gateway/scripts/lua/policies/mapping.lua
diff --git a/scripts/lua/policies/rateLimit.lua b/common/etc-api-gateway/scripts/lua/policies/rateLimit.lua
similarity index 100%
rename from scripts/lua/policies/rateLimit.lua
rename to common/etc-api-gateway/scripts/lua/policies/rateLimit.lua
diff --git a/scripts/lua/policies/security.lua b/common/etc-api-gateway/scripts/lua/policies/security.lua
similarity index 100%
rename from scripts/lua/policies/security.lua
rename to common/etc-api-gateway/scripts/lua/policies/security.lua
diff --git a/scripts/lua/policies/security/apiKey.lua b/common/etc-api-gateway/scripts/lua/policies/security/apiKey.lua
similarity index 100%
rename from scripts/lua/policies/security/apiKey.lua
rename to common/etc-api-gateway/scripts/lua/policies/security/apiKey.lua
diff --git a/scripts/lua/policies/security/clientSecret.lua b/common/etc-api-gateway/scripts/lua/policies/security/clientSecret.lua
similarity index 100%
rename from scripts/lua/policies/security/clientSecret.lua
rename to common/etc-api-gateway/scripts/lua/policies/security/clientSecret.lua
diff --git a/scripts/lua/policies/security/oauth2.lua b/common/etc-api-gateway/scripts/lua/policies/security/oauth2.lua
similarity index 100%
rename from scripts/lua/policies/security/oauth2.lua
rename to common/etc-api-gateway/scripts/lua/policies/security/oauth2.lua
diff --git a/scripts/lua/routing.lua b/common/etc-api-gateway/scripts/lua/routing.lua
similarity index 100%
rename from scripts/lua/routing.lua
rename to common/etc-api-gateway/scripts/lua/routing.lua
diff --git a/init.sh b/common/init.sh
similarity index 100%
rename from init.sh
rename to common/init.sh
diff --git a/core/apigateway-profiling/Dockerfile b/core/apigateway-profiling/Dockerfile
new file mode 100644
index 0000000..ff6dd5c
--- /dev/null
+++ b/core/apigateway-profiling/Dockerfile
@@ -0,0 +1,162 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor
+# license agreements.  See the NOTICE file distributed with this work for additional
+# information regarding copyright ownership.  The ASF licenses this file to you
+# under the Apache License, Version 2.0 (the # "License"); you may not use this
+# file except in compliance with the License.  You may obtain a copy of the License
+# at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations under the License.
+#
+# apigateway
+#
+# VERSION               1.13.6.1
+#
+# From https://hub.docker.com/_/ubuntu/
+#
+FROM ubuntu:xenial
+
+# install dependencies
+RUN apt-get update && apt-get -y install --no-install-recommends \
+        tar \
+        libtool \
+        libjemalloc1 \
+        perl \
+        ca-certificates \
+        wget \
+        curl \
+        python \
+        libssl-dev \
+        libpcre2-dev \
+        zlib1g-dev \
+        lua-zlib lua-zlib-dev \
+        libtest-longstring-perl \
+        liblist-moreutils-perl \
+        libhttp-message-perl \
+        libgeoip-dev \
+        libjemalloc-dev \
+        jq \
+        elfutils systemtap systemtap-sdt-dev \
+        gcc g++ make \
+        automake \
+        autoconf \
+        git \
+        libjansson-dev \
+        kbuild \
+        gnupg \
+    && rm -rf /var/lib/apt/lists/* \
+    && update-ca-certificates
+
+# openresty build
+ENV OPENRESTY_VERSION=1.13.6.1 \
+    NAXSI_VERSION=0.53-2 \
+    PCRE_VERSION=8.37 \
+    TEST_NGINX_VERSION=0.24 \
+    OPM_VERSION=0.0.3 \
+    LUA_RESTY_HTTP_VERSION=0.10 \
+    LUA_RESTY_IPUTILS_VERSION=0.2.1 \
+    LUA_RESTY_STRING_VERSION=0.09 \
+    LUA_RESTY_LRUCACHE_VERSION=0.06 \
+    LUA_RESTY_CJOSE_VERSION=0.4 \
+    NETURL_LUA_VERSION=0.9-1 \
+    CJOSE_VERSION=0.5.1 \
+    LD_LIBRARY_PATH=/usr/local/lib \
+    TINI_VERSION=v0.17.0 \
+    _prefix=/usr/local \
+    _exec_prefix=/usr/local \
+    _localstatedir=/var \
+    _sysconfdir=/etc \
+    _sbindir=/usr/local/sbin
+
+COPY build-scripts /build-scripts
+COPY etc-api-gateway /etc/api-gateway
+
+RUN echo "Beginning OpenRESTy build..." \
+     && bash /build-scripts/build-openresty.sh
+
+RUN echo "        - adding Nginx Test support" \
+    && curl -sSL "https://github.com/openresty/test-nginx/archive/v${TEST_NGINX_VERSION}.tar.gz" \
+        -o "${_prefix}/test-nginx-${TEST_NGINX_VERSION}.tar.gz" \
+    && tar -C "${_prefix}" -xf "${_prefix}/test-nginx-${TEST_NGINX_VERSION}.tar.gz" \
+    && rm "${_prefix}/test-nginx-${TEST_NGINX_VERSION}.tar.gz" \
+    && mkdir -p /usr/local/share/perl5/site_perl \
+    && cp -vr "${_prefix}/test-nginx-${TEST_NGINX_VERSION}/inc"/* /usr/local/share/perl5/site_perl/ \
+    && ln -s "${_sbindir}/api-gateway-debug" "${_sbindir}/nginx"
+
+RUN echo " ... installing opm..." \
+    && mkdir -p /tmp/api-gateway \
+    && curl -sSL "https://github.com/openresty/opm/archive/v${OPM_VERSION}.tar.gz" \
+        -o "/tmp/api-gateway/opm-${OPM_VERSION}.tar.gz" \
+    && tar -xf "/tmp/api-gateway/opm-${OPM_VERSION}.tar.gz" -C /tmp/api-gateway \
+    && cp "/tmp/api-gateway/opm-${OPM_VERSION}/bin/opm" "${_prefix}/api-gateway/bin" \
+    && mkdir -p "${_prefix}/api-gateway/site/manifest" "${prefix}/api-gateway/site/pod" \
+    && if [ ! -x "${_prefix}/api-gateway/lualib" ]; then \
+            ln -s "${_prefix}/api-gateway/site/lualib" "${_prefix}/api-gateway/lualib" \
+       ; fi \
+    && ln -s "${_prefix}/api-gateway/bin/opm" "/usr/bin/opm" \
+    && ln -s "${_prefix}/api-gateway/bin/resty" /usr/bin/resty \
+    && rm -rf /tmp/api-gateway
+
+RUN echo " ... installing opm packages ... " \
+    && opm get "pintsized/lua-resty-http=${LUA_RESTY_HTTP_VERSION}" \
+               "hamishforbes/lua-resty-iputils=${LUA_RESTY_IPUTILS_VERSION}" \
+               "openresty/lua-resty-string=${LUA_RESTY_STRING_VERSION}" \
+               "openresty/lua-resty-lrucache=${LUA_RESTY_LRUCACHE_VERSION}" \
+               "taylorking/lua-resty-cjose=${LUA_RESTY_CJOSE_VERSION}" \
+               taylorking/lua-resty-rate-limit
+
+RUN echo " ... installing neturl.lua ... " \
+    && mkdir -p /tmp/api-gateway \
+    && curl -sSL "https://github.com/golgote/neturl/archive/${NETURL_LUA_VERSION}.tar.gz" \
+        -o "/tmp/api-gateway/neturl.lua-${NETURL_LUA_VERSION}.tar.gz" \
+    && tar -xf "/tmp/api-gateway/neturl.lua-${NETURL_LUA_VERSION}.tar.gz" \
+        -C "/tmp/api-gateway/" \
+    && export LUA_LIB_DIR="${_prefix}/api-gateway/lualib" \
+    && cp "/tmp/api-gateway/neturl-${NETURL_LUA_VERSION}/lib/net/url.lua" "${LUA_LIB_DIR}" \
+    && rm -rf /tmp/api-gateway
+
+RUN echo " ... installing cjose ... " \
+    && mkdir -p /tmp/api-gateway \
+    && curl -L -k "https://github.com/cisco/cjose/archive/${CJOSE_VERSION}.tar.gz" \
+            -o "/tmp/api-gateway/cjose-${CJOSE_VERSION}.tar.gz" \
+    && tar -xf "/tmp/api-gateway/cjose-${CJOSE_VERSION}.tar.gz" -C /tmp/api-gateway/ \
+    && (cd "/tmp/api-gateway/cjose-${CJOSE_VERSION}" && sh configure && make install ) \
+    && rm -rf /tmp/api-gateway
+
+ENV CONFIG_SUPERVISOR_VERSION 1.0.1-RC1
+COPY build_config_supervisor.sh /tmp/build_config_supervisor.sh 
+RUN sh +x /tmp/build_config_supervisor.sh 
+
+COPY init.sh /etc/init-container.sh
+
+# add the default configuration for the Gateway
+
+RUN mkdir -p /profiling \
+ && (cd /tmp && git clone https://github.com/openresty/stapxx.git) \
+ && (cd /tmp/stapxx && git clone https://github.com/brendangregg/FlameGraph.git)
+WORKDIR /tmp/stapp
+
+RUN adduser --system --disabled-password --gecos "" nginx-api-gateway
+
+ARG UNAME_R 
+ARG UNAME_M
+
+COPY linux-headers-${UNAME_R} /usr/src/linux-headers-${UNAME_R}
+
+ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-${UNAME_M} /sbin/tini
+ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-${UNAME_M}.asc /sbin/tini.asc
+RUN gpg --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 595E85A6B1B4779EA4DAAEC70B588DFF0527A9B7 \
+ && gpg --verify /sbin/tini.asc \
+ && chmod +x /sbin/tini
+
+EXPOSE 80 8080 8423 9000
+
+ENTRYPOINT ["/sbin/tini", "--"]
+CMD ["/etc/init-container.sh"]
+
+# VIM: let b:syntastic_dockerfile_hadolint_args = "--ignore DL3008 --ignore SC2154 "
diff --git a/core/apigateway-profiling/build.gradle b/core/apigateway-profiling/build.gradle
new file mode 100644
index 0000000..9001aac
--- /dev/null
+++ b/core/apigateway-profiling/build.gradle
@@ -0,0 +1,61 @@
+buildscript {
+    repositories {
+        jcenter()
+    }
+}
+
+apply plugin: 'com.bmuschko.docker-remote-api'
+
+import com.bmuschko.gradle.docker.tasks.*
+import com.bmuschko.gradle.docker.tasks.image.*
+
+def uname_r = "uname -r".execute().text.trim()
+def uname_m = "uname -m".execute().text.trim()
+
+task dockerInfo(type: DockerInfo) {
+    onNext {
+        logger.quiet "Docker Info retreived for project ${project.name}:"
+        logger.quiet "  OSType = ${it.osType}"
+        logger.quiet "  Architecture = ${it.architecture}"
+        owner.ext.dockerInfo = it
+    }
+}
+
+task dockerBuildImage(type: DockerBuildImage) {
+    def prefix = findProperty('dockerImagePrefix') ?: 'openwhisk'
+    def tag = findProperty('dockerImageTag') ?: 'latest'
+    tags = [    "apigateway-profiling:${tag}",
+                "${prefix}/apigateway-profiling:${tag}"
+            ] as String[]
+    buildArgs = [ 'UNAME_R': uname_r, 'UNAME_M': uname_m ]
+    inputDir = new File(buildDir, 'docker')
+}
+
+task copyFilesForImage(type: Copy) {
+    destinationDir = dockerBuildImage.inputDir
+    into('.') {
+        from(new File(rootDir, 'common')) {
+            include 'init.sh'
+            include 'build_config_supervisor.sh'
+            include 'etc-api-gateway/**'
+            include 'build-scripts/**'
+        }
+        from('./Dockerfile')
+    }
+
+    into("linux-headers-${uname_r}") {
+        from("/usr/src/linux-headers-${uname_r}")
+    }
+}
+
+task copyApiGatewayConf(type: Copy, dependsOn: [copyFilesForImage, dockerInfo]) {
+    from(new File(rootDir, 'common/api-gateway.conf.in')) {
+        expand('worker_processes':'1',
+            'pcre_jit': { dockerInfo.dockerInfo.architecture == 's390x' ? 'no':'yes' })
+        rename { 'api-gateway.conf' }
+    }
+    into new File(dockerBuildImage.inputDir,'etc-api-gateway')
+}
+dockerBuildImage.dependsOn(copyApiGatewayConf)
+
+
diff --git a/core/apigateway/Dockerfile b/core/apigateway/Dockerfile
new file mode 100644
index 0000000..9aec04b
--- /dev/null
+++ b/core/apigateway/Dockerfile
@@ -0,0 +1,147 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor
+# license agreements.  See the NOTICE file distributed with this work for additional
+# information regarding copyright ownership.  The ASF licenses this file to you
+# under the Apache License, Version 2.0 (the # "License"); you may not use this
+# file except in compliance with the License.  You may obtain a copy of the License
+# at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+# CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations under the License.
+#
+# apigateway
+#
+# VERSION               1.13.6.1
+#
+# From https://hub.docker.com/_/alpine/
+#
+FROM alpine:3.7
+
+# install dependencies
+RUN apk --update --no-cache add \
+        tar \
+        libtool \
+        jemalloc \
+        perl \
+        ca-certificates \
+        wget \
+        curl \
+        python2 \
+        libssl1.0 \
+        openssl-dev \
+        pcre \
+        zlib \
+        perl-test-longstring \
+        perl-list-moreutils \
+        perl-http-message \
+        geoip \
+        jq \
+        jansson \
+        tini \
+    && update-ca-certificates
+
+# openresty build
+ENV OPENRESTY_VERSION=1.13.6.1 \
+    NAXSI_VERSION=0.53-2 \
+    PCRE_VERSION=8.37 \
+    TEST_NGINX_VERSION=0.24 \
+    OPM_VERSION=0.0.3 \
+    LUA_RESTY_HTTP_VERSION=0.10 \
+    LUA_RESTY_IPUTILS_VERSION=0.2.1 \
+    LUA_RESTY_STRING_VERSION=0.09 \
+    LUA_RESTY_LRUCACHE_VERSION=0.06 \
+    LUA_RESTY_CJOSE_VERSION=0.4 \
+    NETURL_LUA_VERSION=0.9-1 \
+    CJOSE_VERSION=0.5.1 \
+    LD_LIBRARY_PATH=/usr/local/lib \
+    _prefix=/usr/local \
+    _exec_prefix=/usr/local \
+    _localstatedir=/var \
+    _sysconfdir=/etc \
+    _sbindir=/usr/local/sbin
+
+COPY build-scripts /build-scripts
+COPY etc-api-gateway /etc/api-gateway
+
+RUN echo "Beginning OpenRESTy build..." \
+    && apk add --update --no-cache --virtual .build-deps \
+            bash gcc g++ make jemalloc-dev pcre-dev zlib-dev geoip-dev \
+    && bash /build-scripts/build-openresty.sh \
+    && apk del .build-deps
+
+RUN echo "        - adding Nginx Test support" \
+    && curl -sSL "https://github.com/openresty/test-nginx/archive/v${TEST_NGINX_VERSION}.tar.gz" \ 
+        -o "${_prefix}/test-nginx-${TEST_NGINX_VERSION}.tar.gz" \
+    && tar -C "${_prefix}" -zxf "${_prefix}/test-nginx-${TEST_NGINX_VERSION}.tar.gz" \
+    && rm "${_prefix}/test-nginx-${TEST_NGINX_VERSION}.tar.gz" \
+    && cp -vr "${_prefix}/test-nginx-${TEST_NGINX_VERSION}/inc"/* /usr/local/share/perl5/site_perl/ \
+    && ln -s "${_sbindir}/api-gateway-debug" "${_sbindir}/nginx"
+
+RUN echo " ... installing opm..." \
+    && mkdir -p /tmp/api-gateway \
+    && curl -sSL "https://github.com/openresty/opm/archive/v${OPM_VERSION}.tar.gz" \
+        -o "/tmp/api-gateway/opm-${OPM_VERSION}.tar.gz" \
+    && tar -xf "/tmp/api-gateway/opm-${OPM_VERSION}.tar.gz" -C /tmp/api-gateway \
+    && cp "/tmp/api-gateway/opm-${OPM_VERSION}/bin/opm" "${_prefix}/api-gateway/bin" \
+    && mkdir -p "${_prefix}/api-gateway/site/manifest" "${prefix}/api-gateway/site/pod" \
+    && if [ ! -x "${_prefix}/api-gateway/lualib" ]; then \
+            ln -s "${_prefix}/api-gateway/site/lualib" "${_prefix}/api-gateway/lualib" \
+       ; fi \
+    && ln -s "${_prefix}/api-gateway/bin/opm" "/usr/bin/opm" \
+    && ln -s "${_prefix}/api-gateway/bin/resty" /usr/bin/resty \
+    && rm -rf /tmp/api-gateway
+
+RUN echo " ... installing opm packages ... " \
+    && opm get "pintsized/lua-resty-http=${LUA_RESTY_HTTP_VERSION}" \
+               "hamishforbes/lua-resty-iputils=${LUA_RESTY_IPUTILS_VERSION}" \
+               "openresty/lua-resty-string=${LUA_RESTY_STRING_VERSION}" \
+               "openresty/lua-resty-lrucache=${LUA_RESTY_LRUCACHE_VERSION}" \
+               "taylorking/lua-resty-cjose=${LUA_RESTY_CJOSE_VERSION}" \
+               taylorking/lua-resty-rate-limit
+
+RUN echo " ... installing neturl.lua ... " \
+    && mkdir -p /tmp/api-gateway \
+    && curl -sSL "https://github.com/golgote/neturl/archive/${NETURL_LUA_VERSION}.tar.gz" \
+        -o "/tmp/api-gateway/neturl.lua-${NETURL_LUA_VERSION}.tar.gz" \
+    && tar -xf "/tmp/api-gateway/neturl.lua-${NETURL_LUA_VERSION}.tar.gz" \
+        -C "/tmp/api-gateway/" \
+    && export LUA_LIB_DIR="${_prefix}/api-gateway/lualib" \
+    && cp "/tmp/api-gateway/neturl-${NETURL_LUA_VERSION}/lib/net/url.lua" "${LUA_LIB_DIR}" \
+    && rm -rf /tmp/api-gateway
+
+RUN echo " ... installing cjose ... " \
+    && apk add --update --no-cache --virtual .build-deps \
+            gcc \
+            g++ \
+            make \
+            automake \
+            autoconf \
+            git \
+            jansson-dev \
+    && mkdir -p /tmp/api-gateway \
+    && curl -L -k "https://github.com/cisco/cjose/archive/${CJOSE_VERSION}.tar.gz" \
+            -o "/tmp/api-gateway/cjose-${CJOSE_VERSION}.tar.gz" \
+    && tar -xf "/tmp/api-gateway/cjose-${CJOSE_VERSION}.tar.gz" -C /tmp/api-gateway/ \
+    && (cd "/tmp/api-gateway/cjose-${CJOSE_VERSION}" && sh configure && make install ) \
+    && apk del .build-deps \
+    && rm -rf /tmp/api-gateway
+
+ENV CONFIG_SUPERVISOR_VERSION 1.0.1-RC1
+COPY build_config_supervisor.sh /tmp/build_config_supervisor.sh 
+RUN sh +x /tmp/build_config_supervisor.sh 
+
+COPY init.sh /etc/init-container.sh
+# add the default configuration for the Gateway
+
+RUN adduser -S nginx-api-gateway && addgroup -S nginx-api-gateway
+
+EXPOSE 80 8080 8423 9000
+
+ENTRYPOINT ["/sbin/tini", "--"]
+CMD ["/etc/init-container.sh"]
+
+# VIM: let b:syntastic_dockerfile_hadolint_args = "--ignore DL3018 --ignore SC2154"
diff --git a/core/apigateway/build.gradle b/core/apigateway/build.gradle
new file mode 100644
index 0000000..e4b8bb0
--- /dev/null
+++ b/core/apigateway/build.gradle
@@ -0,0 +1,23 @@
+subprojects {
+    task copyFilesForImage(type: Copy) {
+        from(new File(rootDir, 'common')) {
+            include 'init.sh'
+            include 'build_config_supervisor.sh'
+            include 'etc-api-gateway/**'
+            include 'build-scripts/**'
+        }
+        from('./Dockerfile')
+        into dockerBuildImage.inputDir
+    }
+    task copyApiGatewayConf(type: Copy, dependsOn: [copyFilesForImage, dockerInfo]) {
+        from(new File(rootDir, 'common/api-gateway.conf.in')) {
+            expand('worker_processes':'auto',
+                'pcre_jit': { dockerInfo.dockerInfo.architecture == 's390x' ? 'no':'yes' })
+            rename { 'api-gateway.conf' }
+        }
+        into new File(dockerBuildImage.inputDir,'etc-api-gateway')
+    }
+
+    dockerBuildImage.dependsOn([copyFilesForImage, copyApiGatewayConf])
+}
+
diff --git a/gradle/README.md b/gradle/README.md
new file mode 100644
index 0000000..6de4f54
--- /dev/null
+++ b/gradle/README.md
@@ -0,0 +1,45 @@
+# Gradle
+
+Gradle is used to build OpenWhisk. It does not need to be pre-installed as it installs itself using the [Gradle Wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html). To use it without installing, simply invoke the `gradlew` command at the root of the repository. You can also install `gradle` via [`apt`](http://linuxg.net/how-to-install-gradle-2-1-on-ubuntu-14-10-ubuntu-14-04-ubuntu-12-04-and-derivatives/) on Ubuntu or [`brew`](http://www.brewformulas.org/Gradle) on Mac. In the following we use `gradle` and `gradlew` as synonymous.
+
+## Usage
+
+In general, project level properties are set via `-P{propertyName}={propertyValue}`. A task is called via `gradle {taskName}` and a subproject task is called via `gradle :path:to:subproject:{taskName}`. To run tasks in parallel, use the `--parallel` flag (**Note:** It's an incubating feature and might break stuff).
+
+### Build
+
+To build all Docker images use `gradle distDocker` at the top level project, to build a specific component use `gradle :core:controller:distDocker`.
+
+Project level options that can be used on `distDocker`:
+
+- `dockerImageName` (*required*): The name of the image to build (e.g. whisk/controller)
+- `dockerHost` (*optional*): The docker host to run commands on, default behaviour is docker's own `DOCKER_HOST` environment variable
+- `dockerRegistry` (*optional*): The registry to push to
+- `dockerImageTag` (*optional*, default 'latest'): The tag for the image
+- `dockerTimeout` (*optional*, default 240): Timeout for docker operations in seconds
+- `dockerRetries` (*optional*, default 3): How many times to retry docker operations
+- `dockerBinary` (*optional*, default `docker`): The binary to execute docker commands
+
+### Test
+
+To run tests one uses the `test` task. OpenWhisk consolidates tests into a single `tests` project. Hence the command to run all tests is `gradle :tests:test`.
+
+It is possible to run specific tests using [Gradle testfilters](https://docs.gradle.org/current/userguide/java_plugin.html#test_filtering). For example `gradle :tests:test --tests "your.package.name.TestClass.evenMethodName"`. Wildcard `*` may be used anywhere.
+
+## Build your own `build.gradle`
+In Gradle, most of the tasks we use are default tasks provided by plugins in Gradle. The [`scala` Plugin](https://docs.gradle.org/current/userguide/scala_plugin.html) for example includes tasks, that are needed to build Scala projects. Moreover, Gradle is aware of *Applications*. The [`application` Plugin](https://docs.gradle.org/current/userguide/application_plugin.html) provides tasks that are required to distribute a self-contained application. When `application` and `scala` are used in conjunction, they hook into each other and provide the tasks needed to distribute a Scala application. `distTar` for example compiles the Scala code, creates a jar containing the compiled classes and resources and creates a Tarball including that jar and all of its dependencies (defined in the dependencies section of `build.gradle`). It also creates a start-script which correctly sets the classpath for all those dependencies and starts the app.
+
+In OpenWhisk, we want to distribute our application via Docker images. Hence we wrote a "plugin" that creates the task `distDocker`. That task will build an image from the `Dockerfile` that is located next to the `build.gradle` it is called from, for example Controller's `Dockerfile` and `build.gradle` are both located at `core/controller`.
+
+If you want to create a new `build.gradle` for your component, simply put the `Dockerfile` right next to it and include `docker.gradle` by using
+
+```
+ext.dockerImageName = 'openwwhisk/{IMAGENAME}'
+apply from: 'path/to/docker.gradle'
+```
+
+If your component needs to be build before you can build the image, make `distDocker` depend on any task needed to run before it, for example:
+
+```
+distDocker.dependsOn ':common:scala:distDocker', 'distTar'
+```
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..7a3265e
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..f16d266
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..e95643d
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..968b607
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,86 @@
+import groovy.json.JsonSlurper
+include 'tests'
+
+/* -- BEGIN: Project-specific configuration -- */
+/* TODO: Make this into a JSON configuration file? */
+rootProject.name = 'apigateway'
+
+gradle.ext.dockerBuildProjects =
+[
+    /* TODO: default imageName to project folder name in lowercase? */
+    ':core:apigateway': [ 'dockerImageName': 'apigateway' ]
+]
+
+include ':core:apigateway-profiling'
+/* -- END: Project-specific configuration -- */
+
+/*
+    Quick example of the format of the architectures input:
+
+    {
+        "amd64": null,
+        "ppc64le": {
+            "url": "https://1.2.3.4:2376",
+            "certPath": "/home/myusername/tls/ppc64le"
+        },
+        "s390x": {
+            "url": "https://my-personal-docker.my-domain.com:2376",
+            "certPath": "/home/myusername/tls/s390x"
+        }
+    }
+ */
+
+new JsonSlurper().with { slurper ->
+    def dockerLocalJsonEnv = System.getenv('docker_local_json')
+    def dockerLocalJsonFile = new File(rootProject.projectDir, 'docker-local.json')
+
+    if (dockerLocalJsonEnv) {
+        gradle.ext.architectures = slurper.parseText(dockerLocalJsonEnv)
+    } else if (dockerLocalJsonFile.exists()) {
+        gradle.ext.architectures = slurper.parse(dockerLocalJsonFile)
+    } else {
+        gradle.ext.architectures = [ 'amd64': null ]
+    }
+}
+
+gradle.ext.dockerRegistry = System.getenv('DOCKER_REGISTRY') ?: 'docker.io'
+
+gradle.ext.registryCredentials = [
+    name: gradle.ext.dockerRegistry,
+    url: "https://${gradle.ext.dockerRegistry}/v2/" as String,
+    username: System.getenv('DOCKER_USER'),
+    password: System.getenv('DOCKER_PASSWORD'),
+    email: System.getenv('DOCKER_EMAIL') ?: 'dev@openwhisk.apache.org',
+]
+
+rootProject.name = 'runtime-nodejs'
+
+gradle.dockerBuildProjects.each() { baseProjectName, extensions ->
+    include baseProjectName
+    def baseProject = findProject(baseProjectName)
+
+    gradle.architectures.each() { architectureName, architectureClosure ->
+        def architectureProjectName = "${baseProjectName}:${architectureName}"
+        include architectureProjectName
+        def architectureProject = findProject(architectureProjectName)
+
+        logger.debug 'Setup baseProject: ' + baseProject?.path
+        logger.debug 'Setup architectureProject: ' + architectureProject?.path
+
+        architectureProject.projectDir = baseProject.projectDir
+    }
+}
+
+gradle.ext.openwhisk = [
+        version: '1.0.0-SNAPSHOT'
+]
+
+gradle.ext.scala = [
+    version: '2.11.11',
+    compileFlags: ['-feature', '-unchecked', '-deprecation', '-Xfatal-warnings', '-Ywarn-unused-import']
+]
+
+gradle.ext.scalafmt = [
+    version: '1.5.0',
+    config: new File(rootProject.projectDir, '.scalafmt.conf')
+]
diff --git a/tests/run-tests.sh b/tests/run-tests.sh
index 3a90230..3b23257 100755
--- a/tests/run-tests.sh
+++ b/tests/run-tests.sh
@@ -17,4 +17,4 @@
 #
 
 # Run unit tests
-busted --output=TAP --helper=set_paths --pattern=.lua scripts
+busted --output=TAP --helper=set_paths --pattern=.lua --lpath="$(pwd)/../common/etc-api-gateway/scripts/lua/?.lua" scripts
diff --git a/tools/travis/build.sh b/tools/travis/build.sh
index f5f91e2..a23d032 100755
--- a/tools/travis/build.sh
+++ b/tools/travis/build.sh
@@ -21,17 +21,16 @@ set -x
 
 # Build script for Travis-CI.
 SCRIPTDIR="$(cd "$(dirname "$0")" && pwd)"
-ROOTDIR="$SCRIPTDIR/../.."
-HOMEDIR="$ROOTDIR/.."
-WHISKDIR="$ROOTDIR/../openwhisk"
-UTILDIR="$ROOTDIR/../incubator-openwhisk-utilities"
+ROOTDIR=$(cd "$SCRIPTDIR/../.." && pwd)
+WHISKDIR=$(cd "$ROOTDIR/../openwhisk" && pwd)
+UTILDIR=$(cd "$ROOTDIR/../incubator-openwhisk-utilities" && pwd)
 
-# run scancode util. against project source using the ASF strict configuration
-cd $UTILDIR
-scancode/scanCode.py --config scancode/ASF-Release.cfg $ROOTDIR
+# run the scancode util. against project source code starting at its root
+cd "$UTILDIR"
+scancode/scanCode.py --config scancode/ASF-Release.cfg "$ROOTDIR"
 
 # Install OpenWhisk
-cd $WHISKDIR/ansible
+cd "$WHISKDIR/ansible"
 
 ANSIBLE_CMD="ansible-playbook -i environments/local  -e docker_image_prefix=openwhisk"
 
@@ -40,10 +39,10 @@ $ANSIBLE_CMD prereq.yml
 $ANSIBLE_CMD couchdb.yml
 $ANSIBLE_CMD initdb.yml
 
-# build docker image locally
-pushd $ROOTDIR
+# build docker image
+pushd "$ROOTDIR"
 pwd
-docker build . -t "openwhisk/apigateway"
+./gradlew --console=plain :core:apigateway:dockerBuildImage
 popd
 
 #Use local
@@ -52,7 +51,6 @@ $ANSIBLE_CMD apigateway.yml -e apigateway_local_build=true
 #Use dockerhub
 #$ANSIBLE_CMD apigateway.yml
 
-
 $ANSIBLE_CMD wipe.yml
 $ANSIBLE_CMD openwhisk.yml -e cli_installation_mode=remote -e controllerProtocolForSetup=http
 
@@ -60,13 +58,13 @@ $ANSIBLE_CMD openwhisk.yml -e cli_installation_mode=remote -e controllerProtocol
 export OPENWHISK_HOME=$WHISKDIR
 
 # Tests
-cd $WHISKDIR
+cd "$WHISKDIR"
 cat whisk.properties
 
-WSK_TESTS_DEPS_EXCLUDE="-x :actionRuntimes:pythonAction:distDocker -x :actionRuntimes:javaAction:distDocker -x :actionRuntimes:nodejs6Action:distDocker -x :actionRuntimes:nodejs8Action:distDocker -x :actionRuntimes:actionProxy:distDocker -x :sdk:docker:distDocker -x :actionRuntimes:python2Action:distDocker -x :tests:dat:blackbox:badaction:distDocker -x :tests:dat:blackbox:badproxy:distDocker"
+WSK_TESTS_DEPS_EXCLUDE=( -x :actionRuntimes:pythonAction:distDocker -x :actionRuntimes:javaAction:distDocker -x :actionRuntimes:nodejs6Action:distDocker -x :actionRuntimes:nodejs8Action:distDocker -x :actionRuntimes:actionProxy:distDocker -x :sdk:docker:distDocker -x :actionRuntimes:python2Action:distDocker -x :tests:dat:blackbox:badaction:distDocker -x :tests:dat:blackbox:badproxy:distDocker )
 
-TERM=dumb ./gradlew tests:test --tests apigw.healthtests.* ${WSK_TESTS_DEPS_EXCLUDE}
-sleep 60
-TERM=dumb ./gradlew tests:test --tests whisk.core.apigw.* ${WSK_TESTS_DEPS_EXCLUDE}
-sleep 60
-TERM=dumb ./gradlew tests:test --tests whisk.core.cli.test.ApiGwRestTests ${WSK_TESTS_DEPS_EXCLUDE}
+./gradlew --console=plain :tests:test --tests "apigw.healthtests.*" "${WSK_TESTS_DEPS_EXCLUDE[@]}"
+echo 'Sleeping 60... never fear'; sleep 60
+./gradlew --console=plain :tests:test --tests "whisk.core.apigw.*" "${WSK_TESTS_DEPS_EXCLUDE[@]}"
+echo 'Sleeping 60... never fear'; sleep 60
+./gradlew --console=plain :tests:test --tests "whisk.core.cli.test.ApiGwRestTests" "${WSK_TESTS_DEPS_EXCLUDE[@]}"
diff --git a/tools/travis/deploy.sh b/tools/travis/deploy.sh
deleted file mode 100755
index adc5c9d..0000000
--- a/tools/travis/deploy.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-set -eu
-
-dockerhub_image_prefix="$1"
-dockerhub_image_name="$2"
-dockerhub_image_tag="$3"
-dockerhub_image="${dockerhub_image_prefix}/${dockerhub_image_name}:${dockerhub_image_tag}"
-
-docker login -u "${DOCKER_USER}" -p "${DOCKER_PASSWORD}"
-
-echo docker build . --tag ${dockerhub_image}
-docker build . --tag ${dockerhub_image}
-
-echo docker push ${dockerhub_image}
-docker push ${dockerhub_image}
diff --git a/tools/travis/tls/apache/ppc64le/ca.pem.gpg b/tools/travis/tls/apache/ppc64le/ca.pem.gpg
new file mode 100644
index 0000000..2d53007
Binary files /dev/null and b/tools/travis/tls/apache/ppc64le/ca.pem.gpg differ
diff --git a/tools/travis/tls/apache/ppc64le/cert.pem.gpg b/tools/travis/tls/apache/ppc64le/cert.pem.gpg
new file mode 100644
index 0000000..1ff14aa
Binary files /dev/null and b/tools/travis/tls/apache/ppc64le/cert.pem.gpg differ
diff --git a/tools/travis/tls/apache/ppc64le/key.pem.gpg b/tools/travis/tls/apache/ppc64le/key.pem.gpg
new file mode 100644
index 0000000..7b898a8
Binary files /dev/null and b/tools/travis/tls/apache/ppc64le/key.pem.gpg differ
diff --git a/tools/travis/tls/apache/s390x/ca.pem.gpg b/tools/travis/tls/apache/s390x/ca.pem.gpg
new file mode 100644
index 0000000..69776e6
Binary files /dev/null and b/tools/travis/tls/apache/s390x/ca.pem.gpg differ
diff --git a/tools/travis/tls/apache/s390x/cert.pem.gpg b/tools/travis/tls/apache/s390x/cert.pem.gpg
new file mode 100644
index 0000000..8910f66
Binary files /dev/null and b/tools/travis/tls/apache/s390x/cert.pem.gpg differ
diff --git a/tools/travis/tls/apache/s390x/key.pem.gpg b/tools/travis/tls/apache/s390x/key.pem.gpg
new file mode 100644
index 0000000..c8e11f6
Binary files /dev/null and b/tools/travis/tls/apache/s390x/key.pem.gpg differ
diff --git a/tools/travis/tls/jonpspri/ppc64le/ca.pem.gpg b/tools/travis/tls/jonpspri/ppc64le/ca.pem.gpg
new file mode 100644
index 0000000..2d53007
Binary files /dev/null and b/tools/travis/tls/jonpspri/ppc64le/ca.pem.gpg differ
diff --git a/tools/travis/tls/jonpspri/ppc64le/cert.pem.gpg b/tools/travis/tls/jonpspri/ppc64le/cert.pem.gpg
new file mode 100644
index 0000000..1ff14aa
Binary files /dev/null and b/tools/travis/tls/jonpspri/ppc64le/cert.pem.gpg differ
diff --git a/tools/travis/tls/jonpspri/ppc64le/key.pem.gpg b/tools/travis/tls/jonpspri/ppc64le/key.pem.gpg
new file mode 100644
index 0000000..7b898a8
Binary files /dev/null and b/tools/travis/tls/jonpspri/ppc64le/key.pem.gpg differ
diff --git a/tools/travis/tls/jonpspri/s390x/ca.pem.gpg b/tools/travis/tls/jonpspri/s390x/ca.pem.gpg
new file mode 100644
index 0000000..69776e6
Binary files /dev/null and b/tools/travis/tls/jonpspri/s390x/ca.pem.gpg differ
diff --git a/tools/travis/tls/jonpspri/s390x/cert.pem.gpg b/tools/travis/tls/jonpspri/s390x/cert.pem.gpg
new file mode 100644
index 0000000..8910f66
Binary files /dev/null and b/tools/travis/tls/jonpspri/s390x/cert.pem.gpg differ
diff --git a/tools/travis/tls/jonpspri/s390x/key.pem.gpg b/tools/travis/tls/jonpspri/s390x/key.pem.gpg
new file mode 100644
index 0000000..c8e11f6
Binary files /dev/null and b/tools/travis/tls/jonpspri/s390x/key.pem.gpg differ


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services