Skip to content

Commit ba6a56e

Browse files
Upgrade to springboot 3 (#49)
* Upgrade to springboot 3 * migrate to new way of configuration * fixes issues with generation aws sample * fixes issue generating & starting gradle project * removes zalando starter * typo fix * changing type of test to integrationTest * add Service Junit Test * Polish implementation and gitpod config * fixes issue with hardcoded assertion * Using JPA New mappings
1 parent 968ca79 commit ba6a56e

27 files changed

+358
-267
lines changed

.gitpod.Dockerfile

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM gitpod/workspace-full
2+
3+
USER gitpod
4+
5+
RUN bash -c ". /home/gitpod/.sdkman/bin/sdkman-init.sh \
6+
&& sdk install java 22.3.r17-nik \
7+
&& sdk default java 22.3.r17-nik"

.gitpod.yml

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22
# Please adjust to your needs (see https://www.gitpod.io/docs/config-gitpod-file)
33
# and commit this file to your remote git repository to share the goodness with others.
44

5+
image:
6+
file: .gitpod.Dockerfile
7+
58
tasks:
6-
- init: npm install
9+
- before: npm install -g yo
10+
init: npm install
11+
712

813

.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"java.configuration.updateBuildConfiguration": "automatic"
3+
}

generators/base-generator.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@ module.exports = class extends Generator {
7474
}
7575

7676
_formatCodeMaven() {
77-
const command = this._isWin() ? 'mvnw.bat' : './mvnw';
77+
const command = this._isWin() ? 'mvnw' : './mvnw';
7878
shell.exec(`${command} spotless:apply`);
7979
}
8080

8181
_formatCodeGradle() {
82-
const command = this._isWin() ? 'gradlew.bat' : './gradlew';
82+
const command = this._isWin() ? 'gradlew' : './gradlew';
8383
shell.exec(`${command} googleJavaFormat`);
8484
}
8585

generators/constants.js

