mirror of
https://github.com/spring-projects/spring-petclinic.git
synced 2025-07-15 12:25:50 +00:00
Compare commits
20 commits
5521d79d86
...
15584ebd26
Author | SHA1 | Date | |
---|---|---|---|
![]() |
15584ebd26 | ||
![]() |
f23aa04562 | ||
![]() |
15b228d198 | ||
![]() |
fd0e30c72f | ||
![]() |
29b73475db | ||
![]() |
61a75b5570 | ||
![]() |
0dce1f7d2b | ||
![]() |
684e04e703 | ||
![]() |
ba9fd2a991 | ||
![]() |
a2848f9132 | ||
![]() |
ceb2bc79db | ||
![]() |
89511d3b42 | ||
![]() |
f32d17fd42 | ||
![]() |
2aa53f929d | ||
![]() |
6328d2c9dc | ||
![]() |
7bce202762 | ||
![]() |
aa2273e955 | ||
![]() |
1f89996e1f | ||
![]() |
73d73609b5 | ||
![]() |
b46b97a3e7 |
12 changed files with 158 additions and 23 deletions
2
.github/dco.yml
vendored
Normal file
2
.github/dco.yml
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
require:
|
||||||
|
members: false
|
83
Jenkinsfile
vendored
83
Jenkinsfile
vendored
|
@ -4,7 +4,9 @@ pipeline {
|
||||||
environment {
|
environment {
|
||||||
// Define environment variables
|
// Define environment variables
|
||||||
DOCKER_REGISTRY = "docker.io"
|
DOCKER_REGISTRY = "docker.io"
|
||||||
DOCKER_IMAGE = "mmarcetic/main"
|
DOCKER_IMAGE_MAIN = 'mmarcetic/main'
|
||||||
|
DOCKER_IMAGE_MR = 'mmarcetic/mr'
|
||||||
|
GIT_COMMIT = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
|
@ -15,23 +17,88 @@ pipeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('Build Docker Image') {
|
stage('Set Docker Image') {
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
// Build the Docker image
|
// Set Docker image based on the branch name
|
||||||
def gitCommit = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
|
if (env.BRANCH_NAME == 'main') {
|
||||||
sh "docker build -t ${DOCKER_REGISTRY}/${DOCKER_IMAGE}:${gitCommit} ."
|
env.DOCKER_IMAGE = DOCKER_IMAGE_MAIN
|
||||||
|
} else {
|
||||||
|
env.DOCKER_IMAGE = DOCKER_IMAGE_MR
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Using Docker image: ${env.DOCKER_IMAGE}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stage('Push Docker Image') {
|
stage('Checkstyle Report') {
|
||||||
|
when {
|
||||||
|
changeRequest()
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
// Checkstyle with Gradle
|
||||||
|
sh './gradlew checkstyleMain'
|
||||||
|
archiveArtifacts artifacts: 'build/reports/checkstyle/*.xml', allowEmptyArchive: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Test') {
|
||||||
|
when {
|
||||||
|
changeRequest()
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
// Test using Gradle
|
||||||
|
sh './gradlew clean test'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Build Without Tests') {
|
||||||
|
when {
|
||||||
|
changeRequest()
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
// Build without tests using Gradle
|
||||||
|
sh './gradlew build -x test'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Build Docker Image') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
// Build the Docker image
|
||||||
|
sh "docker build -t ${DOCKER_REGISTRY}/${DOCKER_IMAGE}:${GIT_COMMIT} ."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Push Docker Image for Change Request') {
|
||||||
|
when {
|
||||||
|
changeRequest()
|
||||||
|
}
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
def gitCommit = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
|
|
||||||
withCredentials([usernamePassword(credentialsId: "docker-login", usernameVariable: "DOCKER_USER", passwordVariable: "DOCKER_PASSWORD")]) {
|
withCredentials([usernamePassword(credentialsId: "docker-login", usernameVariable: "DOCKER_USER", passwordVariable: "DOCKER_PASSWORD")]) {
|
||||||
sh "docker login -u ${DOCKER_USER} -p ${DOCKER_PASSWORD}"
|
sh "docker login -u ${DOCKER_USER} -p ${DOCKER_PASSWORD}"
|
||||||
sh "docker push ${DOCKER_REGISTRY}/${DOCKER_IMAGE}:${gitCommit}"
|
sh "docker push ${DOCKER_REGISTRY}/${DOCKER_IMAGE}:${GIT_COMMIT}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Push Docker Image for Main') {
|
||||||
|
when {
|
||||||
|
branch "main"
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
withCredentials([usernamePassword(credentialsId: "docker-login", usernameVariable: "DOCKER_USER", passwordVariable: "DOCKER_PASSWORD")]) {
|
||||||
|
sh "docker login -u ${DOCKER_USER} -p ${DOCKER_PASSWORD}"
|
||||||
|
sh "docker push ${DOCKER_REGISTRY}/${DOCKER_IMAGE}:${GIT_COMMIT}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,7 +155,8 @@ Here is a list of them:
|
||||||
|
|
||||||
The [issue tracker](https://github.com/spring-projects/spring-petclinic/issues) is the preferred channel for bug reports, feature requests and submitting pull requests.
|
The [issue tracker](https://github.com/spring-projects/spring-petclinic/issues) is the preferred channel for bug reports, feature requests and submitting pull requests.
|
||||||
|
|
||||||
For pull requests, editor preferences are available in the [editor config](.editorconfig) for easy use in common text editors. Read more and download plugins at <https://editorconfig.org>. If you have not previously done so, please fill out and submit the [Contributor License Agreement](https://cla.pivotal.io/sign/spring).
|
For pull requests, editor preferences are available in the [editor config](.editorconfig) for easy use in common text editors. Read more and download plugins at <https://editorconfig.org>. All commits must include a __Signed-off-by__ trailer at the end of each commit message to indicate that the contributor agrees to the Developer Certificate of Origin.
|
||||||
|
For additional details, please refer to the blog post [Hello DCO, Goodbye CLA: Simplifying Contributions to Spring](https://spring.io/blog/2025/01/06/hello-dco-goodbye-cla-simplifying-contributions-to-spring).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id 'org.springframework.boot' version '3.4.0'
|
id 'org.springframework.boot' version '3.4.2'
|
||||||
id 'io.spring.dependency-management' version '1.1.6'
|
id 'io.spring.dependency-management' version '1.1.6'
|
||||||
id 'org.graalvm.buildtools.native' version '0.10.3'
|
id 'org.graalvm.buildtools.native' version '0.10.3'
|
||||||
id 'org.cyclonedx.bom' version '1.10.0'
|
id 'org.cyclonedx.bom' version '1.10.0'
|
||||||
|
|
11
config.yaml
Normal file
11
config.yaml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
kind: Cluster
|
||||||
|
apiVersion: kind.x-k8s.io/v1alpha4
|
||||||
|
nodes:
|
||||||
|
- role: control-plane
|
||||||
|
extraPortMappings:
|
||||||
|
- containerPort: 30950
|
||||||
|
hostPort: 30950
|
||||||
|
listenAddress: "127.0.0.1"
|
||||||
|
protocol: TCP
|
||||||
|
|
||||||
|
|
22
deployment.yaml
Normal file
22
deployment.yaml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: spring-boot-app
|
||||||
|
namespace: petclinic
|
||||||
|
spec:
|
||||||
|
replicas: 2
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: spring-boot-app
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: spring-boot-app
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: spring-boot-app
|
||||||
|
image: docker.io/mmarcetic/main:2.0
|
||||||
|
imagePullPolicy: Always
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>3.4.0</version>
|
<version>3.4.2</version>
|
||||||
<relativePath></relativePath>
|
<relativePath></relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
15
service.yaml
Normal file
15
service.yaml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: spring-boot-app-service
|
||||||
|
namespace: petclinic
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: spring-boot-app
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
nodePort: 30950
|
||||||
|
type: NodePort
|
||||||
|
|
|
@ -23,7 +23,6 @@ import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repository class for <code>Owner</code> domain objects All method names are compliant
|
* Repository class for <code>Owner</code> domain objects All method names are compliant
|
||||||
|
|
|
@ -129,7 +129,7 @@ class PetController {
|
||||||
|
|
||||||
String petName = pet.getName();
|
String petName = pet.getName();
|
||||||
|
|
||||||
// checking if the pet name already exist for the owner
|
// checking if the pet name already exists for the owner
|
||||||
if (StringUtils.hasText(petName)) {
|
if (StringUtils.hasText(petName)) {
|
||||||
Pet existingPet = owner.getPet(petName, false);
|
Pet existingPet = owner.getPet(petName, false);
|
||||||
if (existingPet != null && !existingPet.getId().equals(pet.getId())) {
|
if (existingPet != null && !existingPet.getId().equals(pet.getId())) {
|
||||||
|
@ -146,10 +146,28 @@ class PetController {
|
||||||
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
return VIEWS_PETS_CREATE_OR_UPDATE_FORM;
|
||||||
}
|
}
|
||||||
|
|
||||||
owner.addPet(pet);
|
updatePetDetails(owner, pet);
|
||||||
this.owners.save(owner);
|
|
||||||
redirectAttributes.addFlashAttribute("message", "Pet details has been edited");
|
redirectAttributes.addFlashAttribute("message", "Pet details has been edited");
|
||||||
return "redirect:/owners/{ownerId}";
|
return "redirect:/owners/{ownerId}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the pet details if it exists or adds a new pet to the owner.
|
||||||
|
* @param owner The owner of the pet
|
||||||
|
* @param pet The pet with updated details
|
||||||
|
*/
|
||||||
|
private void updatePetDetails(Owner owner, Pet pet) {
|
||||||
|
Pet existingPet = owner.getPet(pet.getId());
|
||||||
|
if (existingPet != null) {
|
||||||
|
// Update existing pet's properties
|
||||||
|
existingPet.setName(pet.getName());
|
||||||
|
existingPet.setBirthDate(pet.getBirthDate());
|
||||||
|
existingPet.setType(pet.getType());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
owner.addPet(pet);
|
||||||
|
}
|
||||||
|
this.owners.save(owner);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,14 +15,13 @@
|
||||||
*/
|
*/
|
||||||
package org.springframework.samples.petclinic.vet;
|
package org.springframework.samples.petclinic.vet;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.Comparator;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.springframework.beans.support.MutableSortDefinition;
|
import org.springframework.samples.petclinic.model.NamedEntity;
|
||||||
import org.springframework.beans.support.PropertyComparator;
|
|
||||||
import org.springframework.samples.petclinic.model.Person;
|
import org.springframework.samples.petclinic.model.Person;
|
||||||
|
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
|
@ -59,9 +58,9 @@ public class Vet extends Person {
|
||||||
|
|
||||||
@XmlElement
|
@XmlElement
|
||||||
public List<Specialty> getSpecialties() {
|
public List<Specialty> getSpecialties() {
|
||||||
List<Specialty> sortedSpecs = new ArrayList<>(getSpecialtiesInternal());
|
return getSpecialtiesInternal().stream()
|
||||||
PropertyComparator.sort(sortedSpecs, new MutableSortDefinition("name", true, true));
|
.sorted(Comparator.comparing(NamedEntity::getName))
|
||||||
return Collections.unmodifiableList(sortedSpecs);
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNrOfSpecialties() {
|
public int getNrOfSpecialties() {
|
||||||
|
|
|
@ -40,7 +40,8 @@ public class MysqlTestApplication {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(PetClinicApplication.class, "--spring.profiles.active=mysql");
|
SpringApplication.run(PetClinicApplication.class, "--spring.profiles.active=mysql",
|
||||||
|
"--spring.docker.compose.enabled=false");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue