Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
tonocp authored Jul 25, 2024
0 parents commit 7a5ff6a
Show file tree
Hide file tree
Showing 314 changed files with 9,601 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .editorconfig
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
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# See apps/main/resources/.env
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
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
12 changes: 12 additions & 0 deletions .gitignore
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
15 changes: 15 additions & 0 deletions Dockerfile
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
29 changes: 29 additions & 0 deletions Makefile
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'
52 changes: 52 additions & 0 deletions README.md
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)
34 changes: 34 additions & 0 deletions apps/main/resources/.env
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.
27 changes: 27 additions & 0 deletions apps/main/resources/backoffice_frontend/templates/master.ftl
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 7a5ff6a

Please sign in to comment.