+8-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
module.exports = {
22
JAVA_VERSION : '17',
3-
SPRING_BOOT_VERSION : '2.7.6',
4-
SPRING_CLOUD_VERSION : '2021.0.4',
5-
SPRING_CLOUD_AWS_VERSION : '2.4.2',
6-
SPRING_DEP_MNGMNT_VERSION : '1.0.15.RELEASE',
3+
SPRING_BOOT_VERSION : '3.0.0',
4+
SPRING_CLOUD_VERSION : '2022.0.0-RC2',
5+
SPRING_CLOUD_AWS_VERSION : '3.0.0-M3',
6+
SPRING_DEP_MNGMNT_VERSION : '1.1.0',
77
DEFAULT_APP_VERSION : '0.0.1-SNAPSHOT',
8-
PROBLEM_SPRING_WEB_VERSION : '0.27.0',
9-
TEST_CONTAINERS_VERSION : '1.17.5',
10-
SPRINGDOC_OPENAPI_VERSION : '1.6.12',
11-
AWAITILITY_VERSION : '4.2.0',
12-
COMMONS_LANG_VERSION : '3.12.0',
8+
TEST_CONTAINERS_VERSION : '1.17.6',
9+
SPRINGDOC_OPENAPI_VERSION : '2.0.0',
1310
COMMONS_IO_VERSION : '2.11.0',
1411
LOGSTASH_LOGBACK_ENCODER : 7.2,
1512

@@ -24,10 +21,11 @@ module.exports = {
2421

2522
MAVEN_DEPENDENCY_CHECK_PLUGIN_VERSION:'7.2.1',
2623
MAVEN_PROPERTIES_PLUGIN_VERSION:'1.1.0',
24+
MAVEN_SUREFIRE_PLUGIN_VERSION:'3.0.0-M7',
2725
MAVEN_FAILSAFE_PLUGIN_VERSION:'3.0.0-M7',
2826
MAVEN_SONAR_PLUGIN_VERSION:'3.9.1.2184',
2927
MAVEN_JACOCO_PLUGIN_VERSION:'0.8.8',
30-
MAVEN_SPOTLESS_PLUGIN_VERSION:'2.27.2',
28+
MAVEN_SPOTLESS_PLUGIN_VERSION:'2.28.0',
3129

3230
KEY_FLYWAY_MIGRATION_COUNTER : 'flywayMigrationCounter',
3331
KEY_LIQUIBASE_MIGRATION_COUNTER : 'liquibaseMigrationCounter',

generators/controller/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ module.exports = class extends BaseGenerator {
7272
const testJavaTemplates = [
7373
{src: 'web/controllers/ControllerTest.java', dest: 'web/controllers/'+configOptions.entityName+'ControllerTest.java'},
7474
{src: 'web/controllers/ControllerIT.java', dest: 'web/controllers/'+configOptions.entityName+'ControllerIT.java'},
75+
{src: 'services/ServiceTest.java', dest: 'services/'+configOptions.entityName+'ServiceTest.java'},
7576
];
7677
this.generateTestJavaCode(configOptions, testJavaTemplates);
7778
}
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
package <%= packageName %>.entities;
22

3-
import javax.persistence.Column;
4-
import javax.persistence.Entity;
5-
import javax.persistence.GeneratedValue;
6-
import javax.persistence.GenerationType;
7-
import javax.persistence.Id;
8-
<%_ if (supportDatabaseSequences) { _%>
9-
import javax.persistence.SequenceGenerator;
10-
<%_ } _%>
11-
import javax.persistence.Table;
12-
import javax.validation.constraints.NotEmpty;
3+
import java.util.Objects;
4+
import jakarta.persistence.Column;
5+
import jakarta.persistence.Entity;
6+
import jakarta.persistence.GeneratedValue;
7+
import jakarta.persistence.GenerationType;
8+
import jakarta.persistence.Id;
9+
import jakarta.persistence.Table;
10+
import jakarta.validation.constraints.NotEmpty;
1311
import lombok.AllArgsConstructor;
1412
import lombok.Getter;
1513
import lombok.NoArgsConstructor;
1614
import lombok.Setter;
15+
import org.hibernate.Hibernate;
1716

1817
@Entity
1918
@Table(name = "<%= tableName %>")
@@ -25,11 +24,7 @@ public class <%= entityName %> {
2524

2625
@Id
2726
<%_ if (supportDatabaseSequences) { _%>
28-
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "<%= entityVarName %>_id_generator")
29-
@SequenceGenerator(
30-
name = "<%= entityVarName %>_id_generator",
31-
sequenceName = "<%= tableName %>_id_seq",
32-
allocationSize = 100)
27+
@GeneratedValue(strategy = GenerationType.SEQUENCE)
3328
<%_ } _%>
3429
<%_ if (!supportDatabaseSequences) { _%>
3530
@GeneratedValue(strategy = GenerationType.IDENTITY)
@@ -39,4 +34,17 @@ public class <%= entityName %> {
3934
@Column(nullable = false)
4035
@NotEmpty(message = "Text cannot be empty")
4136
private String text;
37+
38+
@Override
39+
public boolean equals(Object o) {
40+
if (this == o) return true;
41+
if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false;
42+
<%= entityName %> <%= entityVarName %> = (<%= entityName %>) o;
43+
return id != null && Objects.equals(id, <%= entityVarName %>.id);
44+
}
45+
46+
@Override
47+
public int hashCode() {
48+
return getClass().hashCode();
49+
}
4250
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
create sequence <%= tableName %>_id_seq start with 1 increment by 100;
1+
create sequence <%= tableName %>_seq start with 1 increment by 50;
22

33
create table <%= tableName %> (
4-
id bigint DEFAULT nextval('<%= tableName %>_id_seq') not null,
4+
id bigint DEFAULT nextval('<%= tableName %>_seq') not null,
55
text varchar(1024) not null,
66
primary key (id)
77
);

generators/controller/templates/app/src/main/resources/db/migration/liquibase/changelog/01-new_table_with_seq.xml

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.2.xsd">
77
<changeSet author="app" id="createTable-<%= tableName %>">
88
<createSequence
9-
sequenceName="<%= tableName %>_id_seq"
10-
incrementBy="100"
9+
sequenceName="<%= tableName %>_seq"
10+
incrementBy="50"
1111
startValue="1"
1212
/>
1313
<createTable tableName="<%= tableName %>">
14-
<column name="id" type="bigint" defaultValueSequenceNext="<%= tableName %>_id_seq">
14+
<column name="id" type="bigint" defaultValueSequenceNext="<%= tableName %>_seq">
1515
<constraints primaryKey="true" nullable="false"/>
1616
</column>
1717
<column name="text" type="varchar(1024)">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package <%= packageName %>.services;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.mockito.BDDMockito.given;
5+
import static org.mockito.BDDMockito.times;
6+
import static org.mockito.BDDMockito.verify;
7+
import static org.mockito.BDDMockito.willDoNothing;
8+
9+
import <%= packageName %>.entities.<%= entityName %>;
10+
import <%= packageName %>.model.response.PagedResult;
11+
import <%= packageName %>.repositories.<%= entityName %>Repository;
12+
import java.util.List;
13+
import java.util.Optional;
14+
import org.junit.jupiter.api.Test;
15+
import org.junit.jupiter.api.extension.ExtendWith;
16+
import org.mockito.InjectMocks;
17+
import org.mockito.Mock;
18+
import org.mockito.junit.jupiter.MockitoExtension;
19+
import org.springframework.data.domain.Page;
20+
import org.springframework.data.domain.PageImpl;
21+
import org.springframework.data.domain.PageRequest;
22+
import org.springframework.data.domain.Pageable;
23+
import org.springframework.data.domain.Sort;
24+
25+
@ExtendWith(MockitoExtension.class)
26+
class <%= entityName %>ServiceTest {
27+
28+
@Mock private <%= entityName %>Repository <%= entityVarName %>Repository;
29+
30+
@InjectMocks private <%= entityName %>Service <%= entityVarName %>Service;
31+
32+
@Test
33+
void findAll<%= entityName %>s() {
34+
// given
35+
Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Direction.ASC, "id"));
36+
Page<<%= entityName %>> <%= entityVarName %>Page = new PageImpl<>(List.of(get<%= entityName %>()));
37+
given(<%= entityVarName %>Repository.findAll(pageable)).willReturn(<%= entityVarName %>Page);
38+
39+
// when
40+
PagedResult<<%= entityName %>> pagedResult = <%= entityVarName %>Service.findAll<%= entityName %>s(0, 10, "id", "asc");
41+
42+
// then
43+
assertThat(pagedResult).isNotNull();
44+
assertThat(pagedResult.data()).isNotEmpty().hasSize(1);
45+
assertThat(pagedResult.hasNext()).isFalse();
46+
assertThat(pagedResult.pageNumber()).isEqualTo(1);
47+
assertThat(pagedResult.totalPages()).isEqualTo(1);
48+
assertThat(pagedResult.isFirst()).isTrue();
49+
assertThat(pagedResult.isLast()).isTrue();
50+
assertThat(pagedResult.hasPrevious()).isFalse();
51+
assertThat(pagedResult.totalElements()).isEqualTo(1);
52+
}
53+
54+
@Test
55+
void find<%= entityName %>ById() {
56+
// given
57+
given(<%= entityVarName %>Repository.findById(1L)).willReturn(Optional.of(get<%= entityName %>()));
58+
// when
59+
Optional<<%= entityName %>> optional<%= entityName %> = <%= entityVarName %>Service.find<%= entityName %>ById(1L);
60+
// then
61+
assertThat(optional<%= entityName %>).isPresent();
62+
<%= entityName %> <%= entityVarName %> = optional<%= entityName %>.get();
63+
assertThat(<%= entityVarName %>.getId()).isEqualTo(1L);
64+
assertThat(<%= entityVarName %>.getText()).isEqualTo("junitTest");
65+
}
66+
67+
@Test
68+
void save<%= entityName %>() {
69+
// given
70+
given(<%= entityVarName %>Repository.save(get<%= entityName %>())).willReturn(get<%= entityName %>());
71+
// when
72+
<%= entityName %> persisted<%= entityName %> = <%= entityVarName %>Service.save<%= entityName %>(get<%= entityName %>());
73+
// then
74+
assertThat(persisted<%= entityName %>).isNotNull();
75+
assertThat(persisted<%= entityName %>.getId()).isEqualTo(1L);
76+
assertThat(persisted<%= entityName %>.getText()).isEqualTo("junitTest");
77+
}
78+
79+
@Test
80+
void delete<%= entityName %>ById() {
81+
// given
82+
willDoNothing().given(<%= entityVarName %>Repository).deleteById(1L);
83+
// when
84+
<%= entityVarName %>Service.delete<%= entityName %>ById(1L);
85+
// then
86+
verify(<%= entityVarName %>Repository, times(1)).deleteById(1L);
87+
}
88+
89+
private <%= entityName %> get<%= entityName %>() {
90+
<%= entityName %> <%= entityVarName %> = new <%= entityName %>();
91+
<%= entityVarName %>.setId(1L);
92+
<%= entityVarName %>.setText("junitTest");
93+
return <%= entityVarName %>;
94+
}
95+
}

generators/controller/templates/app/src/test/java/web/controllers/ControllerIT.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,11 @@ void setUp() {
8888
.content(objectMapper.writeValueAsString(<%= entityVarName %>)))
8989
.andExpect(status().isBadRequest())
9090
.andExpect(header().string("Content-Type", is("application/problem+json")))
91-
.andExpect(
92-
jsonPath(
93-
"$.type",
94-
is("https://zalando.github.io/problem/constraint-violation")))
91+
.andExpect(jsonPath("$.type", is("about:blank")))
9592
.andExpect(jsonPath("$.title", is("Constraint Violation")))
9693
.andExpect(jsonPath("$.status", is(400)))
94+
.andExpect(jsonPath("$.detail", is("Invalid request content.")))
95+
.andExpect(jsonPath("$.instance", is("<%= basePath %>")))
9796
.andExpect(jsonPath("$.violations", hasSize(1)))
9897
.andExpect(jsonPath("$.violations[0].field", is("text")))
9998
.andExpect(jsonPath("$.violations[0].message", is("Text cannot be empty")))

generators/controller/templates/app/src/test/java/web/controllers/ControllerTest.java

+3-9
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
import org.springframework.http.MediaType;
3333
import org.springframework.test.context.ActiveProfiles;
3434
import org.springframework.test.web.servlet.MockMvc;
35-
import org.zalando.problem.jackson.ProblemModule;
36-
import org.zalando.problem.violations.ConstraintViolationProblemModule;
3735

3836
@WebMvcTest(controllers = <%= entityName %>Controller.class)
3937
@ActiveProfiles(PROFILE_TEST)
@@ -53,9 +51,6 @@ void setUp() {
5351
this.<%= entityVarName %>List.add(new <%= entityName %>(1L, "text 1"));
5452
this.<%= entityVarName %>List.add(new <%= entityName %>(2L, "text 2"));
5553
this.<%= entityVarName %>List.add(new <%= entityName %>(3L, "text 3"));
56-
57-
objectMapper.registerModule(new ProblemModule());
58-
objectMapper.registerModule(new ConstraintViolationProblemModule());
5954
}
6055

6156
@Test
@@ -125,12 +120,11 @@ void setUp() {
125120
.content(objectMapper.writeValueAsString(<%= entityVarName %>)))
126121
.andExpect(status().isBadRequest())
127122
.andExpect(header().string("Content-Type", is("application/problem+json")))
128-
.andExpect(
129-
jsonPath(
130-
"$.type",
131-
is("https://zalando.github.io/problem/constraint-violation")))
123+
.andExpect(jsonPath("$.type", is("about:blank")))
132124
.andExpect(jsonPath("$.title", is("Constraint Violation")))
133125
.andExpect(jsonPath("$.status", is(400)))
126+
.andExpect(jsonPath("$.detail", is("Invalid request content.")))
127+
.andExpect(jsonPath("$.instance", is("<%= basePath %>")))
134128
.andExpect(jsonPath("$.violations", hasSize(1)))
135129
.andExpect(jsonPath("$.violations[0].field", is("text")))
136130
.andExpect(jsonPath("$.violations[0].message", is("Text cannot be empty")))

generators/server/index.js

+2-5
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,9 @@ module.exports = class extends BaseGenerator {
189189
'config/Initializer.java',
190190
'config/logging/Loggable.java',
191191
'config/logging/LoggingAspect.java',
192+
'exception/ErrorDetailProblemHandlingControllerAdvice.java',
192193
'utils/AppConstants.java'
193194
];
194-
if(configOptions.features.includes("localstack")) {
195-
mainJavaTemplates.push('config/AwsConfig.java');
196-
}
197195
this.generateMainJavaCode(configOptions, mainJavaTemplates);
198196

199197
const mainResTemplates = [
@@ -206,13 +204,12 @@ module.exports = class extends BaseGenerator {
206204

207205
const testJavaTemplates = [
208206
'ApplicationIntegrationTest.java',
209-
'common/ExceptionHandling.java',
210207
'common/AbstractIntegrationTest.java',
211208
'common/DBContainerInitializer.java'
212209
];
213210
if(configOptions.features.includes("localstack")) {
214211
testJavaTemplates.push('common/LocalStackConfig.java');
215-
testJavaTemplates.push('SqsListenerTest.java');
212+
testJavaTemplates.push('SqsListenerIntegrationTest.java');
216213
}
217214
this.generateTestJavaCode(configOptions, testJavaTemplates);
218215

generators/server/templates/app/docker/docker-compose.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,10 @@ services:
4444
- SERVICES=s3,sqs
4545
- DEFAULT_REGION=us-east-1
4646
- DOCKER_HOST=unix:///var/run/docker.sock
47-
- HOST_TMP_FOLDER=${TMPDIR}
47+
- USE_SSL=0
48+
- AWS_CBOR_DISABLE=1
4849
volumes:
49-
- "${TMPDIR:-/private}:/private"
50+
- "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
5051
- "/var/run/docker.sock:/var/run/docker.sock"
5152
- '../.localstack:/docker-entrypoint-initaws.d'
5253
<%_ } _%>

0 commit comments

Comments
 (0)