mirror of
https://github.com/chatopera/cosin.git
synced 2025-08-01 16:38:02 +08:00
https://github.com/cskefu/cskefu/issues/751 add sample codes for server and sample plugin
Signed-off-by: Hai Liang Wang <hai@chatopera.com>
This commit is contained in:
parent
bde6677db6
commit
d1f44e85ee
8
.gitignore
vendored
8
.gitignore
vendored
@ -2,11 +2,13 @@
|
|||||||
*.swo
|
*.swo
|
||||||
*.sublime-*
|
*.sublime-*
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|
||||||
jmeter.log
|
jmeter.log
|
||||||
__pycache__
|
__pycache__
|
||||||
tmp/
|
tmp/
|
||||||
node_modules/
|
node_modules/
|
||||||
sftp-config.json
|
sftp-config.json
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.iml
|
*.iml
|
||||||
*.ipr
|
*.ipr
|
||||||
@ -20,6 +22,12 @@ backups/
|
|||||||
build.gradle
|
build.gradle
|
||||||
.vscode/
|
.vscode/
|
||||||
nohup.out
|
nohup.out
|
||||||
|
logs/
|
||||||
|
|
||||||
docker-compose.dev.yml
|
docker-compose.dev.yml
|
||||||
docker-compose.custom.yml
|
docker-compose.custom.yml
|
||||||
|
.jqwik-database
|
||||||
private
|
private
|
||||||
|
|
||||||
|
target/
|
||||||
|
dist/
|
||||||
|
2
compose/plugins/.gitignore
vendored
Normal file
2
compose/plugins/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
7
compose/sample.env
Normal file
7
compose/sample.env
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# https://docs.docker.com/compose/reference/envvars/#compose_file
|
||||||
|
# use Enterprise edition: docker-compose.yml:./private/docker-compose.ext.yml
|
||||||
|
# use other customize yml, copy docker-compose.yml as docker-compose.custom.yml
|
||||||
|
# and edit .env with COMPOSE_FILE=docker-compose.custom.yml, docker-compose.custom.yml
|
||||||
|
# is ignored with .gitignore
|
||||||
|
COMPOSE_FILE=docker-compose.yml
|
||||||
|
COMPOSE_PROJECT_NAME=cskefu_v8
|
101
plugins/sample/pom.xml
Normal file
101
plugins/sample/pom.xml
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<?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>
|
||||||
|
<groupId>com.cskefu.plugins</groupId>
|
||||||
|
<artifactId>sample</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
<name>CSKeFu Plugin Sample</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>17</java.version>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<bundle.plugin.version>5.1.1</bundle.plugin.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.cskefu</groupId>
|
||||||
|
<artifactId>mod-plugin</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.cskefu</groupId>
|
||||||
|
<artifactId>bom-plugin</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>${project.groupId}-${project.artifactId}-${project.version}.${build.time}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>build-helper-maven-plugin</artifactId>
|
||||||
|
<version>1.10</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>timestamp-property</id>
|
||||||
|
<goals>
|
||||||
|
<goal>timestamp-property</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<name>build.time</name>
|
||||||
|
<pattern>yyyyMMddHHmm</pattern>
|
||||||
|
<locale>zh_CN</locale>
|
||||||
|
<timeZone>Asia/Shanghai</timeZone>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<!-- You might want to condider replacing this with the config from the sample-bundle-src config -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<version>${bundle.plugin.version}</version>
|
||||||
|
<extensions>true</extensions>
|
||||||
|
<configuration>
|
||||||
|
<instructions>
|
||||||
|
<Bundle-SymbolicName>
|
||||||
|
${project.artifactId}
|
||||||
|
</Bundle-SymbolicName>
|
||||||
|
<Bundle-Name>${project.name}</Bundle-Name>
|
||||||
|
<Bundle-Version>${project.version}</Bundle-Version>
|
||||||
|
<Bundle-Activator>com.cskefu.plugins.sample.Activator</Bundle-Activator>
|
||||||
|
<Private-Package>com.cskefu.plugins.sample</Private-Package>
|
||||||
|
<Import-Package>
|
||||||
|
!*,org.osgi.framework,com.cskefu.mod.plugin,com.cskefu.mod.plugin.dto
|
||||||
|
</Import-Package>
|
||||||
|
<Embed-Dependency>
|
||||||
|
<!-- Add here any custom dependency -->
|
||||||
|
slf4j-api;scope=compile|runtime; type=!pom; inline=false,
|
||||||
|
logback-*;scope=compile|runtime; type=!pom; inline=false
|
||||||
|
</Embed-Dependency>
|
||||||
|
<Export-Service>com.cskefu.plugins.sample.Sample</Export-Service>
|
||||||
|
<Embed-Transitive>true</Embed-Transitive>
|
||||||
|
</instructions>
|
||||||
|
<buildDirectory>../../compose/plugins</buildDirectory>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.cskefu.plugins.sample;
|
||||||
|
|
||||||
|
import com.cskefu.mod.plugin.AbstractPluginActivator;
|
||||||
|
import com.cskefu.mod.plugin.IPlugin;
|
||||||
|
import com.cskefu.mod.plugin.PluginDescriptor;
|
||||||
|
|
||||||
|
import java.util.Hashtable;
|
||||||
|
|
||||||
|
public class Activator extends AbstractPluginActivator {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PluginDescriptor registerService() {
|
||||||
|
Hashtable<String, Object> props = new Hashtable<>();
|
||||||
|
props.put("Plugin-Name", "SamplePlugin");
|
||||||
|
return PluginDescriptor.builder()
|
||||||
|
.implementation(new Sample())
|
||||||
|
.name(IPlugin.class.getName())
|
||||||
|
.params(props)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.cskefu.plugins.sample;
|
||||||
|
|
||||||
|
import com.cskefu.mod.plugin.IPlugin;
|
||||||
|
import com.cskefu.mod.plugin.dto.ActionResponse;
|
||||||
|
import com.cskefu.mod.plugin.dto.NotificationResponse;
|
||||||
|
|
||||||
|
public class Sample implements IPlugin {
|
||||||
|
@Override
|
||||||
|
public ActionResponse doAction() {
|
||||||
|
return ActionResponse.builder().body("Action Worked !!").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NotificationResponse doNotification() {
|
||||||
|
return NotificationResponse.builder().body("Notification Processed...").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
# Server
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
```
|
||||||
|
./scripts/package.sh # package JAR
|
||||||
|
./scripts/deploy.sh # deploy JAR, POM into Chatopera Nexus Repo
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Serving API
|
||||||
|
|
||||||
|
```
|
||||||
|
./scripts/dev.sh # run JAR as standalone spring boot application, provide API with 8080
|
||||||
|
```
|
30
server/bom-plugin/pom.xml
Normal file
30
server/bom-plugin/pom.xml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?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">
|
||||||
|
<parent>
|
||||||
|
<artifactId>root</artifactId>
|
||||||
|
<groupId>com.cskefu</groupId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<name>CSKeFu Bom Plugin</name>
|
||||||
|
<artifactId>bom-plugin</artifactId>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<description>Standard Parent POM for CSKeFu Plugins.</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
|
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<artifactId>mod-plugin</artifactId>
|
||||||
|
<groupId>com.cskefu</groupId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
</project>
|
19
server/mod-plugin/pom.xml
Normal file
19
server/mod-plugin/pom.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?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">
|
||||||
|
<parent>
|
||||||
|
<artifactId>root</artifactId>
|
||||||
|
<groupId>com.cskefu</groupId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<name>CSKeFu Module Plugin</name>
|
||||||
|
<artifactId>mod-plugin</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
|
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.cskefu.mod.plugin;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.osgi.framework.BundleActivator;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public abstract class AbstractPluginActivator implements BundleActivator {
|
||||||
|
|
||||||
|
public static BundleContext bundleContext;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void start(BundleContext context) throws Exception {
|
||||||
|
bundleContext = context;
|
||||||
|
PluginDescriptor descriptor = registerService();
|
||||||
|
bundleContext.registerService(descriptor.getName(), descriptor.getImplementation(), descriptor.getParams());
|
||||||
|
log.info("Service registered: " + descriptor.getImplementation().getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void stop(BundleContext context) throws Exception {
|
||||||
|
bundleContext = null;
|
||||||
|
log.info("Stopping plugin " + this.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract PluginDescriptor registerService();
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.cskefu.mod.plugin;
|
||||||
|
|
||||||
|
import com.cskefu.mod.plugin.dto.ActionResponse;
|
||||||
|
import com.cskefu.mod.plugin.dto.NotificationResponse;
|
||||||
|
|
||||||
|
public interface IPlugin {
|
||||||
|
|
||||||
|
ActionResponse doAction();
|
||||||
|
|
||||||
|
NotificationResponse doNotification();
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.cskefu.mod.plugin;
|
||||||
|
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
public class PluginDescriptor {
|
||||||
|
|
||||||
|
Object implementation;
|
||||||
|
String name;
|
||||||
|
Hashtable<String, Object> params;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.cskefu.mod.plugin.dto;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
@Getter
|
||||||
|
public class ActionResponse {
|
||||||
|
String body;
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.cskefu.mod.plugin.dto;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
@Getter
|
||||||
|
public class NotificationResponse {
|
||||||
|
String body;
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package com.cskefu.mod.plugin;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
import com.cskefu.mod.plugin.dto.ActionResponse;
|
||||||
|
import com.cskefu.mod.plugin.dto.NotificationResponse;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class AbstractPluginActivatorTest {
|
||||||
|
|
||||||
|
private AbstractPluginActivator cut;
|
||||||
|
@Mock
|
||||||
|
private BundleContext bundleContext;
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
cut = new TestActivator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("When start method invoked, then the plugin service is registered into the bundle context")
|
||||||
|
void testStart() throws Exception {
|
||||||
|
cut.start(bundleContext);
|
||||||
|
verify(bundleContext, times(1)).registerService(eq("com.mornati.sample.commons.plugins.IPlugin"), any(SampleService.class), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestActivator extends AbstractPluginActivator {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PluginDescriptor registerService() {
|
||||||
|
return PluginDescriptor.builder().implementation(new SampleService()).name(IPlugin.class.getName()).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SampleService implements IPlugin {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResponse doAction() {
|
||||||
|
return ActionResponse.builder().body("sample action").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NotificationResponse doNotification() {
|
||||||
|
return NotificationResponse.builder().body("sample notification").build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
211
server/pom.xml
Normal file
211
server/pom.xml
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<modules>
|
||||||
|
<module>serving-api</module>
|
||||||
|
<module>mod-plugin</module>
|
||||||
|
<module>bom-plugin</module>
|
||||||
|
</modules>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.7.7</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.cskefu</groupId>
|
||||||
|
<artifactId>root</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>CSKeFu Root</name>
|
||||||
|
<description>OpenSource Contact Center</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>17</java.version>
|
||||||
|
<osgi.version>8.0.0</osgi.version>
|
||||||
|
<felix.version>7.0.5</felix.version>
|
||||||
|
<bundle.plugin.version>5.1.1</bundle.plugin.version>
|
||||||
|
<jacoco.maven.plugin.version>0.8.7</jacoco.maven.plugin.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.osgi</groupId>
|
||||||
|
<artifactId>osgi.core</artifactId>
|
||||||
|
<version>${osgi.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.apache.felix/org.apache.felix.framework -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>org.apache.felix.framework</artifactId>
|
||||||
|
<version>${felix.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.apache.felix/org.apache.felix.main -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>org.apache.felix.main</artifactId>
|
||||||
|
<version>${felix.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Core Bundles. Declared here to use maven to download and package them -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>org.apache.felix.fileinstall</artifactId>
|
||||||
|
<version>3.6.8</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.apache.felix/org.apache.felix.scr -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>org.apache.felix.scr</artifactId>
|
||||||
|
<version>2.1.24</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.osgi/org.osgi.util.promise -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.osgi</groupId>
|
||||||
|
<artifactId>org.osgi.util.promise</artifactId>
|
||||||
|
<version>1.1.1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.osgi/org.osgi.util.function -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.osgi</groupId>
|
||||||
|
<artifactId>org.osgi.util.function</artifactId>
|
||||||
|
<version>1.1.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.osgi/org.osgi.service.cm -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.osgi</groupId>
|
||||||
|
<artifactId>org.osgi.service.cm</artifactId>
|
||||||
|
<version>1.5.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.apache.felix/org.apache.felix.shell -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>org.apache.felix.shell</artifactId>
|
||||||
|
<version>1.4.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.apache.felix/org.apache.felix.shell.remote -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>org.apache.felix.shell.remote</artifactId>
|
||||||
|
<version>1.2.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jacoco</groupId>
|
||||||
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
<version>${jacoco.maven.plugin.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.jqwik</groupId>
|
||||||
|
<artifactId>jqwik</artifactId>
|
||||||
|
<version>1.6.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jacoco</groupId>
|
||||||
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
<version>${jacoco.maven.plugin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>prepare-agent</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<!-- attached to Maven test phase -->
|
||||||
|
<execution>
|
||||||
|
<id>report</id>
|
||||||
|
<phase>test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>report</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>chatopera</id>
|
||||||
|
<name>Chatopera Inc.</name>
|
||||||
|
<url>https://nexus.chatopera.com/repository/maven-public</url>
|
||||||
|
<releases>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</releases>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<distributionManagement>
|
||||||
|
<repository>
|
||||||
|
<id>chatopera-releases</id>
|
||||||
|
<name>Chatopera Nexus Releases</name>
|
||||||
|
<url>https://nexus.chatopera.com/repository/maven-releases/</url>
|
||||||
|
</repository>
|
||||||
|
<snapshotRepository>
|
||||||
|
<id>chatopera-snapshots</id>
|
||||||
|
<name>Chatopera Nexus Snapshots</name>
|
||||||
|
<url>https://nexus.chatopera.com/repository/maven-snapshots/</url>
|
||||||
|
</snapshotRepository>
|
||||||
|
</distributionManagement>
|
||||||
|
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<id>hailiang-wang</id>
|
||||||
|
<name>Hai Liang Wang</name>
|
||||||
|
<email>h@cskefu.com</email>
|
||||||
|
<url>https://github.com/hailiang-wang</url>
|
||||||
|
<organization>Chatopera Inc.</organization>
|
||||||
|
<organizationUrl>https://www.chatopera.com</organizationUrl>
|
||||||
|
<roles>
|
||||||
|
<role>chief engineer</role>
|
||||||
|
<role>developer</role>
|
||||||
|
</roles>
|
||||||
|
<timezone>Asia/Shanghai</timezone>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
|
||||||
|
</project>
|
20
server/scripts/deploy.sh
Normal file
20
server/scripts/deploy.sh
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
###########################################
|
||||||
|
#
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
# constants
|
||||||
|
baseDir=$(cd `dirname "$0"`;pwd)
|
||||||
|
cwdDir=$PWD
|
||||||
|
export PYTHONUNBUFFERED=1
|
||||||
|
export PATH=/opt/miniconda3/envs/venv-py3/bin:$PATH
|
||||||
|
export TS=$(date +%Y%m%d%H%M%S)
|
||||||
|
export DATE=`date "+%Y%m%d"`
|
||||||
|
export DATE_WITH_TIME=`date "+%Y%m%d-%H%M%S"` #add %3N as we want millisecond too
|
||||||
|
|
||||||
|
# functions
|
||||||
|
|
||||||
|
# main
|
||||||
|
[ -z "${BASH_SOURCE[0]}" -o "${BASH_SOURCE[0]}" = "$0" ] || return
|
||||||
|
cd $baseDir/..
|
||||||
|
mvn -DskipTests clean package deploy
|
20
server/scripts/dev.sh
Normal file
20
server/scripts/dev.sh
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
###########################################
|
||||||
|
#
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
# constants
|
||||||
|
baseDir=$(cd `dirname "$0"`;pwd)
|
||||||
|
cwdDir=$PWD
|
||||||
|
export PYTHONUNBUFFERED=1
|
||||||
|
export PATH=/opt/miniconda3/envs/venv-py3/bin:$PATH
|
||||||
|
export TS=$(date +%Y%m%d%H%M%S)
|
||||||
|
export DATE=`date "+%Y%m%d"`
|
||||||
|
export DATE_WITH_TIME=`date "+%Y%m%d-%H%M%S"` #add %3N as we want millisecond too
|
||||||
|
|
||||||
|
# functions
|
||||||
|
|
||||||
|
# main
|
||||||
|
[ -z "${BASH_SOURCE[0]}" -o "${BASH_SOURCE[0]}" = "$0" ] || return
|
||||||
|
cd $baseDir/..
|
||||||
|
java -jar serving-api/target/serving-api-0.0.1-SNAPSHOT.jar
|
20
server/scripts/package.sh
Normal file
20
server/scripts/package.sh
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
###########################################
|
||||||
|
#
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
# constants
|
||||||
|
baseDir=$(cd `dirname "$0"`;pwd)
|
||||||
|
cwdDir=$PWD
|
||||||
|
export PYTHONUNBUFFERED=1
|
||||||
|
export PATH=/opt/miniconda3/envs/venv-py3/bin:$PATH
|
||||||
|
export TS=$(date +%Y%m%d%H%M%S)
|
||||||
|
export DATE=`date "+%Y%m%d"`
|
||||||
|
export DATE_WITH_TIME=`date "+%Y%m%d-%H%M%S"` #add %3N as we want millisecond too
|
||||||
|
|
||||||
|
# functions
|
||||||
|
|
||||||
|
# main
|
||||||
|
[ -z "${BASH_SOURCE[0]}" -o "${BASH_SOURCE[0]}" = "$0" ] || return
|
||||||
|
cd $baseDir/..
|
||||||
|
mvn -DskipTests clean package
|
20
server/serving-api/Dockerfile
Normal file
20
server/serving-api/Dockerfile
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
FROM adoptopenjdk/openjdk15:jdk-15.0.1_9-alpine-slim as build
|
||||||
|
WORKDIR /workspace/app
|
||||||
|
COPY target/core*.jar /workspace/app
|
||||||
|
RUN mkdir -p /workspace/app/dependency && (cd /workspace/app/dependency; jar -xf ../*.jar)
|
||||||
|
|
||||||
|
|
||||||
|
FROM adoptopenjdk/openjdk15:jdk-15.0.1_9-alpine-slim
|
||||||
|
VOLUME /tmp
|
||||||
|
|
||||||
|
ARG DEPENDENCY=/workspace/app/dependency
|
||||||
|
RUN addgroup --system app_group && adduser --system app_user --ingroup app_group --home /app
|
||||||
|
COPY --from=build --chown=app_user ${DEPENDENCY}/BOOT-INF/lib /app/lib
|
||||||
|
COPY --from=build --chown=app_user ${DEPENDENCY}/META-INF /app/META-INF
|
||||||
|
COPY --chown=app_user target/internal-bundles /app/internal-bundles
|
||||||
|
COPY --from=build --chown=app_user ${DEPENDENCY}/BOOT-INF/classes /app
|
||||||
|
|
||||||
|
USER app_user:app_group
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENTRYPOINT ["java","-cp","./:lib/*","com.cskefu.serving.api.SampleApplication"]
|
65
server/serving-api/pom.xml
Normal file
65
server/serving-api/pom.xml
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?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">
|
||||||
|
<parent>
|
||||||
|
<artifactId>root</artifactId>
|
||||||
|
<groupId>com.cskefu</groupId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<name>CSKeFu Serving API</name>
|
||||||
|
<artifactId>serving-api</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
|
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.cskefu</groupId>
|
||||||
|
<artifactId>mod-plugin</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<version>3.1.2</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-dependencies</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-dependencies</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<includeArtifactIds>org.apache.felix.fileinstall,org.apache.felix.shell,org.apache.felix.shell.remote,org.osgi.util.function,org.osgi.util.promise,org.apache.felix.scr,org.osgi.service.cm</includeArtifactIds>
|
||||||
|
<outputDirectory>${project.build.directory}/internal-bundles</outputDirectory>
|
||||||
|
<overWriteReleases>false</overWriteReleases>
|
||||||
|
<overWriteSnapshots>true</overWriteSnapshots>
|
||||||
|
<excludeTransitive>true</excludeTransitive>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.cskefu.serving.api;
|
||||||
|
|
||||||
|
import com.cskefu.serving.api.config.PluginsConfigurer;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableConfigurationProperties(PluginsConfigurer.class)
|
||||||
|
public class SampleApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SampleApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.cskefu.serving.api.config;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "plugins")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class PluginsConfigurer {
|
||||||
|
|
||||||
|
private Map<String, String> config;
|
||||||
|
|
||||||
|
// @PostConstruct
|
||||||
|
// public void print() {
|
||||||
|
// for (Map.Entry<String, String> entry : config.entrySet()) {
|
||||||
|
// System.out.println(entry.getKey() + ":" + entry.getValue());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.cskefu.serving.api.controllers;
|
||||||
|
|
||||||
|
import com.cskefu.mod.plugin.dto.ActionResponse;
|
||||||
|
import com.cskefu.mod.plugin.dto.NotificationResponse;
|
||||||
|
import com.cskefu.serving.api.service.PluginList;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/plugins")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SampleController {
|
||||||
|
|
||||||
|
private final PluginList pluginList;
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
@ResponseBody
|
||||||
|
public ResponseEntity<Set<String>> getSamples() {
|
||||||
|
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.body(pluginList.registered());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/{name}")
|
||||||
|
@ResponseBody
|
||||||
|
public ResponseEntity<ActionResponse> doAction(@PathVariable(value = "name") String name) {
|
||||||
|
return pluginList.lookup(name).map(pluginImpl -> ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.body(pluginImpl.doAction())).orElseGet(() -> ResponseEntity.badRequest().body(ActionResponse.builder().body("Plugin not found for " + name).build()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/{name}/notification")
|
||||||
|
@ResponseBody
|
||||||
|
public ResponseEntity<NotificationResponse> doNotify(@PathVariable(value = "name") String name) {
|
||||||
|
return pluginList.lookup(name).map(pluginImpl -> ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.body(pluginImpl.doNotification())).orElseGet(() -> ResponseEntity.badRequest().body(NotificationResponse.builder().body("Plugin not found for " + name).build()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.cskefu.serving.api.dto;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
public class Sample {
|
||||||
|
String name;
|
||||||
|
Long id;
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.cskefu.serving.api.service;
|
||||||
|
|
||||||
|
import com.cskefu.mod.plugin.IPlugin;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class PluginList {
|
||||||
|
private Map<String, IPlugin> plugins = new HashMap<>();
|
||||||
|
|
||||||
|
public Set<String> registered() {
|
||||||
|
return plugins.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<IPlugin> lookup(String name) {
|
||||||
|
return Optional.ofNullable(plugins.get(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register(String name, IPlugin service) {
|
||||||
|
plugins.put(name, service);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unregister(String name) {
|
||||||
|
plugins.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,130 @@
|
|||||||
|
package com.cskefu.serving.api.service;
|
||||||
|
|
||||||
|
import com.cskefu.serving.api.config.PluginsConfigurer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import javax.annotation.PreDestroy;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.felix.main.AutoProcessor;
|
||||||
|
import org.osgi.framework.Bundle;
|
||||||
|
import org.osgi.framework.BundleException;
|
||||||
|
import org.osgi.framework.launch.Framework;
|
||||||
|
import org.osgi.framework.launch.FrameworkFactory;
|
||||||
|
import org.osgi.framework.wiring.BundleRevision;
|
||||||
|
import org.osgi.resource.Capability;
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
|
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||||
|
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||||
|
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
|
||||||
|
import org.springframework.core.type.classreading.MetadataReader;
|
||||||
|
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.util.SystemPropertyUtils;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class PluginService {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Framework framework;
|
||||||
|
private final SpringAwareBundleListener springAwareBundleListener;
|
||||||
|
private final PluginsConfigurer pluginsConfigurer;
|
||||||
|
|
||||||
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
|
public void startFramework() throws BundleException {
|
||||||
|
log.info("Starting Plugin OSGi service...");
|
||||||
|
// Get Felix properties from Spring Boot config
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Create an instance and initialise the framework.
|
||||||
|
FrameworkFactory factory = new org.apache.felix.framework.FrameworkFactory();
|
||||||
|
Map<String, String> felixProperties = new HashMap<>(pluginsConfigurer.getConfig());
|
||||||
|
felixProperties.put("org.osgi.framework.system.packages.extra",
|
||||||
|
findPackageNamesStartingWith(
|
||||||
|
Optional.ofNullable(felixProperties.get("auto.exported.packages"))
|
||||||
|
.map(s -> s.split(","))
|
||||||
|
.map(Arrays::asList)
|
||||||
|
.orElse(List.of())
|
||||||
|
) + "," + felixProperties.get("org.osgi.framework.system.packages.extra"));
|
||||||
|
framework = factory.newFramework(felixProperties);
|
||||||
|
framework.init();
|
||||||
|
|
||||||
|
// Use the system bundle context to process the auto-deploy
|
||||||
|
// and auto-install/auto-start properties.
|
||||||
|
AutoProcessor.process(pluginsConfigurer.getConfig(), framework.getBundleContext());
|
||||||
|
|
||||||
|
// Log Bundle Activations
|
||||||
|
framework.getBundleContext().addBundleListener(springAwareBundleListener);
|
||||||
|
|
||||||
|
// Start the framework.
|
||||||
|
framework.start();
|
||||||
|
|
||||||
|
Bundle b = framework.getBundleContext().getBundle(0);
|
||||||
|
BundleRevision br = b.adapt(BundleRevision.class);
|
||||||
|
List<Capability> caps = br.getCapabilities("osgi.ee");
|
||||||
|
log.debug("OSGi capabilities: " + caps);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("Error initializing the OSGi framework. As it is mandatory the system will be halted", ex);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreDestroy
|
||||||
|
public void destroy() throws BundleException, InterruptedException {
|
||||||
|
log.info("Stopping plugins OSGi service...");
|
||||||
|
framework.stop();
|
||||||
|
framework.waitForStop(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Felix provides an isolated classloader to each bundle. Bundles need to declare what packages they need in there manifest.
|
||||||
|
* If a Bundle needs e.g. something from org.slf4j it either needs to have it as classes itself or another bundle must
|
||||||
|
* export this packages. java.* packages will be provided by the framework from the classloader it was created with.
|
||||||
|
* We can modify this, by giving the framework a list of additional packages, that are provided by the spring boot
|
||||||
|
* container (should include e.g.slf4j)
|
||||||
|
*/
|
||||||
|
protected String findPackageNamesStartingWith(List<String> packages) {
|
||||||
|
return packages.stream().map(this::getPackages)
|
||||||
|
.flatMap(Set::stream)
|
||||||
|
.collect(Collectors.joining(","));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Set<String> getPackages(String basePackage) {
|
||||||
|
try {
|
||||||
|
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
|
||||||
|
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
|
||||||
|
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + File.separator + "**/*.class";
|
||||||
|
return Arrays.stream(resourcePatternResolver.getResources(packageSearchPath)).map(resource -> {
|
||||||
|
try {
|
||||||
|
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
|
||||||
|
Class<?> aClass = Class.forName(metadataReader.getClassMetadata().getClassName());
|
||||||
|
return aClass.getPackage().getName();
|
||||||
|
} catch (ClassNotFoundException | IOException e) {
|
||||||
|
log.error("Error looking for provided package", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}).collect(Collectors.toSet());
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error looking for provided resource", e);
|
||||||
|
return Set.of();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveBasePackage(String basePackage) {
|
||||||
|
return ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(basePackage));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package com.cskefu.serving.api.service;
|
||||||
|
|
||||||
|
import com.cskefu.mod.plugin.IPlugin;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.osgi.framework.Bundle;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
import org.osgi.framework.BundleEvent;
|
||||||
|
import org.osgi.framework.BundleListener;
|
||||||
|
import org.osgi.framework.InvalidSyntaxException;
|
||||||
|
import org.osgi.framework.ServiceReference;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class SpringAwareBundleListener implements BundleListener {
|
||||||
|
|
||||||
|
private final PluginList pluginList;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bundleChanged(BundleEvent bundleEvent) {
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
String.format(
|
||||||
|
"Bundle %s:%s changed state to %s - Type: %s",
|
||||||
|
bundleEvent.getBundle().getSymbolicName(),
|
||||||
|
bundleEvent.getBundle().getVersion(),
|
||||||
|
getBundleStateAsString(bundleEvent.getBundle().getState()),
|
||||||
|
getBundleStateAsString(bundleEvent.getType())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (bundleEvent.getBundle().getState() == Bundle.ACTIVE) {
|
||||||
|
try {
|
||||||
|
Bundle bundle = bundleEvent.getBundle();
|
||||||
|
BundleContext bundleContext = bundle.getBundleContext();
|
||||||
|
ServiceReference<?>[] services = bundleContext.getAllServiceReferences(IPlugin.class.getName(), null);
|
||||||
|
if (services != null && services.length > 0)
|
||||||
|
Arrays.asList(services)
|
||||||
|
.forEach(s -> pluginList.register(s.getBundle().getSymbolicName(), (IPlugin) bundleContext.getService(s)));
|
||||||
|
|
||||||
|
} catch (InvalidSyntaxException e) {
|
||||||
|
log.warn("Problem reading services from BundleContext");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (bundleEvent.getBundle().getState() == Bundle.UNINSTALLED) {
|
||||||
|
pluginList.unregister(bundleEvent.getBundle().getSymbolicName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getBundleStateAsString(int state) {
|
||||||
|
return switch (state) {
|
||||||
|
case Bundle.ACTIVE -> "Active";
|
||||||
|
case Bundle.INSTALLED -> "Installed";
|
||||||
|
case Bundle.RESOLVED -> "Resolved";
|
||||||
|
case Bundle.STARTING -> "Starting";
|
||||||
|
case Bundle.STOPPING -> "Stopping";
|
||||||
|
case Bundle.UNINSTALLED -> "Uninstalled";
|
||||||
|
default -> "Unknown";
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
22
server/serving-api/src/main/resources/application.properties
Normal file
22
server/serving-api/src/main/resources/application.properties
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# --------------------------------
|
||||||
|
# Felix Framework settings
|
||||||
|
# https://felix.apache.org/documentation/subprojects/apache-felix-framework/apache-felix-framework-configuration-properties.html
|
||||||
|
# --------------------------------
|
||||||
|
# If true will configure a shutdown hook to shutdown the framework on JVM shutdown
|
||||||
|
plugins.config.felix.shutdown.hook=true
|
||||||
|
# Where is the felix bundle cache dir
|
||||||
|
plugins.config.org.osgi.framework.storage=./serving-api/target/felix-cache
|
||||||
|
# When to clean the felix-cache directory
|
||||||
|
plugins.config.org.osgi.framework.storage.clean=onFirstInit
|
||||||
|
# Directory to look for bundles to deploy once when framework first loads
|
||||||
|
plugins.config.felix.auto.deploy.dir=./serving-api/target/internal-bundles
|
||||||
|
# Actions to perform on discovered bundles
|
||||||
|
plugins.config.felix.auto.deploy.action=install,start,update,uninstall
|
||||||
|
plugins.config.felix.startlevel.bundle=1
|
||||||
|
plugins.config.felix.fileinstall.dir=../compose/plugins
|
||||||
|
plugins.config.felix.fileinstall.log.level=2
|
||||||
|
plugins.config.felix.fileinstall.bundles.updateWithListeners=true
|
||||||
|
plugins.config.org.osgi.framework.system.packages.extra=org.osgi.framework,org.xml.sax,org.xml.sax.helpers,javax.xml.parsers,javax.naming
|
||||||
|
plugins.config.auto.exported.packages=com.cskefu.mod.plugin,org.slf4j
|
||||||
|
|
||||||
|
server.servlet.context-path=/api
|
@ -0,0 +1,53 @@
|
|||||||
|
package com.cskefu.serving.api.controllers;
|
||||||
|
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@AutoConfigureMockMvc
|
||||||
|
class SampleControllerTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SampleController cut;
|
||||||
|
@Autowired
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("When the SpringBoot application is initialized, then the controller is created")
|
||||||
|
void testControllerInit() {
|
||||||
|
assertNotNull(cut);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("When samples list api is called, then the list of installed bundles is returned")
|
||||||
|
void samplesList() throws Exception {
|
||||||
|
mockMvc.perform(get("/v1/samples")).andDo(print()).andExpect(status().isOk())
|
||||||
|
.andExpect(content().string(containsString("[]")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("When missing sample bundle is called, then the httpStatus is 400 with a message explaining the problem")
|
||||||
|
void missingPluginCall() throws Exception {
|
||||||
|
mockMvc.perform(get("/v1/samples/missing-bundle")).andDo(print()).andExpect(status().isBadRequest())
|
||||||
|
.andExpect(content().string(containsString("Plugin not found for missing-bundle")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("When missing sample bundle notification is called, then the httpStatus is 400 with a message explaining the problem")
|
||||||
|
void missingPluginNotificationCall() throws Exception {
|
||||||
|
mockMvc.perform(get("/v1/samples/missing-bundle/notification")).andDo(print()).andExpect(status().isBadRequest())
|
||||||
|
.andExpect(content().string(containsString("Plugin not found for missing-bundle")));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.cskefu.serving.api.service;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import com.cskefu.serving.api.config.PluginsConfigurer;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
@SpringBootTest(classes = PluginService.class)
|
||||||
|
class PluginServiceTests {
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private SpringAwareBundleListener springAwareBundleListener;
|
||||||
|
@MockBean
|
||||||
|
private PluginsConfigurer pluginsConfigurer;
|
||||||
|
@Autowired
|
||||||
|
private PluginService cut;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName(
|
||||||
|
"when BundleService is initialized, then the Felix framework is created using the Spring ApplicationReadyEvent")
|
||||||
|
void testFelixFrameworkCreation() {
|
||||||
|
assertAll(
|
||||||
|
() -> assertNotNull(cut),
|
||||||
|
() -> assertNotNull(cut.getFramework())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("When find package is called with a specific package, then subpackages are provided too")
|
||||||
|
void testExtraPackageConfiguration() {
|
||||||
|
String result = cut.findPackageNamesStartingWith(List.of("com.mornati.sample"));
|
||||||
|
assertAll(
|
||||||
|
() -> assertNotNull(result),
|
||||||
|
() -> assertTrue(result.contains("com.mornati.sample.service")),
|
||||||
|
() -> assertTrue(result.contains("com.mornati.sample.commons.plugins.dto"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
package com.cskefu.serving.api.service;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.atLeast;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import com.cskefu.mod.plugin.IPlugin;
|
||||||
|
import com.cskefu.mod.plugin.dto.ActionResponse;
|
||||||
|
import com.cskefu.mod.plugin.dto.NotificationResponse;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import net.jqwik.api.ForAll;
|
||||||
|
import net.jqwik.api.Property;
|
||||||
|
import net.jqwik.api.lifecycle.BeforeProperty;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.osgi.framework.Bundle;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
import org.osgi.framework.BundleEvent;
|
||||||
|
import org.osgi.framework.InvalidSyntaxException;
|
||||||
|
import org.osgi.framework.ServiceReference;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class SpringAwareBundleListenerTest {
|
||||||
|
|
||||||
|
private SpringAwareBundleListener cut;
|
||||||
|
private final PluginList pluginList = Mockito.mock(PluginList.class);
|
||||||
|
private final BundleEvent bundleEvent = Mockito.mock(BundleEvent.class);
|
||||||
|
private final Bundle bundle = Mockito.mock(Bundle.class);
|
||||||
|
private final BundleContext bundleContext = Mockito.mock(BundleContext.class);
|
||||||
|
private final ServiceReference serviceReference = Mockito.mock(ServiceReference.class);
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeProperty
|
||||||
|
void setUp() {
|
||||||
|
cut = new SpringAwareBundleListener(pluginList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Property
|
||||||
|
void testActivateBundleEventInvalidPlugin(@ForAll String bundleName) {
|
||||||
|
when(bundleEvent.getBundle()).thenReturn(bundle);
|
||||||
|
when(bundle.getBundleContext()).thenReturn(bundleContext);
|
||||||
|
when(bundle.getState()).thenReturn(Bundle.ACTIVE);
|
||||||
|
when(bundle.getSymbolicName()).thenReturn(bundleName);
|
||||||
|
cut.bundleChanged(bundleEvent);
|
||||||
|
verify(pluginList, never()).register(anyString(), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Property
|
||||||
|
void testActivateBundleEventRegisterService(@ForAll String bundleName) throws InvalidSyntaxException {
|
||||||
|
MockPlugin plugin = new MockPlugin();
|
||||||
|
when(bundleEvent.getBundle()).thenReturn(bundle);
|
||||||
|
when(bundle.getBundleContext()).thenReturn(bundleContext);
|
||||||
|
when(bundle.getState()).thenReturn(Bundle.ACTIVE);
|
||||||
|
when(bundle.getSymbolicName()).thenReturn(bundleName);
|
||||||
|
when(bundleContext.getAllServiceReferences(IPlugin.class.getName(), null)).thenReturn(List.of(serviceReference).toArray(new ServiceReference[0]));
|
||||||
|
when(bundleContext.getService(serviceReference)).thenReturn(plugin);
|
||||||
|
when(serviceReference.getBundle()).thenReturn(bundle);
|
||||||
|
|
||||||
|
cut.bundleChanged(bundleEvent);
|
||||||
|
|
||||||
|
verify(pluginList).register(bundleName, plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Property
|
||||||
|
void testUnregisterService(@ForAll String bundleName) throws InvalidSyntaxException {
|
||||||
|
MockPlugin plugin = new MockPlugin();
|
||||||
|
when(bundleEvent.getBundle()).thenReturn(bundle);
|
||||||
|
when(bundle.getBundleContext()).thenReturn(bundleContext);
|
||||||
|
when(bundle.getState()).thenReturn(Bundle.ACTIVE);
|
||||||
|
when(bundle.getSymbolicName()).thenReturn(bundleName);
|
||||||
|
when(bundleContext.getAllServiceReferences(IPlugin.class.getName(), null)).thenReturn(List.of(serviceReference).toArray(new ServiceReference[0]));
|
||||||
|
when(bundleContext.getService(serviceReference)).thenReturn(plugin);
|
||||||
|
when(serviceReference.getBundle()).thenReturn(bundle);
|
||||||
|
|
||||||
|
cut.bundleChanged(bundleEvent);
|
||||||
|
when(bundle.getState()).thenReturn(Bundle.UNINSTALLED);
|
||||||
|
cut.bundleChanged(bundleEvent);
|
||||||
|
verify(pluginList, atLeast(1)).unregister(bundleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MockPlugin implements IPlugin {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResponse doAction() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NotificationResponse doNotification() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,135 +0,0 @@
|
|||||||
<?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">
|
|
||||||
<groupId>com.cskefu</groupId>
|
|
||||||
<artifactId>cskefu-auth</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<name>cskefu-auth</name>
|
|
||||||
<url>https://www.cskefu.com/</url>
|
|
||||||
<properties>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
<maven.compiler.source>11</maven.compiler.source>
|
|
||||||
<maven.compiler.target>11</maven.compiler.target>
|
|
||||||
<java.version>11</java.version>
|
|
||||||
<spring-boot.version>2.7.4</spring-boot.version>
|
|
||||||
<spring-cloud.version>2021.0.4</spring-cloud.version>
|
|
||||||
<mybatis-spring.version>2.2.2</mybatis-spring.version>
|
|
||||||
<lombok.version>1.18.6</lombok.version>
|
|
||||||
<mysql-connector.version>8.0.30</mysql-connector.version>
|
|
||||||
<redisson-spring.version>3.17.7</redisson-spring.version>
|
|
||||||
<swagger.version>3.0.0</swagger.version>
|
|
||||||
<jsonwebtoken.version>0.11.5</jsonwebtoken.version>
|
|
||||||
<kaptcha.version>0.0.9</kaptcha.version>
|
|
||||||
</properties>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.cskefu</groupId>
|
|
||||||
<artifactId>cskefu-common</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-security</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<!-- <dependency>-->
|
|
||||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
|
||||||
<!-- <artifactId>spring-boot-starter-data-redis</artifactId>-->
|
|
||||||
<!-- </dependency>-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-validation</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<!--
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba.csp</groupId>
|
|
||||||
<artifactId>sentinel-datasource-nacos</artifactId>
|
|
||||||
<version>1.5.2</version>
|
|
||||||
</dependency>
|
|
||||||
-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.axet</groupId>
|
|
||||||
<artifactId>kaptcha</artifactId>
|
|
||||||
<version>${kaptcha.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.jsonwebtoken</groupId>
|
|
||||||
<artifactId>jjwt-api</artifactId>
|
|
||||||
<version>${jsonwebtoken.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.jsonwebtoken</groupId>
|
|
||||||
<artifactId>jjwt-impl</artifactId>
|
|
||||||
<version>${jsonwebtoken.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.jsonwebtoken</groupId>
|
|
||||||
<artifactId>jjwt-jackson</artifactId>
|
|
||||||
<version>${jsonwebtoken.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- <dependency>-->
|
|
||||||
<!-- <groupId>org.redisson</groupId>-->
|
|
||||||
<!-- <artifactId>redisson-spring-boot-starter</artifactId>-->
|
|
||||||
<!-- <version>${redisson-spring.version}</version>-->
|
|
||||||
<!-- </dependency>-->
|
|
||||||
<!-- <dependency>-->
|
|
||||||
<!-- <groupId>org.mybatis.spring.boot</groupId>-->
|
|
||||||
<!-- <artifactId>mybatis-spring-boot-starter</artifactId>-->
|
|
||||||
<!-- <version>${mybatis-spring.version}</version>-->
|
|
||||||
<!-- </dependency>-->
|
|
||||||
<!-- <dependency>-->
|
|
||||||
<!-- <groupId>mysql</groupId>-->
|
|
||||||
<!-- <artifactId>mysql-connector-java</artifactId>-->
|
|
||||||
<!-- <version>${mysql-connector.version}</version>-->
|
|
||||||
<!-- <scope>runtime</scope>-->
|
|
||||||
<!-- </dependency>-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.springfox</groupId>
|
|
||||||
<artifactId>springfox-swagger2</artifactId>
|
|
||||||
<version>${swagger.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.springfox</groupId>
|
|
||||||
<artifactId>springfox-swagger-ui</artifactId>
|
|
||||||
<version>${swagger.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<dependencyManagement>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-dependencies</artifactId>
|
|
||||||
<version>${spring-boot.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-dependencies</artifactId>
|
|
||||||
<version>${spring-cloud.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
|
||||||
<version>${spring-cloud.version}.0</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</dependencyManagement>
|
|
||||||
</project>
|
|
@ -1,11 +0,0 @@
|
|||||||
package com.cskefu.auth;
|
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
|
||||||
public class CskefuAuthApplication {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
SpringApplication.run(CskefuAuthApplication.class, args);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
spring:
|
|
||||||
datasource:
|
|
||||||
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8
|
|
||||||
username: root
|
|
||||||
password: 123456
|
|
||||||
|
|
||||||
cloud:
|
|
||||||
# sentinel配置
|
|
||||||
sentinel:
|
|
||||||
eager: true
|
|
||||||
transport:
|
|
||||||
dashboard:
|
|
||||||
127.0.0.1:8848
|
|
||||||
port: 8719
|
|
||||||
heartbeat-interval-ms: 5000
|
|
||||||
nacos:
|
|
||||||
# 注册中心配置
|
|
||||||
discovery:
|
|
||||||
server-addr: localhost:8848
|
|
||||||
namespace: xxxxxxx
|
|
||||||
# # 配置中心
|
|
||||||
# config:
|
|
||||||
# server-addr: 127.0.0.1:8848
|
|
||||||
# file-extension: yaml
|
|
||||||
# namespace: jm-live-dev
|
|
||||||
# shared-configs[0]:
|
|
||||||
# group: sentinel
|
|
||||||
# data-id: sentinel-shared.yaml
|
|
||||||
# refresh: true
|
|
@ -1,35 +0,0 @@
|
|||||||
server:
|
|
||||||
port: 8000
|
|
||||||
spring:
|
|
||||||
application:
|
|
||||||
name: cskefu-auth
|
|
||||||
profiles:
|
|
||||||
active: dev
|
|
||||||
datasource:
|
|
||||||
type: com.zaxxer.hikari.HikariDataSource
|
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
|
||||||
hikari:
|
|
||||||
connection-timeout: 5000
|
|
||||||
minimum-idle: 5
|
|
||||||
maximum-pool-size: 20
|
|
||||||
auto-commit: false
|
|
||||||
idle-timeout: 600000
|
|
||||||
pool-name: DataSourceHikariCP
|
|
||||||
max-lifetime: 1800000
|
|
||||||
connection-test-query: select 1
|
|
||||||
redis:
|
|
||||||
host: 127.0.0.1
|
|
||||||
port: 6379
|
|
||||||
timeout: 5000
|
|
||||||
database: 0
|
|
||||||
lettuce:
|
|
||||||
pool:
|
|
||||||
max-active: 8
|
|
||||||
max-idle: 8
|
|
||||||
min-idle: 0
|
|
||||||
max-wait: -1ms
|
|
||||||
|
|
||||||
cskefu:
|
|
||||||
cskefu:
|
|
||||||
private-key: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC8TSxdMp76dZS2L8DpvJOgHNJmeI8PM30CFSeVMCHV5dEjtixipsMsSQu0ariAtVfA5M/ma1wcqEpsDO9nVQRsmsJCKMIWOcR6yBQU9f0T7Hkmil4Ckf61C1R7wLrynOjCeUCneQ7R0+dg9K25CymclPnK4ym2GInmuUjdbyQQcX4QBuIbmuY10MG8nW9ovhFML85KoBk5yxV4zVwLGP4TFJVnBmiNO3XSKL2XsX7wFFO93O8jmAnzgpWj8khsZAYG4nijIz2BciS9uQFa/lUX6yD50ykjNklbhCBIMGaQ6rr1WjnwLHDZU9sLvcYMboKPJHWz1FttvxuKSLYbf7j/AgMBAAECggEAEH1rPSrwF47kdW/vibu+uDuat7Tz3w9RpM6lc/Mn6ctoA6PLqN5hvFpJPbhHoAqn1kSZ0EJNA4imIjNsluf8rMyAs1QbN+CnMpMC7zL7jrS1IO+ze+LwVnpyufbbm3nfCE85OKSC7IbAfhHvUYOHIvQI5Zn76FTamFHxh5klpCrY1h8gcVWdRxiK0Q8AQP7KD0QnkzgROhkRmdI01639VyTCTc6Rtv5puU6J6idJwTd3JAiJXZ2qcoAwhnkSHnVnP5ktFxl66eHGJKeol6bGcJIFQRGLVmh78x6MXoqkJ2M7DRntL38TLKT5KCYViGxUpO0gED/HQBhDALyNevJZQQKBgQDr+pZDtRIQ6mMZMswKTo2+zIFEUFES2sR/bunEW5snPR3krKdgzJoEg7WERkMviSlvW6K7a6VeJ9KKO/iE07lcRkN2NQZUkBDsrNRgoOwB17hHJqrMyZ1It+hZmPQTkeyJu/BCxDkIMwbQYXxIe8J/dVYjHJVXZgzPqEXKYqeViwKBgQDMRwr7ceW+9c/GzHd7p6849s3+MbT0kzyXDTdeJkQFSDPufYapTCan/MrdJmnIRz8pq2URZrO4kDDxxeWu2Vkekv9cxVFrQVFfvuq+4BFpQvYkRHk9PDzCmgFJD/wLG8gzNTH7UahaNb7m0tPB3D1g5Q6LzZCc1h3s2K6SLS7g3QKBgE41Bof6ArrIc39ubmEcF64caNsTI0t0ZZs2TxNcqNcgUj/vWKmkJYdJf2cPQkUG2Eynug8TZgMGf6iAp6Sd5tjGEKWkfSyZcoJ95QUBUDZsIA60qfak+xOWn9LR9lJmElazirUWAzDMeH2nUWFUYumLIbkRSA1nLOfFhRvGBnRxAoGBAJvDAAjCzGBTpt77QZA0SFOzPVc6J7TmICk9lp5fpzYv3AlaBbhJrKAjDbybccWZLfxkCGjAWwG8UNXKBFzStjWt+LGQc4jJAXd0aCKrUBtnR7BX1epvaBUqwRgo7BK8WGdThI0RssE2gh4XXAhSGysq/XB0inRMf/z9K/+iHECxAoGAFlcIZ4/xXhbObUPU05hZFoj+zN5obaOLefRJn4uqjD9/VSRnI2bBv7vXKoLX6BwFF/PWvg1hzGy3O9TQ4XYPOqNGcBFDOqwxmVVevzXgRInoiRNP3xZXcqswppEbqORGbRoPLQBqLnPx1GKwbo7Fp9O5ywARVZtf4STt3pRK8PY=
|
|
||||||
public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvE0sXTKe+nWUti/A6byToBzSZniPDzN9AhUnlTAh1eXRI7YsYqbDLEkLtGq4gLVXwOTP5mtcHKhKbAzvZ1UEbJrCQijCFjnEesgUFPX9E+x5JopeApH+tQtUe8C68pzownlAp3kO0dPnYPStuQspnJT5yuMpthiJ5rlI3W8kEHF+EAbiG5rmNdDBvJ1vaL4RTC/OSqAZOcsVeM1cCxj+ExSVZwZojTt10ii9l7F+8BRTvdzvI5gJ84KVo/JIbGQGBuJ4oyM9gXIkvbkBWv5VF+sg+dMpIzZJW4QgSDBmkOq69Vo58Cxw2VPbC73GDG6CjyR1s9Rbbb8biki2G3+4/wIDAQAB
|
|
@ -1,103 +0,0 @@
|
|||||||
<?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">
|
|
||||||
<groupId>com.cskefu</groupId>
|
|
||||||
<artifactId>cskefu-biz</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<name>cskefu-biz</name>
|
|
||||||
<url>https://www.cskefu.com/</url>
|
|
||||||
<properties>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
<maven.compiler.source>11</maven.compiler.source>
|
|
||||||
<maven.compiler.target>11</maven.compiler.target>
|
|
||||||
<java.version>11</java.version>
|
|
||||||
<spring-boot.version>2.7.4</spring-boot.version>
|
|
||||||
<spring-cloud.version>2021.0.4</spring-cloud.version>
|
|
||||||
<mybatis-spring.version>2.2.2</mybatis-spring.version>
|
|
||||||
<lombok.version>1.18.6</lombok.version>
|
|
||||||
<mysql-connector.version>8.0.30</mysql-connector.version>
|
|
||||||
<redisson-spring.version>3.17.7</redisson-spring.version>
|
|
||||||
<swagger.version>3.0.0</swagger.version>
|
|
||||||
</properties>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.cskefu</groupId>
|
|
||||||
<artifactId>cskefu-common</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-security</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-validation</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
<version>${lombok.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.redisson</groupId>
|
|
||||||
<artifactId>redisson-spring-boot-starter</artifactId>
|
|
||||||
<version>${redisson-spring.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mybatis.spring.boot</groupId>
|
|
||||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
|
||||||
<version>${mybatis-spring.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>mysql</groupId>
|
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
|
||||||
<version>${mysql-connector.version}</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.springfox</groupId>
|
|
||||||
<artifactId>springfox-swagger2</artifactId>
|
|
||||||
<version>${swagger.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.springfox</groupId>
|
|
||||||
<artifactId>springfox-swagger-ui</artifactId>
|
|
||||||
<version>${swagger.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<dependencyManagement>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-dependencies</artifactId>
|
|
||||||
<version>${spring-boot.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-dependencies</artifactId>
|
|
||||||
<version>${spring-cloud.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
|
||||||
<version>${spring-cloud.version}.0</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</dependencyManagement>
|
|
||||||
</project>
|
|
@ -1,11 +0,0 @@
|
|||||||
package com.cskefu.biz;
|
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
|
||||||
public class CskefuBIZApplication {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
SpringApplication.run(CskefuBIZApplication.class, args);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
package com.cskefu.biz.swagger;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import springfox.documentation.builders.ApiInfoBuilder;
|
|
||||||
import springfox.documentation.builders.PathSelectors;
|
|
||||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
|
||||||
import springfox.documentation.service.*;
|
|
||||||
import springfox.documentation.spi.DocumentationType;
|
|
||||||
import springfox.documentation.spi.service.contexts.SecurityContext;
|
|
||||||
import springfox.documentation.spring.web.plugins.Docket;
|
|
||||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableSwagger2
|
|
||||||
public class SwaggerConfiguration {
|
|
||||||
@Bean
|
|
||||||
public Docket createRestApi() {
|
|
||||||
return new Docket(DocumentationType.OAS_30)
|
|
||||||
.apiInfo(apiInfo())
|
|
||||||
.select()
|
|
||||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
|
||||||
.paths(PathSelectors.regex("(?!/error.*).*"))
|
|
||||||
.build()
|
|
||||||
.securityContexts(Arrays.asList(securityContext()))
|
|
||||||
.securitySchemes(Arrays.asList(new ApiKey("token", "token", SecuritySchemeIn.HEADER.name())));
|
|
||||||
}
|
|
||||||
|
|
||||||
private SecurityContext securityContext() {
|
|
||||||
return SecurityContext.builder()
|
|
||||||
.securityReferences(defaultAuth())
|
|
||||||
//.forPaths(PathSelectors.regex("/*.*"))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<SecurityReference> defaultAuth() {
|
|
||||||
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
|
|
||||||
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
|
|
||||||
authorizationScopes[0] = authorizationScope;
|
|
||||||
return Collections.singletonList(new SecurityReference("token", authorizationScopes));
|
|
||||||
}
|
|
||||||
|
|
||||||
private ApiInfo apiInfo() {
|
|
||||||
return new ApiInfoBuilder()
|
|
||||||
.title("cskefu Swagger API")
|
|
||||||
.description("春松客服Swagger API")
|
|
||||||
.contact(new Contact("cskefu", "https://www.cskefu.com/", "dev@lists.cskefu.com"))
|
|
||||||
.license("Apache License Version 2.0")
|
|
||||||
.licenseUrl("http://www.apache.org/licenese/LICENSE-2.0")
|
|
||||||
.version("1.0")
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
spring:
|
|
||||||
datasource:
|
|
||||||
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8
|
|
||||||
username: root
|
|
||||||
password: 123456
|
|
||||||
|
|
||||||
cloud:
|
|
||||||
# sentinel配置
|
|
||||||
sentinel:
|
|
||||||
eager: true
|
|
||||||
transport:
|
|
||||||
dashboard:
|
|
||||||
127.0.0.1:8848
|
|
||||||
port: 8719
|
|
||||||
heartbeat-interval-ms: 5000
|
|
||||||
nacos:
|
|
||||||
# 注册中心配置
|
|
||||||
discovery:
|
|
||||||
server-addr: localhost:8848
|
|
||||||
namespace: xxxxxxx
|
|
||||||
# # 配置中心
|
|
||||||
# config:
|
|
||||||
# server-addr: 127.0.0.1:8848
|
|
||||||
# file-extension: yaml
|
|
||||||
# namespace: jm-live-dev
|
|
||||||
# shared-configs[0]:
|
|
||||||
# group: sentinel
|
|
||||||
# data-id: sentinel-shared.yaml
|
|
||||||
# refresh: true
|
|
@ -1,28 +0,0 @@
|
|||||||
spring:
|
|
||||||
application:
|
|
||||||
name: cskefu-biz
|
|
||||||
profiles:
|
|
||||||
active: dev
|
|
||||||
datasource:
|
|
||||||
type: com.zaxxer.hikari.HikariDataSource
|
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
|
||||||
hikari:
|
|
||||||
connection-timeout: 5000
|
|
||||||
minimum-idle: 5
|
|
||||||
maximum-pool-size: 20
|
|
||||||
auto-commit: false
|
|
||||||
idle-timeout: 600000
|
|
||||||
pool-name: DataSourceHikariCP
|
|
||||||
max-lifetime: 1800000
|
|
||||||
connection-test-query: select 1
|
|
||||||
redis:
|
|
||||||
host: 127.0.0.1
|
|
||||||
port: 6379
|
|
||||||
timeout: 5000
|
|
||||||
database: 0
|
|
||||||
lettuce:
|
|
||||||
pool:
|
|
||||||
max-active: 8
|
|
||||||
max-idle: 8
|
|
||||||
min-idle: 0
|
|
||||||
max-wait: -1ms
|
|
@ -1,68 +0,0 @@
|
|||||||
<?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">
|
|
||||||
<groupId>com.cskefu</groupId>
|
|
||||||
<artifactId>cskefu-common</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<name>cskefu-common</name>
|
|
||||||
<url>https://www.cskefu.com/</url>
|
|
||||||
<properties>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
<maven.compiler.source>11</maven.compiler.source>
|
|
||||||
<maven.compiler.target>11</maven.compiler.target>
|
|
||||||
<java.version>11</java.version>
|
|
||||||
<spring-boot.version>2.7.4</spring-boot.version>
|
|
||||||
<spring-cloud.version>2021.0.4</spring-cloud.version>
|
|
||||||
<mybatis-spring.version>2.2.2</mybatis-spring.version>
|
|
||||||
<lombok.version>1.18.6</lombok.version>
|
|
||||||
<mysql-connector.version>8.0.30</mysql-connector.version>
|
|
||||||
<redisson-spring.version>3.17.7</redisson-spring.version>
|
|
||||||
<swagger.version>3.0.0</swagger.version>
|
|
||||||
<jackson.version>2.13.4</jackson.version>
|
|
||||||
</properties>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
|
||||||
<artifactId>jackson-annotations</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
|
||||||
<artifactId>jackson-core</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
|
||||||
<artifactId>jackson-databind</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<dependencyManagement>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-dependencies</artifactId>
|
|
||||||
<version>${spring-boot.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-dependencies</artifactId>
|
|
||||||
<version>${spring-cloud.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
|
||||||
<version>${spring-cloud.version}.0</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</dependencyManagement>
|
|
||||||
</project>
|
|
@ -1,22 +0,0 @@
|
|||||||
package com.cskefu.common;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
|
||||||
public class BaseEntity<T> implements Serializable {
|
|
||||||
private static final long serialVersionUID = -6751846719593132836L;
|
|
||||||
private T id;
|
|
||||||
private Date createTime;
|
|
||||||
private Date updateTime;
|
|
||||||
private String creator;
|
|
||||||
private String updator;
|
|
||||||
private Boolean deleted;
|
|
||||||
private Integer version;
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
package com.cskefu.common;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public class Result<T> {
|
|
||||||
private final boolean success;
|
|
||||||
private final int code;
|
|
||||||
private final T data;
|
|
||||||
private final String message;
|
|
||||||
|
|
||||||
Result(boolean success, int code, T data, String message) {
|
|
||||||
this.success = success;
|
|
||||||
this.code = code;
|
|
||||||
this.data = data;
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> ResultBuilder<T> builder() {
|
|
||||||
return new ResultBuilder<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> Result<T> success() {
|
|
||||||
return Result.<T>builder().code(0).success(true).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> Result<T> success(int code, T data) {
|
|
||||||
return Result.<T>builder().code(code).success(true).data(data).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> Result<T> error(int code, String i18nMessage) {
|
|
||||||
return Result.<T>builder().code(code).success(false).message(i18nMessage).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Result(success=" + this.success + ", code=" + this.code + ", data=" + this.data + ", message=" + this.message + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ResultBuilder<T> {
|
|
||||||
private boolean success;
|
|
||||||
private int code;
|
|
||||||
private T data;
|
|
||||||
private String message;
|
|
||||||
|
|
||||||
ResultBuilder() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResultBuilder<T> success(boolean success) {
|
|
||||||
this.success = success;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResultBuilder<T> code(int code) {
|
|
||||||
this.code = code;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResultBuilder<T> data(T data) {
|
|
||||||
this.data = data;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResultBuilder<T> message(String message) {
|
|
||||||
this.message = message;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Result<T> build() {
|
|
||||||
return new Result(this.success, this.code, this.data, this.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.getClass().getName() + "(success=" + this.success + ", code=" + this.code + ", data=" + this.data + ", message=" + this.message + ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
<?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">
|
|
||||||
<groupId>com.cskefu</groupId>
|
|
||||||
<artifactId>cskefu-conversation</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<name>cskefu-conversation</name>
|
|
||||||
<url>https://www.cskefu.com/</url>
|
|
||||||
<properties>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
<maven.compiler.source>11</maven.compiler.source>
|
|
||||||
<maven.compiler.target>11</maven.compiler.target>
|
|
||||||
<java.version>11</java.version>
|
|
||||||
<spring-boot.version>2.7.4</spring-boot.version>
|
|
||||||
<spring-cloud.version>2021.0.4</spring-cloud.version>
|
|
||||||
<mybatis-spring.version>2.2.2</mybatis-spring.version>
|
|
||||||
<lombok.version>1.18.6</lombok.version>
|
|
||||||
<mysql-connector.version>8.0.30</mysql-connector.version>
|
|
||||||
<redisson-spring.version>3.17.7</redisson-spring.version>
|
|
||||||
<swagger.version>3.0.0</swagger.version>
|
|
||||||
</properties>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.cskefu</groupId>
|
|
||||||
<artifactId>cskefu-common</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-security</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-validation</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.redisson</groupId>
|
|
||||||
<artifactId>redisson-spring-boot-starter</artifactId>
|
|
||||||
<version>${redisson-spring.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mybatis.spring.boot</groupId>
|
|
||||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
|
||||||
<version>${mybatis-spring.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>mysql</groupId>
|
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
|
||||||
<version>${mysql-connector.version}</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.springfox</groupId>
|
|
||||||
<artifactId>springfox-swagger2</artifactId>
|
|
||||||
<version>${swagger.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.springfox</groupId>
|
|
||||||
<artifactId>springfox-swagger-ui</artifactId>
|
|
||||||
<version>${swagger.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<dependencyManagement>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-dependencies</artifactId>
|
|
||||||
<version>${spring-boot.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-dependencies</artifactId>
|
|
||||||
<version>${spring-cloud.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
|
||||||
<version>${spring-cloud.version}.0</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</dependencyManagement>
|
|
||||||
</project>
|
|
@ -1,11 +0,0 @@
|
|||||||
package com.cskefu.io;
|
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
|
||||||
public class CskefuConversationApplication {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
SpringApplication.run(CskefuSessionApplication.class, args);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
package com.cskefu.io.swagger;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import springfox.documentation.builders.ApiInfoBuilder;
|
|
||||||
import springfox.documentation.builders.PathSelectors;
|
|
||||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
|
||||||
import springfox.documentation.service.*;
|
|
||||||
import springfox.documentation.spi.DocumentationType;
|
|
||||||
import springfox.documentation.spi.service.contexts.SecurityContext;
|
|
||||||
import springfox.documentation.spring.web.plugins.Docket;
|
|
||||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableSwagger2
|
|
||||||
public class SwaggerConfiguration {
|
|
||||||
@Bean
|
|
||||||
public Docket createRestApi() {
|
|
||||||
return new Docket(DocumentationType.OAS_30)
|
|
||||||
.apiInfo(apiInfo())
|
|
||||||
.select()
|
|
||||||
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
|
||||||
.paths(PathSelectors.regex("(?!/error.*).*"))
|
|
||||||
.build()
|
|
||||||
.securityContexts(Arrays.asList(securityContext()))
|
|
||||||
.securitySchemes(Arrays.asList(new ApiKey("token", "token", SecuritySchemeIn.HEADER.name())));
|
|
||||||
}
|
|
||||||
|
|
||||||
private SecurityContext securityContext() {
|
|
||||||
return SecurityContext.builder()
|
|
||||||
.securityReferences(defaultAuth())
|
|
||||||
//.forPaths(PathSelectors.regex("/*.*"))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<SecurityReference> defaultAuth() {
|
|
||||||
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
|
|
||||||
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
|
|
||||||
authorizationScopes[0] = authorizationScope;
|
|
||||||
return Collections.singletonList(new SecurityReference("token", authorizationScopes));
|
|
||||||
}
|
|
||||||
|
|
||||||
private ApiInfo apiInfo() {
|
|
||||||
return new ApiInfoBuilder()
|
|
||||||
.title("cskefu Swagger API")
|
|
||||||
.description("春松客服Swagger API")
|
|
||||||
.contact(new Contact("cskefu", "https://www.cskefu.com/", "dev@lists.cskefu.com"))
|
|
||||||
.license("Apache License Version 2.0")
|
|
||||||
.licenseUrl("http://www.apache.org/licenese/LICENSE-2.0")
|
|
||||||
.version("1.0")
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
spring:
|
|
||||||
datasource:
|
|
||||||
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8
|
|
||||||
username: root
|
|
||||||
password: 123456
|
|
||||||
|
|
||||||
cloud:
|
|
||||||
# sentinel配置
|
|
||||||
sentinel:
|
|
||||||
eager: true
|
|
||||||
transport:
|
|
||||||
dashboard:
|
|
||||||
127.0.0.1:8848
|
|
||||||
port: 8719
|
|
||||||
heartbeat-interval-ms: 5000
|
|
||||||
nacos:
|
|
||||||
# 注册中心配置
|
|
||||||
discovery:
|
|
||||||
server-addr: localhost:8848
|
|
||||||
namespace: xxxxxxx
|
|
||||||
# # 配置中心
|
|
||||||
# config:
|
|
||||||
# server-addr: 127.0.0.1:8848
|
|
||||||
# file-extension: yaml
|
|
||||||
# namespace: jm-live-dev
|
|
||||||
# shared-configs[0]:
|
|
||||||
# group: sentinel
|
|
||||||
# data-id: sentinel-shared.yaml
|
|
||||||
# refresh: true
|
|
@ -1,28 +0,0 @@
|
|||||||
spring:
|
|
||||||
application:
|
|
||||||
name: cskefu-conversation
|
|
||||||
profiles:
|
|
||||||
active: dev
|
|
||||||
datasource:
|
|
||||||
type: com.zaxxer.hikari.HikariDataSource
|
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
|
||||||
hikari:
|
|
||||||
connection-timeout: 5000
|
|
||||||
minimum-idle: 5
|
|
||||||
maximum-pool-size: 20
|
|
||||||
auto-commit: false
|
|
||||||
idle-timeout: 600000
|
|
||||||
pool-name: DataSourceHikariCP
|
|
||||||
max-lifetime: 1800000
|
|
||||||
connection-test-query: select 1
|
|
||||||
redis:
|
|
||||||
host: 127.0.0.1
|
|
||||||
port: 6379
|
|
||||||
timeout: 5000
|
|
||||||
database: 0
|
|
||||||
lettuce:
|
|
||||||
pool:
|
|
||||||
max-active: 8
|
|
||||||
max-idle: 8
|
|
||||||
min-idle: 0
|
|
||||||
max-wait: -1ms
|
|
@ -1,60 +0,0 @@
|
|||||||
<?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">
|
|
||||||
<groupId>com.cskefu</groupId>
|
|
||||||
<artifactId>cskefu-gateway</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<name>cskefu-gateway</name>
|
|
||||||
<url>https://www.cskefu.com/</url>
|
|
||||||
<properties>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
<maven.compiler.source>11</maven.compiler.source>
|
|
||||||
<maven.compiler.target>11</maven.compiler.target>
|
|
||||||
<java.version>11</java.version>
|
|
||||||
<spring-boot.version>2.7.4</spring-boot.version>
|
|
||||||
<spring-cloud.version>2021.0.4</spring-cloud.version>
|
|
||||||
<mybatis-spring.version>2.2.2</mybatis-spring.version>
|
|
||||||
<lombok.version>1.18.6</lombok.version>
|
|
||||||
<mysql-connector.version>8.0.30</mysql-connector.version>
|
|
||||||
<redisson-spring.version>3.17.7</redisson-spring.version>
|
|
||||||
<swagger.version>3.0.0</swagger.version>
|
|
||||||
</properties>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.cskefu</groupId>
|
|
||||||
<artifactId>cskefu-common</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-starter-gateway</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<dependencyManagement>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-dependencies</artifactId>
|
|
||||||
<version>${spring-boot.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-dependencies</artifactId>
|
|
||||||
<version>${spring-cloud.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba.cloud</groupId>
|
|
||||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
|
||||||
<version>${spring-cloud.version}.0</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</dependencyManagement>
|
|
||||||
</project>
|
|
@ -1,11 +0,0 @@
|
|||||||
package com.cskefu.gateway;
|
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
|
||||||
public class CskefuGatewayApplication {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
SpringApplication.run(CskefuGatewayApplication.class, args);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
spring:
|
|
||||||
datasource:
|
|
||||||
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8
|
|
||||||
username: root
|
|
||||||
password: 123456
|
|
||||||
|
|
||||||
cloud:
|
|
||||||
# sentinel配置
|
|
||||||
sentinel:
|
|
||||||
eager: true
|
|
||||||
transport:
|
|
||||||
dashboard:
|
|
||||||
127.0.0.1:8848
|
|
||||||
port: 8719
|
|
||||||
heartbeat-interval-ms: 5000
|
|
||||||
nacos:
|
|
||||||
# 注册中心配置
|
|
||||||
discovery:
|
|
||||||
server-addr: localhost:8848
|
|
||||||
namespace: xxxxxxx
|
|
||||||
# # 配置中心
|
|
||||||
# config:
|
|
||||||
# server-addr: 127.0.0.1:8848
|
|
||||||
# file-extension: yaml
|
|
||||||
# namespace: jm-live-dev
|
|
||||||
# shared-configs[0]:
|
|
||||||
# group: sentinel
|
|
||||||
# data-id: sentinel-shared.yaml
|
|
||||||
# refresh: true
|
|
@ -1,5 +0,0 @@
|
|||||||
spring:
|
|
||||||
application:
|
|
||||||
name: cskefu-gateway
|
|
||||||
profiles:
|
|
||||||
active: dev
|
|
Loading…
x
Reference in New Issue
Block a user