3.4.0 Test Camel-SEDA

seda
Yan 4 months ago
parent 13436df52c
commit 1cef5e5d65

4
.gitignore vendored

@ -2,7 +2,3 @@
/.classpath /.classpath
/.project /.project
/.settings /.settings
/conf/
/conf2/
/bruno/
/backup/

@ -0,0 +1,9 @@
{
"version": "1",
"name": "camel-springboot-xml-example",
"type": "collection",
"ignore": [
"node_modules",
".git"
]
}

@ -0,0 +1,8 @@
auth {
mode: basic
}
auth:basic {
username:
password:
}

@ -0,0 +1,20 @@
meta {
name: findSession
type: http
seq: 4
}
get {
url: http://localhost:8761/services/api/session/d4415f6c-da1d-435c-95be-73bafe165768
body: none
auth: basic
}
headers {
operationName: findUsers
}
auth:basic {
username: cxfrs
password: password
}

@ -0,0 +1,20 @@
meta {
name: findSessions
type: http
seq: 2
}
get {
url: http://localhost:8761/services/api/session
body: none
auth: basic
}
headers {
operationName: findUsers
}
auth:basic {
username: cxfrs
password: password
}

@ -0,0 +1,33 @@
meta {
name: updateSession
type: http
seq: 3
}
post {
url: http://localhost:8761/services/api/session
body: json
auth: basic
}
headers {
Content-Type: application/json
X-MethodName: updateUser
}
auth:basic {
username: cxfrs
password: password
}
body:json {
{
"sessionId": "{{uuid}}",
"username": "admin",
"password": "@dminPwd123"
}
}
script:pre-request {
bru.setVar('uuid', require("uuid").v4());
}

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-5level %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/server.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/server.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
<maxHistory>3</maxHistory>
<totalSizeCap>300MB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%-5level %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.htmlunit" level="OFF"/>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>

@ -0,0 +1,21 @@
server:
port: 8761
camel:
springboot:
main-run-controller: true
spring:
ldap:
urls: ldap://localhost:10389
base: dc=example,dc=com
username: uid=admin,ou=system
password: secret
app:
queue-name: "SessionServiceQueue"
database:
url: "jdbc:h2:tcp://localhost/~/h2/db/appdb"
username: "app"
password: "app"
mapper-package: "com.example.sbcamel.mapper"

