|  | 
|  | 1 | +# customer-helidon | 
|  | 2 | + | 
|  | 3 | +Helidon MP version of the "customer" microservice built using the **Helidon MP profile** for enterprise Java applications with CDI, JPA, and microservices capabilities. | 
|  | 4 | + | 
|  | 5 | +## Build and run | 
|  | 6 | + | 
|  | 7 | +### Prerequisites | 
|  | 8 | +- JDK 21 | 
|  | 9 | +- Maven 3.8+ | 
|  | 10 | + | 
|  | 11 | +### Building the Application | 
|  | 12 | + | 
|  | 13 | +The build process creates a **thin JAR deployment package** as a ZIP file containing the application JAR and all dependencies: | 
|  | 14 | + | 
|  | 15 | +```bash | 
|  | 16 | +mvn clean package | 
|  | 17 | +``` | 
|  | 18 | + | 
|  | 19 | +This creates: | 
|  | 20 | +- `target/customer-helidon.jar` - The thin application JAR | 
|  | 21 | +- `target/customer-helidon-deployment.zip` - Complete deployment package with structure: | 
|  | 22 | +  ``` | 
|  | 23 | +  customer-helidon.jar          (main application) | 
|  | 24 | +  app/ | 
|  | 25 | +    libs/                       (all dependency JARs) | 
|  | 26 | +  ``` | 
|  | 27 | + | 
|  | 28 | +### Running the Application | 
|  | 29 | + | 
|  | 30 | +**Option 1: Using the thin JAR (requires dependencies in classpath):** | 
|  | 31 | +```bash | 
|  | 32 | +# Extract the deployment ZIP first | 
|  | 33 | +cd target | 
|  | 34 | +unzip customer-helidon-deployment.zip | 
|  | 35 | +java -jar customer-helidon.jar | 
|  | 36 | +``` | 
|  | 37 | + | 
|  | 38 | +**Option 2: Using Maven to run directly:** | 
|  | 39 | +```bash | 
|  | 40 | +mvn exec:java | 
|  | 41 | +``` | 
|  | 42 | + | 
|  | 43 | +## Quick Start with Local Oracle Database | 
|  | 44 | + | 
|  | 45 | +To run against a local Oracle Docker container, simply: | 
|  | 46 | + | 
|  | 47 | +1. **Start Oracle Database container:** | 
|  | 48 | +   ```bash | 
|  | 49 | +   docker run -d --name oracle-db -p 1521:1521 \ | 
|  | 50 | +       -e ORACLE_PWD=Welcome12345 \ | 
|  | 51 | +       container-registry.oracle.com/database/free:latest | 
|  | 52 | +   ``` | 
|  | 53 | + | 
|  | 54 | +2. **Uncomment database configuration** in `src/main/resources/application.yaml`: | 
|  | 55 | +   ```yaml | 
|  | 56 | +   javax.sql.DataSource.customer.URL = jdbc:oracle:thin:@//localhost:1521/freepdb1 | 
|  | 57 | +   javax.sql.DataSource.customer.user = customer | 
|  | 58 | +   javax.sql.DataSource.customer.password = Welcome12345 | 
|  | 59 | +   ``` | 
|  | 60 | + | 
|  | 61 | +3. **Rebuild and run:** | 
|  | 62 | +   ```bash | 
|  | 63 | +   mvn clean package | 
|  | 64 | +   cd target && unzip customer-helidon-deployment.zip | 
|  | 65 | +   java -jar customer-helidon.jar | 
|  | 66 | +   ``` | 
|  | 67 | + | 
|  | 68 | +The application will automatically create the necessary database tables on startup using Hibernate's DDL auto-generation. | 
|  | 69 | + | 
|  | 70 | +### Basic: | 
|  | 71 | +```bash | 
|  | 72 | +curl -X GET http://localhost:8080/simple-greet | 
|  | 73 | +Hello World! | 
|  | 74 | +``` | 
|  | 75 | + | 
|  | 76 | +### JSON: | 
|  | 77 | +```bash | 
|  | 78 | +curl -X GET http://localhost:8080/greet | 
|  | 79 | +{"message":"Hello World!"} | 
|  | 80 | + | 
|  | 81 | +curl -X GET http://localhost:8080/greet/Joe | 
|  | 82 | +{"message":"Hello Joe!"} | 
|  | 83 | + | 
|  | 84 | +curl -X PUT -H "Content-Type: application/json" -d '{"greeting" : "Hola"}' http://localhost:8080/greet/greeting | 
|  | 85 | + | 
|  | 86 | +curl -X GET http://localhost:8080/greet/Jose | 
|  | 87 | +{"message":"Hola Jose!"} | 
|  | 88 | +``` | 
|  | 89 | + | 
|  | 90 | +### Try health | 
|  | 91 | +```bash | 
|  | 92 | +curl -s -X GET http://localhost:8080/health | 
|  | 93 | +{"outcome":"UP",... | 
|  | 94 | +``` | 
|  | 95 | + | 
|  | 96 | +### Try metrics | 
|  | 97 | +```bash | 
|  | 98 | +# Prometheus Format | 
|  | 99 | +curl -s -X GET http://localhost:8080/metrics | 
|  | 100 | +# TYPE base:gc_g1_young_generation_count gauge | 
|  | 101 | +. . . | 
|  | 102 | + | 
|  | 103 | +# JSON Format | 
|  | 104 | +curl -H 'Accept: application/json' -X GET http://localhost:8080/metrics | 
|  | 105 | +{"base":... | 
|  | 106 | +. . . | 
|  | 107 | +``` | 
|  | 108 | + | 
|  | 109 | +## Building a Native Image | 
|  | 110 | + | 
|  | 111 | +The generation of native binaries requires an installation of GraalVM 22.1.0+. | 
|  | 112 | +You can build a native binary using Maven as follows: | 
|  | 113 | + | 
|  | 114 | +```bash | 
|  | 115 | +mvn -Pnative-image install -DskipTests | 
|  | 116 | +``` | 
|  | 117 | + | 
|  | 118 | +The generation of the executable binary may take a few minutes to complete depending on your hardware and operating system. When completed, the executable file will be available under the `target` directory and be named after the artifact ID you have chosen during the project generation phase. | 
|  | 119 | + | 
|  | 120 | +## Docker Support | 
|  | 121 | + | 
|  | 122 | +### Building the Docker Image | 
|  | 123 | +```bash | 
|  | 124 | +docker build -t customer-helidon . | 
|  | 125 | +``` | 
|  | 126 | + | 
|  | 127 | +### Running the Docker Image | 
|  | 128 | +```bash | 
|  | 129 | +docker run --rm -p 8080:8080 customer-helidon:latest | 
|  | 130 | +``` | 
|  | 131 | + | 
|  | 132 | +Exercise the application as described above. | 
|  | 133 | + | 
|  | 134 | +## Configuration | 
|  | 135 | + | 
|  | 136 | +### Application Properties (`application.yaml`) | 
|  | 137 | +```yaml | 
|  | 138 | +# Microprofile server properties | 
|  | 139 | +server.port=8080 | 
|  | 140 | +server.host=0.0.0.0 | 
|  | 141 | +# Change the following to true to enable the optional MicroProfile Metrics REST.request metrics | 
|  | 142 | +metrics.rest-request.enabled=false | 
|  | 143 | + | 
|  | 144 | +# Application properties. This is the default greeting | 
|  | 145 | +app.greeting=Hello | 
|  | 146 | + | 
|  | 147 | +# Database connection factory - specifies Oracle UCP driver for connection pooling | 
|  | 148 | +javax.sql.DataSource.customer.connectionFactoryClassName = oracle.jdbc.pool.OracleDataSource | 
|  | 149 | + | 
|  | 150 | +# Local Oracle Database Configuration | 
|  | 151 | +# Uncomment the following lines to connect to a local Oracle Docker container out-of-the-box: | 
|  | 152 | +# javax.sql.DataSource.customer.URL = jdbc:oracle:thin:@//localhost:1521/freepdb1 | 
|  | 153 | +# javax.sql.DataSource.customer.user = customer | 
|  | 154 | +# javax.sql.DataSource.customer.password = Welcome12345 | 
|  | 155 | + | 
|  | 156 | +# Hibernate/JPA Configuration | 
|  | 157 | +hibernate.hbm2ddl.auto=create | 
|  | 158 | +hibernate.show_sql=true | 
|  | 159 | +hibernate.format_sql=true | 
|  | 160 | +# Fix JTA transaction coordinator issue | 
|  | 161 | +hibernate.transaction.coordinator_class=jta | 
|  | 162 | + | 
|  | 163 | +# Eureka service discovery configuration | 
|  | 164 | +server.features.eureka.client.base-uri=http://eureka.eureka:8761/eureka | 
|  | 165 | +server.features.eureka.instance.name=helidon-customer-service | 
|  | 166 | +server.features.eureka.instance.hostName=helidon.helidon | 
|  | 167 | +``` | 
|  | 168 | + | 
|  | 169 | +## Build Architecture | 
|  | 170 | + | 
|  | 171 | +This project uses: | 
|  | 172 | +- **Helidon MP (MicroProfile)** - Enterprise Java microservices profile | 
|  | 173 | +- **Thin JAR deployment** - Application JAR + separate dependencies for optimal Docker layering | 
|  | 174 | +- **Maven Assembly Plugin** - Creates deployment ZIP with proper structure for containerization | 
|  | 175 | +- **Hibernate + JTA** - Database persistence with transaction management | 
|  | 176 | +- **Oracle UCP** - Connection pooling for Oracle Database | 
|  | 177 | +- **Eureka integration** - Service discovery support | 
|  | 178 | + | 
|  | 179 | +## Dockerfile Structure | 
|  | 180 | + | 
|  | 181 | +The included Dockerfile uses a **multi-stage build**: | 
|  | 182 | + | 
|  | 183 | +```dockerfile | 
|  | 184 | +# 1st stage, build the app | 
|  | 185 | +FROM container-registry.oracle.com/java/jdk-no-fee-term:21 as build | 
|  | 186 | + | 
|  | 187 | +# Install maven | 
|  | 188 | +WORKDIR /usr/share | 
|  | 189 | +RUN set -x && \ | 
|  | 190 | +    curl -O https://archive.apache.org/dist/maven/maven-3/3.8.4/binaries/apache-maven-3.8.4-bin.tar.gz && \ | 
|  | 191 | +    tar -xvf apache-maven-*-bin.tar.gz && \ | 
|  | 192 | +    rm apache-maven-*-bin.tar.gz && \ | 
|  | 193 | +    mv apache-maven-* maven && \ | 
|  | 194 | +    ln -s /usr/share/maven/bin/mvn /bin/ | 
|  | 195 | + | 
|  | 196 | +WORKDIR /helidon | 
|  | 197 | + | 
|  | 198 | +# Create a first layer to cache the "Maven World" in the local repository. | 
|  | 199 | +ADD pom.xml . | 
|  | 200 | +RUN mvn package -Dmaven.test.skip -Declipselink.weave.skip -DskipOpenApiGenerate | 
|  | 201 | + | 
|  | 202 | +# Do the Maven build with fat JAR! | 
|  | 203 | +ADD src src | 
|  | 204 | +RUN mvn package -DskipTests | 
|  | 205 | + | 
|  | 206 | +# 2nd stage, build the runtime image | 
|  | 207 | +FROM container-registry.oracle.com/java/jdk-no-fee-term:21 | 
|  | 208 | +WORKDIR /helidon | 
|  | 209 | + | 
|  | 210 | +# Copy ONLY the fat JAR (not libs directory) | 
|  | 211 | +COPY --from=build /helidon/target/*.jar app.jar | 
|  | 212 | + | 
|  | 213 | +# Simple fat JAR execution | 
|  | 214 | +CMD ["java", "-jar", "app.jar"] | 
|  | 215 | +EXPOSE 8080 | 
|  | 216 | +``` | 
0 commit comments