Skip to content

Commit f2a4220

Browse files
Add new JPA smoke test to validate IAST visitor
1 parent 0424969 commit f2a4220

File tree

13 files changed

+631
-0
lines changed

13 files changed

+631
-0
lines changed
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
plugins {
2+
id 'java'
3+
id 'war'
4+
id 'org.springframework.boot' version '2.6.0'
5+
}
6+
7+
apply plugin: 'io.spring.dependency-management'
8+
apply from: "$rootDir/gradle/java.gradle"
9+
description = 'SpringBoot JPA Smoke Tests.'
10+
11+
dependencies {
12+
implementation 'org.springframework.boot:spring-boot-starter-web'
13+
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
14+
implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
15+
implementation 'javax.servlet:jstl:1.2'
16+
implementation 'com.h2database:h2:2.1.214'
17+
18+
testImplementation project(':dd-smoke-tests')
19+
20+
compileOnly 'org.projectlombok:lombok:1.18.34'
21+
annotationProcessor 'org.projectlombok:lombok:1.18.34'
22+
23+
testCompileOnly 'org.projectlombok:lombok:1.18.34'
24+
testAnnotationProcessor 'org.projectlombok:lombok:1.18.34'
25+
}
26+
27+
tasks.withType(Test).configureEach {
28+
dependsOn "bootWar"
29+
jvmArgs "-Ddatadog.smoketest.springboot.bootWar.path=${tasks.bootWar.archiveFile.get()}"
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package datadog.smoketest.springboot;
2+
3+
import datadog.smoketest.springboot.filter.SessionVisitorFilter;
4+
import javax.servlet.Filter;
5+
import org.springframework.boot.SpringApplication;
6+
import org.springframework.boot.autoconfigure.SpringBootApplication;
7+
import org.springframework.context.annotation.Bean;
8+
9+
@SpringBootApplication
10+
public class SpringbootApplication {
11+
12+
@Bean
13+
public Filter badBehaviorFilter() {
14+
return new SessionVisitorFilter();
15+
}
16+
17+
public static void main(final String[] args) {
18+
SpringApplication.run(SpringbootApplication.class, args);
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package datadog.smoketest.springboot.controller;
2+
3+
import static java.util.Arrays.asList;
4+
5+
import datadog.smoketest.springboot.entity.Author;
6+
import datadog.smoketest.springboot.entity.Book;
7+
import datadog.smoketest.springboot.entity.Library;
8+
import datadog.smoketest.springboot.entity.Owner;
9+
import datadog.smoketest.springboot.service.LibraryService;
10+
import javax.servlet.http.HttpServletRequest;
11+
import javax.servlet.http.HttpSession;
12+
import lombok.RequiredArgsConstructor;
13+
import org.hibernate.collection.internal.PersistentBag;
14+
import org.hibernate.proxy.HibernateProxy;
15+
import org.springframework.http.ResponseEntity;
16+
import org.springframework.stereotype.Controller;
17+
import org.springframework.ui.ModelMap;
18+
import org.springframework.web.bind.annotation.GetMapping;
19+
import org.springframework.web.bind.annotation.ModelAttribute;
20+
import org.springframework.web.bind.annotation.PathVariable;
21+
import org.springframework.web.bind.annotation.RequestMapping;
22+
import org.springframework.web.bind.annotation.RequestParam;
23+
import org.springframework.web.bind.annotation.SessionAttributes;
24+
import org.springframework.web.bind.support.SessionStatus;
25+
26+
@Controller
27+
@RequestMapping("/library")
28+
@SessionAttributes(LibraryController.COMMAND_NAME)
29+
@RequiredArgsConstructor
30+
public class LibraryController {
31+
32+
public static final String COMMAND_NAME = "library";
33+
34+
private final LibraryService libraryService;
35+
36+
@GetMapping("/{id}")
37+
public ResponseEntity<Boolean> hasIssue(@PathVariable final int id) {
38+
return ResponseEntity.ok(libraryService.findLibraryById(id).isIssueExists());
39+
}
40+
41+
@GetMapping
42+
public ResponseEntity<Integer> create() {
43+
final Library library =
44+
Library.builder()
45+
.books(
46+
asList(
47+
Book.builder()
48+
.title("The Lord of the Rings")
49+
.owner(Owner.builder().name("Peter Jackson").build())
50+
.authors(
51+
asList(
52+
Author.builder().name("J.R.R Tolkien").build(),
53+
Author.builder().name("Peter Jackson").build()))
54+
.build(),
55+
Book.builder()
56+
.title("The Hobbit")
57+
.owner(Owner.builder().name("Edith Tolkien").build())
58+
.authors(
59+
asList(
60+
Author.builder().name("J.R.R Tolkien").build(),
61+
Author.builder().name("Edith Tolkien").build()))
62+
.build()))
63+
.build();
64+
libraryService.save(library);
65+
return ResponseEntity.ok(library.getId());
66+
}
67+
68+
@GetMapping("/update/{id}")
69+
public String update(@PathVariable final int id, final ModelMap model) {
70+
final Library library = libraryService.findLibraryById(id);
71+
model.put(COMMAND_NAME, library);
72+
return "update";
73+
}
74+
75+
@GetMapping("/update")
76+
public String update(
77+
@ModelAttribute(COMMAND_NAME) final Library library, final SessionStatus sessionStatus) {
78+
libraryService.update(library);
79+
sessionStatus.setComplete();
80+
return "redirect:/library/" + library.getId();
81+
}
82+
83+
@GetMapping("/session/add/{id}")
84+
public ResponseEntity<String> addToSession(
85+
@RequestParam("mode") final String mode,
86+
@PathVariable final int id,
87+
final HttpServletRequest request) {
88+
final Library library = libraryService.findLibraryById(id);
89+
final Book book = library.getBooks().get(0);
90+
final HttpSession session = request.getSession();
91+
if (mode.equals("one-to-one")) {
92+
session.setAttribute(mode, book.getOwner());
93+
} else {
94+
session.setAttribute(mode, book.getAuthors());
95+
}
96+
return ResponseEntity.ok("OK");
97+
}
98+
99+
@GetMapping("/session/validate")
100+
public ResponseEntity<Boolean> validateSession(
101+
@RequestParam("mode") final String mode, final HttpServletRequest request) {
102+
final HttpSession session = request.getSession();
103+
final Object sessionItem = session.getAttribute(mode);
104+
final boolean loaded;
105+
if (sessionItem instanceof Owner) {
106+
final HibernateProxy proxy = (HibernateProxy) sessionItem;
107+
loaded = !proxy.getHibernateLazyInitializer().isUninitialized();
108+
} else {
109+
final PersistentBag bag = (PersistentBag) sessionItem;
110+
loaded = bag.wasInitialized();
111+
}
112+
return ResponseEntity.ok(loaded);
113+
}
114+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package datadog.smoketest.springboot.entity;
2+
3+
import javax.persistence.*;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
6+
import lombok.EqualsAndHashCode;
7+
import lombok.Getter;
8+
import lombok.NoArgsConstructor;
9+
import lombok.Setter;
10+
11+
@Entity
12+
@Builder
13+
@NoArgsConstructor
14+
@AllArgsConstructor
15+
@Getter
16+
@Setter
17+
@EqualsAndHashCode(of = "id")
18+
public class Author {
19+
20+
@Id
21+
@GeneratedValue(strategy = GenerationType.SEQUENCE)
22+
private int id;
23+
24+
private String name;
25+
26+
private int updateCount;
27+
28+
public void increaseUpdateCount() {
29+
this.updateCount++;
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package datadog.smoketest.springboot.entity;
2+
3+
import java.util.List;
4+
import javax.persistence.*;
5+
import lombok.AllArgsConstructor;
6+
import lombok.Builder;
7+
import lombok.EqualsAndHashCode;
8+
import lombok.Getter;
9+
import lombok.NoArgsConstructor;
10+
import lombok.Setter;
11+
12+
@Entity
13+
@Builder
14+
@NoArgsConstructor
15+
@AllArgsConstructor
16+
@Getter
17+
@Setter
18+
@EqualsAndHashCode(of = "id")
19+
public class Book {
20+
21+
@Id
22+
@GeneratedValue(strategy = GenerationType.SEQUENCE)
23+
private int id;
24+
25+
private String title;
26+
27+
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
28+
@JoinColumn(name = "book_id")
29+
private List<Author> authors;
30+
31+
@OneToOne(cascade = CascadeType.ALL, optional = false, fetch = FetchType.LAZY)
32+
@JoinColumn(name = "owner_id")
33+
private Owner owner;
34+
35+
private int updateCount;
36+
37+
public void increaseUpdateCount() {
38+
this.updateCount++;
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package datadog.smoketest.springboot.entity;
2+
3+
import java.util.List;
4+
import javax.persistence.*;
5+
import lombok.AllArgsConstructor;
6+
import lombok.Builder;
7+
import lombok.EqualsAndHashCode;
8+
import lombok.Getter;
9+
import lombok.NoArgsConstructor;
10+
import lombok.Setter;
11+
12+
@Entity
13+
@Builder
14+
@NoArgsConstructor
15+
@AllArgsConstructor
16+
@Getter
17+
@Setter
18+
@EqualsAndHashCode(of = "id")
19+
public class Library {
20+
21+
@Id
22+
@GeneratedValue(strategy = GenerationType.SEQUENCE)
23+
private int id;
24+
25+
private String name;
26+
27+
@OneToMany(cascade = CascadeType.ALL)
28+
@JoinColumn(name = "library_id")
29+
private List<Book> books;
30+
31+
private int updateCount;
32+
33+
public void increaseUpdateCount() {
34+
this.updateCount++;
35+
}
36+
37+
public boolean isIssueExists() {
38+
for (Book book : this.getBooks()) {
39+
if (book.getUpdateCount() != book.getOwner().getUpdateCount()) {
40+
return true;
41+
}
42+
for (Author author : book.getAuthors()) {
43+
if (book.getUpdateCount() != author.getUpdateCount()) {
44+
return true;
45+
}
46+
}
47+
}
48+
return false;
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package datadog.smoketest.springboot.entity;
2+
3+
import javax.persistence.Entity;
4+
import javax.persistence.GeneratedValue;
5+
import javax.persistence.GenerationType;
6+
import javax.persistence.Id;
7+
import lombok.AllArgsConstructor;
8+
import lombok.Builder;
9+
import lombok.EqualsAndHashCode;
10+
import lombok.Getter;
11+
import lombok.NoArgsConstructor;
12+
import lombok.Setter;
13+
14+
@Entity
15+
@Builder
16+
@NoArgsConstructor
17+
@AllArgsConstructor
18+
@Getter
19+
@Setter
20+
@EqualsAndHashCode(of = "id")
21+
public class Owner {
22+
23+
@Id
24+
@GeneratedValue(strategy = GenerationType.SEQUENCE)
25+
private int id;
26+
27+
private String name;
28+
29+
private int updateCount;
30+
31+
public void increaseUpdateCount() {
32+
this.updateCount++;
33+
}
34+
}

0 commit comments

Comments
 (0)