Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
arunvariyath committed Jan 31, 2025
2 parents a0e0df4 + 346395d commit cc2cc75
Show file tree
Hide file tree
Showing 17 changed files with 516 additions and 15 deletions.
33 changes: 27 additions & 6 deletions persistence-modules/java-jpa/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,28 @@
<version>1.0.0-SNAPSHOT</version>
</parent>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.11.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>

</dependencies>
</dependencyManagement>


<dependencies>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
Expand Down Expand Up @@ -65,9 +86,9 @@
<version>${jakarta.xml.bind-api.version}</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>${javax.annotation.version}</version>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>${jakarta.annotation.version}</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
Expand Down Expand Up @@ -134,8 +155,8 @@
<build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version>
<h2.version>2.1.214</h2.version>
<jakarta.xml.bind-api.version>4.0.0</jakarta.xml.bind-api.version>
<javax.annotation.version>1.3.2</javax.annotation.version>
<mysql.version>8.2.0</mysql.version>
<jakarta.annotation.version>3.0.0</jakarta.annotation.version>
<mysql.version>8.4.0</mysql.version>
</properties>

</project>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
<property name="jakarta.persistence.jdbc.password" value="YourPassword" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.proc.param_null_passing" value="true" />
</properties>
</persistence-unit>

Expand Down Expand Up @@ -107,4 +108,4 @@
</properties>
</persistence-unit>

</persistence>
</persistence>
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;

import com.baeldung.jpa.model.Car;

Expand Down Expand Up @@ -51,18 +52,29 @@ public void findCarsByYearNamedProcedure() {
final StoredProcedureQuery findByYearProcedure = entityManager.createNamedStoredProcedureQuery("findByYearProcedure");
final StoredProcedureQuery storedProcedure = findByYearProcedure.setParameter("p_year", 2015);
storedProcedure.getResultList()
.forEach(c -> Assert.assertEquals(Integer.valueOf(2015), ((Car) c).getYear()));
.forEach(c -> Assert.assertEquals(Integer.valueOf(2015), ((Car) c).getYear()));
}

@Test
public void findCarsByYearNoNamed() {
final StoredProcedureQuery storedProcedure = entityManager.createStoredProcedureQuery("FIND_CAR_BY_YEAR", Car.class)
.registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN)
.setParameter(1, 2015);
.registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN)
.setParameter(1, 2015);
storedProcedure.getResultList()
.forEach(c -> Assert.assertEquals(Integer.valueOf(2015), ((Car) c).getYear()));
.forEach(c -> Assert.assertEquals(Integer.valueOf(2015), ((Car) c).getYear()));
}


@org.junit.jupiter.api.Test
public void givenStoredProc_whenNullParamPassed_thenNoExceptionThrown() {
final StoredProcedureQuery storedProcedure = entityManager.createStoredProcedureQuery("FIND_CAR_BY_YEAR", Car.class)
.registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN);

assertDoesNotThrow(() -> {
storedProcedure.setParameter(1, null);
});
}

@AfterClass
public static void destroy() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<property name="jakarta.persistence.jdbc.password" value="YourPassword" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.proc.param_null_passing" value="true" />
</properties>
</persistence-unit>

Expand Down
25 changes: 21 additions & 4 deletions spring-boot-modules/spring-boot-springdoc-2/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
Expand Down Expand Up @@ -58,13 +71,16 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.baeldung.springdoc.SpringdocApplication</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>16</source>
<target>16</target>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
</plugins>
Expand Down Expand Up @@ -118,8 +134,9 @@
</profiles>

<properties>
<springdoc.version>2.6.0</springdoc.version>
<spring-boot.version>3.4.2</spring-boot.version>
<springdoc.version>2.8.4</springdoc.version>
<springdoc-openapi-maven-plugin.version>1.4</springdoc-openapi-maven-plugin.version>
</properties>

</project>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.baeldung.cats;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.security.SecurityScheme;