@ -4,21 +4,19 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId> <groupId>com.example</groupId>
<artifactId>camel-springboot-activemq6-example</artifactId> <artifactId>camel-springboot-activemq6-example</artifactId>
<version>3.3.0</version> <version>3.4.0</version>
<name>camel-springboot-activemq6-example</name> <name>camel-springboot-activemq6-example</name>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source> <maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target> <maven.compiler.target>17</maven.compiler.target>
<camel.version>4.8.4</camel.version> <camel.version>4.10.6</camel.version>
<spring-boot-dependencies.version>3.4.4</spring-boot-dependencies.version> <spring-boot-dependencies.version>3.4.6</spring-boot-dependencies.version>
<spring-cloud-dependencies.version>2024.0.1</spring-cloud-dependencies.version>
<mybatis.version>3.5.19</mybatis.version> <mybatis.version>3.5.19</mybatis.version>
<mybatis-spring.version>3.0.4</mybatis-spring.version> <mybatis-spring.version>3.0.4</mybatis-spring.version>
<guava.version>33.1.0-jre</guava.version> <guava.version>33.1.0-jre</guava.version>
<maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version> <maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
<jsoup.version>1.19.1</jsoup.version>
<java.mail.version>1.6.2</java.mail.version> <java.mail.version>1.6.2</java.mail.version>
</properties> </properties>
@ -38,13 +36,6 @@
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
@ -66,10 +57,6 @@
<groupId>org.springframework.security</groupId> <groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId> <artifactId>spring-security-ldap</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId> <artifactId>spring-jdbc</artifactId>
@ -79,6 +66,10 @@
<groupId>org.apache.camel.springboot</groupId> <groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-log-starter</artifactId> <artifactId>camel-log-starter</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-seda-starter</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.apache.camel.springboot</groupId> <groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-bean-starter</artifactId> <artifactId>camel-bean-starter</artifactId>
@ -91,10 +82,6 @@
<groupId>org.apache.camel.springboot</groupId> <groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-cxf-rest-starter</artifactId> <artifactId>camel-cxf-rest-starter</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-activemq6-starter</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.apache.camel.springboot</groupId> <groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jackson-starter</artifactId> <artifactId>camel-jackson-starter</artifactId>
@ -110,10 +97,6 @@
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>${guava.version}</version> <version>${guava.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
</dependency>
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.h2database</groupId>
<artifactId>h2</artifactId> <artifactId>h2</artifactId>
@ -141,11 +124,6 @@
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>${jsoup.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.apache.httpcomponents.client5</groupId> <groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId> <artifactId>httpclient5</artifactId>

@ -4,12 +4,9 @@
``` ```
ApacheDS Server 2.0.0.AM27 ApacheDS Server 2.0.0.AM27
Apache ActiveMQ 6.1.5
H2 Database Version 2.3.232 H2 Database Version 2.3.232
``` ```
2. For LDAP group and user setup, see misc/ldapdb.ldif
2. Please see conf/springboot.yml for LDAP/ActiveMQ Address
3. For LDAP group and user setup, see misc/ldapdb.ldif
## Startup screens ## Startup screens
@ -47,55 +44,8 @@ Starting ApacheDS instance 'default'...
``` ```
**2. Apache ActiveMQ 6.1.5**
```
C:\Users\XXX\apache-activemq-6.1.5\bin>activemq start
Warning: JAVA_HOME environment variable is not set.
Java Runtime: Oracle Corporation 17.0.14 C:\Users\XXX\graalvm-jdk-17.0.14+8.1
Heap sizes: current=1048576k free=1039360k max=1048576k
JVM args: -XX:ThreadPriorityPolicy=1 -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCIProduct -XX:-UnlockExperimentalVMOptions -Dcom.sun.management.jmxremote -Xms1G -Xmx1G -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=C:\Users\XXX\apache-activemq-6.1.5\bin\..\conf\login.config -Dactivemq.classpath=C:\Users\XXX\apache-activemq-6.1.5\bin\..\conf;C:\Users\XXX\apache-activemq-6.1.5\bin\../conf;C:\Users\XXX\apache-activemq-6.1.5\bin\../conf; -Dactivemq.home=C:\Users\XXX\apache-activemq-6.1.5\bin\.. -Dactivemq.base=C:\Users\XXX\apache-activemq-6.1.5\bin\.. -Dactivemq.conf=C:\Users\XXX\apache-activemq-6.1.5\bin\..\conf -Dactivemq.data=C:\Users\XXX\apache-activemq-6.1.5\bin\..\data -Djolokia.conf=file:C:\\Users\\XXX\\apache-activemq-6.1.5\\bin\\..\\conf\\jolokia-access.xml -Djava.io.tmpdir=C:\Users\XXX\apache-activemq-6.1.5\bin\..\data\tmp
Extensions classpath:
[C:\Users\XXX\apache-activemq-6.1.5\bin\..\lib,C:\Users\XXX\apache-activemq-6.1.5\bin\..\lib\camel,C:\Users\XXX\apache-activemq-6.1.5\bin\..\lib\optional,C:\Users\XXX\apache-activemq-6.1.5\bin\..\lib\web,C:\Users\XXX\apache-activemq-6.1.5\bin\..\lib\extra]
ACTIVEMQ_HOME: C:\Users\XXX\apache-activemq-6.1.5\bin\..
ACTIVEMQ_BASE: C:\Users\XXX\apache-activemq-6.1.5\bin\..
ACTIVEMQ_CONF: C:\Users\XXX\apache-activemq-6.1.5\bin\..\conf
ACTIVEMQ_DATA: C:\Users\XXX\apache-activemq-6.1.5\bin\..\data
Loading message broker from: xbean:activemq.xml
INFO | Using Persistence Adapter: KahaDBPersistenceAdapter[C:\Users\XXX\apache-activemq-6.1.5\bin\..\data\kahadb]
INFO | Starting Persistence Adapter: KahaDBPersistenceAdapter[C:\Users\XXX\apache-activemq-6.1.5\bin\..\data\kahadb]
INFO | Starting KahaDBStore
INFO | Opening MessageDatabase
INFO | Page File: C:\Users\XXX\apache-activemq-6.1.5\bin\..\data\kahadb\db.data. Recovering pageFile free list due to prior unclean shutdown..
INFO | KahaDB is version 7
INFO | Page File: C:\Users\XXX\apache-activemq-6.1.5\bin\..\data\kahadb\db.data. Recovered pageFile free list of size: 0
INFO | Starting Temp Data Store
INFO | PListStore:[C:\Users\XXX\apache-activemq-6.1.5\bin\..\data\localhost\tmp_storage] started
INFO | Starting Job Scheduler Store
INFO | Persistence Adapter successfully started
INFO | Apache ActiveMQ 6.1.5 (localhost, ID:DESKTOP-66E87L5-60208-1739018831814-0:1) is starting
INFO | Listening for connections at: tcp://DESKTOP-66E87L5:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600
INFO | Connector openwire started
INFO | Listening for connections at: amqp://DESKTOP-66E87L5:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600
INFO | Connector amqp started
INFO | Listening for connections at: stomp://DESKTOP-66E87L5:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600
INFO | Connector stomp started
INFO | Listening for connections at: mqtt://DESKTOP-66E87L5:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600
INFO | Connector mqtt started
INFO | Starting Jetty server
INFO | Creating Jetty connector
WARN | ServletContext@o.e.j.s.ServletContextHandler@33425811{/,null,STARTING} has uncovered HTTP methods for the following paths: [/]
INFO | Listening for connections at ws://DESKTOP-66E87L5:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600
INFO | Connector ws started
INFO | Apache ActiveMQ 6.1.5 (localhost, ID:DESKTOP-66E87L5-60208-1739018831814-0:1) started
INFO | For help or more information please see: http://activemq.apache.org
INFO | ActiveMQ WebConsole available at http://127.0.0.1:8161/
INFO | ActiveMQ Jolokia REST API available at http://127.0.0.1:8161/api/jolokia/
```
**3. H2 Database Version 2.3.232** **2. H2 Database Version 2.3.232**
``` ```
C:\Users\XXX\Desktop>SET JAVA_HOME=C:\Users\XXX\graalvm-jdk-17.0.14+8.1 C:\Users\XXX\Desktop>SET JAVA_HOME=C:\Users\XXX\graalvm-jdk-17.0.14+8.1

@ -6,10 +6,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication @SpringBootApplication
@EnableEurekaServer
public class Boot { public class Boot {
private static final Logger logger = LoggerFactory.getLogger(Boot.class); private static final Logger logger = LoggerFactory.getLogger(Boot.class);
@ -25,7 +23,6 @@ public class Boot {
System.setProperty("spring.config.location", configDirectory + "/springboot.yml"); System.setProperty("spring.config.location", configDirectory + "/springboot.yml");
System.setProperty("logging.config", configDirectory + "/logback.xml"); System.setProperty("logging.config", configDirectory + "/logback.xml");
} }
System.setProperty("org.apache.activemq.SERIALIZABLE_PACKAGES", "*");
SpringApplication.run(Boot.class, args); SpringApplication.run(Boot.class, args);
} }

@ -1,44 +1,16 @@
package com.example.sbcamel.init; package com.example.sbcamel.init;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import com.example.sbcamel.processor.InspectionProcessor;
import com.example.sbcamel.processor.TestProcessor;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider; import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider;
@Configuration @Configuration
@ImportResource("classpath:schedule.xml")
public class AppConfig { public class AppConfig {
@Value("${app.inspection-client.javamail-config}")
private String javamailCfg;
@Bean
public Properties javaMailProperties() throws IOException {
Properties javaMailProperties = new Properties();
FileInputStream fis = new FileInputStream(javamailCfg);
javaMailProperties.load(fis);
fis.close();
return javaMailProperties;
}
@Bean
public CloseableHttpClient httpClient() {
return HttpClients.createDefault();
}
@Bean("objectMapper") @Bean("objectMapper")
public ObjectMapper objectMapper() { public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
@ -51,14 +23,4 @@ public class AppConfig {
public JacksonJsonProvider jaxrsProvider() { public JacksonJsonProvider jaxrsProvider() {
return new JacksonJsonProvider(); return new JacksonJsonProvider();
} }
@Bean
public InspectionProcessor inspectionProcessor() {
return new InspectionProcessor();
}
@Bean
public TestProcessor testProcessor() {
return new TestProcessor();
}
} }

@ -11,8 +11,6 @@ import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.example.sbcamel.mapper.SessionMapper; import com.example.sbcamel.mapper.SessionMapper;
import com.example.sbcamel.processor.InspectionProcessor;
import com.example.sbcamel.processor.TestProcessor;
import com.example.sbcamel.service.SessionService; import com.example.sbcamel.service.SessionService;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
@ -20,12 +18,11 @@ import jakarta.ws.rs.core.Response;
@Component @Component
public class CamelRouter extends RouteBuilder { public class CamelRouter extends RouteBuilder {
private static final String createSessionSql = "CREATE TABLE IF NOT EXISTS public.session (sessionId UUID not null, " private static final String dropSessionSql = "DROP TABLE IF EXISTS public.session";
private static final String createSessionSql = "CREATE TABLE public.session (sessionId UUID not null, "
+ "username CHARACTER VARYING not null, password CHARACTER VARYING not null, PRIMARY KEY (sessionId))"; + "username CHARACTER VARYING not null, password CHARACTER VARYING not null, PRIMARY KEY (sessionId))";
private static final String addSelector1Sql = "ALTER TABLE IF EXISTS public.session ADD COLUMN IF NOT EXISTS selector1 CHARACTER VARYING NULL";
private static final String addSelector2Sql = "ALTER TABLE IF EXISTS public.session ADD COLUMN IF NOT EXISTS selector2 CHARACTER VARYING NULL";
private static final String addSelector3Sql = "ALTER TABLE IF EXISTS public.session ADD COLUMN IF NOT EXISTS selector3 CHARACTER VARYING NULL";
@Value("${app.queue-name}") @Value("${app.queue-name}")
private String queueName; private String queueName;
@ -33,19 +30,11 @@ public class CamelRouter extends RouteBuilder {
@Autowired @Autowired
private JdbcTemplate jdbcTemplate; private JdbcTemplate jdbcTemplate;
@Autowired
protected InspectionProcessor inspectionProcessor;
@Autowired
protected TestProcessor testProcessor;
@PostConstruct @PostConstruct
private void init() { private void init() {
org.apache.ibatis.logging.LogFactory.useSlf4jLogging(); org.apache.ibatis.logging.LogFactory.useSlf4jLogging();
jdbcTemplate.execute(dropSessionSql);
jdbcTemplate.execute(createSessionSql); jdbcTemplate.execute(createSessionSql);
jdbcTemplate.execute(addSelector1Sql);
jdbcTemplate.execute(addSelector2Sql);
jdbcTemplate.execute(addSelector3Sql);
} }
@Override @Override
@ -56,7 +45,7 @@ public class CamelRouter extends RouteBuilder {
from("cxfrs:/api?resourceClasses=" + SessionService.class.getName() + "&bindingStyle=Default" from("cxfrs:/api?resourceClasses=" + SessionService.class.getName() + "&bindingStyle=Default"
+ "&providers=jaxrsProvider&loggingFeatureEnabled=true").to("log:cxfrs?showAll=true") + "&providers=jaxrsProvider&loggingFeatureEnabled=true").to("log:cxfrs?showAll=true")
.to("activemq6:queue:" + queueName).process(exchange -> { .to("seda:" + queueName).process(exchange -> {
if (exchange.getMessage().getBody() != null && exchange.getMessage().getBody() instanceof byte[] if (exchange.getMessage().getBody() != null && exchange.getMessage().getBody() instanceof byte[]
&& new String((byte[]) exchange.getMessage().getBody()).equals("null")) { && new String((byte[]) exchange.getMessage().getBody()).equals("null")) {
if (exchange.getIn().getHeader(Exchange.HTTP_METHOD).equals("GET")) { if (exchange.getIn().getHeader(Exchange.HTTP_METHOD).equals("GET")) {
@ -65,7 +54,7 @@ public class CamelRouter extends RouteBuilder {
} }
}); });
from("activemq6:queue:" + queueName) from("seda:" + queueName)
.process(exchange -> exchange.getIn().setHeader(BeanConstants.BEAN_METHOD_NAME, .process(exchange -> exchange.getIn().setHeader(BeanConstants.BEAN_METHOD_NAME,
exchange.getIn().getHeader(CxfConstants.OPERATION_NAME.toLowerCase()))) exchange.getIn().getHeader(CxfConstants.OPERATION_NAME.toLowerCase())))
.to("log:activemq?showAll=true").transacted("propagationRequired").choice() .to("log:activemq?showAll=true").transacted("propagationRequired").choice()
@ -78,10 +67,7 @@ public class CamelRouter extends RouteBuilder {
.to("mybatis:" + SessionMapper.class.getName() + ".findSessions?statementType=SelectList") .to("mybatis:" + SessionMapper.class.getName() + ".findSessions?statementType=SelectList")
.when(header(BeanConstants.BEAN_METHOD_NAME).isEqualTo("findSession")) .when(header(BeanConstants.BEAN_METHOD_NAME).isEqualTo("findSession"))
.to("mybatis:" + SessionMapper.class.getName() + ".findSession?statementType=SelectOne") .to("mybatis:" + SessionMapper.class.getName() + ".findSession?statementType=SelectOne")
.when(header(BeanConstants.BEAN_METHOD_NAME).isEqualTo("inspect")) .end().marshal().json(JsonLibrary.Jackson);
.to("mybatis:" + SessionMapper.class.getName() + ".findSession?statementType=SelectOne")
.process(inspectionProcessor).when(header(BeanConstants.BEAN_METHOD_NAME).isEqualTo("test"))
.process(testProcessor).end().marshal().json(JsonLibrary.Jackson);
} }
} }

@ -15,31 +15,25 @@ import com.example.sbcamel.service.UuidTypeHandler;
public interface SessionMapper { public interface SessionMapper {
@Insert({ "<script>", @Insert({ "<script>",
"MERGE INTO public.session (sessionId, username, password, selector1, selector2, selector3) KEY (sessionId) VALUES (#{sessionId, javaType=java.util.UUID, " "MERGE INTO public.session (sessionId, username, password) KEY (sessionId) VALUES (#{sessionId, javaType=java.util.UUID, "
+ "jdbcType=OTHER, typeHandler=com.example.sbcamel.service.UuidTypeHandler}, #{username}, #{password}, #{selector1}, #{selector2}, #{selector3}) ", + "jdbcType=OTHER, typeHandler=com.example.sbcamel.service.UuidTypeHandler}, #{username}, #{password}) ",
"</script>" }) "</script>" })
int updateSession(Session session); int updateSession(Session session);
@Results({ @Results({
@Result(property = "sessionId", column = "sessionId", javaType = UUID.class, jdbcType = JdbcType.OTHER, typeHandler = UuidTypeHandler.class), @Result(property = "sessionId", column = "sessionId", javaType = UUID.class, jdbcType = JdbcType.OTHER, typeHandler = UuidTypeHandler.class),
@Result(property = "username", column = "username"), @Result(property = "password", column = "password"), @Result(property = "username", column = "username"), @Result(property = "password", column = "password")})
@Result(property = "selector1", column = "selector1"),
@Result(property = "selector2", column = "selector2"),
@Result(property = "selector3", column = "selector3") })
@Select({ "<script>", @Select({ "<script>",
"select sessionId, username, password, selector1, selector2, selector3 from public.session where sessionId=#{list[0], javaType=java.util.UUID, " "select sessionId, username, password from public.session where sessionId=#{list[0], javaType=java.util.UUID, "
+ "jdbcType=OTHER, typeHandler=com.example.sbcamel.service.UuidTypeHandler}", + "jdbcType=OTHER, typeHandler=com.example.sbcamel.service.UuidTypeHandler}",
"</script>" }) "</script>" })
Session findSession(UUID sessionId); Session findSession(UUID sessionId);
@Results({ @Results({
@Result(property = "sessionId", column = "sessionId", javaType = UUID.class, jdbcType = JdbcType.OTHER, typeHandler = UuidTypeHandler.class), @Result(property = "sessionId", column = "sessionId", javaType = UUID.class, jdbcType = JdbcType.OTHER, typeHandler = UuidTypeHandler.class),
@Result(property = "username", column = "username"), @Result(property = "password", column = "password"), @Result(property = "username", column = "username"), @Result(property = "password", column = "password") })
@Result(property = "selector1", column = "selector1"),
@Result(property = "selector2", column = "selector2"),
@Result(property = "selector3", column = "selector3") })
@Select({ "<script>", @Select({ "<script>",
"select sessionId, username, password, selector1, selector2, selector3 from public.session order by sessionId", "select sessionId, username, password from public.session order by sessionId",
"</script>" }) "</script>" })
Collection<Session> findSessions(); Collection<Session> findSessions();
} }

@ -1,142 +0,0 @@
package com.example.sbcamel.processor;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.htmlunit.FailingHttpStatusCodeException;
import org.htmlunit.WebClient;
import org.htmlunit.html.HtmlButton;
import org.htmlunit.html.HtmlForm;
import org.htmlunit.html.HtmlPage;
import org.htmlunit.html.HtmlPasswordInput;
import org.htmlunit.html.HtmlTextInput;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import com.example.sbcamel.service.Session;
public class InspectionProcessor implements Processor {
private static final Logger logger = LoggerFactory.getLogger(InspectionProcessor.class);
@Value("${app.htmlunit.login-url}")
private String loginUrl;
@Value("${app.htmlunit.login-btn-selector}")
private String loginBtnSelector;
@Value("${app.htmlunit.login-wait-millis:3000}")
private Long loginWaitMillis;
@Value("${app.htmlunit.user-page-url}")
private String userPageUrl;
@Value("${app.htmlunit.vip11-page-url}")
private String vip11PageUrl;
@Value("${app.htmlunit.vip12-page-url}")
private String vip12PageUrl;
@Value("${app.htmlunit.vip13-page-url}")
private String vip13PageUrl;
@Value("${app.htmlunit.vip21-page-url}")
private String vip21PageUrl;
@Value("${app.htmlunit.vip22-page-url}")
private String vip22PageUrl;
@Value("${app.htmlunit.vip23-page-url}")
private String vip23PageUrl;
@Value("${app.htmlunit.vip31-page-url}")
private String vip31PageUrl;
@Value("${app.htmlunit.vip32-page-url}")
private String vip32PageUrl;
@Value("${app.htmlunit.vip33-page-url}")
private String vip33PageUrl;
@Value("${app.htmlunit.logout-url}")
private String logoutUrl;
@Override
public void process(Exchange exchange) throws Exception {
Session session = (Session) exchange.getMessage().getBody();
logger.debug("session: {}", session);
try (final WebClient webClient = new WebClient()) {
final HtmlPage loginPage = webClient.getPage(loginUrl);
logger.debug("loginPage: {}", loginPage.asXml());
final HtmlForm form = loginPage.getForms().get(0);
final HtmlTextInput usernameField = form.getInputByName("username");
usernameField.type(session.getUsername());
logger.debug("entered username: {}", session.getUsername());
final HtmlPasswordInput passwordField = form.getInputByName("password");
passwordField.type(session.getPassword());
logger.debug("entered password: {}", session.getPassword());
HtmlButton loginBtn = loginPage.querySelector(loginBtnSelector);
logger.debug("loginBtn type: {}", loginBtn.getType());
loginBtn.click();
Thread.sleep(loginWaitMillis);
HtmlPage userPage = webClient.getPage(userPageUrl);
logger.debug("userPage hashcode: {}", userPage.hashCode());
Map<String, List<String>> reply11 = fillResponseMap(webClient, session, vip11PageUrl);
Map<String, List<String>> reply12 = fillResponseMap(webClient, session, vip12PageUrl);
Map<String, List<String>> reply13 = fillResponseMap(webClient, session, vip13PageUrl);
Map<String, List<String>> reply21 = fillResponseMap(webClient, session, vip21PageUrl);
Map<String, List<String>> reply22 = fillResponseMap(webClient, session, vip22PageUrl);
Map<String, List<String>> reply23 = fillResponseMap(webClient, session, vip23PageUrl);
Map<String, List<String>> reply31 = fillResponseMap(webClient, session, vip31PageUrl);
Map<String, List<String>> reply32 = fillResponseMap(webClient, session, vip32PageUrl);
Map<String, List<String>> reply33 = fillResponseMap(webClient, session, vip33PageUrl);
webClient.getPage(logoutUrl);
exchange.getMessage().setBody(Map.of("vip11Page", reply11, "vip12Page", reply12, "vip13Page", reply13,
"vip21Page", reply21, "vip22Page", reply22, "vip23Page", reply23,
"vip31Page", reply31, "vip32Page", reply32, "vip33Page", reply33));
} catch (Exception e) {
logger.error("LoginProcessor process error!", e);
}
}
private Map<String, List<String>> fillResponseMap(WebClient webClient, Session session, String url)
throws FailingHttpStatusCodeException, MalformedURLException, IOException {
Map<String, List<String>> reply = new HashMap<>();
HtmlPage vipPage = webClient.getPage(url);
Document doc = Jsoup.parse(vipPage.asXml());
for (String selector : List.of(session.getSelector1(), session.getSelector2(), session.getSelector3())) {
Elements elements = doc.select(selector);
List<String> selectedList = new ArrayList<>();
for (Element element : elements) {
logger.debug("[fillResponseMap] {} -> {}", selector, element.html());
selectedList.add(element.html());
}
reply.put(selector, selectedList);
}
return reply;
}
}

@ -1,54 +0,0 @@
package com.example.sbcamel.processor;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.commons.io.FileUtils;
import org.apache.cxf.message.MessageContentsList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
public class TestProcessor implements Processor {
private static final Logger logger = LoggerFactory.getLogger(TestProcessor.class);
@Value("${app.jsoup.html-file}")
private String htmlFilePath;
@SuppressWarnings("unchecked")
@Override
public void process(Exchange exchange) throws Exception {
logger.info("in class: {}", exchange.getIn().getBody().getClass().getName());
MessageContentsList mcl = (MessageContentsList) exchange.getIn().getBody();
List<String> selectors = (List<String>) mcl.get(0);
logger.info("selectors: {}", selectors);
File htmlFile = new File(htmlFilePath);
String html = FileUtils.readFileToString(htmlFile, StandardCharsets.UTF_8);
Document doc = Jsoup.parse(html);
Map<String, List<String>> reply = new HashMap<>();
for (String selector : selectors) {
Elements elements = doc.select(selector);
List<String> selectedList = new ArrayList<>();
for (Element element : elements) {
logger.info("{} -> {}", selector, element.html());
selectedList.add(element.html());
}
reply.put(selector, selectedList);
}
exchange.getMessage().setBody(reply);
}
}

@ -1,70 +0,0 @@
package com.example.sbcamel.service;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class EmailService {
private static final Logger logger = LoggerFactory.getLogger(EmailService.class);
@Autowired
private Properties javaMailProperties;
public boolean sendEmail(String fromAddress, String smtpPassword, String[] toAddresses, String subject,
String content) {
try {
logger.debug("[sendEmail] fromAddress: {}, toAddresses: {}", fromAddress, toAddresses);
if (StringUtils.isEmpty(subject) || StringUtils.isEmpty(smtpPassword) || StringUtils.isEmpty(fromAddress)
|| toAddresses.length == 0) {
logger.warn("[sendEmail] subject, smtp-password, source-address or target-address is not set");
return false;
}
String emailHost = javaMailProperties.getProperty("mail.smtp.host");
logger.debug("[sendEmail] {} -> {}, mail.smtp.host: {}", fromAddress, List.of(toAddresses), emailHost);
if (StringUtils.isNotBlank(emailHost) && StringUtils.isNotBlank(fromAddress) && toAddresses.length > 0) {
logger.debug("[sendEmail] starting to send message from: {}", fromAddress);
Session session = Session.getInstance(javaMailProperties);
MimeMessage message = new MimeMessage(session);
message.setContent(content, "text/html; charset=utf-8");
message.setFrom(new InternetAddress(fromAddress));
Arrays.asList(toAddresses).forEach(toAddress -> {
try {
message.addRecipient(Message.RecipientType.TO, new InternetAddress(toAddress));
} catch (Exception e) {
logger.error("sendEmail error!", e);
}
});
message.setSubject(subject);
Transport transport = session.getTransport("smtp");
transport.connect(emailHost, fromAddress, smtpPassword);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
logger.debug("sendEmail to: {}", Arrays.asList(toAddresses));
return true;
} else {
logger.warn("[sendEmail] missing either from-field, to-field or host address!");
}
} catch (Exception e) {
logger.error("sendEmail error!", e);
}
return false;
}
}

@ -1,161 +0,0 @@
package com.example.sbcamel.service;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.MapDifference;
import com.google.common.collect.MapDifference.ValueDifference;
import com.google.common.collect.Maps;
public class InspectionClient {
private static final Logger logger = LoggerFactory.getLogger(InspectionClient.class);
@Autowired
private CloseableHttpClient httpClient;
@Autowired
private EmailService emailService;
@Autowired
private ObjectMapper objectMapper;
@Value("${app.inspection-client.email-password:}")
private String smtpPassword;
@Value("${app.inspection-client.email-sender:}")
private String fromAddress;
@Value("${app.inspection-client.email-recipient:}")
private String[] toAddresses;
@Value("${app.inspection-client.http-url}")
private String url;
@Value("${app.inspection-client.http-method}")
private String httpMethod;
@Value("${app.inspection-client.expected-result-file-path}")
private String expectedResultFilePath;
@Value("${app.inspection-client.alert-subject}")
private String alertSubject;
@Value("${app.inspection-client.http-username}")
private String username;
@Value("${app.inspection-client.http-password}")
private String password;
private static final String getBasicAuthenticationHeader(String username, String password) {
String valueToEncode = username + ":" + password;
return "Basic " + Base64.getEncoder().encodeToString(valueToEncode.getBytes());
}
public void sendMessage() {
try {
File jsonFile = new File(expectedResultFilePath);
if (!jsonFile.exists()) {
logger.info("file does not exist: {}", expectedResultFilePath);
return;
}
String jsonString = FileUtils.readFileToString(jsonFile, StandardCharsets.UTF_8);
logger.info("expected result: {}", jsonString);
HashMap<String, Object> expectedMap = convertStringToMap(jsonString);
logger.info("calling {} {}", httpMethod, url);
HttpUriRequestBase req = new HttpUriRequestBase(httpMethod, URI.create(url));
req.addHeader("Authorization", getBasicAuthenticationHeader(username, password));
Pair<Boolean, Boolean> sendEmailResult = httpClient.execute(req,
new HttpClientResponseHandler<Pair<Boolean, Boolean>>() {
@Override
public Pair<Boolean, Boolean> handleResponse(ClassicHttpResponse result)
throws HttpException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
result.getEntity().writeTo(baos);
String responseText = new String(baos.toByteArray(), StandardCharsets.UTF_8);
logger.info("actual result: {}", responseText);
if (StringUtils.isEmpty(responseText)) {
logger.error("actual result is empty!");
return Pair.of(Boolean.FALSE, Boolean.FALSE);
}
baos.close();
try {
HashMap<String, Object> resultMap = convertStringToMap(responseText);
MapDifference<String, Object> diff = Maps.difference(expectedMap, resultMap);
logger.info("diff.areEqual: {}", diff.areEqual());
StringBuilder contentBuilder = new StringBuilder();
if (!diff.areEqual()) {
Map<String, ValueDifference<Object>> entriesDiffering = diff.entriesDiffering();
entriesDiffering.entrySet().stream().forEach(entry -> {
logger.info("entriesDiffering key: {}", entry.getKey());
logger.info("entriesDiffering expected: {}", entry.getValue().leftValue());
logger.info("entriesDiffering actual: {}", entry.getValue().rightValue());
contentBuilder.append(entry.getKey() + "<br/>\n");
contentBuilder.append("EXPECTED: " + entry.getValue().leftValue() + "<br/>\n");
contentBuilder.append("ACTUAL: " + entry.getValue().rightValue() + "<br/>\n");
contentBuilder.append("<br/>\n");
});
return Pair.of(Boolean.TRUE, emailService.sendEmail(fromAddress, smtpPassword,
toAddresses, alertSubject, contentBuilder.toString()));
}
} catch (IOException e) {
logger.error("Error occurred while parsing message", e);
}
return Pair.of(Boolean.FALSE, Boolean.FALSE);
}
});
logger.info("send email result: {}", sendEmailResult);
} catch (Exception e) {
logger.error("Error occurred while preparing to send message", e);
}
}
public HashMap<String, Object> convertStringToMap(String jsonString) throws IOException {
TypeReference<java.util.HashMap<String, Object>> ref = new TypeReference<>() {
};
return new HashMap<>(objectMapper.readValue(jsonString, ref));
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getHttpMethod() {
return httpMethod;
}
public void setHttpMethod(String httpMethod) {
this.httpMethod = httpMethod;
}
}

@ -25,15 +25,6 @@ public class Session implements Serializable {
@Size(min = 3, max = 40) @Size(min = 3, max = 40)
private String password; private String password;
@NotNull
private String selector1;
@NotNull
private String selector2;
@NotNull
private String selector3;
public Session() { public Session() {
} }
@ -68,30 +59,6 @@ public class Session implements Serializable {
this.password = password; this.password = password;
} }
public String getSelector1() {
return selector1;
}
public void setSelector1(String selector1) {
this.selector1 = selector1;
}
public String getSelector2() {
return selector2;
}
public void setSelector2(String selector2) {
this.selector2 = selector2;
}
public String getSelector3() {
return selector3;
}
public void setSelector3(String selector3) {
this.selector3 = selector3;
}
@Override @Override
public String toString() { public String toString() {
return ReflectionToStringBuilder.toString(this); return ReflectionToStringBuilder.toString(this);

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/task https://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<task:scheduler id="inspectionScheduler" pool-size="2" />
<bean id="inspectionClient"
class="com.example.sbcamel.service.InspectionClient">
</bean>
<task:scheduled-tasks scheduler="inspectionScheduler">
<task:scheduled ref="inspectionClient"
method="sendMessage" cron="0 * * * * ?" />
</task:scheduled-tasks>
</beans>
Loading…
Cancel
Save