Skip to content

Commit

Permalink
feat(4-2): add example
Browse files Browse the repository at this point in the history
  • Loading branch information
rgomezcasas committed Nov 27, 2023
1 parent 0203b67 commit 5da76c2
Show file tree
Hide file tree
Showing 314 changed files with 9,601 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.java]
indent_size = 4
indent_style = tab
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# See apps/main/resources/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: CI

on:
push:
branches:
- main
pull_request:

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: 🐳 Start all the environment
run: make start

- name: 🔦 Lint
run: make lint

- name: 🦭 Wait for the environment to get up
run: |
while ! make ping-mysql &>/dev/null; do
echo "Waiting for database connection..."
sleep 2
done
- name: ✅ Run the tests
run: make test
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Gradle
.gradle
build/

# Ignore Gradle GUI config
gradle-app.setting

/var/log/*
!/var/log/.gitkeep

.env.local
.env.*.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM openjdk:21-slim-buster
WORKDIR /app

RUN apt update && apt install -y curl git

ENV NVM_DIR /usr/local/nvm
ENV NODE_VERSION 18.0.0

RUN mkdir -p $NVM_DIR
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash

RUN . $NVM_DIR/nvm.sh && nvm install $NODE_VERSION && nvm alias default $NODE_VERSION && nvm use default

ENV NODE_PATH $NVM_DIR/versions/node/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
all: build

start:
@docker-compose -f docker-compose.ci.yml up -d

build:
@./gradlew build --warning-mode all

lint:
@docker exec codely-java_ddd_example-test_server ./gradlew spotlessCheck

run-tests:
@./gradlew test --warning-mode all

test:
@docker exec codely-java_ddd_example-test_server ./gradlew test --warning-mode all

run:
@./gradlew :run

ping-mysql:
@docker exec codely-java_ddd_example-mysql mysqladmin --user=root --password= --host "127.0.0.1" ping --silent

# Start the app
start-mooc_backend:
@./gradlew bootRun --args='mooc_backend server'

start-backoffice_frontend:
@./gradlew bootRun --args='backoffice_frontend server'
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# ☕🚀 Java DDD example: Save the boilerplate in your new projects

<img src="http://codely.tv/wp-content/uploads/2016/05/cropped-logo-codelyTV.png" align="left" width="192px" height="192px"/>
<img align="left" width="0" height="192px" hspace="10"/>

> ⚡ Start your Java projects as fast as possible
[![CodelyTV](https://img.shields.io/badge/codely-tv-green.svg?style=flat-square)](https://codely.tv)
[![CI pipeline status](https://github.com/CodelyTV/java-ddd-example/workflows/CI/badge.svg)](https://github.com/CodelyTV/java-ddd-example/actions)

## ℹ️ Introduction

This is a repository intended to serve as a starting point if you want to bootstrap a Java project with JUnit and Gradle.

Here you have the [course on CodelyTV Pro where we explain step by step all this](https://pro.codely.tv/library/ddd-en-java/about/?utm_source=github&utm_medium=social&utm_campaign=readme) (Spanish)

## 🏁 How To Start

1. Install Java 11: `brew cask install corretto`
2. Set it as your default JVM: `export JAVA_HOME='/Library/Java/JavaVirtualMachines/amazon-corretto-11.jdk/Contents/Home'`
3. Clone this repository: `git clone https://github.com/CodelyTV/java-ddd-example`.
4. Bring up the Docker environment: `make up`.
5. Execute some [Gradle lifecycle tasks](https://docs.gradle.org/current/userguide/java_plugin.html#lifecycle_tasks) in order to check everything is OK:
1. Create [the project JAR](https://docs.gradle.org/current/userguide/java_plugin.html#sec:jar): `make build`
2. Run the tests and plugins verification tasks: `make test`
6. Start developing!

## ☝️ How to update dependencies

* Gradle ([releases](https://gradle.org/releases/)): `./gradlew wrapper --gradle-version=WANTED_VERSION --distribution-type=bin`

## 💡 Related repositories

### ☕ Java

* 📂 [Java Basic example](https://github.com/CodelyTV/java-basic-example)
*[Java OOP Examples](https://github.com/CodelyTV/java-oop-examples)
* 🧱 [Java SOLID Examples](https://github.com/CodelyTV/java-solid-examples)
* 🥦 [Java DDD Example](https://github.com/CodelyTV/java-ddd-example)

### 🐘 PHP

* 📂 [PHP Basic example](https://github.com/CodelyTV/php-basic-example)
* 🎩 [PHP DDD example](https://github.com/CodelyTV/php-ddd-example)
* 🥦 [PHP DDD Example](https://github.com/CodelyTV/php-ddd-example)

### 🧬 Scala

* 📂 [Scala Basic example](https://github.com/CodelyTV/scala-basic-example)
*[Scala Basic example (g8 template)](https://github.com/CodelyTV/scala-basic-example.g8)
*[Scala Examples](https://github.com/CodelyTV/scala-examples)
* 🥦 [Scala DDD Example](https://github.com/CodelyTV/scala-ddd-example)
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# MOOC #
#--------------------------------#
MOOC_BACKEND_SERVER_PORT=8030
# MySql
MOOC_DATABASE_HOST=codely-java_ddd_example-mysql
MOOC_DATABASE_PORT=3306
MOOC_DATABASE_NAME=mooc
MOOC_DATABASE_USER=root
MOOC_DATABASE_PASSWORD=

# BACKOFFICE #
#--------------------------------#
BACKOFFICE_BACKEND_SERVER_PORT=8040
BACKOFFICE_FRONTEND_SERVER_PORT=8041
# MySql
BACKOFFICE_DATABASE_HOST=codely-java_ddd_example-mysql
BACKOFFICE_DATABASE_PORT=3306
BACKOFFICE_DATABASE_NAME=backoffice
BACKOFFICE_DATABASE_USER=root
BACKOFFICE_DATABASE_PASSWORD=
# Elasticsearch
BACKOFFICE_ELASTICSEARCH_HOST=codely-java_ddd_example-elasticsearch
BACKOFFICE_ELASTICSEARCH_PORT=9200
BACKOFFICE_ELASTICSEARCH_INDEX_PREFIX=backoffice

# COMMON #
#--------------------------------#
# RabbitMQ
RABBITMQ_HOST=codely-java_ddd_example-rabbitmq
RABBITMQ_PORT=5672
RABBITMQ_LOGIN=codely
RABBITMQ_PASSWORD=c0d3ly
RABBITMQ_EXCHANGE=domain_events
RABBITMQ_MAX_RETRIES=5
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<#import "spring.ftl" as spring />

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">

<title>${title}</title>
<title>${description}</title>
</head>
<body>
<#include "partials/header.ftl">

<div class="container mx-auto px-4 p-5">
<h1 class="font-sans text-gray-800 text-center text-5xl mb-10"><@page_title/></h1>
<@main/>
</div>

<div class="clearfix"></div>

<#include "partials/footer.ftl">
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<#include "../../master.ftl">

<#macro page_title>Cursos</#macro>

<#macro main>
<div class="max-w-sm rounded overflow-hidden shadow-lg float-left">
<img class="w-full" src="https://codely.tv/pro/img/bg/cursos-codelytv-pro.png" alt="Sunset in the mountains">
<div class="px-6 py-4">
<div class="font-bold text-xl mb-2">Cursos</div>
<p class="text-gray-700 text-base">
Actualmente CodelyTV Pro cuenta con <b>${courses_counter}</b> cursos.
</p>
</div>
</div>

<#include "partials/new_course_form.ftl">
<div class="clearfix mb-10"></div>
<hr class="mb-10">
<#include "partials/list_courses.ftl">
</#macro>
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<h3 class="font-sans text-gray-800 text-center text-3xl mb-10">Cursos existentes</h3>


<form action="" method="get" id="courses-filters" name="filter-courses">
<div id="filter-rows">

</div>
<div class="clearfix"></div>
<div class="mt-10 inline-block relative w-2/4">
<button class="md:w-1/4 bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
id="add-field-button"
onclick="addFilter(event)">
Añadir filtro
</button>

<button class="md:w-1/4 bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
id="filter-button"
onclick="filterCourses(event)">
👉 Filtrar 👈
</button>
</div>
</form>
<table class="text-left w-full border-collapse">
<thead>
<tr>
<th class="py-4 px-6 bg-grey-lightest font-bold uppercase text-sm text-grey-dark border-b border-grey-light">
Id
</th>
<th class="py-4 px-6 bg-grey-lightest font-bold uppercase text-sm text-grey-dark border-b border-grey-light">
Nombre
</th>
<th class="py-4 px-6 bg-grey-lightest font-bold uppercase text-sm text-grey-dark border-b border-grey-light">
Duración
</th>
</tr>
</thead>
<tbody id="courses-list">

</tbody>
</table>

<script>
function addCoursesList(url) {
console.log(url);
const tableBody = document.getElementById("courses-list");
fetch(encodeURI(url))
.then(function (response) {
return response.json();
})
.then(function (courses) {
tableBody.innerHTML = "";
courses.forEach(function (course) {
let courseRow = document.createElement("tr");
courseRow.appendChild(tableCellFor(course.id));
courseRow.appendChild(tableCellFor(course.name));
courseRow.appendChild(tableCellFor(course.duration));
tableBody.appendChild(courseRow);
})
});
}
function tableCellFor(text) {
const cell = document.createElement("td");
cell.appendChild(document.createTextNode(text));
return cell;
}
function addFilter(e) {
e.preventDefault();
const filterRows = document.getElementById('filter-rows');
const totalRows = document.getElementById('filter-rows').childElementCount;
const filterRowTemplate = "<div class=\"filter-row\">\n" +
" <div class=\"inline-block relative w-64 mr-3\">\n" +
" <label class=\"block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2\" for=\"field\">\n" +
" Campo\n" +
" </label>\n" +
" <select name=\"filters[" +
totalRows +
"][field]\" id=\"field\"\n" +
" class=\"block appearance-none w-full bg-white border border-gray-400 hover:border-gray-500 px-4 py-2 pr-8 rounded shadow leading-tight focus:outline-none focus:shadow-outline\">\n" +
" <option value=\"id\">Identificador</option>\n" +
" <option value=\"name\">Nombre</option>\n" +
" <option value=\"duration\">Duración</option>\n" +
" </select>\n" +
" <div class=\"pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700\">\n" +
" <svg class=\"fill-current h-4 w-4\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\">\n" +
" <path d=\"M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z\"/>\n" +
" </svg>\n" +
" </div>\n" +
" </div>\n" +
" <div class=\"inline-block relative w-64 mr-3\">\n" +
" <label class=\"block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2\" for=\"operator\">\n" +
" Operador\n" +
" </label>\n" +
" <select id=\"operator\" name=\"filters[" +
totalRows +
"][operator]\"\n" +
" class=\"block appearance-none w-full bg-white border border-gray-400 hover:border-gray-500 px-4 py-2 pr-8 rounded shadow leading-tight focus:outline-none focus:shadow-outline\">\n" +
" <option value=\"=\">es exactamente igual</option>\n" +
" <option value=\"CONTAINS\">contiene</option>\n" +
" <option value=\">\">es más grande que</option>\n" +
" <option value=\"<\">es más pequeño que</option>\n" +
" </select>\n" +
" <div class=\"pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700\">\n" +
" <svg class=\"fill-current h-4 w-4\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\">\n" +
" <path d=\"M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z\"/>\n" +
" </svg>\n" +
" </div>\n" +
" </div>\n" +
" <div class=\"inline-block relative w-64 mr-3\">\n" +
" <label class=\"block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2\" for=\"value\">\n" +
" Valor\n" +
" </label>\n" +
" <input class=\"appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500\"\n" +
" id=\"value\" type=\"text\" name=\"filters[" +
totalRows +
"][value]\" placeholder=\"Lo que sea...\">\n" +
" </div>\n" +
"</div>";
filterRows.insertAdjacentHTML('beforeend', filterRowTemplate);
}
function filterCourses(e) {
e.preventDefault();
const form = document.forms["filter-courses"];
const inputs = Array.from(form.getElementsByTagName("input"))
.concat(Array.from(form.getElementsByTagName("select")));
const urlParts = inputs.map(input => input.name + "=" + input.value);
const url = "http://localhost:8091/courses?" + urlParts.join("&");
addCoursesList(url);
}
</script>

<script>
addCoursesList("http://localhost:8091/courses");
</script>
Loading

0 comments on commit 5da76c2

Please sign in to comment.