Merge branch 'eugenp:master' into master
This commit is contained in:
commit
66f5823c5d
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
|
<artifactId>core-java-modules</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>core-java-19</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>19</maven.compiler.source>
|
||||||
|
<maven.compiler.target>19</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>19</source>
|
||||||
|
<target>19</target>
|
||||||
|
<compilerArgs>--enable-preview</compilerArgs>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,3 @@
|
||||||
|
package com.baeldung.features.records;
|
||||||
|
|
||||||
|
public record GPSPoint (double lat, double lng) { }
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.features.records;
|
||||||
|
|
||||||
|
public sealed interface ILocation permits Location {
|
||||||
|
default String getName() {
|
||||||
|
return switch (this) {
|
||||||
|
case Location(var name, var ignored) -> name;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.features.records;
|
||||||
|
|
||||||
|
public record Location(String name, GPSPoint gpsPoint) implements ILocation {
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
package com.baeldung.features.records;
|
||||||
|
|
||||||
|
public record LocationWrapper<T>(T t, String description) { }
|
|
@ -0,0 +1,99 @@
|
||||||
|
package com.baeldung.features;
|
||||||
|
|
||||||
|
import com.baeldung.features.records.GPSPoint;
|
||||||
|
import com.baeldung.features.records.Location;
|
||||||
|
import com.baeldung.features.records.LocationWrapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||||
|
|
||||||
|
|
||||||
|
public class JEP405RecordPatternsUnitTest {
|
||||||
|
|
||||||
|
Object object = new Location("Home", new GPSPoint(1.0, 2.0));
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenObject_whenTestInstanceOfAndCastIdiom_shouldMatchNewInstanceOf() {
|
||||||
|
// old Code
|
||||||
|
if (object instanceof Location) {
|
||||||
|
Location l = (Location) object;
|
||||||
|
assertThat(l).isInstanceOf(Location.class);
|
||||||
|
}
|
||||||
|
// new code
|
||||||
|
if (object instanceof Location l) {
|
||||||
|
assertThat(l).isInstanceOf(Location.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenObject_whenTestDestruct_shouldMatch() {
|
||||||
|
// when
|
||||||
|
if (object instanceof Location(var name, var gpsPoint)) {
|
||||||
|
// then
|
||||||
|
assertThat(name).isEqualTo("Home");
|
||||||
|
assertThat(gpsPoint).isInstanceOf(GPSPoint.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object instanceof Location(var name, GPSPoint(var lat, var lng))) {
|
||||||
|
assertThat(lat).isEqualTo(1.0);
|
||||||
|
assertThat(lng).isEqualTo(2.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenObjectIsNull_whenTestNullCheck_shouldNotMatch() {
|
||||||
|
Location l = null;
|
||||||
|
if (l instanceof Location location) {
|
||||||
|
assertThat(location).isNotNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenObject_whenTestGenericTypeInstanceOf_shouldMatch() {
|
||||||
|
LocationWrapper<Location> locationWrapper = new LocationWrapper<>(new Location("Home", new GPSPoint(1.0, 2.0)), "Description");
|
||||||
|
if (locationWrapper instanceof LocationWrapper<Location>(var ignored, var description)) {
|
||||||
|
assertThat(description).isEqualTo("Description");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenObject_whenTestSwitchExpressionWithTypePattern_shouldMatch() {
|
||||||
|
String result = switch (object) {
|
||||||
|
case Location l -> l.name();
|
||||||
|
default -> "default";
|
||||||
|
};
|
||||||
|
assertThat(result).isEqualTo("Home");
|
||||||
|
Double result2 = switch (object) {
|
||||||
|
case Location(var name, GPSPoint(var lat, var lng)) -> lat;
|
||||||
|
default -> 0.0;
|
||||||
|
};
|
||||||
|
assertThat(result2).isEqualTo(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenObject_whenTestGuardedSwitchExpressionWithTypePattern_shouldMatchAndGuard() {
|
||||||
|
String result = switch (object) {
|
||||||
|
case Location(var name, var ignored) when name.equals("Home") -> "Test";
|
||||||
|
case Location(var name, var ignored) -> name;
|
||||||
|
default -> "default";
|
||||||
|
};
|
||||||
|
assertThat(result).isEqualTo("Test");
|
||||||
|
|
||||||
|
String otherResult = switch (new Location("Other", new GPSPoint(1.0, 2.0))) {
|
||||||
|
case Location(var name, var ignored) when name.equals("Home") -> "Test";
|
||||||
|
case Location(var name, var ignored) -> name;
|
||||||
|
default -> "default";
|
||||||
|
};
|
||||||
|
assertThat(otherResult).isEqualTo("Other");
|
||||||
|
|
||||||
|
Object noLocation = new GPSPoint(1.0, 2.0);
|
||||||
|
String noLocationResult = switch (noLocation) {
|
||||||
|
case Location(var name, var ignored) when name.equals("Home") -> "Test";
|
||||||
|
case Location(var name, var ignored) -> name;
|
||||||
|
default -> "default";
|
||||||
|
};
|
||||||
|
assertThat(noLocationResult).isEqualTo("default");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.baeldung.getclassfromstr;
|
||||||
|
|
||||||
|
public class MyNiceClass {
|
||||||
|
public String greeting(){
|
||||||
|
return "Hi there, I wish you all the best!";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.baeldung.getclassfromstr;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
public class GetClassObjectFromStringUnitTest {
|
||||||
|
@Test
|
||||||
|
void givenQualifiedClsName_whenUsingClassForName_shouldGetExpectedClassObject() throws ReflectiveOperationException {
|
||||||
|
Class cls = Class.forName("com.baeldung.getclassfromstr.MyNiceClass");
|
||||||
|
assertNotNull(cls);
|
||||||
|
|
||||||
|
MyNiceClass myNiceObject = (MyNiceClass) cls.getDeclaredConstructor().newInstance();
|
||||||
|
assertNotNull(myNiceObject);
|
||||||
|
assertEquals("Hi there, I wish you all the best!", myNiceObject.greeting());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenSimpleName_whenUsingClassForName_shouldGetExpectedException() {
|
||||||
|
assertThrows(ClassNotFoundException.class, () -> Class.forName("MyNiceClass"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -151,4 +151,4 @@
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
1
pom.xml
1
pom.xml
|
@ -1130,6 +1130,7 @@
|
||||||
<!-- <module>core-java-modules/core-java-15</module> --> <!-- uses preview features, to be decided how to handle -->
|
<!-- <module>core-java-modules/core-java-15</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||||
<!-- <module>core-java-modules/core-java-16</module> --> <!-- uses preview features, to be decided how to handle -->
|
<!-- <module>core-java-modules/core-java-16</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||||
<!-- <module>core-java-modules/core-java-17</module> --> <!-- uses preview features, to be decided how to handle -->
|
<!-- <module>core-java-modules/core-java-17</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||||
|
<!-- <module>core-java-modules/core-java-19</module> --> <!-- uses preview features, to be decided how to handle -->
|
||||||
<module>core-java-modules/core-java-collections-set</module>
|
<module>core-java-modules/core-java-collections-set</module>
|
||||||
<module>core-java-modules/core-java-collections-list-4</module>
|
<module>core-java-modules/core-java-collections-list-4</module>
|
||||||
<module>core-java-modules/core-java-collections-maps-4</module>
|
<module>core-java-modules/core-java-collections-maps-4</module>
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
<module>stripe</module>
|
<module>stripe</module>
|
||||||
<module>twilio</module>
|
<module>twilio</module>
|
||||||
<module>twitter4j</module>
|
<module>twitter4j</module>
|
||||||
|
<module>sentry-servlet</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>saas-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>sentry-servlet</artifactId>
|
||||||
|
<name>sentry-servlet</name>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<sentry.version>6.11.0</sentry.version>
|
||||||
|
<cargo.version>1.10.4</cargo.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.sentry</groupId>
|
||||||
|
<artifactId>sentry-servlet</artifactId>
|
||||||
|
<version>${sentry.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.cargo</groupId>
|
||||||
|
<artifactId>cargo-maven3-plugin</artifactId>
|
||||||
|
<version>${cargo.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<container>
|
||||||
|
<containerId>tomcat9x</containerId>
|
||||||
|
<type>embedded</type>
|
||||||
|
</container>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.baeldung.sentry.servlet;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
@WebServlet(urlPatterns = "/fault", loadOnStartup = 1)
|
||||||
|
public class FaultyServlet extends HttpServlet {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
|
|
||||||
|
String op = req.getParameter("op");
|
||||||
|
if( "fault".equals(op) ) {
|
||||||
|
resp.sendError(500, "Something bad happened !");
|
||||||
|
}
|
||||||
|
else if ( "exception".equals(op) ) {
|
||||||
|
throw new IllegalArgumentException("Internal error");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resp.setStatus(200);
|
||||||
|
resp.setContentType("text/plain");
|
||||||
|
resp.getWriter().println("OK");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.baeldung.sentry.support;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletContextEvent;
|
||||||
|
import javax.servlet.ServletContextListener;
|
||||||
|
import javax.servlet.annotation.WebListener;
|
||||||
|
|
||||||
|
import io.sentry.Sentry;
|
||||||
|
import io.sentry.SentryLevel;
|
||||||
|
|
||||||
|
@WebListener
|
||||||
|
public class SentryContextListener implements ServletContextListener {
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent sce) {
|
||||||
|
|
||||||
|
// Besides standard supported locations, let's also allow the DSN to be
|
||||||
|
// passed using servlet container managed parameters. This can be useful if your app
|
||||||
|
// is hosted in a shared application server.
|
||||||
|
ServletContext context = sce.getServletContext();
|
||||||
|
String sentryDsn = context.getInitParameter("sentry.dsn");
|
||||||
|
|
||||||
|
if ( sentryDsn != null ) {
|
||||||
|
context.log("[I21] sentry.dsn init parameter found. Configuring Sentry SDK...");
|
||||||
|
Sentry.init(sentryDsn);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
context.log("[I25] sentry.dsn init parameter not found. Configuring Sentry SDK with defaults");
|
||||||
|
Sentry.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextDestroyed(ServletContextEvent sce) {
|
||||||
|
sce.getServletContext().log("[I34] shutting down context");
|
||||||
|
Sentry.captureMessage("[I35] contextDestroyed", SentryLevel.INFO);
|
||||||
|
Sentry.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.baeldung.sentry.support;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.annotation.WebFilter;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import io.sentry.Sentry;
|
||||||
|
import io.sentry.SentryLevel;
|
||||||
|
|
||||||
|
@WebFilter(urlPatterns = "/*")
|
||||||
|
public class SentryFilter implements Filter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||||
|
try {
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
int rc = ((HttpServletResponse) response).getStatus();
|
||||||
|
if (rc/100 == 5) {
|
||||||
|
Sentry.captureMessage("Application error: code=" + rc, SentryLevel.ERROR);
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
Sentry.captureException(t);
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Sentry configuration file
|
||||||
|
# put your DSN here
|
||||||
|
dsn=https://xxxxxxxxxxxxxxxx@zzzzzzz.ingest.sentry.io/wwww
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app
|
||||||
|
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
|
||||||
|
version="4.0">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<context-param>
|
||||||
|
<param-name>sentry.dsn</param-name>
|
||||||
|
<param-value>https://093dbb121a584893b17677bd87c5ec1f@o75061.ingest.sentry.io/4504352731627520</param-value>
|
||||||
|
</context-param>
|
||||||
|
-->
|
||||||
|
</web-app>
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.baeldung.sentry.servlet;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class FaultyServletLiveTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGivenFaultyRequestWithNoQueryString_thenSuccess() throws Exception {
|
||||||
|
|
||||||
|
//int port = getServerPort();
|
||||||
|
URL u = new URL("http://localhost:8080/sentry-servlet/fault");
|
||||||
|
HttpURLConnection conn = (HttpURLConnection)u.openConnection();
|
||||||
|
int rc = conn.getResponseCode();
|
||||||
|
assertThat(rc)
|
||||||
|
.isEqualTo(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGivenFaultyRequestWithFaultString_thenFail() throws Exception {
|
||||||
|
|
||||||
|
//int port = getServerPort();
|
||||||
|
URL u = new URL("http://localhost:8080/sentry-servlet/fault?fault=true");
|
||||||
|
HttpURLConnection conn = (HttpURLConnection)u.openConnection();
|
||||||
|
int rc = conn.getResponseCode();
|
||||||
|
assertThat(rc)
|
||||||
|
.isEqualTo(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGivenFaultyRequestWithExceptionString_thenFail() throws Exception {
|
||||||
|
|
||||||
|
//int port = getServerPort();
|
||||||
|
URL u = new URL("http://localhost:8080/sentry-servlet/fault?exception=true");
|
||||||
|
HttpURLConnection conn = (HttpURLConnection)u.openConnection();
|
||||||
|
int rc = conn.getResponseCode();
|
||||||
|
assertThat(rc)
|
||||||
|
.isEqualTo(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue