From f2efa87d7af445549d865b46d1c0f81ae97a81ad Mon Sep 17 00:00:00 2001 From: Carlos Augusto Daniel da Costa Rubim Leao - DATAPREVRJ Date: Sat, 29 Jul 2023 06:38:22 -0300 Subject: [PATCH] compatibility with oracle database included --- .devcontainer/devcontainer.json | 5 +- .gitignore | 2 + .devcontainer/Dockerfile => Dockerfile | 13 ++- docker-compose.yml | 86 ++++++++++++++----- pom.xml | 9 +- .../petclinic/PetClinicApplication.java | 1 + .../resources/application-mysql.properties | 1 + .../resources/application-oracle.properties | 41 +++++++++ .../resources/application-postgres.properties | 1 + src/main/resources/db/oracle/1_schema.sql | 64 ++++++++++++++ src/main/resources/db/oracle/2_data.sql | 53 ++++++++++++ src/main/resources/db/oracle/initdb.sh | 2 + .../db/oracle/petclinic_db_setup_oracle.txt | 38 ++++++++ src/main/resources/db/oracle/user.sql | 4 + 14 files changed, 288 insertions(+), 32 deletions(-) rename .devcontainer/Dockerfile => Dockerfile (54%) create mode 100644 src/main/resources/application-oracle.properties create mode 100644 src/main/resources/db/oracle/1_schema.sql create mode 100644 src/main/resources/db/oracle/2_data.sql create mode 100644 src/main/resources/db/oracle/initdb.sh create mode 100644 src/main/resources/db/oracle/petclinic_db_setup_oracle.txt create mode 100644 src/main/resources/db/oracle/user.sql diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a732481a5..b61e9a14f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,9 @@ { "name": "Petclinic", - "dockerFile": "Dockerfile", + // "dockerFile": "../Dockerfile", + "dockerComposeFile": "../docker-compose.yml", + "service": "app", + "workspaceFolder": "/workspace", "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", diff --git a/.gitignore b/.gitignore index af0cb9bb0..a93fc1671 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ target/* bin/* build/* +.m2/* .gradle/* + .settings/* .classpath .project diff --git a/.devcontainer/Dockerfile b/Dockerfile similarity index 54% rename from .devcontainer/Dockerfile rename to Dockerfile index 804a6d446..d8512220a 100644 --- a/.devcontainer/Dockerfile +++ b/Dockerfile @@ -1,13 +1,12 @@ -ARG VARIANT=17-bullseye -FROM mcr.microsoft.com/vscode/devcontainers/java:0-${VARIANT} +FROM mcr.microsoft.com/vscode/devcontainers/java:0-17-bullseye + +WORKDIR /workspace ARG NODE_VERSION="none" RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi -ARG USER=vscode -VOLUME /home/$USER/.m2 -VOLUME /home/$USER/.gradle - ARG JAVA_VERSION=17.0.7-ms -RUN sudo mkdir /home/$USER/.m2 /home/$USER/.gradle && sudo chown $USER:$USER /home/$USER/.m2 /home/$USER/.gradle +RUN ln -s bash /bin/sh.bash +RUN mv /bin/sh.bash /bin/sh RUN bash -lc '. /usr/local/sdkman/bin/sdkman-init.sh && sdk install java $JAVA_VERSION && sdk use java $JAVA_VERSION' + diff --git a/docker-compose.yml b/docker-compose.yml index f949dc915..168d4be72 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,27 +1,69 @@ +# must edit apprication-.properties too version: "2.2" services: - mysql: - image: mysql:8.0 + + app: + build: . + container_name: spring-petclinic ports: - - "3306:3306" - environment: - - MYSQL_ROOT_PASSWORD= - - MYSQL_ALLOW_EMPTY_PASSWORD=true - - MYSQL_USER=petclinic - - MYSQL_PASSWORD=petclinic - - MYSQL_DATABASE=petclinic + - "8080:8080" + environment: + # uncomment one of folowing lines to run app with database of our choice + # (all commented, by default, uses h2 in memory) + - spring.profiles.active= + # - spring.profiles.active=mysql + # - spring.profiles.active=postgres + # - spring.profiles.active=oracle volumes: - - "./conf.d:/etc/mysql/conf.d:ro" - profiles: - - mysql - postgres: - image: postgres:15.3 - ports: - - "5432:5432" - environment: - - POSTGRES_PASSWORD=petclinic - - POSTGRES_USER=petclinic - - POSTGRES_DB=petclinic - profiles: - - postgres + - .:/workspace:cached + - ./.m2:/home/vscode/.m2 + - ./.gradle:/home/vscode/.gradle + command: /bin/sh -c "while sleep 1000; do :; done" + # uncomment depends_on and one of the folow services to run app with database of your choice + # and garant load app only after database is ready + # depends_on: + # - mysql + # - postgres + # - oracle + + # uncomment folowing service to run app with mysql + # mysql: + # image: mysql:8.0 + # ports: + # - "3306:3306" + # environment: + # - MYSQL_ROOT_PASSWORD= + # - MYSQL_ALLOW_EMPTY_PASSWORD=true + # - MYSQL_USER=petclinic + # - MYSQL_PASSWORD=petclinic + # - MYSQL_DATABASE=petclinic + # volumes: + # - "./conf.d:/etc/mysql/conf.d:ro" + + # uncomment folowing service to run app with postgres + # postgres: + # image: postgres:15.3 + # ports: + # - "5432:5432" + # environment: + # - POSTGRES_PASSWORD=petclinic + # - POSTGRES_USER=petclinic + # - POSTGRES_DB=petclinic + + # uncomment folowing service to run app with oracle + # oracle: + # image: gvenzl/oracle-xe:18.4.0-slim-faststart + # container_name: oracle + # environment: + # - ORACLE_PASSWORD=oracle + # - ORACLE_DATABASE=petclinic + # - APP_USER=petclinic + # - APP_USER_PASSWORD=petclinic + # ports: + # - "1521:1521" + # - "8081:8081" + # volumes: + # - ./src/main/resources/db/oracle/1_schema.sql:/db/oracle/scripts/1_schema.sql + # - ./src/main/resources/db/oracle/2_data.sql:/db/oracle/scripts/2_data.sql + # - .src/main/resources/db/oracle/initdb.sh:/container-entrypoint-initdb.d/initdb.sh \ No newline at end of file diff --git a/pom.xml b/pom.xml index ce92ea579..84152e107 100644 --- a/pom.xml +++ b/pom.xml @@ -83,6 +83,11 @@ postgresql runtime + + com.oracle.database.jdbc + ojdbc8 + 19.6.0.0 + @@ -204,7 +209,7 @@ - + diff --git a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java index ac6e15030..203f05063 100644 --- a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java +++ b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java @@ -31,6 +31,7 @@ import org.springframework.context.annotation.ImportRuntimeHints; public class PetClinicApplication { public static void main(String[] args) { + SpringApplication.run(PetClinicApplication.class, args); } diff --git a/src/main/resources/application-mysql.properties b/src/main/resources/application-mysql.properties index e23dfa605..f0b30b8ed 100644 --- a/src/main/resources/application-mysql.properties +++ b/src/main/resources/application-mysql.properties @@ -1,5 +1,6 @@ # database init, supports mysql too database=mysql + # change localhost to mysql if you are using containers spring.datasource.url=${MYSQL_URL:jdbc:mysql://localhost/petclinic} spring.datasource.username=${MYSQL_USER:petclinic} spring.datasource.password=${MYSQL_PASS:petclinic} diff --git a/src/main/resources/application-oracle.properties b/src/main/resources/application-oracle.properties new file mode 100644 index 000000000..8713aa4c2 --- /dev/null +++ b/src/main/resources/application-oracle.properties @@ -0,0 +1,41 @@ +# database init, supports mysql too +database=oracle +spring.datasource.platform=oracle +spring.datasource.initialization-mode=always +spring.datasource.driver-class-name=oracle.jdbc.OracleDriver + # change localhost to oracle if you are using containers +spring.datasource.url=jdbc:oracle:thin:@localhost:1521/petclinic +spring.datasource.username=petclinic +spring.datasource.password=petclinic + +# Web +spring.thymeleaf.mode=HTML + +# JPA +# Choose JPA database dialect +spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect +spring.jpa.properties.hibernate.show_sql=true +spring.jpa.properties.hibernate.use_sql_comments=true +spring.jpa.properties.hibernate.format_sql=true +spring.jpa.hibernate.ddl-auto=none +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.Oracle12cDialect +# spring.jpa.defer-datasource-initialization=true +# spring.sql.init.mode=always + +# Internationalization +spring.messages.basename=messages/messages + +# Actuator / Management +management.endpoints.web.base-path=/manage +management.endpoints.web.exposure.include=* + +# Logging +logging.level.org.springframework=INFO +#logging.level.org.hibernate.SQL=INFO +#logging.level.org.hibernate.type.descriptor.sql=TRACE +#logging.level.org.springframework.web=DEBUG +#logging.level.org.springframework.context.annotation=TRACE + +# Maximum time static resources should be cached +spring.resources.cache.cachecontrol.max-age=12h diff --git a/src/main/resources/application-postgres.properties b/src/main/resources/application-postgres.properties index 60889b43c..329bd746c 100644 --- a/src/main/resources/application-postgres.properties +++ b/src/main/resources/application-postgres.properties @@ -1,4 +1,5 @@ database=postgres + # change localhost to postgres if you are using containers spring.datasource.url=${POSTGRES_URL:jdbc:postgresql://localhost/petclinic} spring.datasource.username=${POSTGRES_USER:petclinic} spring.datasource.password=${POSTGRES_PASS:petclinic} diff --git a/src/main/resources/db/oracle/1_schema.sql b/src/main/resources/db/oracle/1_schema.sql new file mode 100644 index 000000000..899b1e22b --- /dev/null +++ b/src/main/resources/db/oracle/1_schema.sql @@ -0,0 +1,64 @@ +CREATE table petclinic.vets ( + id number(10,0) generated as identity, + first_name varchar2(255 char), + last_name varchar2(255 char), + primary key (id) +); +CREATE INDEX vets_last_name ON vets(last_name); + +CREATE table specialties ( + id number(10,0) generated as identity, + name varchar2(255 char), + primary key (id) +); +CREATE INDEX specialties_name ON specialties (name); + +CREATE table vet_specialties ( + vet_id number(10,0) not null, + specialty_id number(10,0) not null, + primary key (vet_id, specialty_id) +); + +CREATE table types ( + id number(10,0) generated as identity, + name varchar2(255 char), + primary key (id) +); +CREATE INDEX types_name ON types (name); + +CREATE table owners ( + id number(10,0) generated as identity, + first_name varchar2(255 char), + last_name varchar2(255 char), + address varchar2(255 char), + city varchar2(255 char), + telephone varchar2(255 char), + primary key (id) +); +CREATE INDEX owners_last_name ON owners (last_name); + +CREATE table pets ( + id number(10,0) generated as identity, + name varchar2(255 char), + birth_date date, + owner_id number(10,0), + type_id number(10,0), + primary key (id) +); +CREATE INDEX pets_name ON pets(name); + +CREATE table visits ( + id number(10,0) generated as identity, + visit_date date, + description varchar2(255 char), + pet_id number(10,0), + primary key (id) +); +CREATE INDEX visits_pet_id ON visits (pet_id); + + +ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_vets FOREIGN KEY (vet_id) REFERENCES vets (id); +ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_specialties FOREIGN KEY (specialty_id) REFERENCES specialties (id); +ALTER TABLE pets ADD CONSTRAINT fk_pets_owners FOREIGN KEY (owner_id) REFERENCES owners (id); +ALTER TABLE pets ADD CONSTRAINT fk_pets_types FOREIGN KEY (type_id) REFERENCES types (id); +ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets (id); \ No newline at end of file diff --git a/src/main/resources/db/oracle/2_data.sql b/src/main/resources/db/oracle/2_data.sql new file mode 100644 index 000000000..a6b5b9444 --- /dev/null +++ b/src/main/resources/db/oracle/2_data.sql @@ -0,0 +1,53 @@ +INSERT INTO vets(FIRST_NAME,LAST_NAME) VALUES ('James', 'Carter'); +INSERT INTO vets(FIRST_NAME,LAST_NAME) VALUES ('Helen', 'Leary'); +INSERT INTO vets(FIRST_NAME,LAST_NAME) VALUES ('Linda', 'Douglas'); +INSERT INTO vets(FIRST_NAME,LAST_NAME) VALUES ('Rafael', 'Ortega'); +INSERT INTO vets(FIRST_NAME,LAST_NAME) VALUES ('Henry', 'Stevens'); +INSERT INTO vets(FIRST_NAME,LAST_NAME) VALUES ('Sharon', 'Jenkins'); + +INSERT INTO specialties(NAME) VALUES ('radiology'); +INSERT INTO specialties(NAME) VALUES ('surgery'); +INSERT INTO specialties(NAME) VALUES ('dentistry'); + +INSERT INTO types(NAME) VALUES ('cat'); +INSERT INTO types(NAME) VALUES ('dog'); +INSERT INTO types(NAME) VALUES ('lizard'); +INSERT INTO types(NAME) VALUES ('snake'); +INSERT INTO types(NAME) VALUES ('bird'); +INSERT INTO types(NAME) VALUES ('hamster'); + +INSERT INTO owners(FIRST_NAME,LAST_NAME,ADDRESS,CITY,TELEPHONE) VALUES ('George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023'); +INSERT INTO owners(FIRST_NAME,LAST_NAME,ADDRESS,CITY,TELEPHONE) VALUES ('Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749'); +INSERT INTO owners(FIRST_NAME,LAST_NAME,ADDRESS,CITY,TELEPHONE) VALUES ('Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763'); +INSERT INTO owners(FIRST_NAME,LAST_NAME,ADDRESS,CITY,TELEPHONE) VALUES ('Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198'); +INSERT INTO owners(FIRST_NAME,LAST_NAME,ADDRESS,CITY,TELEPHONE) VALUES ('Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765'); +INSERT INTO owners(FIRST_NAME,LAST_NAME,ADDRESS,CITY,TELEPHONE) VALUES ('Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654'); +INSERT INTO owners(FIRST_NAME,LAST_NAME,ADDRESS,CITY,TELEPHONE) VALUES ('Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387'); +INSERT INTO owners(FIRST_NAME,LAST_NAME,ADDRESS,CITY,TELEPHONE) VALUES ('Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683'); +INSERT INTO owners(FIRST_NAME,LAST_NAME,ADDRESS,CITY,TELEPHONE) VALUES ('David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435'); +INSERT INTO owners(FIRST_NAME,LAST_NAME,ADDRESS,CITY,TELEPHONE) VALUES ('Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487'); + +INSERT INTO vet_specialties(VET_ID,SPECIALTY_ID) VALUES (2, 1); +INSERT INTO vet_specialties(VET_ID,SPECIALTY_ID) VALUES (3, 2); +INSERT INTO vet_specialties(VET_ID,SPECIALTY_ID) VALUES (3, 3); +INSERT INTO vet_specialties(VET_ID,SPECIALTY_ID) VALUES (4, 2); +INSERT INTO vet_specialties(VET_ID,SPECIALTY_ID) VALUES (5, 1); + +INSERT INTO pets(NAME,BIRTH_DATE,TYPE_ID,OWNER_ID) VALUES ('Leo', to_date('2010-09-07', 'yyyy-mm-dd'), 1, 1); +INSERT INTO pets(NAME,BIRTH_DATE,TYPE_ID,OWNER_ID) VALUES ('Basil', to_date('2012-08-06', 'yyyy-mm-dd'), 6, 2); +INSERT INTO pets(NAME,BIRTH_DATE,TYPE_ID,OWNER_ID) VALUES ('Rosy', to_date('2011-04-17', 'yyyy-mm-dd'), 2, 3); +INSERT INTO pets(NAME,BIRTH_DATE,TYPE_ID,OWNER_ID) VALUES ('Jewel', to_date('2010-03-07', 'yyyy-mm-dd'), 2, 3); +INSERT INTO pets(NAME,BIRTH_DATE,TYPE_ID,OWNER_ID) VALUES ('Iggy', to_date('2010-11-30', 'yyyy-mm-dd'), 3, 4); +INSERT INTO pets(NAME,BIRTH_DATE,TYPE_ID,OWNER_ID) VALUES ('George', to_date('2010-01-20', 'yyyy-mm-dd'), 4, 5); +INSERT INTO pets(NAME,BIRTH_DATE,TYPE_ID,OWNER_ID) VALUES ('Samantha', to_date('2012-09-04', 'yyyy-mm-dd'), 1, 6); +INSERT INTO pets(NAME,BIRTH_DATE,TYPE_ID,OWNER_ID) VALUES ('Max', to_date('2012-09-04', 'yyyy-mm-dd'), 1, 6); +INSERT INTO pets(NAME,BIRTH_DATE,TYPE_ID,OWNER_ID) VALUES ('Lucky', to_date('2011-08-06', 'yyyy-mm-dd'), 5, 7); +INSERT INTO pets(NAME,BIRTH_DATE,TYPE_ID,OWNER_ID) VALUES ('Mulligan', to_date('2007-02-24', 'yyyy-mm-dd'), 2, 8); +INSERT INTO pets(NAME,BIRTH_DATE,TYPE_ID,OWNER_ID) VALUES ('Freddy', to_date('2010-03-09', 'yyyy-mm-dd'), 5, 9); +INSERT INTO pets(NAME,BIRTH_DATE,TYPE_ID,OWNER_ID) VALUES ('Lucky', to_date('2010-06-24', 'yyyy-mm-dd'), 2, 10); +INSERT INTO pets(NAME,BIRTH_DATE,TYPE_ID,OWNER_ID) VALUES ('Sly', to_date('2012-06-08', 'yyyy-mm-dd'), 1, 10); + +INSERT INTO visits(PET_ID,VISIT_DATE,DESCRIPTION) VALUES (7, to_date('2013-01-01', 'yyyy-mm-dd'), 'rabies shot'); +INSERT INTO visits(PET_ID,VISIT_DATE,DESCRIPTION) VALUES (8, to_date('2013-01-02', 'yyyy-mm-dd'), 'rabies shot'); +INSERT INTO visits(PET_ID,VISIT_DATE,DESCRIPTION) VALUES (8, to_date('2013-01-03', 'yyyy-mm-dd'), 'neutered'); +INSERT INTO visits(PET_ID,VISIT_DATE,DESCRIPTION) VALUES (7, to_date('2013-01-04', 'yyyy-mm-dd'), 'spayed'); \ No newline at end of file diff --git a/src/main/resources/db/oracle/initdb.sh b/src/main/resources/db/oracle/initdb.sh new file mode 100644 index 000000000..2b479cdcf --- /dev/null +++ b/src/main/resources/db/oracle/initdb.sh @@ -0,0 +1,2 @@ +sqlplus petclinic/petclinic@//localhost:1521/petclinic @/db/oracle/1_schema.sql +sqlplus petclinic/petclinic@//localhost:1521/petclinic @/db/oracle/2_data.sql \ No newline at end of file diff --git a/src/main/resources/db/oracle/petclinic_db_setup_oracle.txt b/src/main/resources/db/oracle/petclinic_db_setup_oracle.txt new file mode 100644 index 000000000..50427b8fd --- /dev/null +++ b/src/main/resources/db/oracle/petclinic_db_setup_oracle.txt @@ -0,0 +1,38 @@ +================================================================================ +=== Spring PetClinic sample application - Oracle Configuration === +================================================================================ + +@author Sam Brannen +@author Costin Leau +@author Dave Syer +@author Guto Leão +-------------------------------------------------------------------------------- + +1) Download and install the Oracle Database 21c Express Edition, + which can be found here: https://www.oracle.com/database/technologies/xe-downloads.html. Or + edit "docker-compose.yml" from the root of the project (if you have docker installed + locally) folowing instructions in file coments: + + $ docker-compose up + ... + oracle | ######################### + oracle | DATABASE IS READY TO USE! + oracle | ######################### + ... + +2) (Once only) create the PetClinic database and user by executing the "db/oracle/user.sql" + scripts. You can connect to the database running in the docker container using + `sqlplus petclinic/petclinic@//localhost:1521/petclinic`, but you don't need to run the script there + because the petclinic user is already set up if you use the provided `docker-compose.yml`. + +3) Run the app with `spring.profiles.active=oracle` (e.g. as a System property via the command + line, but any way that sets that property in a Spring Boot app should work). For example use + + mvn spring-boot:run -Dspring-boot.run.profiles=oracle + + To activate the profile on the command line. + +N.B. the "petclinic" database has to exist for the app to work with the JDBC URL value +as it is configured by default. This condition is taken care of automatically by the +docker-compose configuration provided, or by the `user.sql` script if you run that as +system user. \ No newline at end of file diff --git a/src/main/resources/db/oracle/user.sql b/src/main/resources/db/oracle/user.sql new file mode 100644 index 000000000..9ee2a6c45 --- /dev/null +++ b/src/main/resources/db/oracle/user.sql @@ -0,0 +1,4 @@ +-- connected as SYSTEM +CREATE USER petclinic IDENTIFIED BY petclinic; + +GRANT CREATE SESSION, ALTER SESSION, CREATE DATABASE LINK, CREATE MATERIALIZED VIEW, CREATE PROCEDURE, CREATE PUBLIC SYNONYM, CREATE ROLE, CREATE SEQUENCE, CREATE SYNONYM, CREATE TABLE, CREATE TRIGGER, CREATE TYPE, CREATE VIEW, UNLIMITED TABLESPACE to petclinic; \ No newline at end of file