diff --git a/microservices/.gitignore b/microservices/.gitignore
new file mode 100644
index 0000000..102a55e
--- /dev/null
+++ b/microservices/.gitignore
@@ -0,0 +1,22 @@
+## FOR MAVEN
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+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
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+*.env
\ No newline at end of file
diff --git a/microservices/README.md b/microservices/README.md
new file mode 100644
index 0000000..69a3206
--- /dev/null
+++ b/microservices/README.md
@@ -0,0 +1,27 @@
+# Microservices/Docker Practice
+
+## Docker Containers
+
+
+
+
+
+## Product Email
+
+
+
+
+
+
+
+
+
+## Category Email
+
+
+
+
+
+
+
+
diff --git a/microservices/api/.classpath b/microservices/api/.classpath
new file mode 100644
index 0000000..c6f2285
--- /dev/null
+++ b/microservices/api/.classpath
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/microservices/api/.factorypath b/microservices/api/.factorypath
new file mode 100644
index 0000000..888b54d
--- /dev/null
+++ b/microservices/api/.factorypath
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/microservices/api/.mvn/wrapper/MavenWrapperDownloader.java b/microservices/api/.mvn/wrapper/MavenWrapperDownloader.java
new file mode 100644
index 0000000..e76d1f3
--- /dev/null
+++ b/microservices/api/.mvn/wrapper/MavenWrapperDownloader.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007-present the original author or authors.
+ *
+ * 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
+ *
+ * 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.
+ */
+import java.net.*;
+import java.io.*;
+import java.nio.channels.*;
+import java.util.Properties;
+
+public class MavenWrapperDownloader {
+
+ private static final String WRAPPER_VERSION = "0.5.6";
+ /**
+ * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
+ */
+ private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
+
+ /**
+ * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
+ * use instead of the default one.
+ */
+ private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
+ ".mvn/wrapper/maven-wrapper.properties";
+
+ /**
+ * Path where the maven-wrapper.jar will be saved to.
+ */
+ private static final String MAVEN_WRAPPER_JAR_PATH =
+ ".mvn/wrapper/maven-wrapper.jar";
+
+ /**
+ * Name of the property which should be used to override the default download url for the wrapper.
+ */
+ private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
+
+ public static void main(String args[]) {
+ System.out.println("- Downloader started");
+ File baseDirectory = new File(args[0]);
+ System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
+
+ // If the maven-wrapper.properties exists, read it and check if it contains a custom
+ // wrapperUrl parameter.
+ File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
+ String url = DEFAULT_DOWNLOAD_URL;
+ if(mavenWrapperPropertyFile.exists()) {
+ FileInputStream mavenWrapperPropertyFileInputStream = null;
+ try {
+ mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
+ Properties mavenWrapperProperties = new Properties();
+ mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
+ url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
+ } catch (IOException e) {
+ System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
+ } finally {
+ try {
+ if(mavenWrapperPropertyFileInputStream != null) {
+ mavenWrapperPropertyFileInputStream.close();
+ }
+ } catch (IOException e) {
+ // Ignore ...
+ }
+ }
+ }
+ System.out.println("- Downloading from: " + url);
+
+ File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
+ if(!outputFile.getParentFile().exists()) {
+ if(!outputFile.getParentFile().mkdirs()) {
+ System.out.println(
+ "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+ }
+ }
+ System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
+ try {
+ downloadFileFromURL(url, outputFile);
+ System.out.println("Done");
+ System.exit(0);
+ } catch (Throwable e) {
+ System.out.println("- Error downloading");
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+ if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+ String username = System.getenv("MVNW_USERNAME");
+ char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+ Authenticator.setDefault(new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(username, password);
+ }
+ });
+ }
+ URL website = new URL(urlString);
+ ReadableByteChannel rbc;
+ rbc = Channels.newChannel(website.openStream());
+ FileOutputStream fos = new FileOutputStream(destination);
+ fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+ fos.close();
+ rbc.close();
+ }
+
+}
diff --git a/microservices/api/.mvn/wrapper/maven-wrapper.properties b/microservices/api/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..a9f1ef8
--- /dev/null
+++ b/microservices/api/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
diff --git a/microservices/api/.project b/microservices/api/.project
new file mode 100644
index 0000000..42d3c3d
--- /dev/null
+++ b/microservices/api/.project
@@ -0,0 +1,39 @@
+
+
+ openmarket-app
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.springframework.ide.eclipse.boot.validation.springbootbuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
+
+ 1687937687134
+
+ 30
+
+ org.eclipse.core.resources.regexFilterMatcher
+ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
+
+
+
+
diff --git a/microservices/api/Dockerfile b/microservices/api/Dockerfile
new file mode 100644
index 0000000..8a4ce77
--- /dev/null
+++ b/microservices/api/Dockerfile
@@ -0,0 +1,4 @@
+FROM openjdk:11-jdk-slim
+ARG JAR_FILE=target/*.jar
+COPY ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-jar","/app.jar"]
\ No newline at end of file
diff --git a/microservices/api/HELP.md b/microservices/api/HELP.md
new file mode 100644
index 0000000..8801ae4
--- /dev/null
+++ b/microservices/api/HELP.md
@@ -0,0 +1,26 @@
+# Read Me First
+The following was discovered as part of building this project:
+
+* The original package name 'com.sahydo.openmarket-app' is invalid and this project uses 'com.sahydo.openmarketapp' instead.
+
+# Getting Started
+
+### Reference Documentation
+For further reference, please consider the following sections:
+
+* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
+* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.6.2/maven-plugin/reference/html/)
+* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.6.2/maven-plugin/reference/html/#build-image)
+* [Spring Web](https://docs.spring.io/spring-boot/docs/2.6.2/reference/htmlsingle/#boot-features-developing-web-applications)
+* [Spring Data JPA](https://docs.spring.io/spring-boot/docs/2.6.2/reference/htmlsingle/#boot-features-jpa-and-spring-data)
+* [Spring Boot DevTools](https://docs.spring.io/spring-boot/docs/2.6.2/reference/htmlsingle/#using-boot-devtools)
+
+### Guides
+The following guides illustrate how to use some features concretely:
+
+* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
+* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
+* [Building REST services with Spring](https://spring.io/guides/tutorials/bookmarks/)
+* [Accessing Data with JPA](https://spring.io/guides/gs/accessing-data-jpa/)
+* [Accessing data with MySQL](https://spring.io/guides/gs/accessing-data-mysql/)
+
diff --git a/microservices/api/README.md b/microservices/api/README.md
new file mode 100644
index 0000000..59d9651
--- /dev/null
+++ b/microservices/api/README.md
@@ -0,0 +1,2 @@
+# openmarket-app
+This project contains a REST API to control business logic to save and get Openmarket Requests.
diff --git a/microservices/api/mvnw b/microservices/api/mvnw
new file mode 100644
index 0000000..a16b543
--- /dev/null
+++ b/microservices/api/mvnw
@@ -0,0 +1,310 @@
+#!/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
+#
+# 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.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# 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 /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
+ export JAVA_HOME="`/usr/libexec/java_home`"
+ else
+ export JAVA_HOME="/Library/Java/Home"
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ 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
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -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 "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -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="`which 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
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# 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
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+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
+ jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $jarUrl"
+ 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
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaClass" ]; then
+ if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaClass")
+ fi
+ if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; 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
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+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 "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -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 \
+ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/microservices/api/mvnw.cmd b/microservices/api/mvnw.cmd
new file mode 100644
index 0000000..c8d4337
--- /dev/null
+++ b/microservices/api/mvnw.cmd
@@ -0,0 +1,182 @@
+@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 https://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 Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@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 "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\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 DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_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 DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %DOWNLOAD_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('%DOWNLOAD_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 "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\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%
+
+exit /B %ERROR_CODE%
diff --git a/microservices/api/pom.xml b/microservices/api/pom.xml
new file mode 100644
index 0000000..bc01fc2
--- /dev/null
+++ b/microservices/api/pom.xml
@@ -0,0 +1,86 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.6.2
+
+
+ com.sahydo
+ openmarket-app-api
+ 0.0.1-SNAPSHOT
+ Openmarket system
+ This project contains a REST API to control business logic to save and get Openmarket Requests.
+
+ 11
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
+
+ mysql
+ mysql-connector-java
+ runtime
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-hateoas
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ com.h2database
+ h2
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+
+
+
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/OpenmarketSystemApplication.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/OpenmarketSystemApplication.java
new file mode 100644
index 0000000..da37ab6
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/OpenmarketSystemApplication.java
@@ -0,0 +1,13 @@
+package com.sahydo.openmarketapp;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class OpenmarketSystemApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(OpenmarketSystemApplication.class, args);
+ }
+
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/access/dao/ICategoryRequestDAO.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/access/dao/ICategoryRequestDAO.java
new file mode 100644
index 0000000..9cb2bf7
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/access/dao/ICategoryRequestDAO.java
@@ -0,0 +1,9 @@
+package com.sahydo.openmarketapp.access.dao;
+
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+import com.sahydo.openmarketapp.domain.model.CategoryEvent;
+
+public interface ICategoryRequestDAO extends PagingAndSortingRepository {
+
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/access/dao/IProductRequestDAO.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/access/dao/IProductRequestDAO.java
new file mode 100644
index 0000000..6bce00e
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/access/dao/IProductRequestDAO.java
@@ -0,0 +1,9 @@
+package com.sahydo.openmarketapp.access.dao;
+
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+import com.sahydo.openmarketapp.domain.model.ProductEvent;
+
+public interface IProductRequestDAO extends PagingAndSortingRepository {
+
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/model/CategoryEvent.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/model/CategoryEvent.java
new file mode 100644
index 0000000..978d4f5
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/model/CategoryEvent.java
@@ -0,0 +1,43 @@
+package com.sahydo.openmarketapp.domain.model;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.validation.constraints.NotNull;
+
+import lombok.Data;
+
+/**
+ * @author Santiago Hyun
+ */
+@Entity
+@Table(name = "categories")
+@Data
+public class CategoryEvent implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @Id // This makes the id as primary key
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @Column(name = "name")
+ @NotNull(message = "El nombre es obligatorio")
+ private String name;
+
+ @Column(name = "description")
+ private String description;
+
+ @Column(name = "action")
+ @NotNull(message = "La accion es obligatoria")
+ private String action;
+
+ @Column(name = "holderEmail")
+ @NotNull(message = "El correo es obligatorio")
+ private String holderEmail;
+
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/model/ProductEvent.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/model/ProductEvent.java
new file mode 100644
index 0000000..6075041
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/model/ProductEvent.java
@@ -0,0 +1,44 @@
+package com.sahydo.openmarketapp.domain.model;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.validation.constraints.NotNull;
+
+import lombok.Data;
+
+/**
+ * @author Santiago Hyun
+ */
+@Entity
+@Table(name = "products")
+@Data
+public class ProductEvent implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @Id // This makes the id as primary key
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @Column(name = "name")
+ @NotNull(message = "El nombre es obligatorio")
+ private String name;
+
+ @Column(name = "price")
+ @NotNull(message = "El precio es obligatorio")
+ private Double price;
+
+ @Column(name = "action")
+ @NotNull(message = "La accion es obligatoria")
+ private String action;
+
+ @Column(name = "holderEmail")
+ @NotNull(message = "El correo es obligatorio")
+ private String holderEmail;
+
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/model/wrapper/CategoryRequestWrapper.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/model/wrapper/CategoryRequestWrapper.java
new file mode 100644
index 0000000..950ff73
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/model/wrapper/CategoryRequestWrapper.java
@@ -0,0 +1,20 @@
+package com.sahydo.openmarketapp.domain.model.wrapper;
+
+import org.springframework.hateoas.RepresentationModel;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.sahydo.openmarketapp.domain.model.CategoryEvent;
+
+public class CategoryRequestWrapper extends RepresentationModel {
+ private final CategoryEvent categoryRequest;
+
+ @JsonCreator
+ public CategoryRequestWrapper(@JsonProperty("categoryRequest") CategoryEvent categoryRequest) {
+ this.categoryRequest = categoryRequest;
+ }
+
+ public CategoryEvent getOpenmarketRequest() {
+ return categoryRequest;
+ }
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/model/wrapper/ProductRequestWrapper.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/model/wrapper/ProductRequestWrapper.java
new file mode 100644
index 0000000..a5ecf2d
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/model/wrapper/ProductRequestWrapper.java
@@ -0,0 +1,20 @@
+package com.sahydo.openmarketapp.domain.model.wrapper;
+
+import org.springframework.hateoas.RepresentationModel;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.sahydo.openmarketapp.domain.model.ProductEvent;
+
+public class ProductRequestWrapper extends RepresentationModel {
+ private final ProductEvent productRequest;
+
+ @JsonCreator
+ public ProductRequestWrapper(@JsonProperty("productRequest") ProductEvent productRequest) {
+ this.productRequest = productRequest;
+ }
+
+ public ProductEvent getOpenmarketRequest() {
+ return productRequest;
+ }
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/CategoryRequestImplService.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/CategoryRequestImplService.java
new file mode 100644
index 0000000..66becb9
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/CategoryRequestImplService.java
@@ -0,0 +1,67 @@
+package com.sahydo.openmarketapp.domain.service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.sahydo.openmarketapp.access.dao.ICategoryRequestDAO;
+import com.sahydo.openmarketapp.domain.model.CategoryEvent;
+import com.sahydo.openmarketapp.presentation.rest.exception.OpenmarketErrorDomainException;
+import com.sahydo.openmarketapp.presentation.rest.exception.OpenmarketRequestError;
+import com.sahydo.openmarketapp.presentation.rest.exception.EnumErrorCode;
+import com.sahydo.openmarketapp.presentation.rest.exception.ResourceNotFoundException;
+import com.sahydo.openmarketapp.utilities.EmailTemplateUtil;
+
+@Service
+public class CategoryRequestImplService implements ICategoryEventService {
+
+ @Autowired
+ private ICategoryRequestDAO categoryRequestDAO;
+ @Autowired
+ private IEmailService emailService;
+
+ @Override
+ @Transactional(readOnly = true) // To sync with db
+ public List findAll() {
+ return (List) categoryRequestDAO.findAll();
+ }
+
+ @Override
+ @Transactional(readOnly = true) // To sync with db
+ public CategoryEvent findById(Long id) throws ResourceNotFoundException {
+ CategoryEvent openmarketRequest = categoryRequestDAO.findById(id).orElse(null);
+ if (openmarketRequest == null) {
+ throw new ResourceNotFoundException(id);
+ }
+ return openmarketRequest;
+ }
+
+ @Override
+ @Transactional
+ public CategoryEvent create(CategoryEvent openmarketRequest) throws OpenmarketErrorDomainException {
+ List errors = validateOpenmarketRequest(openmarketRequest);
+ if (!errors.isEmpty()) {
+ throw new OpenmarketErrorDomainException(errors);
+ }
+ CategoryEvent openmarketRequestSaved = categoryRequestDAO.save(openmarketRequest);
+ if (openmarketRequestSaved != null) {
+ emailService.sendSimpleEmail(openmarketRequest.getHolderEmail(),
+ EmailTemplateUtil.OPENMARKET_SUCCESSFULLY_CREATED_SUBJECT,
+ "The Openmarket request was created successfully. Please check the details below: \n"
+ + openmarketRequest.toString());
+ }
+ return openmarketRequestSaved;
+ }
+
+ private List validateOpenmarketRequest(final CategoryEvent openmarketRequest) {
+ List errors = new ArrayList<>();
+ if (!openmarketRequest.getHolderEmail().contains("@")) {
+ errors.add(new OpenmarketRequestError(EnumErrorCode.INVALID_FIELD, "Invalid email",
+ "The email is invalid"));
+ }
+ return errors;
+ }
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/EmailImplService.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/EmailImplService.java
new file mode 100644
index 0000000..b4c12ec
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/EmailImplService.java
@@ -0,0 +1,45 @@
+package com.sahydo.openmarketapp.domain.service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.stereotype.Service;
+
+import com.sahydo.openmarketapp.presentation.rest.exception.OpenmarketRequestError;
+import com.sahydo.openmarketapp.utilities.EmailTemplateUtil;
+
+@Service
+public class EmailImplService implements IEmailService {
+
+ @Autowired
+ private JavaMailSender emailSender;
+
+ @Override
+ public void sendSimpleEmail(final String to, final String subject, final String body) {
+ if (EmailTemplateUtil.IS_ENABLED_EMAILING) {
+ SimpleMailMessage message = new SimpleMailMessage();
+ message.setFrom("noreply@bogus.com");
+ message.setTo(to);
+ message.setSubject(subject);
+ message.setText(body);
+ emailSender.send(message);
+ System.out.println("Correo enviado correctamente a " + to);
+ }
+ }
+
+ @Override
+ public void sendSimpleFailureEmail(String to, String subject, List errors) {
+ sendSimpleEmail(to, subject, getErrorMessageFromOpenmarketErrors(errors));
+ }
+
+ private String getErrorMessageFromOpenmarketErrors(List errors) {
+ String message = "The Openmarket Request was not processed due to the next problems: \n";
+ List errorMessages = errors.stream().map(error -> "\n" + error.message.concat(" "))
+ .collect(Collectors.toList());
+ return message.concat(String.join(" ", errorMessages));
+ }
+
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/ICategoryEventService.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/ICategoryEventService.java
new file mode 100644
index 0000000..3144944
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/ICategoryEventService.java
@@ -0,0 +1,6 @@
+package com.sahydo.openmarketapp.domain.service;
+
+import com.sahydo.openmarketapp.domain.model.CategoryEvent;
+
+public interface ICategoryEventService extends IServiceRequestService {
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/IEmailService.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/IEmailService.java
new file mode 100644
index 0000000..7c7cd28
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/IEmailService.java
@@ -0,0 +1,11 @@
+package com.sahydo.openmarketapp.domain.service;
+
+import java.util.List;
+
+import com.sahydo.openmarketapp.presentation.rest.exception.OpenmarketRequestError;
+
+public interface IEmailService {
+ public void sendSimpleEmail(String to, String subject, String body);
+
+ public void sendSimpleFailureEmail(String to, String subject, List errors);
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/IProductEventService.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/IProductEventService.java
new file mode 100644
index 0000000..f7c718e
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/IProductEventService.java
@@ -0,0 +1,6 @@
+package com.sahydo.openmarketapp.domain.service;
+
+import com.sahydo.openmarketapp.domain.model.ProductEvent;
+
+public interface IProductEventService extends IServiceRequestService {
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/IServiceRequestService.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/IServiceRequestService.java
new file mode 100644
index 0000000..629a895
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/IServiceRequestService.java
@@ -0,0 +1,15 @@
+package com.sahydo.openmarketapp.domain.service;
+
+import java.io.Serializable;
+import java.util.List;
+
+import com.sahydo.openmarketapp.presentation.rest.exception.OpenmarketErrorDomainException;
+import com.sahydo.openmarketapp.presentation.rest.exception.ResourceNotFoundException;
+
+public interface IServiceRequestService {
+ public List findAll();
+
+ public T findById(Long id) throws ResourceNotFoundException;
+
+ public T create(T T) throws OpenmarketErrorDomainException;
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/ProductRequestImplService.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/ProductRequestImplService.java
new file mode 100644
index 0000000..998367c
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/domain/service/ProductRequestImplService.java
@@ -0,0 +1,67 @@
+package com.sahydo.openmarketapp.domain.service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.sahydo.openmarketapp.access.dao.IProductRequestDAO;
+import com.sahydo.openmarketapp.domain.model.ProductEvent;
+import com.sahydo.openmarketapp.presentation.rest.exception.OpenmarketErrorDomainException;
+import com.sahydo.openmarketapp.presentation.rest.exception.OpenmarketRequestError;
+import com.sahydo.openmarketapp.presentation.rest.exception.EnumErrorCode;
+import com.sahydo.openmarketapp.presentation.rest.exception.ResourceNotFoundException;
+import com.sahydo.openmarketapp.utilities.EmailTemplateUtil;
+
+@Service
+public class ProductRequestImplService implements IProductEventService {
+
+ @Autowired
+ private IProductRequestDAO productRequestDAO;
+ @Autowired
+ private IEmailService emailService;
+
+ @Override
+ @Transactional(readOnly = true) // To sync with db
+ public List findAll() {
+ return (List) productRequestDAO.findAll();
+ }
+
+ @Override
+ @Transactional(readOnly = true) // To sync with db
+ public ProductEvent findById(Long id) throws ResourceNotFoundException {
+ ProductEvent openmarketRequest = productRequestDAO.findById(id).orElse(null);
+ if (openmarketRequest == null) {
+ throw new ResourceNotFoundException(id);
+ }
+ return openmarketRequest;
+ }
+
+ @Override
+ @Transactional
+ public ProductEvent create(ProductEvent openmarketRequest) throws OpenmarketErrorDomainException {
+ List errors = validateOpenmarketRequest(openmarketRequest);
+ if (!errors.isEmpty()) {
+ throw new OpenmarketErrorDomainException(errors);
+ }
+ ProductEvent openmarketRequestSaved = productRequestDAO.save(openmarketRequest);
+ if (openmarketRequestSaved != null) {
+ emailService.sendSimpleEmail(openmarketRequest.getHolderEmail(),
+ EmailTemplateUtil.OPENMARKET_SUCCESSFULLY_CREATED_SUBJECT,
+ "The Openmarket request was created successfully. Please check the details below: \n"
+ + openmarketRequest.toString());
+ }
+ return openmarketRequestSaved;
+ }
+
+ private List validateOpenmarketRequest(final ProductEvent openmarketRequest) {
+ List errors = new ArrayList<>();
+ if (!openmarketRequest.getHolderEmail().contains("@")) {
+ errors.add(new OpenmarketRequestError(EnumErrorCode.INVALID_FIELD, "Invalid email",
+ "The email is invalid"));
+ }
+ return errors;
+ }
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/CategoryRequestController.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/CategoryRequestController.java
new file mode 100644
index 0000000..60a55ad
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/CategoryRequestController.java
@@ -0,0 +1,89 @@
+package com.sahydo.openmarketapp.presentation.rest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.sahydo.openmarketapp.domain.service.ICategoryEventService;
+import com.sahydo.openmarketapp.presentation.rest.exception.ResourceNotFoundException;
+import com.sahydo.openmarketapp.domain.model.CategoryEvent;
+import com.sahydo.openmarketapp.domain.model.wrapper.CategoryRequestWrapper;
+import com.sahydo.openmarketapp.presentation.rest.exception.OpenmarketErrorDomainException;
+import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
+
+/**
+ * @author Santiago Hyun
+ */
+
+@RestController
+@RequestMapping("categoryRequests")
+public class CategoryRequestController {
+ @Autowired
+ private ICategoryEventService categoryRequestService;
+
+ /**
+ *
+ * @return list of Category Requests
+ */
+ @RequestMapping(method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public HttpEntity> findAll() {
+ List categoryRequests = new ArrayList<>();
+ categoryRequestService.findAll().stream().forEach(br -> {
+ CategoryRequestWrapper wrapper = new CategoryRequestWrapper(br);
+ try {
+ wrapper.add(linkTo(methodOn(CategoryRequestController.class).findById(br.getId())).withSelfRel());
+ } catch (ResourceNotFoundException e) {
+ e.printStackTrace();
+ }
+ categoryRequests.add(wrapper);
+ });
+ return new ResponseEntity<>(categoryRequests, HttpStatus.OK);
+ }
+
+ /**
+ * get a Category Request by Id
+ *
+ * @param id
+ * @return CategoryEvent JSON
+ * @throws Exception
+ */
+ @RequestMapping(value = "{id}", method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public HttpEntity findById(@PathVariable Long id) throws ResourceNotFoundException {
+ CategoryEvent categoryRequest = categoryRequestService.findById(id);
+ CategoryRequestWrapper wrapper = new CategoryRequestWrapper(categoryRequest);
+ wrapper.add(linkTo(methodOn(CategoryRequestController.class).findById(id)).withSelfRel());
+ return new ResponseEntity<>(wrapper, HttpStatus.OK);
+ }
+
+ /**
+ * Creates a CategoryEvent
+ *
+ * @param CategoryEvent JSON
+ * @return CategoryRequesto JSON
+ * @throws ResourceNotFoundException
+ */
+
+ @RequestMapping(method = RequestMethod.POST, produces = "application/json")
+ @ResponseBody
+ public HttpEntity create(@RequestBody CategoryEvent categoryRequest)
+ throws OpenmarketErrorDomainException, ResourceNotFoundException {
+ CategoryEvent categoryRequestCreated = categoryRequestService.create(categoryRequest);
+ CategoryRequestWrapper wrapper = new CategoryRequestWrapper(categoryRequestCreated);
+ wrapper.add(
+ linkTo(methodOn(CategoryRequestController.class).findById(categoryRequestCreated.getId()))
+ .withSelfRel());
+ return new ResponseEntity<>(wrapper, HttpStatus.OK);
+ }
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/ProductRequestController.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/ProductRequestController.java
new file mode 100644
index 0000000..232835c
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/ProductRequestController.java
@@ -0,0 +1,89 @@
+package com.sahydo.openmarketapp.presentation.rest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.sahydo.openmarketapp.domain.service.IProductEventService;
+import com.sahydo.openmarketapp.presentation.rest.exception.ResourceNotFoundException;
+import com.sahydo.openmarketapp.domain.model.ProductEvent;
+import com.sahydo.openmarketapp.domain.model.wrapper.ProductRequestWrapper;
+import com.sahydo.openmarketapp.presentation.rest.exception.OpenmarketErrorDomainException;
+import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
+
+/**
+ * @author Santiago Hyun
+ */
+
+@RestController
+@RequestMapping("productRequests")
+public class ProductRequestController {
+ @Autowired
+ private IProductEventService productRequestService;
+
+ /**
+ *
+ * @return list of Product Requests
+ */
+ @RequestMapping(method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public HttpEntity> findAll() {
+ List productRequests = new ArrayList<>();
+ productRequestService.findAll().stream().forEach(br -> {
+ ProductRequestWrapper wrapper = new ProductRequestWrapper(br);
+ try {
+ wrapper.add(linkTo(methodOn(ProductRequestController.class).findById(br.getId())).withSelfRel());
+ } catch (ResourceNotFoundException e) {
+ e.printStackTrace();
+ }
+ productRequests.add(wrapper);
+ });
+ return new ResponseEntity<>(productRequests, HttpStatus.OK);
+ }
+
+ /**
+ * get a Product Request by Id
+ *
+ * @param id
+ * @return ProductEvent JSON
+ * @throws Exception
+ */
+ @RequestMapping(value = "{id}", method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public HttpEntity findById(@PathVariable Long id) throws ResourceNotFoundException {
+ ProductEvent openmarketRequest = productRequestService.findById(id);
+ ProductRequestWrapper wrapper = new ProductRequestWrapper(openmarketRequest);
+ wrapper.add(linkTo(methodOn(ProductRequestController.class).findById(id)).withSelfRel());
+ return new ResponseEntity<>(wrapper, HttpStatus.OK);
+ }
+
+ /**
+ * Creates a ProductEvent
+ *
+ * @param ProductEvent JSON
+ * @return ProductRequesto JSON
+ * @throws ResourceNotFoundException
+ */
+
+ @RequestMapping(method = RequestMethod.POST, produces = "application/json")
+ @ResponseBody
+ public HttpEntity create(@RequestBody ProductEvent openmarketRequest)
+ throws OpenmarketErrorDomainException, ResourceNotFoundException {
+ ProductEvent openmarketRequestCreated = productRequestService.create(openmarketRequest);
+ ProductRequestWrapper wrapper = new ProductRequestWrapper(openmarketRequestCreated);
+ wrapper.add(
+ linkTo(methodOn(ProductRequestController.class).findById(openmarketRequestCreated.getId()))
+ .withSelfRel());
+ return new ResponseEntity<>(wrapper, HttpStatus.OK);
+ }
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/EnumErrorCode.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/EnumErrorCode.java
new file mode 100644
index 0000000..5d0ac03
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/EnumErrorCode.java
@@ -0,0 +1,5 @@
+package com.sahydo.openmarketapp.presentation.rest.exception;
+
+public enum EnumErrorCode {
+ EMPTY_FIELD, INVALID_FIELD, NOT_FOUND;
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/ErrorsPayload.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/ErrorsPayload.java
new file mode 100644
index 0000000..5b88792
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/ErrorsPayload.java
@@ -0,0 +1,11 @@
+package com.sahydo.openmarketapp.presentation.rest.exception;
+
+import java.util.List;
+
+public class ErrorsPayload {
+ public final List errors;
+
+ public ErrorsPayload(List applicationErrors) {
+ this.errors = applicationErrors;
+ }
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/GlobalDefaultExceptionHandler.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/GlobalDefaultExceptionHandler.java
new file mode 100644
index 0000000..b93c88d
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/GlobalDefaultExceptionHandler.java
@@ -0,0 +1,60 @@
+package com.sahydo.openmarketapp.presentation.rest.exception;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.validation.ConstraintViolationException;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.sahydo.openmarketapp.domain.model.ProductEvent;
+
+@ControllerAdvice
+public class GlobalDefaultExceptionHandler {
+
+ @ExceptionHandler(ResourceNotFoundException.class)
+ @RequestMapping(produces = "application/json")
+ @ResponseBody
+ public ResponseEntity handleResourceNotFoundException(ResourceNotFoundException e) {
+ List openmarketErrors = new ArrayList<>();
+ openmarketErrors.add(
+ new OpenmarketRequestError(EnumErrorCode.NOT_FOUND, ProductEvent.class.getSimpleName(),
+ e.getMessage()));
+ return new ResponseEntity<>(new ErrorsPayload(openmarketErrors), HttpStatus.NOT_FOUND);
+ }
+
+ @ExceptionHandler(OpenmarketErrorDomainException.class)
+ @RequestMapping(produces = "application/json")
+ @ResponseBody
+ public ResponseEntity handleOpenmarketErrorDomainException(OpenmarketErrorDomainException e) {
+ return new ResponseEntity<>(new ErrorsPayload(e.errors), HttpStatus.UNPROCESSABLE_ENTITY);
+ }
+
+ @ExceptionHandler(ConstraintViolationException.class)
+ @RequestMapping(produces = "application/json")
+ @ResponseBody
+ public ResponseEntity handleConstrainViolationException(ConstraintViolationException error) {
+ List openmarketErrors = new ArrayList<>();
+ error.getConstraintViolations().stream().forEach(violation -> {
+ openmarketErrors.add(new OpenmarketRequestError(EnumErrorCode.INVALID_FIELD,
+ violation.getPropertyPath().toString(), violation.getMessage()));
+ });
+ return new ResponseEntity<>(new ErrorsPayload(openmarketErrors), HttpStatus.UNPROCESSABLE_ENTITY);
+ }
+
+ @ExceptionHandler(HttpMessageNotReadableException.class)
+ @RequestMapping(produces = "application/json")
+ @ResponseBody
+ public ResponseEntity handleHttpMessageNotReadableException(HttpMessageNotReadableException error) {
+ List openmarketErrors = new ArrayList<>();
+ openmarketErrors.add(new OpenmarketRequestError(EnumErrorCode.INVALID_FIELD, ProductEvent.class.getSimpleName(),
+ error.getMessage()));
+ return new ResponseEntity<>(new ErrorsPayload(openmarketErrors), HttpStatus.UNPROCESSABLE_ENTITY);
+ }
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/OpenmarketErrorDomainException.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/OpenmarketErrorDomainException.java
new file mode 100644
index 0000000..0a20583
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/OpenmarketErrorDomainException.java
@@ -0,0 +1,17 @@
+package com.sahydo.openmarketapp.presentation.rest.exception;
+
+import java.util.List;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public class OpenmarketErrorDomainException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public final List errors;
+
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/OpenmarketRequestError.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/OpenmarketRequestError.java
new file mode 100644
index 0000000..f103bdf
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/OpenmarketRequestError.java
@@ -0,0 +1,10 @@
+package com.sahydo.openmarketapp.presentation.rest.exception;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public class OpenmarketRequestError {
+ public final EnumErrorCode code;
+ public final String field;
+ public final String message;
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/ResourceNotFoundException.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/ResourceNotFoundException.java
new file mode 100644
index 0000000..671a65c
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/presentation/rest/exception/ResourceNotFoundException.java
@@ -0,0 +1,15 @@
+package com.sahydo.openmarketapp.presentation.rest.exception;
+
+public class ResourceNotFoundException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+ public Long id;
+
+ public ResourceNotFoundException(Long id) {
+ super("There is no Resource with id: " + id);
+ }
+
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/utilities/DateTimeUtil.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/utilities/DateTimeUtil.java
new file mode 100644
index 0000000..07dfa61
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/utilities/DateTimeUtil.java
@@ -0,0 +1,15 @@
+package com.sahydo.openmarketapp.utilities;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class DateTimeUtil {
+ public static int diffInDays(Date start, Date end) {
+ long time = end.getTime() - start.getTime();
+ return (int) (time / (1000 * 60 * 60 * 24)) % 365;
+ }
+
+ public static String dateFormatYYYYMMDD(Date date) {
+ return new SimpleDateFormat("yyyy-MM-dd").format(date);
+ }
+}
diff --git a/microservices/api/src/main/java/com/sahydo/openmarketapp/utilities/EmailTemplateUtil.java b/microservices/api/src/main/java/com/sahydo/openmarketapp/utilities/EmailTemplateUtil.java
new file mode 100644
index 0000000..f37cb28
--- /dev/null
+++ b/microservices/api/src/main/java/com/sahydo/openmarketapp/utilities/EmailTemplateUtil.java
@@ -0,0 +1,14 @@
+package com.sahydo.openmarketapp.utilities;
+
+public class EmailTemplateUtil {
+
+ private EmailTemplateUtil() {
+
+ }
+
+ public static final String OPENMARKET_SUCCESSFULLY_CREATED_SUBJECT = "Openmarket Request created successfully";
+ public static final String OPENMARKET_FAILURE_CREATE_SUBJECT = "Problems With Openmarket";
+ public static final boolean IS_ENABLED_EMAILING = System.getenv("IS_ENABLED_EMAILING") != null
+ && System.getenv("IS_ENABLED_EMAILING").equals("true");
+
+}
diff --git a/microservices/api/src/main/resources/application.properties b/microservices/api/src/main/resources/application.properties
new file mode 100644
index 0000000..de4c38b
--- /dev/null
+++ b/microservices/api/src/main/resources/application.properties
@@ -0,0 +1,18 @@
+server.port=8084
+#Remove of this file the .example extension and set the values in <>
+#DATABASE setup
+spring.jpa.hibernate.ddl-auto=update
+spring.datasource.url=jdbc:mysql://${DATABASE_HOST:localhost}:${DATABASE_PORT:3307}/${DATABASE_NAME:openmarket_app_db}
+spring.datasource.username=${DATABASE_USER:root}
+spring.datasource.password=${DATABASE_PASSWORD:12345678}
+spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver
+#spring.jpa.show-sql: true
+
+#MAIL setup
+spring.mail.host=smtp.gmail.com
+spring.mail.port=587
+#Need a configured gmail account. Please check https://support.google.com/accounts/answer/185833
+spring.mail.username=${MAIL_USERNAME:prestrepo@unicauca.edu.co}
+spring.mail.password=${MAIL_PASSWORD:xxxxxxxxx}
+spring.mail.properties.mail.smtp.auth=true
+spring.mail.properties.mail.smtp.starttls.enable=true
diff --git a/microservices/api/src/test/java/com/sahydo/openmarketapp/BookingSystemApplicationTests.java b/microservices/api/src/test/java/com/sahydo/openmarketapp/BookingSystemApplicationTests.java
new file mode 100644
index 0000000..369475a
--- /dev/null
+++ b/microservices/api/src/test/java/com/sahydo/openmarketapp/BookingSystemApplicationTests.java
@@ -0,0 +1,13 @@
+package com.sahydo.openmarketapp;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class OpenmarketSystemApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/microservices/consumercategory/.gitignore b/microservices/consumercategory/.gitignore
new file mode 100644
index 0000000..549e00a
--- /dev/null
+++ b/microservices/consumercategory/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/microservices/consumercategory/.mvn/wrapper/maven-wrapper.jar b/microservices/consumercategory/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000..bf82ff0
Binary files /dev/null and b/microservices/consumercategory/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/microservices/consumercategory/.mvn/wrapper/maven-wrapper.properties b/microservices/consumercategory/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..ca5ab4b
--- /dev/null
+++ b/microservices/consumercategory/.mvn/wrapper/maven-wrapper.properties
@@ -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.8.7/apache-maven-3.8.7-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
diff --git a/microservices/consumercategory/Dockerfile b/microservices/consumercategory/Dockerfile
new file mode 100644
index 0000000..8a4ce77
--- /dev/null
+++ b/microservices/consumercategory/Dockerfile
@@ -0,0 +1,4 @@
+FROM openjdk:11-jdk-slim
+ARG JAR_FILE=target/*.jar
+COPY ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-jar","/app.jar"]
\ No newline at end of file
diff --git a/microservices/consumercategory/mvnw b/microservices/consumercategory/mvnw
new file mode 100644
index 0000000..8a8fb22
--- /dev/null
+++ b/microservices/consumercategory/mvnw
@@ -0,0 +1,316 @@
+#!/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
+#
+# 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.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# 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
+ export JAVA_HOME="`/usr/libexec/java_home`"
+ else
+ export JAVA_HOME="/Library/Java/Home"
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ 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
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -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 "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -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
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# 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
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+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
+ jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $jarUrl"
+ 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
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaClass" ]; then
+ if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaClass")
+ fi
+ if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; 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
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+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 "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -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.home=${M2_HOME}" \
+ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/microservices/consumercategory/mvnw.cmd b/microservices/consumercategory/mvnw.cmd
new file mode 100644
index 0000000..1d8ab01
--- /dev/null
+++ b/microservices/consumercategory/mvnw.cmd
@@ -0,0 +1,188 @@
+@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 https://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 Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@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 DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_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 DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %DOWNLOAD_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('%DOWNLOAD_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%
diff --git a/microservices/consumercategory/pom.xml b/microservices/consumercategory/pom.xml
new file mode 100644
index 0000000..4eec3ce
--- /dev/null
+++ b/microservices/consumercategory/pom.xml
@@ -0,0 +1,87 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.13
+
+
+ com.unicauca
+ consumercategory
+ 0.0.1-SNAPSHOT
+ consumercategory
+ Demo project for Spring Boot
+
+ 11
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+
+ org.springframework.boot
+ spring-boot-starter-amqp
+
+
+ com.google.code.gson
+ gson
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.amqp
+ spring-rabbit-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+
+
+
diff --git a/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/ConsumercategoryApplication.java b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/ConsumercategoryApplication.java
new file mode 100644
index 0000000..9a1ca03
--- /dev/null
+++ b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/ConsumercategoryApplication.java
@@ -0,0 +1,13 @@
+package com.unicauca.consumercategory;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ConsumercategoryApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ConsumercategoryApplication.class, args);
+ }
+
+}
diff --git a/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/access/repository/ICategoryEventRepository.java b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/access/repository/ICategoryEventRepository.java
new file mode 100644
index 0000000..1892a8f
--- /dev/null
+++ b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/access/repository/ICategoryEventRepository.java
@@ -0,0 +1,9 @@
+package com.unicauca.consumercategory.access.repository;
+
+import org.springframework.data.repository.CrudRepository;
+
+import com.unicauca.consumercategory.domain.entity.CategoryEvent;
+
+public interface ICategoryEventRepository extends CrudRepository {
+
+}
diff --git a/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/config/RabbitMQConfig.java b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/config/RabbitMQConfig.java
new file mode 100644
index 0000000..3542c46
--- /dev/null
+++ b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/config/RabbitMQConfig.java
@@ -0,0 +1,46 @@
+package com.unicauca.consumercategory.config;
+
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.FanoutExchange;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.rabbit.connection.ConnectionFactory;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.amqp.support.converter.MessageConverter;
+import org.springframework.amqp.support.converter.SimpleMessageConverter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class RabbitMQConfig {
+
+ public static final String CATEGORY_EVENTS_EXCHANGE = "category-events-exchange";
+ public static final String DB_LOG_QUEUE = "category-database-log-queue";
+
+ @Bean
+ public FanoutExchange category_events_exchange() {
+ return new FanoutExchange(CATEGORY_EVENTS_EXCHANGE);
+ }
+
+ @Bean
+ public Queue db_log_queue() {
+ return new Queue(DB_LOG_QUEUE);
+ }
+
+ @Bean
+ public Binding binding2(Queue db_log_queue, FanoutExchange category_events_exchange) {
+ return BindingBuilder.bind(db_log_queue).to(category_events_exchange);
+ }
+
+ @Bean
+ public MessageConverter messageConverter() {
+ return new SimpleMessageConverter();
+ }
+
+ @Bean
+ public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
+ RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
+ rabbitTemplate.setMessageConverter(messageConverter());
+ return rabbitTemplate;
+ }
+}
diff --git a/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/entity/CategoryEvent.java b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/entity/CategoryEvent.java
new file mode 100644
index 0000000..c667e77
--- /dev/null
+++ b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/entity/CategoryEvent.java
@@ -0,0 +1,39 @@
+package com.unicauca.consumercategory.domain.entity;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.validation.constraints.NotNull;
+
+import lombok.Data;
+
+@Entity
+@Table(name = "categories")
+@Data // Generare constructor, getters and setters and ToString methods
+public class CategoryEvent implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @Id // This makes the id as primary key
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @Column(name = "name")
+ @NotNull(message = "El nombre es obligatorio")
+ private String name;
+
+ @Column(name = "description")
+ private String description;
+
+ @Column(name = "action")
+ @NotNull(message = "La accion es obligatoria")
+ private String action;
+
+ @Column(name = "holderEmail")
+ @NotNull(message = "El correo es obligatorio")
+ private String holderEmail;
+}
diff --git a/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/CategoryEventServiceImpl.java b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/CategoryEventServiceImpl.java
new file mode 100644
index 0000000..d4e3a48
--- /dev/null
+++ b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/CategoryEventServiceImpl.java
@@ -0,0 +1,88 @@
+package com.unicauca.consumercategory.domain.service;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.unicauca.consumercategory.access.repository.ICategoryEventRepository;
+import com.unicauca.consumercategory.domain.entity.CategoryEvent;
+
+@Service // Para que sea un componente de Spring
+public class CategoryEventServiceImpl implements ICategoryEventService {
+ @Autowired // Inyecta una dependencia
+ private ICategoryEventRepository repository;
+
+ /**
+ * Busca todos los evento de categoryos
+ *
+ * @return Lista de evento de categoryos
+ */
+ @Override
+ @Transactional(readOnly = true)
+ public List findAll() {
+ return (List) repository.findAll();
+ }
+
+ /**
+ * Busca un evento de categoryo por su id
+ *
+ * @param id id del evento de categoryo
+ * @return evento de categoryo
+ */
+ @Override
+ @Transactional
+ public CategoryEvent find(Long id) {
+ CategoryEvent category = repository.findById(id).orElse(null);
+ return category;
+ }
+
+ /**
+ * Crea un evento de categoryo
+ *
+ * @param category evento de categoryo a crear
+ * @return evento de categoryo creado
+ */
+ @Override
+ @Transactional
+ public CategoryEvent create(CategoryEvent category) {
+
+ // Save the category
+ CategoryEvent savedCategory = repository.save(category);
+ // Send the event message
+ return savedCategory;
+
+ }
+
+ /**
+ * Actualiza un evento de categoryo
+ *
+ * @param id id del evento de categoryo
+ * @param category evento de categoryo a actualizar
+ * @return evento de categoryo actualizado
+ */
+ @Override
+ @Transactional
+ public CategoryEvent update(Long id, CategoryEvent category) {
+ CategoryEvent categoryUpdate = this.find(id);
+ categoryUpdate.setName(category.getName());
+ categoryUpdate.setDescription(category.getDescription());
+ // Save the category
+ CategoryEvent updateCategory = repository.save(categoryUpdate);
+ // Send the event message
+ return updateCategory;
+ }
+
+ /**
+ * Elimina un evento de categoryo
+ *
+ * @param id id del evento de categoryo
+ */
+ @Override
+ @Transactional
+ public void delete(Long id) {
+
+ repository.deleteById(id);
+ }
+}
diff --git a/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/CategoryRequestConsumerImplService.java b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/CategoryRequestConsumerImplService.java
new file mode 100644
index 0000000..b7505c1
--- /dev/null
+++ b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/CategoryRequestConsumerImplService.java
@@ -0,0 +1,36 @@
+package com.unicauca.consumercategory.domain.service;
+
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import com.google.gson.JsonObject;
+import com.unicauca.consumercategory.domain.entity.CategoryEvent;
+import com.unicauca.consumercategory.utilities.CategoryRequestsConstants;
+
+@Service
+public class CategoryRequestConsumerImplService implements ICategoryRequestConsumerService {
+
+ @Override
+ public void sendCategoryRequest(CategoryEvent category) {
+ RestTemplate restTemplate = new RestTemplate();
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ JsonObject json = new JsonObject();
+ json.addProperty("name", category.getName());
+ json.addProperty("description", category.getDescription());
+ json.addProperty("action", category.getAction());
+ json.addProperty("holderEmail", category.getHolderEmail() != null ? category.getHolderEmail() : "");
+ HttpEntity entity = new HttpEntity(json.toString(), headers);
+
+ // send request and parse result
+ ResponseEntity response = restTemplate.exchange(CategoryRequestsConstants.OPENMARKET_API_URL,
+ HttpMethod.POST, entity, String.class);
+ System.out.println(response);
+ }
+
+}
diff --git a/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/ICategoryEventService.java b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/ICategoryEventService.java
new file mode 100644
index 0000000..69ac484
--- /dev/null
+++ b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/ICategoryEventService.java
@@ -0,0 +1,6 @@
+package com.unicauca.consumercategory.domain.service;
+
+import com.unicauca.consumercategory.domain.entity.CategoryEvent;
+
+public interface ICategoryEventService extends IService {
+}
diff --git a/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/ICategoryRequestConsumerService.java b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/ICategoryRequestConsumerService.java
new file mode 100644
index 0000000..0e4ad42
--- /dev/null
+++ b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/ICategoryRequestConsumerService.java
@@ -0,0 +1,7 @@
+package com.unicauca.consumercategory.domain.service;
+
+import com.unicauca.consumercategory.domain.entity.CategoryEvent;
+
+public interface ICategoryRequestConsumerService {
+ public void sendCategoryRequest(CategoryEvent category);
+}
diff --git a/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/IService.java b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/IService.java
new file mode 100644
index 0000000..cc4da2c
--- /dev/null
+++ b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/IService.java
@@ -0,0 +1,16 @@
+package com.unicauca.consumercategory.domain.service;
+
+import java.io.Serializable;
+import java.util.List;
+
+public interface IService {
+ public List findAll();
+
+ public T find(Long id);
+
+ public T create(T object);
+
+ public T update(Long id, T object);
+
+ public void delete(Long id);
+}
diff --git a/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/RabbitMQConsumer.java b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/RabbitMQConsumer.java
new file mode 100644
index 0000000..a455345
--- /dev/null
+++ b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/domain/service/RabbitMQConsumer.java
@@ -0,0 +1,43 @@
+package com.unicauca.consumercategory.domain.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.HttpClientErrorException;
+
+import com.unicauca.consumercategory.config.RabbitMQConfig;
+import com.unicauca.consumercategory.domain.entity.CategoryEvent;
+
+import org.springframework.amqp.AmqpRejectAndDontRequeueException;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+
+@Component
+public class RabbitMQConsumer {
+ @Autowired
+ ICategoryEventService categoryLogService;
+
+ @Autowired
+ private ICategoryRequestConsumerService categoryServiceConsumer;
+
+ @RabbitListener(queues = RabbitMQConfig.DB_LOG_QUEUE)
+ public void consumeMessageFromQueue(String message) {
+ System.out.println("Message recieved from queue : " + message);
+ CategoryEvent category = new CategoryEvent();
+ String[] parts = message.split(",");
+ if (parts.length == 5) {
+ try {
+ category.setId(Long.parseLong(parts[0]));
+ category.setName(parts[1]);
+ category.setDescription(parts[2]);
+ category.setAction(parts[3]);
+ category.setHolderEmail(parts[4]);
+ categoryLogService.create(category);
+ categoryServiceConsumer.sendCategoryRequest(category);
+ } catch (HttpClientErrorException e) {
+ System.err.println(e);
+ throw new AmqpRejectAndDontRequeueException(e);
+ } catch (Exception e) {
+ throw new AmqpRejectAndDontRequeueException(e);
+ }
+ }
+ }
+}
diff --git a/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/presentation/rest/CategorysController.java b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/presentation/rest/CategorysController.java
new file mode 100644
index 0000000..d2b047d
--- /dev/null
+++ b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/presentation/rest/CategorysController.java
@@ -0,0 +1,84 @@
+package com.unicauca.consumercategory.presentation.rest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+import com.unicauca.consumercategory.domain.service.ICategoryEventService;
+import com.unicauca.consumercategory.domain.entity.CategoryEvent;
+
+@RestController
+@RequestMapping("categorylogs")
+public class CategorysController {
+ @Autowired
+ private ICategoryEventService categoryService;
+
+ /**
+ * Busca todos los categoryos
+ *
+ * @return Lista de categoryos
+ */
+ @RequestMapping(method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public List findAll() {
+ return (List) categoryService.findAll();
+ }
+
+ /**
+ * Busca un categoryo por su id
+ *
+ * @param id id del categoryo
+ * @return categoryo
+ */
+ @RequestMapping(value = "{id}", method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public CategoryEvent findById(@PathVariable Long id) {
+ return categoryService.find(id);
+ }
+
+ /**
+ * Crea un categoryo
+ *
+ * @param category categoryo a crear
+ * @return categoryo creado
+ */
+ @RequestMapping(method = RequestMethod.POST, produces = "application/json")
+ @ResponseBody
+ public CategoryEvent create(@RequestBody CategoryEvent category) {
+ return categoryService.create(category);
+ }
+
+ /**
+ * Actualiza un categoryo
+ *
+ * @param category categoryo a actualizar
+ * @param id id del categoryo a actualizar
+ * @return categoryo eliminado
+ */
+
+ @RequestMapping(value = "{id}", method = RequestMethod.PUT, produces = "application/json")
+ @ResponseBody
+ public CategoryEvent update(@RequestBody CategoryEvent category, @PathVariable Long id) {
+ return categoryService.update(id, category);
+ }
+
+ /**
+ * Elimina un categoryo
+ *
+ * @param id id del categoryo a eliminar
+ */
+ @RequestMapping(value = "{id}", method = RequestMethod.DELETE, produces = "application/json")
+ @ResponseBody
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ public void delete(@PathVariable Long id) {
+ categoryService.delete(id);
+ }
+}
diff --git a/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/utilities/CategoryRequestsConstants.java b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/utilities/CategoryRequestsConstants.java
new file mode 100644
index 0000000..fa3fcca
--- /dev/null
+++ b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/utilities/CategoryRequestsConstants.java
@@ -0,0 +1,13 @@
+package com.unicauca.consumercategory.utilities;
+
+public class CategoryRequestsConstants {
+ public static final String DIRECT_EXCHANGE_NAME = "categoryrequest-direct-exchange";
+ public static final String DEAD_LETTER_EXCHANGE_NAME = "deadLetterExchange";
+ public static final String DEAD_LETTER_ROUTING_KEY_NAME = "deadLetter";
+ public static final String QUEUE_NAME = "openmarketrequest";
+ public static final String OPENMARKET_REQUEST_ENDPOINT = "/categoryRequests";
+ public static final String OPENMARKET_API_URL = (System.getenv("OPENMARKET_API_URL") != null
+ ? System.getenv("OPENMARKET_API_URL")
+ : "http://localhost:8084") + OPENMARKET_REQUEST_ENDPOINT;
+
+}
\ No newline at end of file
diff --git a/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/utilities/DateTimeUtil.java b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/utilities/DateTimeUtil.java
new file mode 100644
index 0000000..4ebdb7d
--- /dev/null
+++ b/microservices/consumercategory/src/main/java/com/unicauca/consumercategory/utilities/DateTimeUtil.java
@@ -0,0 +1,15 @@
+package com.unicauca.consumercategory.utilities;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class DateTimeUtil {
+ public static int diffInDays(Date start, Date end) {
+ long time = end.getTime() - start.getTime();
+ return (int) (time / (1000 * 60 * 60 * 24)) % 365;
+ }
+
+ public static String dateFormatYYYYMMDD(Date date) {
+ return new SimpleDateFormat("yyyy-MM-dd").format(date);
+ }
+}
diff --git a/microservices/consumercategory/src/main/resources/application.properties b/microservices/consumercategory/src/main/resources/application.properties
new file mode 100644
index 0000000..45c0edf
--- /dev/null
+++ b/microservices/consumercategory/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+spring.h2.console.enabled=true
+server.port=8083
+spring.rabbitmq.host:${RABBITMQ_HOST:localhost}
+spring.rabbitmq.port:${RABBITMQ_PORT:5672}
\ No newline at end of file
diff --git a/microservices/consumercategory/src/main/resources/import.sql b/microservices/consumercategory/src/main/resources/import.sql
new file mode 100644
index 0000000..e69de29
diff --git a/microservices/consumercategory/src/test/java/com/unicauca/consumercategory/ConsumercategoryApplicationTests.java b/microservices/consumercategory/src/test/java/com/unicauca/consumercategory/ConsumercategoryApplicationTests.java
new file mode 100644
index 0000000..a764b57
--- /dev/null
+++ b/microservices/consumercategory/src/test/java/com/unicauca/consumercategory/ConsumercategoryApplicationTests.java
@@ -0,0 +1,13 @@
+package com.unicauca.consumercategory;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class ConsumercategoryApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/microservices/consumerproduct/.gitignore b/microservices/consumerproduct/.gitignore
new file mode 100644
index 0000000..549e00a
--- /dev/null
+++ b/microservices/consumerproduct/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/microservices/consumerproduct/.mvn/wrapper/maven-wrapper.jar b/microservices/consumerproduct/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000..bf82ff0
Binary files /dev/null and b/microservices/consumerproduct/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/microservices/consumerproduct/.mvn/wrapper/maven-wrapper.properties b/microservices/consumerproduct/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..ca5ab4b
--- /dev/null
+++ b/microservices/consumerproduct/.mvn/wrapper/maven-wrapper.properties
@@ -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.8.7/apache-maven-3.8.7-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
diff --git a/microservices/consumerproduct/Dockerfile b/microservices/consumerproduct/Dockerfile
new file mode 100644
index 0000000..8a4ce77
--- /dev/null
+++ b/microservices/consumerproduct/Dockerfile
@@ -0,0 +1,4 @@
+FROM openjdk:11-jdk-slim
+ARG JAR_FILE=target/*.jar
+COPY ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-jar","/app.jar"]
\ No newline at end of file
diff --git a/microservices/consumerproduct/mvnw b/microservices/consumerproduct/mvnw
new file mode 100644
index 0000000..8a8fb22
--- /dev/null
+++ b/microservices/consumerproduct/mvnw
@@ -0,0 +1,316 @@
+#!/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
+#
+# 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.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# 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
+ export JAVA_HOME="`/usr/libexec/java_home`"
+ else
+ export JAVA_HOME="/Library/Java/Home"
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ 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
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -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 "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -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
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# 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
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+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
+ jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $jarUrl"
+ 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
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaClass" ]; then
+ if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaClass")
+ fi
+ if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; 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
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+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 "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -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.home=${M2_HOME}" \
+ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/microservices/consumerproduct/mvnw.cmd b/microservices/consumerproduct/mvnw.cmd
new file mode 100644
index 0000000..1d8ab01
--- /dev/null
+++ b/microservices/consumerproduct/mvnw.cmd
@@ -0,0 +1,188 @@
+@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 https://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 Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@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 DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_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 DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %DOWNLOAD_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('%DOWNLOAD_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%
diff --git a/microservices/consumerproduct/pom.xml b/microservices/consumerproduct/pom.xml
new file mode 100644
index 0000000..6b5c679
--- /dev/null
+++ b/microservices/consumerproduct/pom.xml
@@ -0,0 +1,89 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.13
+
+
+ com.unicauca
+ consumerproduct
+ 0.0.1-SNAPSHOT
+ consumerproduct
+ Demo project for Spring Boot
+
+ 11
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+
+ org.springframework.boot
+ spring-boot-starter-amqp
+
+
+ com.google.code.gson
+ gson
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.amqp
+ spring-rabbit-test
+ test
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+
+
+
diff --git a/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/ConsumerProductApplication.java b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/ConsumerProductApplication.java
new file mode 100644
index 0000000..e821cde
--- /dev/null
+++ b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/ConsumerProductApplication.java
@@ -0,0 +1,13 @@
+package com.unicauca.consumerproduct;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ConsumerProductApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ConsumerProductApplication.class, args);
+ }
+
+}
diff --git a/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/access/repository/IProductEventRepository.java b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/access/repository/IProductEventRepository.java
new file mode 100644
index 0000000..7a7cc94
--- /dev/null
+++ b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/access/repository/IProductEventRepository.java
@@ -0,0 +1,9 @@
+package com.unicauca.consumerproduct.access.repository;
+
+import org.springframework.data.repository.CrudRepository;
+
+import com.unicauca.consumerproduct.domain.entity.ProductEvent;
+
+public interface IProductEventRepository extends CrudRepository {
+
+}
diff --git a/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/config/RabbitMQConfig.java b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/config/RabbitMQConfig.java
new file mode 100644
index 0000000..896259d
--- /dev/null
+++ b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/config/RabbitMQConfig.java
@@ -0,0 +1,46 @@
+package com.unicauca.consumerproduct.config;
+
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.FanoutExchange;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.rabbit.connection.ConnectionFactory;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.amqp.support.converter.MessageConverter;
+import org.springframework.amqp.support.converter.SimpleMessageConverter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class RabbitMQConfig {
+
+ public static final String PRODUCT_EVENTS_EXCHANGE = "product-events-exchange";
+ public static final String DB_LOG_QUEUE = "database-log-queue";
+
+ @Bean
+ public FanoutExchange product_events_exchange() {
+ return new FanoutExchange(PRODUCT_EVENTS_EXCHANGE);
+ }
+
+ @Bean
+ public Queue db_log_queue() {
+ return new Queue(DB_LOG_QUEUE);
+ }
+
+ @Bean
+ public Binding binding2(Queue db_log_queue, FanoutExchange product_events_exchange) {
+ return BindingBuilder.bind(db_log_queue).to(product_events_exchange);
+ }
+
+ @Bean
+ public MessageConverter messageConverter() {
+ return new SimpleMessageConverter();
+ }
+
+ @Bean
+ public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
+ RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
+ rabbitTemplate.setMessageConverter(messageConverter());
+ return rabbitTemplate;
+ }
+}
diff --git a/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/entity/ProductEvent.java b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/entity/ProductEvent.java
new file mode 100644
index 0000000..f9f0e4c
--- /dev/null
+++ b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/entity/ProductEvent.java
@@ -0,0 +1,41 @@
+package com.unicauca.consumerproduct.domain.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.validation.constraints.NotNull;
+
+import lombok.Data;
+
+@Entity
+@Table(name = "products")
+@Data // Generare constructor, getters and setters and ToString methods
+public class ProductEvent implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @Id // This makes the id as primary key
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @Column(name = "name")
+ @NotNull(message = "El nombre es obligatorio")
+ private String name;
+
+ @Column(name = "price")
+ @NotNull(message = "El precio es obligatorio")
+ private Double price;
+
+ @Column(name = "action")
+ @NotNull(message = "La accion es obligatoria")
+ private String action;
+
+ @Column(name = "holderEmail")
+ @NotNull(message = "El correo es obligatorio")
+ private String holderEmail;
+}
diff --git a/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/IProductEventService.java b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/IProductEventService.java
new file mode 100644
index 0000000..9e84377
--- /dev/null
+++ b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/IProductEventService.java
@@ -0,0 +1,6 @@
+package com.unicauca.consumerproduct.domain.service;
+
+import com.unicauca.consumerproduct.domain.entity.ProductEvent;
+
+public interface IProductEventService extends IService {
+}
diff --git a/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/IProductRequestConsumerService.java b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/IProductRequestConsumerService.java
new file mode 100644
index 0000000..725e732
--- /dev/null
+++ b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/IProductRequestConsumerService.java
@@ -0,0 +1,7 @@
+package com.unicauca.consumerproduct.domain.service;
+
+import com.unicauca.consumerproduct.domain.entity.ProductEvent;
+
+public interface IProductRequestConsumerService {
+ public void sendProductRequest(ProductEvent product);
+}
diff --git a/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/IService.java b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/IService.java
new file mode 100644
index 0000000..2465503
--- /dev/null
+++ b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/IService.java
@@ -0,0 +1,16 @@
+package com.unicauca.consumerproduct.domain.service;
+
+import java.io.Serializable;
+import java.util.List;
+
+public interface IService {
+ public List findAll();
+
+ public T find(Long id);
+
+ public T create(T object);
+
+ public T update(Long id, T object);
+
+ public void delete(Long id);
+}
diff --git a/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/ProductEventServiceImpl.java b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/ProductEventServiceImpl.java
new file mode 100644
index 0000000..2394ff9
--- /dev/null
+++ b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/ProductEventServiceImpl.java
@@ -0,0 +1,88 @@
+package com.unicauca.consumerproduct.domain.service;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.unicauca.consumerproduct.access.repository.IProductEventRepository;
+import com.unicauca.consumerproduct.domain.entity.ProductEvent;
+
+@Service // Para que sea un componente de Spring
+public class ProductEventServiceImpl implements IProductEventService {
+ @Autowired // Inyecta una dependencia
+ private IProductEventRepository repository;
+
+ /**
+ * Busca todos los evento de productos
+ *
+ * @return Lista de evento de productos
+ */
+ @Override
+ @Transactional(readOnly = true)
+ public List findAll() {
+ return (List) repository.findAll();
+ }
+
+ /**
+ * Busca un evento de producto por su id
+ *
+ * @param id id del evento de producto
+ * @return evento de producto
+ */
+ @Override
+ @Transactional
+ public ProductEvent find(Long id) {
+ ProductEvent product = repository.findById(id).orElse(null);
+ return product;
+ }
+
+ /**
+ * Crea un evento de producto
+ *
+ * @param product evento de producto a crear
+ * @return evento de producto creado
+ */
+ @Override
+ @Transactional
+ public ProductEvent create(ProductEvent product) {
+
+ // Save the product
+ ProductEvent savedProduct = repository.save(product);
+ // Send the event message
+ return savedProduct;
+
+ }
+
+ /**
+ * Actualiza un evento de producto
+ *
+ * @param id id del evento de producto
+ * @param product evento de producto a actualizar
+ * @return evento de producto actualizado
+ */
+ @Override
+ @Transactional
+ public ProductEvent update(Long id, ProductEvent product) {
+ ProductEvent productUpdate = this.find(id);
+ productUpdate.setName(product.getName());
+ productUpdate.setPrice(product.getPrice());
+ // Save the product
+ ProductEvent updateProduct = repository.save(productUpdate);
+ // Send the event message
+ return updateProduct;
+ }
+
+ /**
+ * Elimina un evento de producto
+ *
+ * @param id id del evento de producto
+ */
+ @Override
+ @Transactional
+ public void delete(Long id) {
+
+ repository.deleteById(id);
+ }
+}
diff --git a/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/ProductRequestConsumerImplService.java b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/ProductRequestConsumerImplService.java
new file mode 100644
index 0000000..e037a57
--- /dev/null
+++ b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/ProductRequestConsumerImplService.java
@@ -0,0 +1,36 @@
+package com.unicauca.consumerproduct.domain.service;
+
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import com.google.gson.JsonObject;
+import com.unicauca.consumerproduct.domain.entity.ProductEvent;
+import com.unicauca.consumerproduct.utilities.ProductRequestsConstants;
+
+@Service
+public class ProductRequestConsumerImplService implements IProductRequestConsumerService {
+
+ @Override
+ public void sendProductRequest(ProductEvent product) {
+ RestTemplate restTemplate = new RestTemplate();
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ JsonObject json = new JsonObject();
+ json.addProperty("name", product.getName());
+ json.addProperty("price", product.getPrice());
+ json.addProperty("action", product.getAction());
+ json.addProperty("holderEmail", product.getHolderEmail() != null ? product.getHolderEmail() : "");
+ HttpEntity entity = new HttpEntity(json.toString(), headers);
+
+ // send request and parse result
+ ResponseEntity response = restTemplate.exchange(ProductRequestsConstants.OPENMARKET_API_URL,
+ HttpMethod.POST, entity, String.class);
+ System.out.println(response);
+ }
+
+}
diff --git a/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/RabbitMQConsumer.java b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/RabbitMQConsumer.java
new file mode 100644
index 0000000..df51a1a
--- /dev/null
+++ b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/domain/service/RabbitMQConsumer.java
@@ -0,0 +1,43 @@
+package com.unicauca.consumerproduct.domain.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.HttpClientErrorException;
+
+import com.unicauca.consumerproduct.config.RabbitMQConfig;
+import com.unicauca.consumerproduct.domain.entity.ProductEvent;
+
+import org.springframework.amqp.AmqpRejectAndDontRequeueException;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+
+@Component
+public class RabbitMQConsumer {
+ @Autowired
+ IProductEventService productLogService;
+
+ @Autowired
+ private IProductRequestConsumerService productServiceConsumer;
+
+ @RabbitListener(queues = RabbitMQConfig.DB_LOG_QUEUE)
+ public void consumeMessageFromQueue(String message) {
+ System.out.println("Message recieved from queue : " + message);
+ ProductEvent product = new ProductEvent();
+ String[] parts = message.split(",");
+ if (parts.length == 5) {
+ try {
+ product.setId(Long.parseLong(parts[0]));
+ product.setName(parts[1]);
+ product.setPrice(Double.parseDouble(parts[2]));
+ product.setAction(parts[3]);
+ product.setHolderEmail(parts[4]);
+ productLogService.create(product);
+ productServiceConsumer.sendProductRequest(product);
+ } catch (HttpClientErrorException e) {
+ System.err.println(e);
+ throw new AmqpRejectAndDontRequeueException(e);
+ } catch (Exception e) {
+ throw new AmqpRejectAndDontRequeueException(e);
+ }
+ }
+ }
+}
diff --git a/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/presentation/rest/ProductsController.java b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/presentation/rest/ProductsController.java
new file mode 100644
index 0000000..4ccd16f
--- /dev/null
+++ b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/presentation/rest/ProductsController.java
@@ -0,0 +1,84 @@
+package com.unicauca.consumerproduct.presentation.rest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+import com.unicauca.consumerproduct.domain.service.IProductEventService;
+import com.unicauca.consumerproduct.domain.entity.ProductEvent;
+
+@RestController
+@RequestMapping("productlogs")
+public class ProductsController {
+ @Autowired
+ private IProductEventService productService;
+
+ /**
+ * Busca todos los productos
+ *
+ * @return Lista de productos
+ */
+ @RequestMapping(method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public List findAll() {
+ return (List) productService.findAll();
+ }
+
+ /**
+ * Busca un producto por su id
+ *
+ * @param id id del producto
+ * @return producto
+ */
+ @RequestMapping(value = "{id}", method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public ProductEvent findById(@PathVariable Long id) {
+ return productService.find(id);
+ }
+
+ /**
+ * Crea un producto
+ *
+ * @param product producto a crear
+ * @return producto creado
+ */
+ @RequestMapping(method = RequestMethod.POST, produces = "application/json")
+ @ResponseBody
+ public ProductEvent create(@RequestBody ProductEvent product) {
+ return productService.create(product);
+ }
+
+ /**
+ * Actualiza un producto
+ *
+ * @param product producto a actualizar
+ * @param id id del producto a actualizar
+ * @return producto eliminado
+ */
+
+ @RequestMapping(value = "{id}", method = RequestMethod.PUT, produces = "application/json")
+ @ResponseBody
+ public ProductEvent update(@RequestBody ProductEvent product, @PathVariable Long id) {
+ return productService.update(id, product);
+ }
+
+ /**
+ * Elimina un producto
+ *
+ * @param id id del producto a eliminar
+ */
+ @RequestMapping(value = "{id}", method = RequestMethod.DELETE, produces = "application/json")
+ @ResponseBody
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ public void delete(@PathVariable Long id) {
+ productService.delete(id);
+ }
+}
diff --git a/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/utilities/DateTimeUtil.java b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/utilities/DateTimeUtil.java
new file mode 100644
index 0000000..51b9ab9
--- /dev/null
+++ b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/utilities/DateTimeUtil.java
@@ -0,0 +1,15 @@
+package com.unicauca.consumerproduct.utilities;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class DateTimeUtil {
+ public static int diffInDays(Date start, Date end) {
+ long time = end.getTime() - start.getTime();
+ return (int) (time / (1000 * 60 * 60 * 24)) % 365;
+ }
+
+ public static String dateFormatYYYYMMDD(Date date) {
+ return new SimpleDateFormat("yyyy-MM-dd").format(date);
+ }
+}
diff --git a/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/utilities/ProductRequestsConstants.java b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/utilities/ProductRequestsConstants.java
new file mode 100644
index 0000000..cb92ca7
--- /dev/null
+++ b/microservices/consumerproduct/src/main/java/com/unicauca/consumerproduct/utilities/ProductRequestsConstants.java
@@ -0,0 +1,13 @@
+package com.unicauca.consumerproduct.utilities;
+
+public class ProductRequestsConstants {
+ public static final String DIRECT_EXCHANGE_NAME = "productrequest-direct-exchange";
+ public static final String DEAD_LETTER_EXCHANGE_NAME = "deadLetterExchange";
+ public static final String DEAD_LETTER_ROUTING_KEY_NAME = "deadLetter";
+ public static final String QUEUE_NAME = "openmarketrequest";
+ public static final String OPENMARKET_REQUEST_ENDPOINT = "/productRequests";
+ public static final String OPENMARKET_API_URL = (System.getenv("OPENMARKET_API_URL") != null
+ ? System.getenv("OPENMARKET_API_URL")
+ : "http://localhost:8084") + OPENMARKET_REQUEST_ENDPOINT;
+
+}
\ No newline at end of file
diff --git a/microservices/consumerproduct/src/main/resources/application.properties b/microservices/consumerproduct/src/main/resources/application.properties
new file mode 100644
index 0000000..f0825c8
--- /dev/null
+++ b/microservices/consumerproduct/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+spring.h2.console.enabled=true
+server.port=8081
+spring.rabbitmq.host:${RABBITMQ_HOST:localhost}
+spring.rabbitmq.port:${RABBITMQ_PORT:5672}
\ No newline at end of file
diff --git a/microservices/consumerproduct/src/main/resources/import.sql b/microservices/consumerproduct/src/main/resources/import.sql
new file mode 100644
index 0000000..e69de29
diff --git a/microservices/consumerproduct/src/test/java/com/unicauca/consumerproduct/ConsumerproductApplicationTests.java b/microservices/consumerproduct/src/test/java/com/unicauca/consumerproduct/ConsumerproductApplicationTests.java
new file mode 100644
index 0000000..81b71fb
--- /dev/null
+++ b/microservices/consumerproduct/src/test/java/com/unicauca/consumerproduct/ConsumerproductApplicationTests.java
@@ -0,0 +1,13 @@
+package com.unicauca.consumerproduct;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class consumerproductApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/microservices/deploy.sh b/microservices/deploy.sh
new file mode 100644
index 0000000..48f0d9f
--- /dev/null
+++ b/microservices/deploy.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+echo "Deteniendo y eliminando los contenedores y volúmenes..."
+docker-compose down -v
+
+echo "Ejecutando el contenedor de MySQL..."
+# Verificar si el contenedor ya existe
+if docker inspect openmarket_app_db_container >/dev/null 2>&1; then
+ echo "El contenedor openmarket_app_db_container ya está creado. Saltando la ejecución de 'docker run'."
+else
+ echo "Ejecutando el contenedor de MySQL..."
+ docker run --rm --name openmarket_app_db_container -e MYSQL_ROOT_PASSWORD=12345678 -e MYSQL_DATABASE=openmarket_app_db -d -p 3307:3306 mysql
+fi
+
+echo "Compilando y empaquetando el proyecto consumerproduct..."
+mvn clean package -f consumerproduct/pom.xml
+
+echo "Compilando y empaquetando el proyecto consumercategory..."
+mvn clean package -f consumercategory/pom.xml
+
+echo "Compilando y empaquetando el proyecto producerproduct..."
+mvn clean package -f producerproduct/pom.xml
+
+echo "Compilando y empaquetando el proyecto producercategory..."
+mvn clean package -f producercategory/pom.xml
+
+echo "Compilando y empaquetando el proyecto api..."
+mvn clean package -f api/pom.xml
+
+echo "Creando y ejecutando los servicios definidos en docker-compose.yml..."
+docker-compose up --build -d
diff --git a/microservices/docker-compose.yml b/microservices/docker-compose.yml
new file mode 100644
index 0000000..87e86e6
--- /dev/null
+++ b/microservices/docker-compose.yml
@@ -0,0 +1,76 @@
+version: "3.9"
+services:
+ rabbitmq:
+ container_name: rabbitmq-openmarket
+ restart: always
+ image: rabbitmq:management
+ ports:
+ - "5672:5672"
+ - "15672:15672"
+ volumes:
+ - queue-volume:/var/lib/rabbitmq
+ mysql-db:
+ image: mysql
+ container_name: openmarket-app-db-container
+ restart: always
+ env_file:
+ - ./env/database.env
+ volumes:
+ - data-volume:/var/lib/mysql
+ api:
+ build: ./api
+ container_name: openmarket-app-api-container
+ restart: always
+ env_file:
+ - ./env/api.env
+ depends_on:
+ - mysql-db
+ ports:
+ - "8084:8084"
+ producerproduct:
+ build: ./producerproduct
+ container_name: openmarket-app-producerproduct-container
+ restart: always
+ env_file:
+ - ./env/producerproduct.env
+ depends_on:
+ - rabbitmq
+ ports:
+ - "8080:8080"
+ producercategory:
+ build: ./producercategory
+ container_name: openmarket-app-producercategory-container
+ restart: always
+ env_file:
+ - ./env/producercategory.env
+ depends_on:
+ - rabbitmq
+ ports:
+ - "8082:8082"
+ consumerproduct:
+ build: ./consumerproduct
+ container_name: openmarket-app-consumerproduct-container
+ restart: always
+ env_file:
+ - ./env/consumerproduct.env
+ depends_on:
+ - rabbitmq
+ - api
+ - producerproduct
+ ports:
+ - "8081:8081"
+ consumercategory:
+ build: ./consumercategory
+ container_name: openmarket-app-consumercategory-container
+ restart: always
+ env_file:
+ - ./env/consumercategory.env
+ depends_on:
+ - rabbitmq
+ - api
+ - producercategory
+ ports:
+ - "8083:8083"
+volumes:
+ data-volume:
+ queue-volume:
diff --git a/microservices/docs/categoryhttp.png b/microservices/docs/categoryhttp.png
new file mode 100644
index 0000000..142edd7
Binary files /dev/null and b/microservices/docs/categoryhttp.png differ
diff --git a/microservices/docs/docker.png b/microservices/docs/docker.png
new file mode 100644
index 0000000..6a3be3f
Binary files /dev/null and b/microservices/docs/docker.png differ
diff --git a/microservices/docs/emailcategory.png b/microservices/docs/emailcategory.png
new file mode 100644
index 0000000..b49813e
Binary files /dev/null and b/microservices/docs/emailcategory.png differ
diff --git a/microservices/docs/emailproduct.png b/microservices/docs/emailproduct.png
new file mode 100644
index 0000000..17a0eb7
Binary files /dev/null and b/microservices/docs/emailproduct.png differ
diff --git a/microservices/docs/producthttp.png b/microservices/docs/producthttp.png
new file mode 100644
index 0000000..51eb52d
Binary files /dev/null and b/microservices/docs/producthttp.png differ
diff --git a/microservices/producercategory/.gitignore b/microservices/producercategory/.gitignore
new file mode 100644
index 0000000..549e00a
--- /dev/null
+++ b/microservices/producercategory/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/microservices/producercategory/.mvn/wrapper/maven-wrapper.jar b/microservices/producercategory/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000..bf82ff0
Binary files /dev/null and b/microservices/producercategory/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/microservices/producercategory/.mvn/wrapper/maven-wrapper.properties b/microservices/producercategory/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..ca5ab4b
--- /dev/null
+++ b/microservices/producercategory/.mvn/wrapper/maven-wrapper.properties
@@ -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.8.7/apache-maven-3.8.7-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
diff --git a/microservices/producercategory/Dockerfile b/microservices/producercategory/Dockerfile
new file mode 100644
index 0000000..8a4ce77
--- /dev/null
+++ b/microservices/producercategory/Dockerfile
@@ -0,0 +1,4 @@
+FROM openjdk:11-jdk-slim
+ARG JAR_FILE=target/*.jar
+COPY ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-jar","/app.jar"]
\ No newline at end of file
diff --git a/microservices/producercategory/mvnw b/microservices/producercategory/mvnw
new file mode 100644
index 0000000..8a8fb22
--- /dev/null
+++ b/microservices/producercategory/mvnw
@@ -0,0 +1,316 @@
+#!/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
+#
+# 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.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# 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
+ export JAVA_HOME="`/usr/libexec/java_home`"
+ else
+ export JAVA_HOME="/Library/Java/Home"
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ 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
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -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 "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -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
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# 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
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+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
+ jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $jarUrl"
+ 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
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaClass" ]; then
+ if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaClass")
+ fi
+ if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; 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
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+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 "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -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.home=${M2_HOME}" \
+ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/microservices/producercategory/mvnw.cmd b/microservices/producercategory/mvnw.cmd
new file mode 100644
index 0000000..1d8ab01
--- /dev/null
+++ b/microservices/producercategory/mvnw.cmd
@@ -0,0 +1,188 @@
+@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 https://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 Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@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 DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_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 DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %DOWNLOAD_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('%DOWNLOAD_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%
diff --git a/microservices/producercategory/pom.xml b/microservices/producercategory/pom.xml
new file mode 100644
index 0000000..38d2b54
--- /dev/null
+++ b/microservices/producercategory/pom.xml
@@ -0,0 +1,83 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.13
+
+
+ com.unicauca
+ producercategory
+ 0.0.1-SNAPSHOT
+ producercategory
+ Demo project for Spring Boot
+
+ 11
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+
+ org.springframework.boot
+ spring-boot-starter-amqp
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.amqp
+ spring-rabbit-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+
+
+
diff --git a/microservices/producercategory/src/main/java/com/unicauca/producercategory/ProducerCategoryApplication.java b/microservices/producercategory/src/main/java/com/unicauca/producercategory/ProducerCategoryApplication.java
new file mode 100644
index 0000000..36859ee
--- /dev/null
+++ b/microservices/producercategory/src/main/java/com/unicauca/producercategory/ProducerCategoryApplication.java
@@ -0,0 +1,13 @@
+package com.unicauca.producercategory;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ProducerCategoryApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ProducerCategoryApplication.class, args);
+ }
+
+}
diff --git a/microservices/producercategory/src/main/java/com/unicauca/producercategory/access/repository/ICategoryRepository.java b/microservices/producercategory/src/main/java/com/unicauca/producercategory/access/repository/ICategoryRepository.java
new file mode 100644
index 0000000..a23dc63
--- /dev/null
+++ b/microservices/producercategory/src/main/java/com/unicauca/producercategory/access/repository/ICategoryRepository.java
@@ -0,0 +1,9 @@
+package com.unicauca.producercategory.access.repository;
+
+import org.springframework.data.repository.CrudRepository;
+
+import com.unicauca.producercategory.domain.entity.Category;
+
+public interface ICategoryRepository extends CrudRepository {
+
+}
diff --git a/microservices/producercategory/src/main/java/com/unicauca/producercategory/config/RabbitMQConfig.java b/microservices/producercategory/src/main/java/com/unicauca/producercategory/config/RabbitMQConfig.java
new file mode 100644
index 0000000..af22792
--- /dev/null
+++ b/microservices/producercategory/src/main/java/com/unicauca/producercategory/config/RabbitMQConfig.java
@@ -0,0 +1,32 @@
+package com.unicauca.producercategory.config;
+
+import org.springframework.amqp.core.FanoutExchange;
+import org.springframework.amqp.rabbit.connection.ConnectionFactory;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.amqp.support.converter.MessageConverter;
+import org.springframework.amqp.support.converter.SimpleMessageConverter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class RabbitMQConfig {
+
+ public static final String CATEGORY_EVENTS_EXCHANGE = "category-events-exchange";
+
+ @Bean
+ public FanoutExchange category_events_exchange() {
+ return new FanoutExchange(CATEGORY_EVENTS_EXCHANGE);
+ }
+
+ @Bean
+ public MessageConverter messageConverter() {
+ return new SimpleMessageConverter();
+ }
+
+ @Bean
+ public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
+ RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
+ rabbitTemplate.setMessageConverter(messageConverter());
+ return rabbitTemplate;
+ }
+}
diff --git a/microservices/producercategory/src/main/java/com/unicauca/producercategory/domain/entity/Category.java b/microservices/producercategory/src/main/java/com/unicauca/producercategory/domain/entity/Category.java
new file mode 100644
index 0000000..12d2ab0
--- /dev/null
+++ b/microservices/producercategory/src/main/java/com/unicauca/producercategory/domain/entity/Category.java
@@ -0,0 +1,40 @@
+package com.unicauca.producercategory.domain.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.validation.constraints.NotNull;
+
+import lombok.Data;
+
+@Entity
+@Table(name = "categories")
+@Data
+public class Category implements Serializable {
+ private static final long serialVersionUID = 1L;
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @Column(name = "name")
+ @NotNull(message = "El nombre es obligatorio")
+ private String name;
+
+ @Column(name = "description")
+ private String description;
+
+ @Column(name = "created_at")
+ @Temporal(TemporalType.DATE)
+ private Date createdAt;
+
+ @Column(name = "holderEmail")
+ private String holderEmail;
+}
diff --git a/microservices/producercategory/src/main/java/com/unicauca/producercategory/domain/service/CategoryServiceImpl.java b/microservices/producercategory/src/main/java/com/unicauca/producercategory/domain/service/CategoryServiceImpl.java
new file mode 100644
index 0000000..952907d
--- /dev/null
+++ b/microservices/producercategory/src/main/java/com/unicauca/producercategory/domain/service/CategoryServiceImpl.java
@@ -0,0 +1,92 @@
+package com.unicauca.producercategory.domain.service;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.unicauca.producercategory.access.repository.ICategoryRepository;
+import com.unicauca.producercategory.domain.entity.Category;
+
+@Service // Para que sea un componente de Spring
+public class CategoryServiceImpl implements ICategoryService {
+ @Autowired // Inyecta una dependencia
+ private ICategoryRepository repository;
+
+ @Autowired
+ private RabbitMQProducer rabbitMQProducer;
+
+ /**
+ * Busca todas las categorias
+ *
+ * @return Lista de categorias
+ */
+ @Override
+ @Transactional(readOnly = true)
+ public List findAll() {
+ return (List) repository.findAll();
+ }
+
+ /**
+ * Busca una categoria por su id
+ *
+ * @param id id de la categoria
+ * @return categoria
+ */
+ @Override
+ @Transactional
+ public Category find(Long id) {
+ Category category = repository.findById(id).orElse(null);
+ return category;
+ }
+
+ /**
+ * Crea una categoria
+ *
+ * @param category categoria a crear
+ * @return categoria creada
+ */
+ @Override
+ @Transactional
+ public Category create(Category category) {
+ // Save the category
+ Category savedCategory = repository.save(category);
+ // Send the event message
+ rabbitMQProducer.send(savedCategory, "create");
+ return savedCategory;
+ }
+
+ /**
+ * Actualiza una categoria
+ *
+ * @param id id de la categoria
+ * @param category categoria a actualizar
+ * @return categoria actualizada
+ */
+ @Override
+ @Transactional
+ public Category update(Long id, Category category) {
+ Category categoryUpdate = this.find(id);
+ categoryUpdate.setName(category.getName());
+ categoryUpdate.setDescription(category.getDescription());
+ Category updateCategory = repository.save(categoryUpdate);
+ rabbitMQProducer.send(updateCategory, "update");
+ return repository.save(categoryUpdate);
+ }
+
+ /**
+ * Elimina una categoria
+ *
+ * @param id id de la categoria
+ */
+ @Override
+ @Transactional
+ public void delete(Long id) {
+ Category categoryDelete = this.find(id);
+ if (categoryDelete != null) {
+ rabbitMQProducer.send(categoryDelete, "delete");
+ }
+ repository.deleteById(id);
+ }
+}
diff --git a/microservices/producercategory/src/main/java/com/unicauca/producercategory/domain/service/ICategoryService.java b/microservices/producercategory/src/main/java/com/unicauca/producercategory/domain/service/ICategoryService.java
new file mode 100644
index 0000000..4f3ba39
--- /dev/null
+++ b/microservices/producercategory/src/main/java/com/unicauca/producercategory/domain/service/ICategoryService.java
@@ -0,0 +1,6 @@
+package com.unicauca.producercategory.domain.service;
+
+import com.unicauca.producercategory.domain.entity.Category;
+
+public interface ICategoryService extends IService {
+}
diff --git a/microservices/producercategory/src/main/java/com/unicauca/producercategory/domain/service/IService.java b/microservices/producercategory/src/main/java/com/unicauca/producercategory/domain/service/IService.java
new file mode 100644
index 0000000..0503b56
--- /dev/null
+++ b/microservices/producercategory/src/main/java/com/unicauca/producercategory/domain/service/IService.java
@@ -0,0 +1,16 @@
+package com.unicauca.producercategory.domain.service;
+
+import java.io.Serializable;
+import java.util.List;
+
+public interface IService {
+ public List findAll();
+
+ public T find(Long id);
+
+ public T create(T object);
+
+ public T update(Long id, T object);
+
+ public void delete(Long id);
+}
diff --git a/microservices/producercategory/src/main/java/com/unicauca/producercategory/domain/service/RabbitMQProducer.java b/microservices/producercategory/src/main/java/com/unicauca/producercategory/domain/service/RabbitMQProducer.java
new file mode 100644
index 0000000..3c6f8e3
--- /dev/null
+++ b/microservices/producercategory/src/main/java/com/unicauca/producercategory/domain/service/RabbitMQProducer.java
@@ -0,0 +1,22 @@
+package com.unicauca.producercategory.domain.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.unicauca.producercategory.config.RabbitMQConfig;
+import com.unicauca.producercategory.domain.entity.Category;
+
+import org.springframework.amqp.core.AmqpTemplate;
+
+@Service
+public class RabbitMQProducer {
+ @Autowired
+ private AmqpTemplate rabbitTemplate;
+
+ public void send(Category category, String action) {
+ String message = category.getId() + "," + category.getName() + "," + category.getDescription() + "," + action
+ + ","
+ + category.getHolderEmail();
+ rabbitTemplate.convertAndSend(RabbitMQConfig.CATEGORY_EVENTS_EXCHANGE, "", message);
+ }
+}
diff --git a/microservices/producercategory/src/main/java/com/unicauca/producercategory/presentation/rest/CategoriesController.java b/microservices/producercategory/src/main/java/com/unicauca/producercategory/presentation/rest/CategoriesController.java
new file mode 100644
index 0000000..730d6d4
--- /dev/null
+++ b/microservices/producercategory/src/main/java/com/unicauca/producercategory/presentation/rest/CategoriesController.java
@@ -0,0 +1,84 @@
+package com.unicauca.producercategory.presentation.rest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+import com.unicauca.producercategory.domain.service.ICategoryService;
+import com.unicauca.producercategory.domain.entity.Category;
+
+@RestController
+@RequestMapping("categories")
+public class CategoriesController {
+ @Autowired
+ private ICategoryService categoryService;
+
+ /**
+ * Busca todas las categorias
+ *
+ * @return Lista de categorias
+ */
+ @RequestMapping(method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public List findAll() {
+ return (List) categoryService.findAll();
+ }
+
+ /**
+ * Busca un categoria por su id
+ *
+ * @param id id del categoria
+ * @return categoria
+ */
+ @RequestMapping(value = "{id}", method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public Category findById(@PathVariable Long id) {
+ return categoryService.find(id);
+ }
+
+ /**
+ * Crea un categoria
+ *
+ * @param category categoria a crear
+ * @return categoria creada
+ */
+ @RequestMapping(method = RequestMethod.POST, produces = "application/json")
+ @ResponseBody
+ public Category create(@RequestBody Category category) {
+ return categoryService.create(category);
+ }
+
+ /**
+ * Actualiza un categoria
+ *
+ * @param category categoria a actualizar
+ * @param id id del categoria a actualizar
+ * @return categoria eliminada
+ */
+
+ @RequestMapping(value = "{id}", method = RequestMethod.PUT, produces = "application/json")
+ @ResponseBody
+ public Category update(@RequestBody Category category, @PathVariable Long id) {
+ return categoryService.update(id, category);
+ }
+
+ /**
+ * Elimina un categoria
+ *
+ * @param id id del categoria a eliminar
+ */
+ @RequestMapping(value = "{id}", method = RequestMethod.DELETE, produces = "application/json")
+ @ResponseBody
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ public void delete(@PathVariable Long id) {
+ categoryService.delete(id);
+ }
+}
diff --git a/microservices/producercategory/src/main/resources/application.properties b/microservices/producercategory/src/main/resources/application.properties
new file mode 100644
index 0000000..c03a3d3
--- /dev/null
+++ b/microservices/producercategory/src/main/resources/application.properties
@@ -0,0 +1,3 @@
+server.port=8082
+spring.rabbitmq.host:${RABBITMQ_HOST:localhost}
+spring.rabbitmq.port:${RABBITMQ_PORT:5672}
\ No newline at end of file
diff --git a/microservices/producercategory/src/main/resources/import.sql b/microservices/producercategory/src/main/resources/import.sql
new file mode 100644
index 0000000..7df1f1b
--- /dev/null
+++ b/microservices/producercategory/src/main/resources/import.sql
@@ -0,0 +1,4 @@
+insert into categories(name) values ('Fruits');
+insert into categories(name) values ('Vegetables');
+insert into categories(name) values ('Meat');
+insert into categories(name) values ('Fish');
diff --git a/microservices/producercategory/src/test/java/com/unicauca/producercategory/ProducerCategoryApplicationTests.java b/microservices/producercategory/src/test/java/com/unicauca/producercategory/ProducerCategoryApplicationTests.java
new file mode 100644
index 0000000..4bb28fa
--- /dev/null
+++ b/microservices/producercategory/src/test/java/com/unicauca/producercategory/ProducerCategoryApplicationTests.java
@@ -0,0 +1,13 @@
+package com.unicauca.producercategory;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class ProducerCategoryApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/microservices/producerproduct/.gitignore b/microservices/producerproduct/.gitignore
new file mode 100644
index 0000000..549e00a
--- /dev/null
+++ b/microservices/producerproduct/.gitignore
@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/microservices/producerproduct/.mvn/wrapper/maven-wrapper.jar b/microservices/producerproduct/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000..bf82ff0
Binary files /dev/null and b/microservices/producerproduct/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/microservices/producerproduct/.mvn/wrapper/maven-wrapper.properties b/microservices/producerproduct/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..ca5ab4b
--- /dev/null
+++ b/microservices/producerproduct/.mvn/wrapper/maven-wrapper.properties
@@ -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.8.7/apache-maven-3.8.7-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
diff --git a/microservices/producerproduct/Dockerfile b/microservices/producerproduct/Dockerfile
new file mode 100644
index 0000000..8a4ce77
--- /dev/null
+++ b/microservices/producerproduct/Dockerfile
@@ -0,0 +1,4 @@
+FROM openjdk:11-jdk-slim
+ARG JAR_FILE=target/*.jar
+COPY ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-jar","/app.jar"]
\ No newline at end of file
diff --git a/microservices/producerproduct/mvnw b/microservices/producerproduct/mvnw
new file mode 100644
index 0000000..8a8fb22
--- /dev/null
+++ b/microservices/producerproduct/mvnw
@@ -0,0 +1,316 @@
+#!/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
+#
+# 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.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# 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
+ export JAVA_HOME="`/usr/libexec/java_home`"
+ else
+ export JAVA_HOME="/Library/Java/Home"
+ fi
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ 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
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -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 "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -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
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# 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
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+BASE_DIR=`find_maven_basedir "$(pwd)"`
+if [ -z "$BASE_DIR" ]; then
+ exit 1;
+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
+ jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ fi
+ while IFS="=" read key value; do
+ case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
+ esac
+ done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Downloading from: $jarUrl"
+ 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
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found wget ... using wget"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+ fi
+ elif command -v curl > /dev/null; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Found curl ... using curl"
+ fi
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
+ else
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo "Falling back to using Java to download"
+ fi
+ javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
+ if [ -e "$javaClass" ]; then
+ if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
+ if [ "$MVNW_VERBOSE" = true ]; then
+ echo " - Compiling MavenWrapperDownloader.java ..."
+ fi
+ # Compiling the Java class
+ ("$JAVA_HOME/bin/javac" "$javaClass")
+ fi
+ if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; 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
+##########################################################################################
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+if [ "$MVNW_VERBOSE" = true ]; then
+ echo $MAVEN_PROJECTBASEDIR
+fi
+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 "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -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.home=${M2_HOME}" \
+ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/microservices/producerproduct/mvnw.cmd b/microservices/producerproduct/mvnw.cmd
new file mode 100644
index 0000000..1d8ab01
--- /dev/null
+++ b/microservices/producerproduct/mvnw.cmd
@@ -0,0 +1,188 @@
+@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 https://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 Maven Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@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 DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_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 DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %DOWNLOAD_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('%DOWNLOAD_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%
diff --git a/microservices/producerproduct/pom.xml b/microservices/producerproduct/pom.xml
new file mode 100644
index 0000000..83b4d6c
--- /dev/null
+++ b/microservices/producerproduct/pom.xml
@@ -0,0 +1,85 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.13
+
+
+ com.unicauca
+ producerproduct
+ 0.0.1-SNAPSHOT
+ producerproduct
+ Demo project for Spring Boot
+
+ 11
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+
+ org.springframework.boot
+ spring-boot-starter-amqp
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+ true
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.amqp
+ spring-rabbit-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+
+
+
diff --git a/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/ProducerProductApplication.java b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/ProducerProductApplication.java
new file mode 100644
index 0000000..5b28d79
--- /dev/null
+++ b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/ProducerProductApplication.java
@@ -0,0 +1,13 @@
+package com.unicauca.producerproduct;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ProducerProductApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ProducerProductApplication.class, args);
+ }
+
+}
diff --git a/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/access/repository/IProductRepository.java b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/access/repository/IProductRepository.java
new file mode 100644
index 0000000..f413771
--- /dev/null
+++ b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/access/repository/IProductRepository.java
@@ -0,0 +1,9 @@
+package com.unicauca.producerproduct.access.repository;
+
+import org.springframework.data.repository.CrudRepository;
+
+import com.unicauca.producerproduct.domain.entity.Product;
+
+public interface IProductRepository extends CrudRepository {
+
+}
diff --git a/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/config/RabbitMQConfig.java b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/config/RabbitMQConfig.java
new file mode 100644
index 0000000..ea0c075
--- /dev/null
+++ b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/config/RabbitMQConfig.java
@@ -0,0 +1,32 @@
+package com.unicauca.producerproduct.config;
+
+import org.springframework.amqp.core.FanoutExchange;
+import org.springframework.amqp.rabbit.connection.ConnectionFactory;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.amqp.support.converter.MessageConverter;
+import org.springframework.amqp.support.converter.SimpleMessageConverter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class RabbitMQConfig {
+
+ public static final String PRODUCT_EVENTS_EXCHANGE = "product-events-exchange";
+
+ @Bean
+ public FanoutExchange product_events_exchange() {
+ return new FanoutExchange(PRODUCT_EVENTS_EXCHANGE);
+ }
+
+ @Bean
+ public MessageConverter messageConverter() {
+ return new SimpleMessageConverter();
+ }
+
+ @Bean
+ public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
+ RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
+ rabbitTemplate.setMessageConverter(messageConverter());
+ return rabbitTemplate;
+ }
+}
diff --git a/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/domain/entity/Product.java b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/domain/entity/Product.java
new file mode 100644
index 0000000..1982df1
--- /dev/null
+++ b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/domain/entity/Product.java
@@ -0,0 +1,45 @@
+package com.unicauca.producerproduct.domain.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.validation.constraints.NotNull;
+
+import lombok.Data;
+
+@Entity
+@Table(name = "products")
+@Data // Generare constructor, getters and setters and ToString methods
+public class Product implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @Id // This makes the id as primary key
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @Column(name = "name")
+ @NotNull(message = "El nombre es obligatorio")
+ private String name;
+
+ @Column(name = "description")
+ private String description;
+
+ @Column(name = "price")
+ @NotNull(message = "El precio es obligatorio")
+ private Double price;
+
+ @Column(name = "created_at")
+ @Temporal(TemporalType.DATE)
+ private Date createdAt;
+
+ @Column(name = "holderEmail")
+ private String holderEmail;
+}
diff --git a/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/domain/service/IProductService.java b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/domain/service/IProductService.java
new file mode 100644
index 0000000..5544601
--- /dev/null
+++ b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/domain/service/IProductService.java
@@ -0,0 +1,6 @@
+package com.unicauca.producerproduct.domain.service;
+
+import com.unicauca.producerproduct.domain.entity.Product;
+
+public interface IProductService extends IService {
+}
diff --git a/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/domain/service/IService.java b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/domain/service/IService.java
new file mode 100644
index 0000000..33f86f9
--- /dev/null
+++ b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/domain/service/IService.java
@@ -0,0 +1,16 @@
+package com.unicauca.producerproduct.domain.service;
+
+import java.io.Serializable;
+import java.util.List;
+
+public interface IService {
+ public List findAll();
+
+ public T find(Long id);
+
+ public T create(T object);
+
+ public T update(Long id, T object);
+
+ public void delete(Long id);
+}
diff --git a/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/domain/service/ProductServiceImpl.java b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/domain/service/ProductServiceImpl.java
new file mode 100644
index 0000000..19c6a09
--- /dev/null
+++ b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/domain/service/ProductServiceImpl.java
@@ -0,0 +1,97 @@
+package com.unicauca.producerproduct.domain.service;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.unicauca.producerproduct.access.repository.IProductRepository;
+import com.unicauca.producerproduct.domain.entity.Product;
+
+@Service // Para que sea un componente de Spring
+public class ProductServiceImpl implements IProductService {
+ @Autowired // Inyecta una dependencia
+ private IProductRepository repository;
+
+ @Autowired
+ private RabbitMQProducer rabbitMQProducer;
+
+ /**
+ * Busca todos los productos
+ *
+ * @return Lista de productos
+ */
+ @Override
+ @Transactional(readOnly = true)
+ public List findAll() {
+ return (List) repository.findAll();
+ }
+
+ /**
+ * Busca un producto por su id
+ *
+ * @param id id del producto
+ * @return producto
+ */
+ @Override
+ @Transactional
+ public Product find(Long id) {
+ Product product = repository.findById(id).orElse(null);
+ return product;
+ }
+
+ /**
+ * Crea un producto
+ *
+ * @param product producto a crear
+ * @return producto creado
+ */
+ @Override
+ @Transactional
+ public Product create(Product product) {
+
+ // Save the product
+ Product savedProduct = repository.save(product);
+ // Send the event message
+ rabbitMQProducer.send(savedProduct, "create");
+ return savedProduct;
+
+ }
+
+ /**
+ * Actualiza un producto
+ *
+ * @param id id del producto
+ * @param product producto a actualizar
+ * @return producto actualizado
+ */
+ @Override
+ @Transactional
+ public Product update(Long id, Product product) {
+ Product productUpdate = this.find(id);
+ productUpdate.setName(product.getName());
+ productUpdate.setDescription(product.getDescription());
+ productUpdate.setPrice(product.getPrice());
+ // Save the product
+ Product updateProduct = repository.save(productUpdate);
+ // Send the event message
+ rabbitMQProducer.send(updateProduct, "update");
+ return updateProduct;
+ }
+
+ /**
+ * Elimina un producto
+ *
+ * @param id id del producto
+ */
+ @Override
+ @Transactional
+ public void delete(Long id) {
+ Product productDelete = this.find(id);
+ if (productDelete != null) {
+ rabbitMQProducer.send(productDelete, "delete");
+ }
+ repository.deleteById(id);
+ }
+}
diff --git a/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/domain/service/RabbitMQProducer.java b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/domain/service/RabbitMQProducer.java
new file mode 100644
index 0000000..342491d
--- /dev/null
+++ b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/domain/service/RabbitMQProducer.java
@@ -0,0 +1,21 @@
+package com.unicauca.producerproduct.domain.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.unicauca.producerproduct.config.RabbitMQConfig;
+import com.unicauca.producerproduct.domain.entity.Product;
+
+import org.springframework.amqp.core.AmqpTemplate;
+
+@Service
+public class RabbitMQProducer {
+ @Autowired
+ private AmqpTemplate rabbitTemplate;
+
+ public void send(Product product, String action) {
+ String message = product.getId() + "," + product.getName() + "," + product.getPrice() + "," + action + ","
+ + product.getHolderEmail();
+ rabbitTemplate.convertAndSend(RabbitMQConfig.PRODUCT_EVENTS_EXCHANGE, "", message);
+ }
+}
diff --git a/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/presentation/rest/ProductsController.java b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/presentation/rest/ProductsController.java
new file mode 100644
index 0000000..adc5e60
--- /dev/null
+++ b/microservices/producerproduct/src/main/java/com/unicauca/producerproduct/presentation/rest/ProductsController.java
@@ -0,0 +1,84 @@
+package com.unicauca.producerproduct.presentation.rest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.unicauca.producerproduct.domain.entity.Product;
+import com.unicauca.producerproduct.domain.service.IProductService;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("products")
+public class ProductsController {
+ @Autowired
+ private IProductService productService;
+
+ /**
+ * Busca todos los productos
+ *
+ * @return Lista de productos
+ */
+ @RequestMapping(method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public List findAll() {
+ return (List) productService.findAll();
+ }
+
+ /**
+ * Busca un producto por su id
+ *
+ * @param id id del producto
+ * @return producto
+ */
+ @RequestMapping(value = "{id}", method = RequestMethod.GET, produces = "application/json")
+ @ResponseBody
+ public Product findById(@PathVariable Long id) {
+ return productService.find(id);
+ }
+
+ /**
+ * Crea un producto
+ *
+ * @param product producto a crear
+ * @return producto creado
+ */
+ @RequestMapping(method = RequestMethod.POST, produces = "application/json")
+ @ResponseBody
+ public Product create(@RequestBody Product product) {
+ return productService.create(product);
+ }
+
+ /**
+ * Actualiza un producto
+ *
+ * @param product producto a actualizar
+ * @param id id del producto a actualizar
+ * @return producto eliminado
+ */
+
+ @RequestMapping(value = "{id}", method = RequestMethod.PUT, produces = "application/json")
+ @ResponseBody
+ public Product update(@RequestBody Product product, @PathVariable Long id) {
+ return productService.update(id, product);
+ }
+
+ /**
+ * Elimina un producto
+ *
+ * @param id id del producto a eliminar
+ */
+ @RequestMapping(value = "{id}", method = RequestMethod.DELETE, produces = "application/json")
+ @ResponseBody
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ public void delete(@PathVariable Long id) {
+ productService.delete(id);
+ }
+}
diff --git a/microservices/producerproduct/src/main/resources/application.properties b/microservices/producerproduct/src/main/resources/application.properties
new file mode 100644
index 0000000..f13fb6a
--- /dev/null
+++ b/microservices/producerproduct/src/main/resources/application.properties
@@ -0,0 +1,3 @@
+server.port=8080
+spring.rabbitmq.host:${RABBITMQ_HOST:localhost}
+spring.rabbitmq.port:${RABBITMQ_PORT:5672}
\ No newline at end of file
diff --git a/microservices/producerproduct/src/main/resources/import.sql b/microservices/producerproduct/src/main/resources/import.sql
new file mode 100644
index 0000000..bda5c2d
--- /dev/null
+++ b/microservices/producerproduct/src/main/resources/import.sql
@@ -0,0 +1,4 @@
+insert into products(name, price, created_at) values ('Apple', 0.60, now());
+insert into products(name, price, created_at) values ('Orange', 0.25, now());
+insert into products(name, price, created_at) values ('Banana', 0.20, now());
+insert into products(name, price, created_at) values ('Papaya', 0.50, now());
diff --git a/microservices/producerproduct/src/test/java/com/unicauca/ProducerProduct/ProducerProductApplicationTests.java b/microservices/producerproduct/src/test/java/com/unicauca/ProducerProduct/ProducerProductApplicationTests.java
new file mode 100644
index 0000000..3b1f6c7
--- /dev/null
+++ b/microservices/producerproduct/src/test/java/com/unicauca/ProducerProduct/ProducerProductApplicationTests.java
@@ -0,0 +1,13 @@
+package com.unicauca.ProducerProduct;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class ProducerProductApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}