@SpringBootApplication
@OpenAPIDefinition(info = @Info(title = "Automated Testing for OpenAPI Endpoints Using CATS", version = "1.0.0"), security = { @SecurityRequirement(name = "Authorization") })
@SecurityScheme(type = SecuritySchemeType.HTTP, name = "Authorization", in = SecuritySchemeIn.HEADER, scheme = "Bearer")
public class CatsApplication {

public static void main(String[] args) {
SpringApplication.run(CatsApplication.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.baeldung.cats.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonFactoryBuilder;
import com.fasterxml.jackson.core.StreamReadConstraints;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
public class JacksonConfig {

@Bean
public ObjectMapper objectMapper() {
JsonFactory factory = new JsonFactoryBuilder().streamReadConstraints(StreamReadConstraints.builder()
.maxStringLength(100)
.build())
.build();

ObjectMapper mapper = new ObjectMapper(factory);
mapper.enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS);
mapper.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

mapper.disable(DeserializationFeature.ACCEPT_FLOAT_AS_INT);
mapper.enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
return mapper;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.baeldung.cats.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtException;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

private static final String TEST_TOKEN = "valid-token";
private static final String ACCESS_DENIED = "access denied";

private final Logger log = LoggerFactory.getLogger(SecurityConfig.class);

@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http.authorizeHttpRequests(auth -> auth.requestMatchers("/swagger-ui-custom.html", "/swagger-ui.html", "/swagger-ui/**", "/v3/api-docs/**", "/webjars/**", "/swagger-ui/index.html", "/api-docs/**")
.permitAll()
.anyRequest()
.authenticated())
.oauth2ResourceServer(rs -> rs.jwt(jwt -> jwt.decoder(jwtDecoder())))
.build();
}

@Bean
JwtDecoder jwtDecoder() {
return token -> {
if (!TEST_TOKEN.equals(token)) {
log.warn(ACCESS_DENIED);
throw new JwtException(ACCESS_DENIED);
}

return Jwt.withTokenValue(token)
.claim("token", TEST_TOKEN)
.header("token", TEST_TOKEN)
.build();
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.baeldung.cats.config;

import java.io.IOException;

import com.baeldung.cats.utils.RegexUtils;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

public class ZeroWidthIntDeserializer extends JsonDeserializer<Integer> {

@Override
public Integer deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return Integer.valueOf(RegexUtils.removeZeroWidthChars(parser.getText()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.baeldung.cats.config;

import java.io.IOException;

import com.baeldung.cats.utils.RegexUtils;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

public class ZeroWidthStringDeserializer extends JsonDeserializer<String> {

@Override
public String deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return RegexUtils.removeZeroWidthChars(parser.getText());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.baeldung.cats.controller;

import java.util.List;

import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baeldung.cats.model.BadApiRequest;
import com.baeldung.cats.model.Item;
import com.baeldung.cats.service.ItemService;

import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import jakarta.persistence.EntityNotFoundException;
import jakarta.validation.Valid;

@RestController
@RequestMapping("/api/v2/item")
@ApiResponse(responseCode = "401", description = "Unauthorized", content = { @Content(mediaType = MediaType.TEXT_PLAIN_VALUE, schema = @Schema(implementation = String.class)) })
@ApiResponse(responseCode = "400", description = "Bad Request", content = { @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = BadApiRequest.class)) })
public class ItemController {

private ItemService service;

public ItemController(ItemService service) {
this.service = service;
}

@PostMapping
@ApiResponse(responseCode = "200", description = "Success", content = { @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = Item.class)) })
public ResponseEntity<Item> post(@Valid @RequestBody Item item) {
service.insert(item);
return ResponseEntity.ok(item);
}

@GetMapping
@ApiResponse(responseCode = "200", description = "Success", content = { @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, array = @ArraySchema(schema = @Schema(implementation = Item.class))) })
public ResponseEntity<List<Item>> get() {
return ResponseEntity.ok(service.findAll());
}

@GetMapping("/{id}")
@ApiResponse(responseCode = "200", description = "Success", content = { @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = Item.class)) })
public ResponseEntity<Item> get(@PathVariable String id) {
try {
return ResponseEntity.ok(service.findById(id));
} catch (EntityNotFoundException e) {
return ResponseEntity.status(404)
.build();
}
}

@DeleteMapping("/{id}")
@ApiResponse(responseCode = "204", description = "Success")
public ResponseEntity<Void> delete(@PathVariable String id) {
try {
service.deleteById(id);

return ResponseEntity.status(204)
.build();
} catch (EntityNotFoundException e) {
return ResponseEntity.status(404)
.build();
}
}
}
Loading

0 comments on commit cc2cc75

Please sign in to comment.