Compare commits

...

2 Commits

Author SHA1 Message Date
b0c2d597ee zuul tmp
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-13 03:33:44 +01:00
fdd8e68ac0 [dev] Fast switch to Netflix Zuul API Gateway
All checks were successful
continuous-integration/drone/push Build is passing
2022-10-13 02:34:34 +02:00
36 changed files with 2201 additions and 157 deletions

19
.dockerignore Normal file
View File

@ -0,0 +1,19 @@
apigw/target/**
apigw/.gitignore
### IntelliJ IDEA ###
apigw/.idea
apigw/*.iws
apigw/*.iml
apigw/*.ipr
### NetBeans ###
apigw/nbproject/
apigw/nbbuild/
apigw/dist/
apigw/nbdist/
apigw/.nb-gradle/
apigw/build/
### VS Code ###
.vscode/

View File

@ -1,8 +1,29 @@
FROM nginx:alpine FROM amazoncorretto:17-alpine3.16 as builder
LABEL author="Piotr Biernat" LABEL author="Piotr Biernat"
LABEL service="api-gw" LABEL service="api-gw"
LABEL vendor="Egommerce" LABEL vendor="Egommerce"
LABEL version="1.0" LABEL version="1.0"
COPY ./data/etc/nginx/ /etc/nginx/ RUN mkdir /app
WORKDIR /app
COPY apigw .
RUN ./mvnw clean compile install
FROM amazoncorretto:17-alpine3.16
#ENV CA_CERT_DIR /usr/lib/jvm/java-8-amazon-corretto/lib/security
COPY --from=builder /app/target/apigw-dev-jar-with-dependencies.jar /api-gw.jar
# Add own ca to cacert trusted db
#COPY --from=builder /app/src/main/resources/ca.pem /tmp/ca.pem
#RUN keytool -import -trustcacerts -keystore ${CA_CERT_DIR}/cacerts \
# -storepass changeit -noprompt -alias mycert -file /tmp/ca.pem && \
# rm /tmp/ca.pem
# "-Djavax.net.debug=all",
ENTRYPOINT ["java", "-Xmx1g", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/api-gw.jar", "--spring.profiles.active=docker"]
EXPOSE 443

19
api-gateway/.gitignore vendored Normal file
View File

@ -0,0 +1,19 @@
# Eclipse m2e generated files
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath
# VS Code
.vscode/
# Maven
target/
bin/
pom.xml.*
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
# .mvn/wrapper/maven-wrapper.jar

Binary file not shown.

View File

@ -0,0 +1,18 @@
# 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
#
# https://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.
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar

287
api-gateway/mvnw vendored Executable file
View File

@ -0,0 +1,287 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# 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.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.1.1
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /usr/local/etc/mavenrc ] ; then
. /usr/local/etc/mavenrc
fi
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
JAVA_HOME="`/usr/libexec/java_home`"; export JAVA_HOME
else
JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
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
else
JAVACMD="`\\unset -f command; \\command -v java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
printf '%s' "$(cd "$basedir"; pwd)"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=$(find_maven_basedir "$(dirname $0)")
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
else
wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
fi
while IFS="=" read key value; do
case "$key" in (wrapperUrl) wrapperUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $wrapperUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
fi
if command -v wget > /dev/null; then
QUIET="--quiet"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
QUIET=""
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget $QUIET "$wrapperUrl" -O "$wrapperJarPath"
else
wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath"
fi
[ $? -eq 0 ] || rm -f "$wrapperJarPath"
elif command -v curl > /dev/null; then
QUIET="--silent"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
QUIET=""
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L
else
curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L
fi
[ $? -eq 0 ] || rm -f "$wrapperJarPath"
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaSource="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaSource=`cygpath --path --windows "$javaSource"`
javaClass=`cygpath --path --windows "$javaClass"`
fi
if [ -e "$javaSource" ]; then
if [ ! -e "$javaClass" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaSource")
fi
if [ -e "$javaClass" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

187
api-gateway/mvnw.cmd vendored Normal file
View File

@ -0,0 +1,187 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.1.1
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %WRAPPER_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%

410
api-gateway/pom.xml Normal file
View File

@ -0,0 +1,410 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.egommerce</groupId>
<artifactId>api-gateway</artifactId>
<name>api-gateway</name>
<description>API Gateway - built using netflix-zuul v2</description>
<version>dev</version>
<url>https://egommerce.dev</url>
<packaging>jar</packaging>
<properties>
<java.version>18</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.fork>true</maven.compiler.fork>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<netflix.zull.version>2.3.0</netflix.zull.version>
<netflix.eureka.version>1.10.17</netflix.eureka.version>
<netflix.ribbon.version>2.4.4</netflix.ribbon.version>
<groovy.all>3.0.13</groovy.all>
<groovy.eclipse.batch>2.5.14-01</groovy.eclipse.batch>
<!-- <groovy.eclipse.batch>3.0.8-01</groovy.eclipse.batch> -->
<groovy.eclipse.compiler>2.9.1-01</groovy.eclipse.compiler>
<!-- <groovy.eclipse.compiler>3.3.0-01</groovy.eclipse.compiler> -->
<slf4j.version>1.7.36</slf4j.version>
<io.netty.version>4.1.84.Final</io.netty.version>
<io.netty.io_uring.version>0.0.15.Final</io.netty.io_uring.version>
</properties>
<!-- <repositories>
<repository>
<id>groovy-libs-release</id>
<url>https://groovy.jfrog.io/artifactory/libs-release</url>
</repository>
</repositories> -->
<pluginRepositories>
<pluginRepository>
<id>groovy-plugins-release</id>
<url>https://groovy.jfrog.io/artifactory/plugins-release</url>
</pluginRepository>
</pluginRepositories>
<build>
<!-- <pluginManagement> -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-batch</artifactId>
<version>${groovy.eclipse.batch}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-compiler</artifactId>
<version>${groovy.eclipse.compiler}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<configuration>
<compilerId>groovy-eclipse-compiler</compilerId>
<encoding>UTF-8</encoding>
<extensions>true</extensions>
<failOnWarning>true</failOnWarning>
<verbose>true</verbose>
</configuration>
</plugin>
<!-- </plugins> -->
<!-- </pluginManagement> -->
<!-- <plugins> -->
<plugin>
<!-- Build JAR with all dependencies -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.egommerce.apigateway.Bootstrap</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<plugin>
<!-- Enforce dependency conflicts free-->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M2</version>
<executions>
<execution>
<id>enforce</id>
<configuration>
<rules>
<dependencyConvergence />
</rules>
</configuration>
<goals>
<goal>enforce</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>ssl/</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>ssl/</include>
</includes>
</resource>
</resources>
</build>
<dependencies>
<dependency>
<groupId>com.netflix.zuul</groupId>
<artifactId>zuul-core</artifactId>
<version>${netflix.zull.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.zuul</groupId>
<artifactId>zuul-groovy</artifactId>
<version>${netflix.zull.version}</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.netflix.eureka</groupId>
<artifactId>eureka-client</artifactId>
<version>${netflix.eureka.version}</version>
</dependency>
<!--
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-core</artifactId>
<version>0.7.7</version>
</dependency>
<dependency>
<groupId>com.netflix.netflix-commons</groupId>
<artifactId>netflix-commons-util</artifactId>
<version>0.3.0</version>
</dependency> -->
<dependency>
<groupId>com.netflix.zuul</groupId>
<artifactId>zuul-guice</artifactId>
<version>${netflix.zull.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<!-- <classifier>indy</classifier> -->
<version>${groovy.all}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
<version>${io.netty.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.68</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.netflix.eureka</groupId>
<artifactId>eureka-client</artifactId>
<version>${netflix.eureka.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-core</artifactId>
<version>0.7.7</version>
</dependency>
<dependency>
<groupId>com.netflix.netflix-commons</groupId>
<artifactId>netflix-commons-util</artifactId>
<version>0.3.0</version>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-core</artifactId>
<version>2.4.8</version>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-archaius</artifactId>
<version>2.4.8</version>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-eureka</artifactId>
<version>2.4.8</version>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-loadbalancer</artifactId>
<version>2.4.8</version>
</dependency>
<dependency>
<groupId>com.netflix.servo</groupId>
<artifactId>servo-core</artifactId>
<version>0.10.1</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.10.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>com.google.errorprone</groupId>
<artifactId>error_prone_annotations</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.4.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.13.4</version>
</dependency>
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava</artifactId>
<version>1.3.8</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>io.netty.incubator</groupId>
<artifactId>netty-incubator-transport-native-io_uring</artifactId>
<version>${io.netty.io_uring.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-bom</artifactId>
<version>${io.netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
<version>${io.netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http</artifactId>
<version>${io.netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http2</artifactId>
<version>${io.netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>2.0.54.Final</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-common</artifactId>
<version>${io.netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
<version>${io.netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport</artifactId>
<version>${io.netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-codec-haproxy</artifactId>
<version>${io.netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-unix-common</artifactId>
<version>${io.netty.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<version>${io.netty.version}</version>
<classifier>linux-x86_64</classifier>
</dependency>
</dependencies>
</dependencyManagement>
</project>

14
api-gateway/run.sh Normal file
View File

@ -0,0 +1,14 @@
#!/bin/sh
# --add-opens java.base/jdk.internal.misc=ALL-UNNAMED \
java -jar target/api-gateway-dev-jar-with-dependencies.jar \
-Xmx1g \
-Djava.security.egd=file:/dev/./urandom \
-Djavax.net.debug=ALL \
-DTZ=GMT \
-Darchaius.deployment.environment=test \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.local.only=false \
-Deureka.validateInstanceId=false \
-Deureka.mt.num_retries=1 \
-X -e

View File

@ -0,0 +1,46 @@
/*
* Copyright 2018 Netflix, Inc.
*
* Licensed 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.
*/
package com.egommerce.apigateway.filters.endpoint
import com.netflix.zuul.filters.http.HttpSyncEndpoint
import com.netflix.zuul.message.http.HttpRequestMessage
import com.netflix.zuul.message.http.HttpResponseMessage
import com.netflix.zuul.message.http.HttpResponseMessageImpl
import com.netflix.zuul.stats.status.StatusCategoryUtils
import com.netflix.zuul.stats.status.ZuulStatusCategory
/**
* Healthcheck Sample Endpoint
*
* Author: Arthur Gonigberg
* Date: November 21, 2017
*/
class Healthcheck extends HttpSyncEndpoint {
@Override
HttpResponseMessage apply(HttpRequestMessage request) {
HttpResponseMessage resp = new HttpResponseMessageImpl(request.getContext(), request, 200)
resp.setBodyAsText("healthy")
// print "HEALTHCHECK::PLUGIN"
// need to set this manually since we are not going through the ProxyEndpoint
StatusCategoryUtils.setStatusCategory(request.getContext(), ZuulStatusCategory.SUCCESS)
return resp
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright 2018 Netflix, Inc.
*
* Licensed 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.
*/
package com.egommerce.apigateway.filters.inbound
import com.netflix.zuul.context.Debug
import com.netflix.zuul.context.SessionContext
import com.netflix.zuul.filters.http.HttpInboundSyncFilter
import com.netflix.zuul.message.http.HttpRequestMessage
/**
* Add debug request info to the context if request is marked as debug.
*
* Author: Arthur Gonigberg
* Date: December 22, 2017
*/
class DebugRequest extends HttpInboundSyncFilter {
@Override
int filterOrder() {
return 21
}
@Override
boolean shouldFilter(HttpRequestMessage request) {
return true
// return request.getContext().debugRequest()
}
@Override
boolean needsBodyBuffered(HttpRequestMessage request) {
return shouldFilter(request)
}
@Override
HttpRequestMessage apply(HttpRequestMessage request) {
SessionContext ctx = request.getContext()
Debug.addRequestDebug(ctx, "REQUEST:: " + request.getOriginalScheme() + " " + request.getOriginalHost() + ":" + request.getOriginalPort())
Debug.addRequestDebug(ctx, "REQUEST:: > " + request.getMethod() + " " + request.reconstructURI() + " " + request.getProtocol())
Iterator headerIt = request.getHeaders().iterator()
while (headerIt.hasNext()) {
String name = (String) headerIt.next()
String value = request.getHeaders().getFirst(name)
Debug.addRequestDebug(ctx, "REQUEST:: > " + name + ":" + value)
}
if (request.hasBody()) {
Debug.addRequestDebug(ctx, "REQUEST:: > " + request.getBodyAsText())
}
return request
}
}

View File

@ -0,0 +1,69 @@
/*
* Copyright 2018 Netflix, Inc.
*
* Licensed 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.
*/
package com.egommerce.apigateway.filters.inbound
import com.netflix.zuul.context.SessionContext
import com.netflix.zuul.filters.endpoint.ProxyEndpoint
import com.netflix.zuul.filters.http.HttpInboundSyncFilter
import com.netflix.zuul.message.http.HttpRequestMessage
import com.egommerce.apigateway.filters.endpoint.Healthcheck
/**
* Routes configuration
*
* Author: Arthur Gonigberg
* Date: November 21, 2017
*/
class Routes extends HttpInboundSyncFilter {
@Override
int filterOrder() {
return 0
}
@Override
boolean shouldFilter(HttpRequestMessage httpRequestMessage) {
return true
}
@Override
HttpRequestMessage apply(HttpRequestMessage request) {
SessionContext context = request.getContext()
String path = request.getPath()
// print "ROUTES::PLUGIN"
// Route healthchecks to the healthcheck endpoint.;
if (path.equalsIgnoreCase("/healthcheck")) {
context.setEndpoint(Healthcheck.class.getCanonicalName())
}
else if (path.containsIgnoreCase("/auth")) {
context.setEndpoint(ProxyEndpoint.class.getCanonicalName())
context.setRouteVIP("identity-svc")
}
else if (path.containsIgnoreCase("/basket")) {
context.setEndpoint(ProxyEndpoint.class.getCanonicalName())
context.setRouteVIP("basket-svc")
}
else {
context.setEndpoint(ProxyEndpoint.class.getCanonicalName())
context.setRouteVIP("unknown-svc")
}
return request
}
}

View File

@ -0,0 +1,107 @@
/*
* Copyright 2018 Netflix, Inc.
*
* Licensed 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.
*/
package com.egommerce.apigateway.filters.outbound
import com.netflix.config.DynamicBooleanProperty
import com.netflix.config.DynamicStringProperty
import com.netflix.zuul.context.Debug
import com.netflix.zuul.context.SessionContext
import com.netflix.zuul.exception.ZuulException
import com.netflix.zuul.filters.http.HttpOutboundSyncFilter
import com.netflix.zuul.message.Headers
import com.netflix.zuul.message.http.HttpResponseMessage
import com.netflix.zuul.niws.RequestAttempts
import com.netflix.zuul.passport.CurrentPassport
import com.netflix.zuul.stats.status.StatusCategory
import com.netflix.zuul.stats.status.StatusCategoryUtils
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import static com.netflix.zuul.constants.ZuulHeaders.*
/**
* Sample Response Filter - adding custom response headers for better analysis of how the request was proxied
*
* Author: Arthur Gonigberg
* Date: December 21, 2017
*/
class ZuulResponseFilter extends HttpOutboundSyncFilter {
private static final Logger logger = LoggerFactory.getLogger(ZuulResponseFilter.class)
private static final DynamicBooleanProperty SEND_RESPONSE_HEADERS =
new DynamicBooleanProperty("zuul.responseFilter.send.headers", true)
private static final DynamicStringProperty INSTANCE_ID =
new DynamicStringProperty("eureka.instanceId", "127.0.0.1") // FIXME
@Override
int filterOrder() {
return 999
}
@Override
boolean shouldFilter(HttpResponseMessage request) {
return true
}
@Override
HttpResponseMessage apply(HttpResponseMessage response) {
SessionContext context = response.getContext()
if (SEND_RESPONSE_HEADERS.get()) {
Headers headers = response.getHeaders()
StatusCategory statusCategory = StatusCategoryUtils.getStatusCategory(response)
if (statusCategory != null) {
headers.set(X_ZUUL_STATUS, statusCategory.name())
}
RequestAttempts attempts = RequestAttempts.getFromSessionContext(response.getContext())
String headerStr = ""
if (attempts != null) {
headerStr = attempts.toString()
}
headers.set(X_ZUUL_PROXY_ATTEMPTS, headerStr)
headers.set(X_ZUUL, "zuul")
headers.set(X_ZUUL_INSTANCE, INSTANCE_ID.get() ?: "unknown")
headers.set(CONNECTION, KEEP_ALIVE)
headers.set(X_ORIGINATING_URL, response.getInboundRequest().reconstructURI())
if (response.getStatus() >= 400 && context.getError() != null) {
Throwable error = context.getError()
headers.set(X_ZUUL_ERROR_CAUSE,
error instanceof ZuulException ? ((ZuulException) error).getErrorCause() : error.toString())
}
if (response.getStatus() >= 500) {
logger.info("Passport: {}", CurrentPassport.fromSessionContext(context))
}
if (logger.isDebugEnabled()) {
logger.debug("Filter execution summary :: {}", context.getFilterExecutionSummary())
}
}
if (context.debugRequest()) {
Debug.getRequestDebug(context).forEach({ s -> logger.info("REQ_DEBUG: " + s) })
Debug.getRoutingDebug(context).forEach({ s -> logger.info("ZUUL_DEBUG: " + s) })
}
return response
}
}

View File

@ -0,0 +1,234 @@
package com.egommerce.apigateway;
import java.io.File;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.egommerce.apigateway.module.ApiGwFiltersModule;
import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.config.DynamicIntProperty;
import com.netflix.config.DynamicStringProperty;
import com.netflix.discovery.EurekaClient;
import com.netflix.netty.common.accesslog.AccessLogPublisher;
import com.netflix.netty.common.channel.config.ChannelConfig;
import com.netflix.netty.common.channel.config.ChannelConfigValue;
import com.netflix.netty.common.channel.config.CommonChannelConfigKeys;
import com.netflix.netty.common.metrics.EventLoopGroupMetrics;
import com.netflix.netty.common.proxyprotocol.StripUntrustedProxyHeadersHandler;
import com.netflix.netty.common.ssl.ServerSslConfig;
import com.netflix.netty.common.status.ServerStatusManager;
import com.netflix.spectator.api.Registry;
import com.netflix.zuul.FilterLoader;
import com.netflix.zuul.FilterUsageNotifier;
import com.netflix.zuul.RequestCompleteHandler;
import com.netflix.zuul.context.SessionContextDecorator;
import com.netflix.zuul.netty.server.BaseServerStartup;
import com.netflix.zuul.netty.server.DirectMemoryMonitor;
import com.netflix.zuul.netty.server.NamedSocketAddress;
import com.netflix.zuul.netty.server.SocketAddressProperty;
import com.netflix.zuul.netty.server.ZuulServerChannelInitializer;
import com.netflix.zuul.netty.server.http2.Http2SslChannelInitializer;
import com.netflix.zuul.netty.ssl.BaseSslContextFactory;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.group.ChannelGroup;
import io.netty.handler.ssl.ClientAuth;
/**
* ApiGw Server Startup - class that configures the Netty server startup settings
*/
@Singleton
public class ApiGwServerStartup extends BaseServerStartup {
private static final Logger log = LoggerFactory.getLogger(ApiGwFiltersModule.class);
enum ServerType {
HTTP,
HTTP2,
// HTTP_MUTUAL_TLS,
}
private static final String[] WWW_PROTOCOLS = new String[]{"TLSv1.3", "TLSv1.2", "TLSv1.1", "TLSv1"};
private static final ServerType SERVER_TYPE = ServerType.HTTP2;
@Inject
public ApiGwServerStartup(ServerStatusManager serverStatusManager, FilterLoader filterLoader,
SessionContextDecorator sessionCtxDecorator, FilterUsageNotifier usageNotifier,
RequestCompleteHandler reqCompleteHandler, Registry registry,
DirectMemoryMonitor directMemoryMonitor, EventLoopGroupMetrics eventLoopGroupMetrics,
EurekaClient discoveryClient, ApplicationInfoManager applicationInfoManager,
AccessLogPublisher accessLogPublisher) {
super(serverStatusManager, filterLoader, sessionCtxDecorator, usageNotifier, reqCompleteHandler, registry,
directMemoryMonitor, eventLoopGroupMetrics, discoveryClient, applicationInfoManager, accessLogPublisher);
log.info("API-GATEWAY:Startup: Initialization...");
// Call PostConstruct by hand, cause inject.*.PostConstruct annotation issue...
PostConstruct();
}
public void PostConstruct() {
log.debug("API-DATEWAY:Startup: PostConstruct");
try {
init();
} catch (Exception e) {
log.error("Failed to server netty server. Quitting.");
}
}
@Override
protected Map<NamedSocketAddress, ChannelInitializer<?>> chooseAddrsAndChannels(ChannelGroup clientChannels) {
Map<NamedSocketAddress, ChannelInitializer<?>> addrsToChannels = new HashMap<>();
try {
int port = new DynamicIntProperty("zuul.server.port", 8000).get();
String addr = new DynamicStringProperty("zuul.server.addr", "127.0.0.1").get();
SocketAddress sockAddr = new SocketAddressProperty(addr, "=" + port).getValue();
String metricId = sockAddr.toString();
if (sockAddr instanceof InetSocketAddress) {
metricId = String.valueOf(((InetSocketAddress) sockAddr).getPort());
}
// log.debug("API-GATEWAY:chooseAddrsAndChannels:$metricId: " +metricId);
String mainListenAddressName = "main";
ServerSslConfig sslConfig;
ChannelConfig channelConfig = defaultChannelConfig(mainListenAddressName);
ChannelConfig channelDependencies = defaultChannelDependencies(mainListenAddressName);
/* These settings may need to be tweaked depending if you're running behind an ELB HTTP listener, TCP listener,
* or directly on the internet.
*/
switch (SERVER_TYPE) {
/* The below settings can be used when running behind an ELB HTTP listener that terminates SSL for you
* and passes XFF headers.
*/
case HTTP:
channelConfig.set(CommonChannelConfigKeys.allowProxyHeadersWhen, StripUntrustedProxyHeadersHandler.AllowWhen.ALWAYS);
channelConfig.set(CommonChannelConfigKeys.preferProxyProtocolForClientIp, false);
channelConfig.set(CommonChannelConfigKeys.isSSlFromIntermediary, false);
channelConfig.set(CommonChannelConfigKeys.withProxyProtocol, false);
logAddrConfigured(sockAddr);
addrsToChannels.put(
new NamedSocketAddress("http", sockAddr),
new ZuulServerChannelInitializer(metricId, channelConfig, channelDependencies, clientChannels)
);
break;
/* The below settings can be used when running behind an ELB TCP listener with proxy protocol, terminating
* SSL in Zuul.
*/
case HTTP2:
// sslConfig = new ServerSslConfig(
// WWW_PROTOCOLS,
// ServerSslConfig.getDefaultCiphers(),
// loadFromResources("ssl/api-gateway-svc.cert"),
// loadFromResources("ssl/api-gateway-svc-pem.key"),
// ClientAuth.NONE
// );
sslConfig = ServerSslConfig.withDefaultCiphers(
loadFromResources("ssl/api-gateway-svc.cert"),
loadFromResources("ssl/api-gateway-svc.pem"),
WWW_PROTOCOLS
);
channelConfig.set(CommonChannelConfigKeys.allowProxyHeadersWhen, StripUntrustedProxyHeadersHandler.AllowWhen.NEVER);
channelConfig.set(CommonChannelConfigKeys.preferProxyProtocolForClientIp, true);
channelConfig.set(CommonChannelConfigKeys.withProxyProtocol, true);
channelConfig.set(CommonChannelConfigKeys.isSSlFromIntermediary, false);
channelConfig.set(CommonChannelConfigKeys.serverSslConfig, sslConfig);
channelConfig.set(CommonChannelConfigKeys.sslContextFactory, new BaseSslContextFactory(registry, sslConfig));
// channelConfig.set(ChannelOption.SO_KEEPALIVE, true);
// channelConfig.set(ChannelOption.TCP_NODELAY, true);
// channelConfig.set(ChannelOption., );
addHttp2DefaultConfig(channelConfig, String.valueOf(port));
logAddrConfigured(sockAddr, sslConfig);
addrsToChannels.put(new NamedSocketAddress("https", sockAddr), new Http2SslChannelInitializer(metricId, channelConfig, channelDependencies, clientChannels));
break;
/* The below settings can be used when running behind an ELB TCP listener with proxy protocol, terminating
* SSL in Zuul.
*
* Can be tested using certs in resources directory:
* curl https://localhost:7001/test -vk --cert src/main/resources/ssl/client.cert:zuul123 --key src/main/resources/ssl/client.key
*/
// case HTTP_MUTUAL_TLS:
// sslConfig = new ServerSslConfig(
// WWW_PROTOCOLS,
// ServerSslConfig.getDefaultCiphers(),
// loadFromResources("server.cert"),
// loadFromResources("server.key"),
// // null,
// ClientAuth.REQUIRE,
// loadFromResources("truststore.jks"),
// loadFromResources("truststore.key"),
// false);
// channelConfig.set(CommonChannelConfigKeys.allowProxyHeadersWhen, StripUntrustedProxyHeadersHandler.AllowWhen.NEVER);
// channelConfig.set(CommonChannelConfigKeys.preferProxyProtocolForClientIp, true);
// channelConfig.set(CommonChannelConfigKeys.isSSlFromIntermediary, false);
// channelConfig.set(CommonChannelConfigKeys.withProxyProtocol, true);
// channelConfig.set(CommonChannelConfigKeys.serverSslConfig, sslConfig);
// channelConfig.set(CommonChannelConfigKeys.sslContextFactory, new BaseSslContextFactory(registry, sslConfig));
// addrsToChannels.put(new NamedSocketAddress("http_mtls", sockAddr), new Http1MutualSslChannelInitializer(metricId, channelConfig, channelDependencies, clientChannels));
// logAddrConfigured(sockAddr, sslConfig);
// break;
}
log.debug("$addrsToChannel:", addrsToChannels);
// Class s = server.getClass();
// for (Method method : s.getDeclaredMethods()) {
// log.debug(method.getName());
// }
} catch (Exception e) {
log.error("Startup::Exception: " + e.getMessage());
for (StackTraceElement tr : e.getStackTrace()) {
log.error(tr.toString());
}
}
return addrsToChannels;
}
// public static void addHttp2DefaultConfig(ChannelConfig config, String listenAddressName) {
// config.add(new ChannelConfigValue<>(CommonChannelConfigKeys.maxConcurrentStreams,
// chooseIntChannelProperty(
// listenAddressName,
// "http2.max.concurrent.streams",
// CommonChannelConfigKeys.maxConcurrentStreams.defaultValue())));
// config.add(new ChannelConfigValue<>(CommonChannelConfigKeys.initialWindowSize,
// chooseIntChannelProperty(
// listenAddressName,
// "http2.initialwindowsize",
// CommonChannelConfigKeys.initialWindowSize.defaultValue())));
// config.add(new ChannelConfigValue<>(CommonChannelConfigKeys.maxHttp2HeaderTableSize,
// chooseIntChannelProperty(listenAddressName, "http2.maxheadertablesize", 65536)));
// config.add(new ChannelConfigValue<>(CommonChannelConfigKeys.maxHttp2HeaderListSize,
// chooseIntChannelProperty(listenAddressName, "http2.maxheaderlistsize", 32768)));
// // Override this to a lower value, as we'll be using ELB TCP listeners for h2, and therefore the connection
// // is direct from each device rather than shared in an ELB pool.
// config.add(new ChannelConfigValue<>(CommonChannelConfigKeys.maxRequestsPerConnection,
// chooseIntChannelProperty(listenAddressName, "connection.max.requests", 4000)));
// config.add(new ChannelConfigValue<>(CommonChannelConfigKeys.http2AllowGracefulDelayed,
// chooseBooleanChannelProperty(listenAddressName, "connection.close.graceful.delayed.allow", true)));
// config.add(new ChannelConfigValue<>(CommonChannelConfigKeys.http2SwallowUnknownExceptionsOnConnClose,
// chooseBooleanChannelProperty(listenAddressName, "connection.close.swallow.unknown.exceptions", false)));
// }
private File loadFromResources(String s) {
return new File(ClassLoader.getSystemResource(s).getFile());
}
}

View File

@ -0,0 +1,20 @@
package com.egommerce.apigateway;
// package com.egommerce.apigw;
// import com.netflix.appinfo.ApplicationInfoManager;
// import com.netflix.discovery.DiscoveryClient;
// import com.netflix.netty.common.status.ServerStatusManager;
// import javax.inject.Inject;
// import javax.inject.Singleton;
// @Singleton
// public class ApiGwServerStatusManager extends ServerStatusManager
// {
// @Inject
// public ApiGwServerStatusManager(ApplicationInfoManager applicationInfoManager/*, DiscoveryClient discoveryClient*/) {
// super(applicationInfoManager/* , discoveryClient*/);
// // System.out.println(discoveryClient);
// // System.exit(1);
// }
// }

View File

@ -0,0 +1,53 @@
package com.egommerce.apigateway;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.netflix.zuul.netty.server.BaseServerStartup;
import com.netflix.zuul.netty.server.Server;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// import io.netty.handler.codec.http.DefaultHttpRequest;
import com.netflix.zuul.filters.endpoint.ProxyEndpoint;
public class Bootstrap {
private static final Logger logger = LoggerFactory.getLogger(Bootstrap.class);
public static void main(String[] args) {
new Bootstrap().start();
}
public void start() {
long startNanos = System.nanoTime();
logger.info("###############");
logger.info("Starting up...");
int exitCode = 0;
Server server = null;
try {
Injector injector = Guice.createInjector(new ZuulApiGwModule());
BaseServerStartup serverStartup = injector.getInstance(BaseServerStartup.class);
server = serverStartup.server();
server.start();
long startupDuration = System.nanoTime() - startNanos;
logger.info("Finished startup. Duration = {}s", TimeUnit.NANOSECONDS.toSeconds(startupDuration));
server.awaitTermination();
} catch (Throwable t) {
t.printStackTrace();
logger.error("Initialization failed. Forcing shutdown now...");
exitCode = 1;
} finally {
if (server != null) {
server.stop();
}
logger.info("Shutdown completed. Quiting.");
logger.info("###############");
System.exit(exitCode);
}
}
}

View File

@ -0,0 +1,86 @@
package com.egommerce.apigateway;
// import com.egommerce.apigateway.config.ApiGwServerSslConfig;
import com.egommerce.apigateway.module.ApiGwEurekaModule;
import com.egommerce.apigateway.module.ApiGwFiltersModule;
import com.google.inject.AbstractModule;
import com.netflix.config.ConfigurationManager;
import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs;
import com.netflix.discovery.DiscoveryClient;
import com.netflix.discovery.shared.resolver.EndpointRandomizer;
import com.netflix.discovery.shared.resolver.ResolverUtils;
import com.netflix.netty.common.accesslog.AccessLogPublisher;
import com.netflix.netty.common.ssl.ServerSslConfig;
import com.netflix.netty.common.status.ServerStatusManager;
import com.netflix.spectator.api.DefaultRegistry;
import com.netflix.spectator.api.Registry;
import com.netflix.zuul.BasicRequestCompleteHandler;
import com.netflix.zuul.DynamicCodeCompiler;
import com.netflix.zuul.DynamicFilterLoader;
import com.netflix.zuul.FilterFileManager;
import com.netflix.zuul.FilterLoader;
import com.netflix.zuul.RequestCompleteHandler;
import com.netflix.zuul.context.SessionContextDecorator;
import com.netflix.zuul.context.ZuulSessionContextDecorator;
import com.netflix.zuul.filters.FilterRegistry;
import com.netflix.zuul.filters.MutableFilterRegistry;
import com.netflix.zuul.groovy.GroovyCompiler;
import com.netflix.zuul.groovy.GroovyFileFilter;
import com.netflix.zuul.netty.server.BaseServerStartup;
import com.netflix.zuul.netty.server.ClientRequestReceiver;
import com.netflix.zuul.origins.BasicNettyOriginManager;
import com.netflix.zuul.origins.OriginManager;
import com.netflix.zuul.stats.BasicRequestMetricsPublisher;
import com.netflix.zuul.stats.RequestMetricsPublisher;
import java.io.FilenameFilter;
import org.apache.commons.configuration.AbstractConfiguration;
// import org.slf4j.Logger;
// import org.slf4j.LoggerFactory;
public class ZuulApiGwModule extends AbstractModule {
// private static final Logger log = LoggerFactory.getLogger(ZuulApiGwModule.class);
@Override
protected void configure() {
try {
ConfigurationManager.loadCascadedPropertiesFromResources("application");
} catch (Exception ex) {
throw new RuntimeException("Error loading configuration: " + ex.getMessage(), ex);
}
bind(AbstractConfiguration.class).toInstance(ConfigurationManager.getConfigInstance());
bind(DynamicCodeCompiler.class).to(GroovyCompiler.class);
bind(FilenameFilter.class).to(GroovyFileFilter.class);
// bind(ServerSslConfig.class).to(ApiGwServerSslConfig.class);
// zuul eureka module
bind(EndpointRandomizer.class).toInstance(ResolverUtils::randomize);
install(new ApiGwEurekaModule());
// server specific bindings
bind(BaseServerStartup.class).to(ApiGwServerStartup.class);
// use provided basic netty origin manager
bind(OriginManager.class).to(BasicNettyOriginManager.class);
// general server bindings
bind(ServerStatusManager.class); // health/discovery status
bind(SessionContextDecorator.class).to(ZuulSessionContextDecorator.class); // decorate new sessions when requests come in
bind(Registry.class).to(DefaultRegistry.class); // atlas metrics registry
bind(RequestCompleteHandler.class).to(BasicRequestCompleteHandler.class); // metrics post-request completion
bind(AbstractDiscoveryClientOptionalArgs.class).to(DiscoveryClient.DiscoveryClientOptionalArgs.class); // discovery client
bind(RequestMetricsPublisher.class).to(BasicRequestMetricsPublisher.class); // timings publisher
// zuul filter loading
install(new ApiGwFiltersModule());
bind(FilterLoader.class).to(DynamicFilterLoader.class);
bind(FilterRegistry.class).to(MutableFilterRegistry.class);
bind(FilterFileManager.class).asEagerSingleton();
// access logger, including request ID generator
bind(AccessLogPublisher.class).toInstance(new AccessLogPublisher("ACCESS",
(channel, httpRequest) -> ClientRequestReceiver.getRequestFromChannel(channel).getContext().getUUID())
);
}
}

View File

@ -0,0 +1,18 @@
// package com.egommerce.apigateway.config;
// import java.io.File;
// import com.netflix.netty.common.ssl.ServerSslConfig;
// import io.netty.handler.ssl.ClientAuth;
// public class ApiGwServerSslConfig extends ServerSslConfig {
// public ApiGwServerSslConfig(
// String[] protocols, String[] ciphers, File certChainFile, File keyFile, ClientAuth clientAuth,
// File clientAuthTrustStoreFile, File clientAuthTrustStorePasswordFile, boolean sessionTicketsEnabled) {
// super(protocols, ciphers, certChainFile, keyFile, ClientAuth.NONE, getCertChainFile(), getClientAuthTrustStorePassword(), sessionTicketsEnabled)
// this.clientAuthTrustStorePassword = null;
// }
// }

View File

@ -0,0 +1,43 @@
package com.egommerce.apigateway.module;
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.appinfo.EurekaInstanceConfig;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.MyDataCenterInstanceConfig;
import com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider;
import com.netflix.discovery.DiscoveryClient;
import com.netflix.discovery.DefaultEurekaClientConfig;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.EurekaClientConfig;
// import org.slf4j.Logger;
// import org.slf4j.LoggerFactory;
public class ApiGwEurekaModule extends AbstractModule {
// private static final Logger log = LoggerFactory.getLogger(ApiGwFiltersModule.class);
@Override
protected void configure() {
// need to eagerly initialize
bind(ApplicationInfoManager.class).asEagerSingleton();
bind(EurekaClient.class).to(DiscoveryClient.class).in(Scopes.SINGLETON);
bind(EurekaInstanceConfig.class).to(MyDataCenterInstanceConfig.class);
bind(EurekaClientConfig.class).to(DefaultEurekaClientConfig.class);
// bind(EurekaClientConfig.class).toProvider(DefaultEurekaClientConfigProvider.class).in(Scopes.SINGLETON);
// // this is the self instanceInfo used for registration purposes
bind(InstanceInfo.class).toProvider(EurekaConfigBasedInstanceInfoProvider.class).in(Scopes.SINGLETON);
}
@Override
public boolean equals(Object obj) {
return obj != null && getClass().equals(obj.getClass());
}
@Override
public int hashCode() {
return getClass().hashCode();
}
}

View File

@ -0,0 +1,109 @@
package com.egommerce.apigateway.module;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.reflect.ClassPath;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.netflix.zuul.BasicFilterUsageNotifier;
import com.netflix.zuul.FilterFactory;
import com.netflix.zuul.FilterFileManager.FilterFileManagerConfig;
import com.netflix.zuul.FilterUsageNotifier;
import com.netflix.zuul.filters.ZuulFilter;
import com.netflix.zuul.guice.GuiceFilterFactory;
import java.io.FilenameFilter;
import org.apache.commons.configuration.AbstractConfiguration;
import java.io.IOException;
import java.util.Arrays;
import java.util.function.Predicate;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ApiGwFiltersModule extends AbstractModule {
private static final Logger log = LoggerFactory.getLogger(ApiGwFiltersModule.class);
private static Predicate<String> blank = String::isEmpty;
@Override
protected void configure() {
log.info("Starting Groovy Filter file manager");
bind(FilterFactory.class).to(GuiceFilterFactory.class);
bind(FilterUsageNotifier.class).to(BasicFilterUsageNotifier.class);
log.info("Groovy Filter file manager started");
}
@Provides
FilterFileManagerConfig provideFilterFileManagerConfig(
AbstractConfiguration config, FilenameFilter filenameFilter) {
// Get filter directories.
String[] filterLocations = findFilterLocations(config);
String[] filterClassNames = findClassNames(config);
// Init the FilterStore.
FilterFileManagerConfig filterConfig =
new FilterFileManagerConfig(filterLocations, filterClassNames, 5, filenameFilter);
return filterConfig;
}
// Get compiled filter classes to be found on classpath.
@VisibleForTesting
String[] findClassNames(AbstractConfiguration config) {
// Find individually-specified filter classes.
String[] filterClassNamesStrArray = config.getStringArray("zuul.filters.classes");
Stream<String> classNameStream = Arrays.stream(filterClassNamesStrArray)
.map(String::trim)
.filter(blank.negate());
// Find filter classes in specified packages.
String[] packageNamesStrArray = config.getStringArray("zuul.filters.packages");
ClassPath cp;
try {
cp = ClassPath.from(this.getClass().getClassLoader());
}
catch (IOException e) {
throw new RuntimeException("Error attempting to read classpath to find filters!", e);
}
Stream<String> packageStream = Arrays.stream(packageNamesStrArray)
.map(String::trim)
.filter(blank.negate())
.flatMap(packageName -> cp.getTopLevelClasses(packageName).stream())
.map(ClassPath.ClassInfo::load)
.filter(ZuulFilter.class::isAssignableFrom)
.map(Class::getCanonicalName);
String[] filterClassNames = Stream.concat(classNameStream, packageStream).toArray(String[]::new);
if (filterClassNames.length != 0) {
log.info("Using filter classnames: ");
for (String location : filterClassNames) {
log.info(" " + location);
}
}
return filterClassNames;
}
@VisibleForTesting
String[] findFilterLocations(AbstractConfiguration config) {
String[] locations = config.getStringArray("zuul.filters.locations");
if (locations == null) {
locations = new String[]{"inbound", "outbound", "endpoint"};
}
String[] filterLocations = Arrays.stream(locations)
.map(String::trim)
.filter(blank.negate())
.toArray(String[]::new);
if (filterLocations.length != 0) {
log.info("Using filter locations: ");
for (String location : filterLocations) {
log.info(" " + location);
}
}
return filterLocations;
}
}

View File

@ -0,0 +1,164 @@
# shortcuts
api_eureka_port=8761
# end: shortcuts
# dev mode
zuul.responseFilter.send.headers=true
# STABLE
zuul.server.port=8443
zuul.server.addr=127.0.0.1
# Loading filters
zuul.filters.root=src/main/groovy/com/egommerce/apigateway/filters
zuul.filters.locations=${zuul.filters.root}/inbound,${zuul.filters.root}/outbound,${zuul.filters.root}/endpoint
zuul.filters.packages=com.netflix.zuul.filters.common
# Eureka configuration
# eureka api registry svc url
eureka.serviceUrl.default=http://127.0.0.1:${api_eureka_port}/eureka/
eureka.region=default
# fetch registry from eureka service
eureka.shouldFetchRegistry=true
# register instance in eureka service
eureka.registration.enabled=true
eureka.validateInstanceId=false
eureka.preferSameZone=true
eureka.shouldUseDns=false
# Test
# api-gateway-svc.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
api-gateway-svc.ribbon.DeploymentContextBasedVipAddresses=api-gateway-svc
identity-svc.ribbon.DeploymentContextBasedVipAddresses=identity-svc
identity-svc.ribbon.IsSecure=true
# api.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
# api.ribbon.DeploymentContextBasedVipAddresses=identity-svc
# eureka.shouldFilterOnlyUpInstance=false
# eureka.shouldOnDemandUpdateStatusChange=false
# Ribbon
# ribbon.eureka.enabled=true
# api.ribbon.listOfServers=identity-svc:8080
# api.ribbon.NIWSServerListClassName=com.netflix.loadbalancer.ConfigurationBasedServerList
# api.client.NIWSServerListClassName=com.netflix.loadbalancer.ConfigurationBasedServerList
# api.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
# api.ribbon.DeploymentContextBasedVipAddresses=identity-svc
# ribbon.listOfServers=127.0.0.1:8761
# ribbon.DeploymentContextBasedVipAddresses="other-path:443"
# ribbon.listOfServers=127.0.0.1:9999
# ribbon.client.NIWSServerListClassName=com.netflix.loadbalancer.ConfigurationBasedServerList
# ribbon.DeploymentContextBasedVipAddresses=${eureka.vipAddress}
# ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
# ribbon.NIWSServerListClassName=com.netflix.loadbalancer.ConfigurationBasedServerList
# ribbon.DeploymentContextBasedVipAddresses=${zuul.server.addr}:${zuul.server.port}
# eureka.virtualHostName=${eureka.name}
# eureka.nonSecurePortEnabled=true
# eureka.nonSecurePort={$eureka.port}
# eureka.securePortEnabled=false
# eureka.securePort={$eureka.port}
# eureka.instance.virtualHostName=${eureka.name}
# eureka.instance.nonSecurePortEnabled=true
# eureka.instance.nonSecurePort={$eureka.port}
# eureka.instance.securePortEnabled=false
# eureka.instance.securePort={$eureka.port}
# eureka.instance.secureVirtualHostName=${eureka.name}
# eureka.client.fetchRegistry=true
# eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://127.0.0.1:8761/eureka}
# eureka.serviceUrl.defaultZone=${eureka.serviceUrl.default}
# eureka.client.serviceUrl.defaultZone=${eureka.serviceUrl.default}
# store routes in config.properties ...
# zuul.retryable=true
# zuul.http2.enabled=true
# SSL configuration
# zuul.ssl.enabled=true
# zuul.ssl.protocol=TLS
# zuul.ssl.keyAlias=${spring.application.name}
# zuul.ssl.keyStore=classpath:keystore.p12
# zuul.ssl.keyStoreType=PKCS12
# zuul.ssl.keyStorePassword=${KEYSTORE_PASSWORD}
# zuul.ssl.keyPassword=${KEYSTORE_PASSWORD}
# zuul.ssl.trustStore=classpath:truststore.p12
# zuul.ssl.trustStoreType=PKCS12
# zuul.ssl.trustStorePassword=${KEYSTORE_PASSWORD}
# zuul.ssl.hostnameValidationEnabled=false
# Timeouts configuration
# zuul.host.socketTimeoutMillis=10000
# zuul.host.connectTimeoutMillis=10000
# zuul.host.maxTotalConnections=5000
# zuul.host.maxPerRouteConnections=5
# Ribbon configuration
# ribbon.okhttp.enabled=true
# ribbon:
# ReadTimeout: 20000
# ConnectTimeout: 20000
# MaxAutoRetries: 0
# MaxAutoRetriesNextServer: 1
# MaxTotalHttpConnections: 2000
# MaxConnectionsPerHost: 1000
# Routing to proxied backend services
# api.ribbon.port=8761
# api.ribbon.ReadTimeout: 9999
# api.ribbon.ConnectTimeout: 8888
# api.ribbon.MaxAutoRetries: 5
# api.ribbon.MaxAutoRetriesNextServer: 6
# api.ribbon.MaxTotalHttpConnections: 7777
# api.ribbon.MaxConnectionsPerHost: 6666
# management: # debug
# endpoints:
# web:
# exposure:
# include:
# - "*"
# ribbon:
# eureka:
# enabled: true
# okhttp:
# enabled: true
# ReadTimeout: 20000
# ConnectTimeout: 20000
# MaxAutoRetries: 0
# MaxAutoRetriesNextServer: 1
# MaxTotalHttpConnections: 2000
# MaxConnectionsPerHost: 1000
# hystrix:
# command:
# default:
# execution:
# timeout:
# enabled: false
# isolation:
# thread:
# timeoutInMilliseconds: 60000

View File

@ -0,0 +1,13 @@
zuul.routes.identity-svc.path=/auth/**
zuul.routes.identity-svc.serviceId=identity-svc
# zuul.routes.identity-svc.url=grpc://127.0.0.1:8080/
#zuul.routes.api-gateway-svc.path=/gateway/**
#zuul.routes.api-gateway-svc.serviceId=api-dateway-svc
#zuul.routes.identity-svc.path=/AuthService/**
#zuul.routes.identity-svc.url=http://127.0.0.1:9999/auth/
#zuul.routes.basket-svc.path=/BasketService/**
#zuul.routes.basket-svc.serviceId=basket-svc

View File

@ -0,0 +1,18 @@
# Client registratio config
eureka.name=api-gateway-svc
eureka.instanceId=api-gateway-svc
eureka.app=api-gateway-svc
# eureka.hostName=api-gateway-svc-hostname
eureka.appGroup=egommerce
eureka.vipAddress=api-gateway-svc
eureka.port=8000
eureka.port.enabled=true
eureka.securePort=8443
eureka.securePort.enabled=false
eureka.homePageUrl=http://${zuul.server.addr}:${zuul.server.port}/API
eureka.statusPageUrl=http://${zuul.server.addr}:${zuul.server.port}/API/status
eureka.healthCheckUrl=http://${zuul.server.addr}:${zuul.server.port}/API/healthcheck

View File

@ -0,0 +1,30 @@
org.slf4j.simpleLogger.defaultLogLevel=debug
org.slf4j.simpleLogger.showDateTime=true
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z
org.slf4j.simpleLogger.showThreadName=true
log4j.rootLogger=debug, STDOUT
log4j.logger.deng=debug
rootLogger.level = debug
# log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
# log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
# log4j.appender.STDOUT.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
# rootLogger.appenderRef.stdout.ref = STDOUT
# log4j.logger.com.netflix.loadbalancer=debug
# log4j.logger.com.netflix.config=debug
# log4j.logger.com.egommerce.apigw=debug
# log4j.logger.com.egommerce.apigw.level=debug
# log4j.logger.com.egommerce.apigw.module.level=debug
# # log4j.appender.R=org.apache.log4j.RollingFileAppender
# # log4j.appender.R.File=example.log
# # log4j.appender.R.MaxFileSize=100KB
# # # Keep one backup file
# # log4j.appender.R.MaxBackupIndex=1
# # log4j.appender.R.layout=org.apache.log4j.PatternLayout
# # log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

View File

@ -0,0 +1,34 @@
-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----

View File

@ -0,0 +1,54 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
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
gi9AIDRe7xUKIxlzjYTJbw==
-----END ENCRYPTED PRIVATE KEY-----

View File

@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
30ORlCczdDMlDQoGa9jOX7k1R34fxCU=
-----END PRIVATE KEY-----

View File

@ -1,43 +0,0 @@
include apigw_backends.conf;
include apigw_keys.conf;
server {
access_log /var/log/nginx/apigw_access.log main;
error_log /var/log/nginx/apigw_error.log warn;
listen 80;
# listen 443 ssl;
# server_name apigw_svc; # container name from stack config
# server_name api.example.com;
# TLS config
# ssl_certificate /etc/ssl/certs/apigw.example.com.crt;
# ssl_certificate_key /etc/ssl/private/apigw.example.com.key;
# ssl_session_cache shared:SSL:10m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_protocols TLSv1.2 TLSv1.3;
# API definitions, one per file
include apigw_conf.d/*.conf;
# Error responses
# error_page 404 = @400; # Treat invalid paths as bad requests
proxy_intercept_errors on; # Do not send backend errors to client
include apigw_json_errors.conf; # API client-friendly JSON errors
default_type application/json; # If no content-type, assume JSON
# API key validation
location = /_validate_apikey {
internal;
if ($http_apikey = "") {
return 401; # Unauthorized
}
if ($apigw_client_name = "") {
return 403; # Forbidden
}
return 204; # OK (no content)
}
}

View File

@ -1,9 +0,0 @@
upstream identity_api {
# zone inventory_service 64k;
server identity_svc:8080; # container name from stack config
}
upstream basket_api {
# zone pricing_service 64k;
server basket_svc:8080; # container name from stack config
}

View File

@ -1,14 +0,0 @@
# Basket API
#
location /api/basket/ {
access_log /var/log/nginx/basket_access.log main;
error_log /var/log/nginx/basket_error.log warn;
auth_request /_validate_apikey;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header User-Agent "api-gw"; # TMP - FIXME
proxy_pass http://basket_api/;
}

View File

@ -1,32 +0,0 @@
# Identity API
#
location /api/identity/ {
access_log /var/log/nginx/identity_access.log main;
error_log /var/log/nginx/identity_error.log warn;
auth_request /_validate_apikey;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header User-Agent "egommerce-api-gateway/0.1"; # TMP - FIXME
proxy_pass http://identity_api/;
}
# # URI routing
# #
# location = /api/warehouse/inventory { # Complete inventory
# proxy_pass http://warehouse_inventory;
# }
# location ~ ^/api/warehouse/inventory/shelf/[^/]+$ { # Shelf inventory
# proxy_pass http://warehouse_inventory;
# }
# location ~ ^/api/warehouse/inventory/shelf/[^/]+/box/[^/]+$ { # Box on shelf
# proxy_pass http://warehouse_inventory;
# }
# location ~ ^/api/warehouse/pricing/[^/]+$ { # Price for specific item
# proxy_pass http://warehouse_pricing;
# }

View File

@ -1,11 +0,0 @@
error_page 400 = @400;
location @400 { return 400 '{"status":400,"message":"Bad request"}\n'; }
error_page 401 = @401;
location @401 { return 401 '{"status":401,"message":"Unauthorized"}\n'; }
error_page 403 = @403;
location @403 { return 403 '{"status":403,"message":"Forbidden"}\n'; }
error_page 404 = @404;
location @404 { return 404 '{"status":404,"message":"Resource not found"}\n'; }

View File

@ -1,9 +0,0 @@
map $http_apikey $apigw_client_name {
default "";
"R7HVf14WE5m4d5L3uv2sZU8Y" "identity_api";
"fd7uAN3/GKIfvFrOdfEAoo1y" "basket_api";
}
# $ openssl rand -base64 18
# 7B5zIqmRGXmrJTFmKa99vcit

View File

@ -1,32 +0,0 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/apigw.conf;
}

View File

@ -1,16 +1,15 @@
#!/bin/sh #!/bin/sh
# RUN IN REPO ROOT DIR !! # RUN IN REPO ROOT DIR !!
export IMAGE_NAME="git.pbiernat.dev/egommerce/apigw-svc" IMAGE_NAME="git.pbiernat.dev/egommerce/apigw-svc"
TARGET=${1:-latest} TARGET=${1:-latest}
echo "Building: $IMAGE_NAME:$TARGET" echo "Building: $IMAGE_NAME:$TARGET"
if [ $TARGET = "dev" ] if [ $TARGET = "latest" ]
then then
docker build --rm --no-cache -t "$IMAGE_NAME:dev" . >/dev/null 2>&1 docker build --rm --cache-from "$IMAGE_NAME:$TARGET" -t "$IMAGE_NAME:$TARGET"
else else
docker build --rm --cache-from "$IMAGE_NAME:$TARGET" -t "$IMAGE_NAME:$TARGET" . >/dev/null 2>&1 docker build --rm --no-cache -t "$IMAGE_NAME:$TARGET" . #>/dev/null 2>&1
fi fi
echo "Done." echo "Done."

0
test
View File