提交 5710801f 编写于 作者: M mxd

初步实现插件机制

上级 e6578fc3
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.0.0-alpha.2</version>
</parent>
<artifactId>magic-api-plugin-cluster</artifactId>
<packaging>jar</packaging>
<name>magic-api-plugin-cluster</name>
<description>magic-api-plugin-cluster</description>
<dependencies>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugin-redis</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
package org.ssssssss.magicapi.spring.boot.starter;
package org.ssssssss.magicapi.cluster;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.UUID;
......@@ -8,39 +10,14 @@ import java.util.UUID;
* @author mxd
* @since 1.2.0
*/
@ConfigurationProperties(prefix = "magic-api.cluster")
public class ClusterConfig {
/**
* 是否启用,默认不启用
*/
private boolean enable = false;
/**
* 实例ID,集群环境下,要保证每台机器不同。默认启动后随机生成uuid
*/
private String instanceId = UUID.randomUUID().toString();
/**
* redis 通道
*/
private String channel = "magic-api:notify:channel";
public String getInstanceId() {
return instanceId;
}
public void setInstanceId(String instanceId) {
this.instanceId = instanceId;
}
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public String getChannel() {
return channel;
}
......
package org.ssssssss.magicapi.spring.boot.starter;
package org.ssssssss.magicapi.cluster;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.ssssssss.magicapi.core.resource.Resource;
import org.ssssssss.magicapi.core.resource.RedisResource;
import org.ssssssss.magicapi.core.config.MagicAPIProperties;
import org.ssssssss.magicapi.core.config.MagicPluginConfiguration;
import org.ssssssss.magicapi.core.model.MagicNotify;
import org.ssssssss.magicapi.modules.redis.RedisModule;
import org.ssssssss.magicapi.core.model.Plugin;
import org.ssssssss.magicapi.core.service.MagicAPIService;
import org.ssssssss.magicapi.core.service.MagicNotifyService;
import org.ssssssss.magicapi.core.service.MagicSynchronizationService;
import org.ssssssss.magicapi.utils.JsonUtils;
import java.util.Objects;
/**
* redis配置
*
* @author mxd
*/
@ConditionalOnClass(RedisConnectionFactory.class)
@EnableConfigurationProperties(ClusterConfig.class)
@Configuration
@AutoConfigureBefore(MagicAPIAutoConfiguration.class)
public class MagicRedisAutoConfiguration {
public class MagicClusterConfiguration implements MagicPluginConfiguration {
private final static Logger logger = LoggerFactory.getLogger(MagicRedisAutoConfiguration.class);
private final ClusterConfig config;
private final MagicAPIProperties properties;
private final StringRedisTemplate stringRedisTemplate;
public MagicRedisAutoConfiguration(MagicAPIProperties properties, ObjectProvider<StringRedisTemplate> stringRedisTemplateProvider) {
private final Logger logger = LoggerFactory.getLogger(MagicClusterConfiguration.class);
public MagicClusterConfiguration(MagicAPIProperties properties, ClusterConfig config, ObjectProvider<StringRedisTemplate> stringRedisTemplateProvider) {
this.properties = properties;
this.config = config;
this.stringRedisTemplate = stringRedisTemplateProvider.getIfAvailable();
}
/**
* 注入redis模块
*/
@Bean
public RedisModule redisFunctions(RedisConnectionFactory connectionFactory) {
return new RedisModule(connectionFactory);
}
/**
* 使用Redis存储
*/
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "magic-api", name = "resource.type", havingValue = "redis")
public Resource magicRedisResource(RedisConnectionFactory connectionFactory) {
ResourceConfig resource = properties.getResource();
return new RedisResource(new StringRedisTemplate(connectionFactory), resource.getPrefix(), resource.isReadonly());
@Override
public Plugin plugin() {
return new Plugin("Cluster");
}
/**
......@@ -69,9 +52,8 @@ public class MagicRedisAutoConfiguration {
*/
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "magic-api", name = "cluster-config.enable", havingValue = "true")
public MagicNotifyService magicNotifyService() {
return magicNotify -> stringRedisTemplate.convertAndSend(properties.getClusterConfig().getChannel(), Objects.requireNonNull(JsonUtils.toJsonString(magicNotify)));
return magicNotify -> stringRedisTemplate.convertAndSend(config.getChannel(), Objects.requireNonNull(JsonUtils.toJsonString(magicNotify)));
}
/**
......@@ -79,18 +61,15 @@ public class MagicRedisAutoConfiguration {
*/
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "magic-api", name = "cluster-config.enable", havingValue = "true")
public MagicSynchronizationService magicSynchronizationService(MagicNotifyService magicNotifyService) {
return new MagicSynchronizationService(magicNotifyService, properties.getClusterConfig().getInstanceId());
return new MagicSynchronizationService(magicNotifyService, properties.getInstanceId());
}
/**
* 集群通知监听
*/
@Bean
@ConditionalOnProperty(prefix = "magic-api", name = "cluster-config.enable", havingValue = "true")
public RedisMessageListenerContainer magicRedisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory, MagicAPIService magicAPIService) {
ClusterConfig config = properties.getClusterConfig();
logger.info("开启集群通知监听, Redis channel: {}", config.getChannel());
RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
......
package org.ssssssss.magicapi.core.service;
package org.ssssssss.magicapi.cluster;
import org.springframework.context.event.EventListener;
import org.ssssssss.magicapi.core.event.*;
import org.ssssssss.magicapi.core.config.Constants;
import org.ssssssss.magicapi.core.model.MagicNotify;
import org.ssssssss.magicapi.core.service.MagicNotifyService;
public class MagicSynchronizationService {
......
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.ssssssss.magicapi.cluster.MagicClusterConfiguration
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.0.0-alpha.2</version>
</parent>
<artifactId>magic-api-plugin-elasticsearch</artifactId>
<packaging>jar</packaging>
<name>magic-api-plugin-elasticsearch</name>
<description>magic-api-plugin-elasticsearch</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
</dependencies>
</project>
package org.ssssssss.magicapi.modules.elasticsearch;
package org.ssssssss.magicapi.elasticsearch;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.ml.PutJobResponse;
import org.ssssssss.magicapi.utils.JsonUtils;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Objects;
public class ElasticSearchConnection extends ElasticSearchRest {
......
package org.ssssssss.magicapi.modules.elasticsearch;
package org.ssssssss.magicapi.elasticsearch;
import org.elasticsearch.client.RestClient;
import org.ssssssss.magicapi.utils.JsonUtils;
import org.ssssssss.script.annotation.Comment;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import java.util.Map;
......
package org.ssssssss.magicapi.modules.elasticsearch;
package org.ssssssss.magicapi.elasticsearch;
import org.elasticsearch.client.RestClient;
import org.ssssssss.magicapi.core.config.MagicModule;
import org.ssssssss.magicapi.modules.elasticsearch.ElasticSearchConnection;
import org.ssssssss.magicapi.modules.elasticsearch.ElasticSearchIndex;
import org.ssssssss.script.annotation.Comment;
public class ElasticSearchModule implements MagicModule {
......@@ -16,7 +14,7 @@ public class ElasticSearchModule implements MagicModule {
this.restClient = restClient;
}
@Comment(value = "ElasticSearch REST Api")
@Comment(value = "ElasticSearch REST API")
public ElasticSearchConnection rest(String url){
return new ElasticSearchConnection(this.restClient, url);
}
......
package org.ssssssss.magicapi.modules.elasticsearch;
package org.ssssssss.magicapi.elasticsearch;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.xcontent.XContentParserUtils;
import org.ssssssss.magicapi.utils.JsonUtils;
import java.io.IOException;
......
package org.ssssssss.magicapi.spring.boot.starter;
package org.ssssssss.magicapi.elasticsearch;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.ssssssss.magicapi.modules.elasticsearch.ElasticSearchModule;
import org.ssssssss.magicapi.core.config.MagicPluginConfiguration;
import org.ssssssss.magicapi.core.model.Plugin;
@Configuration
@ConditionalOnMissingBean(ElasticSearchModule.class)
@ConditionalOnClass(RestHighLevelClient.class)
public class MagicElasticSearchAutoConfiguration {
public class MagicElasticSearchConfiguration implements MagicPluginConfiguration {
@Override
public Plugin plugin() {
return new Plugin("ElasticSearch");
}
@Bean
@ConditionalOnBean(RestHighLevelClient.class)
......
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.ssssssss.magicapi.elasticsearch.MagicElasticSearchConfiguration
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.0.0-alpha.2</version>
</parent>
<artifactId>magic-api-plugin-mongo</artifactId>
<packaging>jar</packaging>
<name>magic-api-plugin-mongo</name>
<description>magic-api-plugin-mongo</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
</dependencies>
</project>
package org.ssssssss.magicapi.spring.boot.starter;
package org.ssssssss.magicapi.mongo;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.ssssssss.magicapi.modules.mongo.MongoCollectionExtension;
import org.ssssssss.magicapi.modules.mongo.MongoFindIterableExtension;
import org.ssssssss.magicapi.modules.mongo.MongoModule;
import org.ssssssss.magicapi.core.config.MagicPluginConfiguration;
import org.ssssssss.magicapi.core.model.Plugin;
import org.ssssssss.script.reflection.JavaReflection;
/**
* mongo配置
*
* @author mxd
*/
@Configuration
@ConditionalOnBean(MongoTemplate.class)
@AutoConfigureBefore(MagicAPIAutoConfiguration.class)
public class MagicMongoAutoConfiguration {
public class MagicMongoConfiguration implements MagicPluginConfiguration {
@Override
public Plugin plugin() {
return new Plugin("Mongo");
}
/**
* 注入mongo模块
*/
@Bean
@ConditionalOnMissingBean
public MongoModule mongoFunctions(MongoTemplate mongoTemplate) {
JavaReflection.registerMethodExtension(MongoCollection.class, new MongoCollectionExtension());
JavaReflection.registerMethodExtension(FindIterable.class, new MongoFindIterableExtension());
......
package org.ssssssss.magicapi.modules.mongo;
package org.ssssssss.magicapi.mongo;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
......
package org.ssssssss.magicapi.modules.mongo;
package org.ssssssss.magicapi.mongo;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCursor;
......
package org.ssssssss.magicapi.modules.mongo;
package org.ssssssss.magicapi.mongo;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
......@@ -8,8 +8,8 @@ import org.bson.conversions.Bson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.ssssssss.magicapi.core.config.MagicModule;
import org.ssssssss.magicapi.core.config.Constants;
import org.ssssssss.magicapi.core.config.MagicModule;
import org.ssssssss.script.convert.ClassImplicitConvert;
import org.ssssssss.script.reflection.JavaInvoker;
import org.ssssssss.script.reflection.JavaReflection;
......
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.ssssssss.magicapi.mongo.MagicMongoConfiguration
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.0.0-alpha.2</version>
</parent>
<artifactId>magic-api-plugin-redis</artifactId>
<packaging>jar</packaging>
<name>magic-api-plugin-redis</name>
<description>magic-api-plugin-redis</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
</project>
package org.ssssssss.magicapi.redis;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.ssssssss.magicapi.core.config.MagicAPIProperties;
import org.ssssssss.magicapi.core.config.MagicPluginConfiguration;
import org.ssssssss.magicapi.core.config.Resource;
import org.ssssssss.magicapi.core.model.Plugin;
import org.ssssssss.magicapi.core.resource.RedisResource;
@Configuration
public class MagicRedisConfiguration implements MagicPluginConfiguration {
private final MagicAPIProperties properties;
public MagicRedisConfiguration(MagicAPIProperties properties) {
this.properties = properties;
}
/**
* 使用Redis存储
*/
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "magic-api", name = "resource.type", havingValue = "redis")
public org.ssssssss.magicapi.core.resource.Resource magicRedisResource(RedisConnectionFactory connectionFactory) {
Resource resource = properties.getResource();
return new RedisResource(new StringRedisTemplate(connectionFactory), resource.getPrefix(), resource.isReadonly());
}
/**
* 注入redis模块
*/
@Bean
public RedisModule redisFunctions(RedisConnectionFactory connectionFactory) {
return new RedisModule(connectionFactory);
}
@Override
public Plugin plugin() {
return new Plugin("Redis");
}
}
package org.ssssssss.magicapi.modules.redis;
package org.ssssssss.magicapi.redis;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisCallback;
......
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.ssssssss.magicapi.redis.MagicRedisConfiguration
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.0.0-alpha.2</version>
</parent>
<artifactId>magic-api-plugin-swagger</artifactId>
<packaging>jar</packaging>
<name>magic-api-plugin-swagger</name>
<description>magic-api-plugin-swagger</description>
<properties>
<swagger.version>2.9.2</swagger.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
package org.ssssssss.magicapi.spring.boot.starter;
package org.ssssssss.magicapi.swagger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
......@@ -11,10 +11,13 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.ssssssss.magicapi.core.config.MagicAPIProperties;
import org.ssssssss.magicapi.core.config.MagicPluginConfiguration;
import org.ssssssss.magicapi.core.model.Plugin;
import org.ssssssss.magicapi.core.service.MagicResourceService;
import org.ssssssss.magicapi.core.service.impl.RequestMagicDynamicRegistry;
import org.ssssssss.magicapi.swagger.SwaggerEntity;
import org.ssssssss.magicapi.swagger.SwaggerProvider;
import org.ssssssss.magicapi.swagger.entity.SwaggerEntity;
import org.ssssssss.magicapi.swagger.entity.SwaggerProvider;
import org.ssssssss.magicapi.utils.Mapping;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
......@@ -25,32 +28,36 @@ import java.util.List;
import java.util.Map;
@Configuration
@AutoConfigureAfter({MagicAPIAutoConfiguration.class})
@EnableConfigurationProperties(MagicAPIProperties.class)
@EnableConfigurationProperties(SwaggerConfig.class)
@ConditionalOnClass(name = "springfox.documentation.swagger.web.SwaggerResourcesProvider")
public class MagicSwaggerConfiguration {
public class MagicSwaggerConfiguration implements MagicPluginConfiguration {
private final MagicAPIProperties properties;
private final SwaggerConfig swaggerConfig;
private final ApplicationContext applicationContext;
@Autowired
@Lazy
private RequestMappingHandlerMapping requestMappingHandlerMapping;
public MagicSwaggerConfiguration(MagicAPIProperties properties, ApplicationContext applicationContext) {
public MagicSwaggerConfiguration(MagicAPIProperties properties, SwaggerConfig swaggerConfig, ApplicationContext applicationContext) {
this.properties = properties;
this.swaggerConfig = swaggerConfig;
this.applicationContext = applicationContext;
}
@Override
public Plugin plugin() {
return new Plugin("Swagger");
}
@Bean
@Primary
public SwaggerResourcesProvider magicSwaggerResourcesProvider(RequestMagicDynamicRegistry requestMagicDynamicRegistry, MagicResourceService magicResourceService, ServletContext servletContext) throws NoSuchMethodException {
SwaggerConfig config = properties.getSwaggerConfig();
Mapping mapping = Mapping.create(requestMappingHandlerMapping);
RequestMappingInfo requestMappingInfo = mapping.paths(config.getLocation()).build();
RequestMappingInfo requestMappingInfo = mapping.paths(swaggerConfig.getLocation()).build();
SwaggerEntity.License license = new SwaggerEntity.License("MIT", "https://gitee.com/ssssssss-team/magic-api/blob/master/LICENSE");
SwaggerEntity.Info info = new SwaggerEntity.Info(config.getDescription(), config.getVersion(), config.getTitle(), license, config.getConcat());
SwaggerEntity.Info info = new SwaggerEntity.Info(swaggerConfig.getDescription(), swaggerConfig.getVersion(), swaggerConfig.getTitle(), license, swaggerConfig.getConcat());
// 构建文档信息
SwaggerProvider swaggerProvider = new SwaggerProvider(requestMagicDynamicRegistry, magicResourceService, servletContext.getContextPath(), info, properties.isPersistenceResponseBody());
......@@ -61,7 +68,7 @@ public class MagicSwaggerConfiguration {
return () -> {
List<SwaggerResource> resources = new ArrayList<>();
// 追加Magic Swagger信息
resources.add(swaggerResource(config.getName(), config.getLocation()));
resources.add(swaggerResource(swaggerConfig.getName(), swaggerConfig.getLocation()));
Map<String, SwaggerResourcesProvider> beans = applicationContext.getBeansOfType(SwaggerResourcesProvider.class);
// 获取已定义的文档信息
for (Map.Entry<String, SwaggerResourcesProvider> entry : beans.entrySet()) {
......
package org.ssssssss.magicapi.spring.boot.starter;
package org.ssssssss.magicapi.swagger;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.ssssssss.magicapi.swagger.SwaggerEntity;
import org.ssssssss.magicapi.swagger.entity.SwaggerEntity;
/**
* Swagger 配置
*
* @author mxd
*/
@ConfigurationProperties(prefix = "magic-api.swagger")
public class SwaggerConfig {
/**
......
package org.ssssssss.magicapi.swagger;
package org.ssssssss.magicapi.swagger.entity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
......
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.ssssssss.magicapi.swagger.MagicSwaggerConfiguration
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-plugins</artifactId>
<version>2.0.0-alpha.2</version>
</parent>
<artifactId>magic-api-plugin-task</artifactId>
<packaging>jar</packaging>
<name>magic-api-plugin-task</name>
<description>magic-api-plugin-task</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<!-- npm install && npm run build -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<id>exec-npm-install</id>
<phase>generate-resources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>npm</executable>
<arguments>
<argument>install</argument>
</arguments>
<workingDirectory>${basedir}/src/console</workingDirectory>
</configuration>
</execution>
<execution>
<id>exec-npm-run-build</id>
<phase>generate-resources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>npm</executable>
<arguments>
<argument>run</argument>
<argument>build</argument>
</arguments>
<workingDirectory>${basedir}/src/console</workingDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>copy-resource</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/classes/magic-editor/plugins</outputDirectory>
<resources>
<resource>
<directory>${basedir}/src/console/dist</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
{
"name": "magic-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "vite build"
},
"author": "",
"license": "ISC",
"devDependencies": {
"vue": "^3.2.26",
"@vitejs/plugin-vue": "^2.0.1",
"vite-plugin-svg-icons": "^1.1.0",
"vite": "^2.7.10"
}
}
<template>
<div class="magic-task-info">
<form>
<label>{{ $i('message.enable') }}</label>
<magic-checkbox v-model:value="info.enabled" />
<label>cron</label>
<magic-input v-model:value="info.cron" :placeholder="$i('task.form.placeholder.cron')" width="250px"/>
<label>{{ $i('task.form.name') }}</label>
<magic-input v-model:value="info.name" :placeholder="$i('task.form.placeholder.name')" width="250px"/>
<label>{{ $i('task.form.path') }}</label>
<magic-input v-model:value="info.path" :placeholder="$i('task.form.placeholder.path')" width="auto" style="flex:1"/>
</form>
<div style="flex:1;padding-top:5px;">
<magic-textarea v-model:value="info.description" :placeholder="$i('task.form.placeholder.description')"/>
</div>
</div>
</template>
<script setup>
import { inject } from 'vue'
const $i = inject('i18n.format')
const info = inject('info')
</script>
<style scoped>
.magic-task-info{
display: flex;
flex-direction: column;
flex: 1;
padding: 5px;
}
.magic-task-info form{
display: flex;
}
.magic-task-info form label{
display: inline-block;
width: 75px;
height: 22px;
line-height: 22px;
font-weight: 400;
text-align: right;
padding: 0 5px;
}
.magic-task-info form :deep(.magic-checkbox){
width: 22px;
height: 22px;
}
.magic-task-info form :deep(.magic-textarea){
margin: 5px;
}
</style>
\ No newline at end of file
export default {
task: {
title: 'Task Info',
name: 'Task',
form: {
name: 'Task Name',
path: 'Task Path',
placeholder: {
cron: 'Please Enter Cron Expression',
name: 'Please Enter Task Name',
path: 'Please Enter Task Path',
description: 'Please Enter Task Description'
}
}
},
}
\ No newline at end of file
export default {
task: {
title: '定时任务信息',
name: '定时任务',
form: {
name: '任务名称',
path: '任务路径',
placeholder: {
cron: '请输入Cron表达式',
name: '请输入任务名称',
path: '请输入任务路径',
description: '请输入任务描述'
}
}
}
}
\ No newline at end of file
<svg class="icon" style="width: 1em;height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512.78747336 189.40294037A372.25009177 372.25009177 0 1 1 512.73122556 933.8468761a372.25009177 372.25009177 0 0 1 0-744.50018353z m20.02433313 179.43151904h-39.93616901a6.69352725 6.69352725 0 0 0-6.69352725 6.69352725V604.2328627c0 2.19367667 1.01246621 4.1623613 2.75615881 5.39982038l137.41416897 100.23415877a6.63727863 6.63727863 0 0 0 9.28094102-1.4624511l23.79295651-32.39891977a6.5247822 6.5247822 0 0 0-1.51869891-9.22469321L539.44908511 581.17113175V375.52798666a6.69352725 6.69352725 0 0 0-6.63727862-6.69352726zM711.28710712 90.125a24.80542356 24.80542356 0 0 1-1e-8 49.61084629H314.23159262a24.80542356 24.80542356 0 0 1 0-49.61084629h397.1117623z" /></svg>
\ No newline at end of file
import MagicTask from './service/magic-task.js'
import localZhCN from './i18n/zh-cn.js'
import localEn from './i18n/en.js'
import MagicTaskInfo from './components/magic-task-info.vue'
import 'vite-plugin-svg-icons/register'
export default (opt) => {
const i18n = opt.i18n
// 添加i18n 国际化信息
i18n.add('zh-cn', localZhCN)
i18n.add('en', localEn)
return {
// 左侧资源
resource: [{
// 资源类型,和后端存储结构一致
type: 'task',
// 展示图标
icon: '#magic-task-task', // #开头表示图标在插件中
// 展示名称
title: 'task.name',
// 运行服务
service: MagicTask(opt.bus, opt.constants, i18n.format, opt.Message, opt.request),
}],
// 底部工具条
toolbars: [{
// 当打开的资源类型为 task 时显示
type: 'task',
// 工具条展示的标题
title: 'task.title',
// 展示图标
icon: 'parameter',
// 对应的组件
component: MagicTaskInfo,
}]
}
}
export default function (bus, constants, $i, Message, request) {
return {
// svg text
getIcon: item => 'task',
// 任务名称
name: $i('task.name'),
// 执行测试的逻辑
doTest: (opened) => {
opened.running = true
const info = opened.item
const requestConfig = {
baseURL: constants.SERVER_URL,
url: '/task/execute',
method: 'POST',
responseType: 'json',
headers: {},
withCredentials: true
}
bus.$emit(Message.SWITCH_TOOLBAR, 'log')
requestConfig.headers[constants.HEADER_REQUEST_CLIENT_ID] = constants.CLIENT_ID
requestConfig.headers[constants.HEADER_REQUEST_SCRIPT_ID] = opened.item.id
requestConfig.headers[constants.HEADER_MAGIC_TOKEN] = constants.HEADER_MAGIC_TOKEN_VALUE
// 设置断点
requestConfig.headers[constants.HEADER_REQUEST_BREAKPOINTS] = (opened.decorations || []).filter(it => it.options.linesDecorationsClassName === 'breakpoints').map(it => it.range.startLineNumber).join(',')
const fullName = opened.path()
bus.status(`开始测试定时任务「${fullName}」`)
request.sendPost('/task/execute', { id: info.id }, requestConfig).success(res => {
opened.running = false
}).end(() => {
bus.status(`定时任务「${fullName}」测试完毕`)
opened.running = false
})
},
// 是否允许执行测试
runnable: true,
// 是否需要填写路径
requirePath: true,
// 合并
merge: item => item
}
}
\ No newline at end of file
import vue from '@vitejs/plugin-vue'
import viteSvgIcons from 'vite-plugin-svg-icons'
import path from 'path'
import pkg from './package.json'
export default {
base: './',
build: {
minify: false,
cssCodeSplit: true, // 将组件的 style 打包到 js 文件中
outDir: 'dist',
lib: {
target: 'esnext',
formats: ['iife'],
entry: path.resolve(__dirname, 'src/index.js'),
name: 'MagicTask',
fileName: (format) => `magic-task.${pkg.version}.${format}.js`
},
rollupOptions: {
// 确保外部化处理那些你不想打包进库的依赖
external: ['vue'],
output: {
// 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
globals: {
vue: 'Vue'
}
}
}
},
plugins: [
vue(),
viteSvgIcons({
iconDirs: [path.resolve(process.cwd(), 'src/icons')],
symbolId: 'magic-task-[name]'
}),
]
}
\ No newline at end of file
package org.ssssssss.magicapi.task.starter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.ssssssss.magicapi.core.config.MagicPluginConfiguration;
import org.ssssssss.magicapi.core.model.Plugin;
import org.ssssssss.magicapi.core.web.MagicControllerRegister;
import org.ssssssss.magicapi.task.service.TaskInfoMagicResourceStorage;
import org.ssssssss.magicapi.task.service.TaskMagicDynamicRegistry;
import org.ssssssss.magicapi.task.web.MagicTaskController;
@Configuration
@EnableScheduling
public class MagicAPITaskConfiguration implements MagicPluginConfiguration{
@Bean
@ConditionalOnMissingBean
public TaskInfoMagicResourceStorage taskInfoMagicResourceStorage() {
return new TaskInfoMagicResourceStorage();
}
@Bean
@ConditionalOnMissingBean
public TaskMagicDynamicRegistry taskMagicDynamicRegistry(TaskInfoMagicResourceStorage taskInfoMagicResourceStorage, TaskScheduler taskScheduler) {
return new TaskMagicDynamicRegistry(taskInfoMagicResourceStorage, taskScheduler);
}
@Override
public Plugin plugin() {
return new Plugin("定时任务", "magic-task.1.0.0.iife.js");
}
@Override
public MagicControllerRegister controllerRegister() {
return (mapping, configuration) -> mapping.registerController(new MagicTaskController(configuration));
}
}
......@@ -2,13 +2,13 @@ package org.ssssssss.magicapi.task.web;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.ssssssss.magicapi.core.web.MagicExceptionHandler;
import org.ssssssss.magicapi.core.config.MagicConfiguration;
import org.ssssssss.magicapi.core.logging.MagicLoggerContext;
import org.ssssssss.magicapi.core.model.DebugRequest;
import org.ssssssss.magicapi.core.model.JsonBean;
import org.ssssssss.magicapi.core.model.MagicEntity;
import org.ssssssss.magicapi.core.web.MagicController;
import org.ssssssss.magicapi.core.web.MagicExceptionHandler;
import org.ssssssss.magicapi.utils.ScriptManager;
import org.ssssssss.script.MagicScriptDebugContext;
......
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.ssssssss.magicapi.task.starter.MagicAPITaskConfiguration
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-parent</artifactId>
<version>2.0.0-alpha.2</version>
</parent>
<artifactId>magic-api-plugins</artifactId>
<version>2.0.0-alpha.2</version>
<packaging>pom</packaging>
<name>magic-api-plugins</name>
<description>auto generate http api</description>
<modules>
<module>magic-api-plugin-task</module>
<module>magic-api-plugin-swagger</module>
<module>magic-api-plugin-redis</module>
<module>magic-api-plugin-mongo</module>
<module>magic-api-plugin-elasticsearch</module>
<module>magic-api-plugin-cluster</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-script</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
......@@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-parent</artifactId>
<version>2.0.0-alpha.1</version>
<version>2.0.0-alpha.2</version>
</parent>
<artifactId>magic-api-spring-boot-starter</artifactId>
<packaging>jar</packaging>
......@@ -28,11 +28,6 @@
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
......@@ -60,20 +55,10 @@
<artifactId>fastjson</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
......@@ -7,6 +7,7 @@ import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.ssssssss.magicapi.core.config.MagicAPIProperties;
import org.ssssssss.magicapi.utils.PathUtils;
import java.net.InetAddress;
......@@ -25,7 +26,7 @@ import java.util.Objects;
@Order
public class ApplicationUriPrinter implements CommandLineRunner {
@Value("${server.port:9999}")
@Value("${server.port:8080}")
private int port;
@Value("${server.servlet.context-path:}")
......
......@@ -22,7 +22,6 @@ import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
......@@ -44,6 +43,7 @@ import org.ssssssss.magicapi.core.handler.MagicDebugHandler;
import org.ssssssss.magicapi.core.handler.MagicWebSocketDispatcher;
import org.ssssssss.magicapi.core.handler.MagicWorkbenchHandler;
import org.ssssssss.magicapi.core.interceptor.*;
import org.ssssssss.magicapi.core.model.Plugin;
import org.ssssssss.magicapi.core.service.*;
import org.ssssssss.magicapi.core.web.MagicResourceController;
import org.ssssssss.magicapi.core.web.MagicWorkbenchController;
......@@ -57,7 +57,6 @@ import org.ssssssss.magicapi.jsr223.JSR223LanguageProvider;
import org.ssssssss.magicapi.jsr223.LanguageProvider;
import org.ssssssss.magicapi.modules.db.ColumnMapperAdapter;
import org.ssssssss.magicapi.modules.db.dialect.DialectAdapter;
import org.ssssssss.magicapi.core.resource.Resource;
import org.ssssssss.magicapi.core.resource.ResourceAdapter;
import org.ssssssss.magicapi.core.resource.DatabaseResource;
import org.ssssssss.magicapi.function.service.FunctionInfoMagicResourceStorage;
......@@ -84,9 +83,6 @@ import org.ssssssss.magicapi.modules.servlet.RequestModule;
import org.ssssssss.magicapi.modules.servlet.ResponseModule;
import org.ssssssss.magicapi.modules.spring.EnvModule;
import org.ssssssss.magicapi.core.service.impl.*;
import org.ssssssss.magicapi.task.service.TaskInfoMagicResourceStorage;
import org.ssssssss.magicapi.task.service.TaskMagicDynamicRegistry;
import org.ssssssss.magicapi.task.web.MagicTaskController;
import org.ssssssss.magicapi.utils.ClassScanner;
import org.ssssssss.magicapi.utils.Mapping;
import org.ssssssss.script.MagicResourceLoader;
......@@ -106,6 +102,7 @@ import java.util.*;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
/**
* magic-api自动配置类
......@@ -115,7 +112,7 @@ import java.util.function.BiFunction;
@Configuration
@ConditionalOnClass({RequestMappingHandlerMapping.class})
@EnableConfigurationProperties(MagicAPIProperties.class)
@Import({MagicRedisAutoConfiguration.class, MagicElasticSearchAutoConfiguration.class, MagicMongoAutoConfiguration.class, MagicSwaggerConfiguration.class, MagicJsonAutoConfiguration.class, ApplicationUriPrinter.class})
@Import({MagicJsonAutoConfiguration.class, ApplicationUriPrinter.class})
@EnableWebSocket
public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketConfigurer {
......@@ -164,6 +161,8 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
*/
private final ObjectProvider<List<MagicFunction>> magicFunctionsProvider;
private final ObjectProvider<List<MagicPluginConfiguration>> magicPluginsProvider;
private final ObjectProvider<MagicNotifyService> magicNotifyServiceProvider;
private final ObjectProvider<List<MagicDynamicRegistry<? extends MagicEntity>>> magicDynamicRegistriesProvider;
......@@ -204,6 +203,7 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
ObjectProvider<List<HttpMessageConverter<?>>> httpMessageConvertersProvider,
ObjectProvider<List<ColumnMapperProvider>> columnMapperProvidersProvider,
ObjectProvider<List<MagicFunction>> magicFunctionsProvider,
ObjectProvider<List<MagicPluginConfiguration>> magicPluginsProvider,
ObjectProvider<MagicNotifyService> magicNotifyServiceProvider,
ObjectProvider<AuthorizationInterceptor> authorizationInterceptorProvider,
ObjectProvider<List<NamedTableInterceptor>> namedTableInterceptorsProvider,
......@@ -221,6 +221,7 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
this.httpMessageConvertersProvider = httpMessageConvertersProvider;
this.columnMapperProvidersProvider = columnMapperProvidersProvider;
this.magicFunctionsProvider = magicFunctionsProvider;
this.magicPluginsProvider = magicPluginsProvider;
this.magicNotifyServiceProvider = magicNotifyServiceProvider;
this.authorizationInterceptorProvider = authorizationInterceptorProvider;
this.namedTableInterceptorsProvider = namedTableInterceptorsProvider;
......@@ -278,10 +279,10 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
}
@Bean
@ConditionalOnMissingBean(Resource.class)
@ConditionalOnMissingBean(org.ssssssss.magicapi.core.resource.Resource.class)
@ConditionalOnProperty(prefix = "magic-api", name = "resource.type", havingValue = "database")
public Resource magicDatabaseResource(MagicDynamicDataSource magicDynamicDataSource) {
ResourceConfig resourceConfig = properties.getResource();
public org.ssssssss.magicapi.core.resource.Resource magicDatabaseResource(MagicDynamicDataSource magicDynamicDataSource) {
Resource resourceConfig = properties.getResource();
if (magicDynamicDataSource.isEmpty()) {
throw new MagicAPIException("当前未配置数据源,如已配置,请引入 spring-boot-starter-jdbc 后在试!");
}
......@@ -290,18 +291,18 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
}
@Bean
@ConditionalOnMissingBean(Resource.class)
@ConditionalOnMissingBean(org.ssssssss.magicapi.core.resource.Resource.class)
@ConditionalOnProperty(prefix = "magic-api", name = "resource.type", havingValue = "file", matchIfMissing = true)
public Resource magicResource() throws IOException {
ResourceConfig resourceConfig = properties.getResource();
public org.ssssssss.magicapi.core.resource.Resource magicResource() throws IOException {
Resource resourceConfig = properties.getResource();
return ResourceAdapter.getResource(resourceConfig.getLocation(), resourceConfig.isReadonly());
}
@Bean
@ConditionalOnMissingBean(MagicBackupService.class)
@ConditionalOnProperty(prefix = "magic-api", name = "backup-config.enable", havingValue = "true")
@ConditionalOnProperty(prefix = "magic-api", name = "backup.enable", havingValue = "true")
public MagicBackupService magicDatabaseBackupService(MagicDynamicDataSource magicDynamicDataSource) {
BackupConfig backupConfig = properties.getBackupConfig();
Backup backupConfig = properties.getBackup();
MagicDynamicDataSource.DataSourceNode dataSourceNode = magicDynamicDataSource.getDataSource(backupConfig.getDatasource());
return new MagicDatabaseBackupService(new JdbcTemplate(dataSourceNode.getDataSource()), backupConfig.getTableName());
}
......@@ -350,7 +351,7 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
@Bean
@ConditionalOnMissingBean(PageProvider.class)
public PageProvider pageProvider() {
PageConfig pageConfig = properties.getPageConfig();
Page pageConfig = properties.getPage();
logger.info("未找到分页实现,采用默认分页实现,分页配置:(页码={},页大小={},默认首页={},默认页大小={})", pageConfig.getPage(), pageConfig.getSize(), pageConfig.getDefaultPage(), pageConfig.getDefaultSize());
return new DefaultPageProvider(pageConfig.getPage(), pageConfig.getSize(), pageConfig.getDefaultPage(), pageConfig.getDefaultSize());
}
......@@ -370,14 +371,14 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
@Bean
@ConditionalOnMissingBean(SqlCache.class)
public SqlCache sqlCache() {
CacheConfig cacheConfig = properties.getCacheConfig();
Cache cacheConfig = properties.getCache();
logger.info("未找到SQL缓存实现,采用默认缓存实现(LRU+TTL),缓存配置:(容量={},TTL={})", cacheConfig.getCapacity(), cacheConfig.getTtl());
return new DefaultSqlCache(cacheConfig.getCapacity(), cacheConfig.getTtl());
}
@Bean
@ConditionalOnMissingBean
public MagicResourceService magicResourceService(Resource workspace) {
public MagicResourceService magicResourceService(org.ssssssss.magicapi.core.resource.Resource workspace) {
return new DefaultMagicResourceService(workspace, magicResourceStoragesProvider.getObject(), applicationContext);
}
......@@ -417,23 +418,11 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
return new DataSourceMagicDynamicRegistry(dataSourceInfoMagicResourceStorage, magicDynamicDataSource);
}
@Bean
@ConditionalOnMissingBean
public TaskInfoMagicResourceStorage taskInfoMagicResourceStorage() {
return new TaskInfoMagicResourceStorage();
}
@Bean
@ConditionalOnMissingBean
public TaskMagicDynamicRegistry taskMagicDynamicRegistry(TaskInfoMagicResourceStorage taskInfoMagicResourceStorage, TaskScheduler taskScheduler) {
return new TaskMagicDynamicRegistry(taskInfoMagicResourceStorage, taskScheduler);
}
@Bean
@ConditionalOnMissingBean(MagicNotifyService.class)
public MagicNotifyService magicNotifyService() {
logger.info("未配置集群通知服务,本实例不会推送通知,集群环境下可能会有问题,如需开启,请配置magic-api.cluster-config.enable=true,若开启后本提示还在,请检查 spring-boot-starter-data-redis 是否引入");
logger.info("未配置集群通知服务,本实例不会推送通知,集群环境下可能会有问题,如需开启,请引用magic-api-plugin-cluster插件");
return magicNotify -> {
};
}
......@@ -444,7 +433,7 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
@Bean
@ConditionalOnMissingBean
public MagicAPIService magicAPIService(ResultProvider resultProvider, MagicResourceService magicResourceService, RequestMagicDynamicRegistry requestMagicDynamicRegistry, FunctionMagicDynamicRegistry functionMagicDynamicRegistry) {
return new DefaultMagicAPIService(resultProvider, properties.getClusterConfig().getInstanceId(), magicResourceService, requestMagicDynamicRegistry, functionMagicDynamicRegistry, properties.isThrowException(), applicationContext);
return new DefaultMagicAPIService(resultProvider, properties.getInstanceId(), magicResourceService, requestMagicDynamicRegistry, functionMagicDynamicRegistry, properties.isThrowException(), applicationContext);
}
/**
......@@ -478,8 +467,8 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
DialectAdapter dialectAdapter = new DialectAdapter();
dialectsProvider.getIfAvailable(Collections::emptyList).forEach(dialectAdapter::add);
sqlModule.setDialectAdapter(dialectAdapter);
sqlModule.setLogicDeleteColumn(properties.getCrudConfig().getLogicDeleteColumn());
sqlModule.setLogicDeleteValue(properties.getCrudConfig().getLogicDeleteValue());
sqlModule.setLogicDeleteColumn(properties.getCrud().getLogicDeleteColumn());
sqlModule.setLogicDeleteValue(properties.getCrud().getLogicDeleteValue());
return sqlModule;
}
......@@ -563,7 +552,7 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
SQLModule sqlModule,
List<MagicModule> magicModules,
List<LanguageProvider> languageProviders,
Resource magicResource,
org.ssssssss.magicapi.core.resource.Resource magicResource,
ResultProvider resultProvider,
MagicResourceService magicResourceService,
MagicAPIService magicAPIService,
......@@ -575,7 +564,7 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
DataType.DATE_PATTERNS = properties.getDatePattern();
MagicScript.setCompileCache(properties.getCompileCacheSize());
// 设置响应结果的code值
ResponseCodeConfig responseCodeConfig = properties.getResponseCodeConfig();
ResponseCode responseCodeConfig = properties.getResponseCode();
Constants.RESPONSE_CODE_SUCCESS = responseCodeConfig.getSuccess();
Constants.RESPONSE_CODE_INVALID = responseCodeConfig.getInvalid();
Constants.RESPONSE_CODE_EXCEPTION = responseCodeConfig.getException();
......@@ -584,12 +573,12 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
MagicConfiguration configuration = new MagicConfiguration();
configuration.setMagicAPIService(magicAPIService);
configuration.setMagicNotifyService(magicNotifyService);
configuration.setInstanceId(properties.getClusterConfig().getInstanceId());
configuration.setInstanceId(properties.getInstanceId());
configuration.setMagicResourceService(magicResourceService);
configuration.setMagicDynamicRegistries(magicDynamicRegistriesProvider.getObject());
configuration.setMagicBackupService(magicBackupService);
SecurityConfig securityConfig = properties.getSecurityConfig();
configuration.setDebugTimeout(properties.getDebugConfig().getTimeout());
Security securityConfig = properties.getSecurityConfig();
configuration.setDebugTimeout(properties.getDebug().getTimeout());
configuration.setHttpMessageConverters(httpMessageConvertersProvider.getIfAvailable(Collections::emptyList));
configuration.setResultProvider(resultProvider);
configuration.setThrowException(properties.isThrowException());
......@@ -602,17 +591,19 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
securityConfig.setUsername(null);
securityConfig.setPassword(null);
requestMagicDynamicRegistry.setHandler(new RequestHandler(configuration, requestMagicDynamicRegistry));
List<MagicPluginConfiguration> pluginConfigurations = magicPluginsProvider.getIfAvailable(Collections::emptyList);
List<Plugin> plugins = pluginConfigurations.stream().map(MagicPluginConfiguration::plugin).collect(Collectors.toList());
// 构建UI请求处理器
String base = properties.getWeb();
Mapping mapping = Mapping.create(requestMappingHandlerMapping, base, properties.getPrefix());
MagicWorkbenchController magicWorkbenchController = new MagicWorkbenchController(configuration, properties.getSecretKey());
MagicWorkbenchController magicWorkbenchController = new MagicWorkbenchController(configuration, plugins, properties.getSecretKey());
if (base != null) {
configuration.setEnableWeb(true);
mapping.registerController(magicWorkbenchController)
.registerController(new MagicResourceController(configuration))
.registerController(new MagicDataSourceController(configuration))
.registerController(new MagicTaskController(configuration))
.registerController(new MagicBackupController(configuration));
pluginConfigurations.forEach(it -> it.controllerRegister().register(mapping, configuration));
}
// 注册接收推送的接口
if (StringUtils.isNotBlank(properties.getSecretKey())) {
......@@ -625,14 +616,14 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
});
// 打印banner
if (this.properties.isBanner()) {
configuration.printBanner();
configuration.printBanner(plugins.stream().map(Plugin::getName).collect(Collectors.toList()));
}
if (magicBackupService == null) {
logger.error("当前备份设置未配置,强烈建议配置备份设置,以免代码丢失。");
}
// 备份清理
if (properties.getBackupConfig().getMaxHistory() > 0 && magicBackupService != null) {
long interval = properties.getBackupConfig().getMaxHistory() * 86400000L;
if (properties.getBackup().isEnable() && properties.getBackup().getMaxHistory() > 0 && magicBackupService != null) {
long interval = properties.getBackup().getMaxHistory() * 86400000L;
// 1小时执行1次
new ScheduledThreadPoolExecutor(1, r -> new Thread(r, "magic-api-clean-task")).scheduleAtFixedRate(() -> {
try {
......@@ -652,7 +643,7 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
if (defaultAuthorizationInterceptor != null) {
return defaultAuthorizationInterceptor;
}
SecurityConfig securityConfig = properties.getSecurityConfig();
Security securityConfig = properties.getSecurityConfig();
defaultAuthorizationInterceptor = new DefaultAuthorizationInterceptor(securityConfig.getUsername(), securityConfig.getPassword());
return defaultAuthorizationInterceptor;
}
......@@ -679,7 +670,7 @@ public class MagicAPIAutoConfiguration implements WebMvcConfigurer, WebSocketCon
WebSocketSessionManager.setMagicNotifyService(magicNotifyService);
if (web != null && !registerWebsocket) {
registerWebsocket = true;
MagicWebSocketDispatcher dispatcher = new MagicWebSocketDispatcher(properties.getClusterConfig().getInstanceId(), magicNotifyService, Arrays.asList(
MagicWebSocketDispatcher dispatcher = new MagicWebSocketDispatcher(properties.getInstanceId(), magicNotifyService, Arrays.asList(
new MagicDebugHandler(),
new MagicCoordinationHandler(),
new MagicWorkbenchHandler(authorizationInterceptorProvider.getIfAvailable(this::createAuthorizationInterceptor))
......
{
"groups": [
{
"sourceType": "org.ssssssss.magicapi.spring.boot.starter.MagicAPIProperties",
"name": "magic-api",
"type": "org.ssssssss.magicapi.spring.boot.starter.MagicAPIProperties"
},
{
"sourceType": "org.ssssssss.magicapi.spring.boot.starter.MagicAPIProperties",
"name": "page-config",
"sourceMethod": "getPageConfig()",
"type": "org.ssssssss.magicapi.spring.boot.starter.PageConfig"
},
{
"sourceType": "org.ssssssss.magicapi.spring.boot.starter.MagicAPIProperties",
"name": "cache-config",
"sourceMethod": "getCacheConfig()",
"type": "org.ssssssss.magicapi.spring.boot.starter.CacheConfig"
},
{
"sourceType": "org.ssssssss.magicapi.spring.boot.starter.MagicAPIProperties",
"name": "debug-config",
"sourceMethod": "getDebugConfig()",
"type": "org.ssssssss.magicapi.spring.boot.starter.DebugConfig"
},
{
"sourceType": "org.ssssssss.magicapi.spring.boot.starter.MagicAPIProperties",
"name": "crud-config",
"sourceMethod": "getCrudConfig()",
"type": "org.ssssssss.magicapi.spring.boot.starter.CrudConfig"
}
]
}
\ No newline at end of file
......@@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-parent</artifactId>
<version>2.0.0-alpha.1</version>
<version>2.0.0-alpha.2</version>
</parent>
<artifactId>magic-api</artifactId>
<packaging>jar</packaging>
......@@ -39,12 +39,6 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
......@@ -76,5 +70,10 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
package org.ssssssss.magicapi.spring.boot.starter;
package org.ssssssss.magicapi.core.config;
/**
* 备份配置
......@@ -6,7 +6,7 @@ package org.ssssssss.magicapi.spring.boot.starter;
* @author mxd
* @since 2.0.0
*/
public class BackupConfig {
public class Backup {
/**
* 是否启用备份配置,默认不启用
......
package org.ssssssss.magicapi.spring.boot.starter;
package org.ssssssss.magicapi.core.config;
/**
* 缓存配置
*
* @author mxd
*/
public class CacheConfig {
public class Cache {
/**
* 是否启用缓存
......
package org.ssssssss.magicapi.spring.boot.starter;
package org.ssssssss.magicapi.core.config;
/**
* CRUD 配置
......@@ -7,7 +7,7 @@ package org.ssssssss.magicapi.spring.boot.starter;
* @date 2021-7-15 09:26:17
* @since 1.3.4
*/
public class CrudConfig {
public class Crud {
/**
* 逻辑删除列
*/
......
package org.ssssssss.magicapi.spring.boot.starter;
package org.ssssssss.magicapi.core.config;
/**
* Debug配置
*
* @author mxd
*/
public class DebugConfig {
public class Debug {
/**
* 断点超时时间
......
package org.ssssssss.magicapi.spring.boot.starter;
package org.ssssssss.magicapi.core.config;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
......@@ -8,6 +8,7 @@ import org.ssssssss.magicapi.core.web.RequestHandler;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
/**
* magic-api配置信息
......@@ -135,51 +136,34 @@ public class MagicAPIProperties {
*/
private boolean persistenceResponseBody = true;
@NestedConfigurationProperty
private SecurityConfig securityConfig = new SecurityConfig();
@NestedConfigurationProperty
private PageConfig pageConfig = new PageConfig();
/**
* 实例ID,集群环境下,要保证每台机器不同。默认启动后随机生成uuid
*/
private String instanceId = UUID.randomUUID().toString();
@NestedConfigurationProperty
private CacheConfig cacheConfig = new CacheConfig();
private Security securityConfig = new Security();
@NestedConfigurationProperty
private DebugConfig debugConfig = new DebugConfig();
private Page page = new Page();
@NestedConfigurationProperty
private SwaggerConfig swaggerConfig = new SwaggerConfig();
private Cache cache = new Cache();
@NestedConfigurationProperty
private ResourceConfig resource = new ResourceConfig();
private Debug debug = new Debug();
@NestedConfigurationProperty
private ResponseCodeConfig responseCodeConfig = new ResponseCodeConfig();
private Resource resource = new Resource();
@NestedConfigurationProperty
private ClusterConfig clusterConfig = new ClusterConfig();
private ResponseCode responseCode = new ResponseCode();
@NestedConfigurationProperty
private CrudConfig crudConfig = new CrudConfig();
private Crud crud = new Crud();
@NestedConfigurationProperty
private BackupConfig backupConfig = new BackupConfig();
public CrudConfig getCrudConfig() {
return crudConfig;
}
public void setCrudConfig(CrudConfig crudConfig) {
this.crudConfig = crudConfig;
}
public String getEditorConfig() {
return editorConfig;
}
public void setEditorConfig(String editorConfig) {
this.editorConfig = editorConfig;
}
private Backup backup = new Backup();
public String getWeb() {
if (StringUtils.isBlank(web)) {
......@@ -217,44 +201,20 @@ public class MagicAPIProperties {
this.banner = banner;
}
public PageConfig getPageConfig() {
return pageConfig;
}
public void setPageConfig(PageConfig pageConfig) {
this.pageConfig = pageConfig;
}
public boolean isThrowException() {
return throwException;
}
public void setThrowException(boolean throwException) {
this.throwException = throwException;
}
public CacheConfig getCacheConfig() {
return cacheConfig;
}
public void setCacheConfig(CacheConfig cacheConfig) {
this.cacheConfig = cacheConfig;
}
public DebugConfig getDebugConfig() {
return debugConfig;
}
public void setDebugConfig(DebugConfig debugConfig) {
this.debugConfig = debugConfig;
public List<String> getAutoImportModuleList() {
return Arrays.asList(autoImportModule.replaceAll("\\s", "").split(","));
}
public SecurityConfig getSecurityConfig() {
return securityConfig;
public List<String> getAutoImportPackageList() {
if (autoImportPackage == null) {
return Collections.emptyList();
}
return Arrays.asList(autoImportPackage.replaceAll("\\s", "").split(","));
}
public void setSecurityConfig(SecurityConfig securityConfig) {
this.securityConfig = securityConfig;
public String getVersion() {
return version;
}
public String getPrefix() {
......@@ -265,24 +225,20 @@ public class MagicAPIProperties {
this.prefix = prefix;
}
public String getAutoImportModule() {
return autoImportModule;
}
public void setAutoImportModule(String autoImport) {
this.autoImportModule = autoImport;
public boolean isThrowException() {
return throwException;
}
public List<String> getAutoImportModuleList() {
return Arrays.asList(autoImportModule.replaceAll("\\s", "").split(","));
public void setThrowException(boolean throwException) {
this.throwException = throwException;
}
public boolean isAllowOverride() {
return allowOverride;
public String getAutoImportModule() {
return autoImportModule;
}
public void setAllowOverride(boolean allowOverride) {
this.allowOverride = allowOverride;
public void setAutoImportModule(String autoImportModule) {
this.autoImportModule = autoImportModule;
}
public String getAutoImportPackage() {
......@@ -293,11 +249,12 @@ public class MagicAPIProperties {
this.autoImportPackage = autoImportPackage;
}
public List<String> getAutoImportPackageList() {
if (autoImportPackage == null) {
return Collections.emptyList();
}
return Arrays.asList(autoImportPackage.replaceAll("\\s", "").split(","));
public boolean isAllowOverride() {
return allowOverride;
}
public void setAllowOverride(boolean allowOverride) {
this.allowOverride = allowOverride;
}
public int getThreadPoolExecutorSize() {
......@@ -308,17 +265,12 @@ public class MagicAPIProperties {
this.threadPoolExecutorSize = threadPoolExecutorSize;
}
public String getVersion() {
return version;
}
public ResourceConfig getResource() {
return resource;
public String getEditorConfig() {
return editorConfig;
}
public void setResource(ResourceConfig resource) {
this.resource = resource;
public void setEditorConfig(String editorConfig) {
this.editorConfig = editorConfig;
}
public boolean isSupportCrossDomain() {
......@@ -337,22 +289,6 @@ public class MagicAPIProperties {
this.response = response;
}
public ResponseCodeConfig getResponseCodeConfig() {
return responseCodeConfig;
}
public void setResponseCodeConfig(ResponseCodeConfig responseCodeConfig) {
this.responseCodeConfig = responseCodeConfig;
}
public ClusterConfig getClusterConfig() {
return clusterConfig;
}
public void setClusterConfig(ClusterConfig clusterConfig) {
this.clusterConfig = clusterConfig;
}
public String getSecretKey() {
return secretKey;
}
......@@ -377,14 +313,6 @@ public class MagicAPIProperties {
this.showUrl = showUrl;
}
public BackupConfig getBackupConfig() {
return backupConfig;
}
public void setBackupConfig(BackupConfig backupConfig) {
this.backupConfig = backupConfig;
}
public boolean isShowSql() {
return showSql;
}
......@@ -417,11 +345,75 @@ public class MagicAPIProperties {
this.persistenceResponseBody = persistenceResponseBody;
}
public SwaggerConfig getSwaggerConfig() {
return swaggerConfig;
public String getInstanceId() {
return instanceId;
}
public void setInstanceId(String instanceId) {
this.instanceId = instanceId;
}
public Security getSecurityConfig() {
return securityConfig;
}
public void setSecurityConfig(Security securityConfig) {
this.securityConfig = securityConfig;
}
public Page getPage() {
return page;
}
public void setPage(Page page) {
this.page = page;
}
public Cache getCache() {
return cache;
}
public void setCache(Cache cache) {
this.cache = cache;
}
public Debug getDebug() {
return debug;
}
public void setDebug(Debug debug) {
this.debug = debug;
}
public Resource getResource() {
return resource;
}
public void setResource(Resource resource) {
this.resource = resource;
}
public ResponseCode getResponseCode() {
return responseCode;
}
public void setResponseCode(ResponseCode responseCode) {
this.responseCode = responseCode;
}
public Crud getCrud() {
return crud;
}
public void setCrud(Crud crud) {
this.crud = crud;
}
public Backup getBackup() {
return backup;
}
public void setSwaggerConfig(SwaggerConfig swaggerConfig) {
this.swaggerConfig = swaggerConfig;
public void setBackup(Backup backup) {
this.backup = backup;
}
}
......@@ -197,12 +197,16 @@ public class MagicConfiguration {
/**
* 打印banner
*/
public void printBanner() {
public void printBanner(List<String> plugins) {
System.out.println(" __ __ _ _ ____ ___ ");
System.out.println(" | \\/ | __ _ __ _ (_) ___ / \\ | _ \\|_ _|");
System.out.println(" | |\\/| | / _` | / _` || | / __| / _ \\ | |_) || | ");
System.out.println(" | | | || (_| || (_| || || (__ / ___ \\ | __/ | | ");
System.out.println(" |_| |_| \\__,_| \\__, ||_| \\___|/_/ \\_\\|_| |___|");
System.out.println(" |___/ " + RequestHandler.class.getPackage().getImplementationVersion());
if(!plugins.isEmpty()){
System.out.println("集成插件:");
plugins.stream().peek(it -> System.out.print("- ")).forEach(System.out::println);
}
}
}
package org.ssssssss.magicapi.core.config;
import org.ssssssss.magicapi.core.model.Plugin;
import org.ssssssss.magicapi.core.web.MagicControllerRegister;
public interface MagicPluginConfiguration {
Plugin plugin();
/**
* 注册Controller
*/
default MagicControllerRegister controllerRegister(){
return (mapping, configuration) -> { };
}
}
package org.ssssssss.magicapi.spring.boot.starter;
package org.ssssssss.magicapi.core.config;
/**
* 分页配置
*
* @author mxd
*/
public class PageConfig {
public class Page {
/**
* 默认page表达式
......
package org.ssssssss.magicapi.spring.boot.starter;
package org.ssssssss.magicapi.core.config;
/**
* 接口存储配置
*
* @author mxd
*/
public class ResourceConfig {
public class Resource {
/**
* 存储类型,默认是文件
......
package org.ssssssss.magicapi.spring.boot.starter;
package org.ssssssss.magicapi.core.config;
/**
* json结果code配置
......@@ -6,7 +6,7 @@ package org.ssssssss.magicapi.spring.boot.starter;
* @author mxd
* @since 1.1.2
*/
public class ResponseCodeConfig {
public class ResponseCode {
/**
* 执行成功的code值
......
package org.ssssssss.magicapi.spring.boot.starter;
package org.ssssssss.magicapi.core.config;
/**
* 安全配置
......@@ -6,7 +6,7 @@ package org.ssssssss.magicapi.spring.boot.starter;
* @author mxd
* @since 0.4.0
*/
public class SecurityConfig {
public class Security {
/**
* 登录用的用户名
......
package org.ssssssss.magicapi.core.model;
public class Plugin {
/**
* 插件名
*/
private String name;
/**
* js文件名
*/
private String javascriptFilename;
public Plugin(String name, String javascriptFilename) {
this.name = name;
this.javascriptFilename = javascriptFilename;
}
public Plugin(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJavascriptFilename() {
return javascriptFilename;
}
public void setJavascriptFilename(String javascriptFilename) {
this.javascriptFilename = javascriptFilename;
}
}
package org.ssssssss.magicapi.core.web;
import org.ssssssss.magicapi.core.config.MagicConfiguration;
import org.ssssssss.magicapi.utils.Mapping;
public interface MagicControllerRegister {
void register(Mapping mapping, MagicConfiguration configuration);
}
......@@ -47,14 +47,17 @@ public class MagicWorkbenchController extends MagicController implements MagicEx
private static final Logger logger = LoggerFactory.getLogger(MagicWorkbenchController.class);
private final String secretKey;
private static final Pattern SINGLE_LINE_COMMENT_TODO = Pattern.compile("((TODO)|(todo)|(fixme)|(FIXME))[ \t]+[^\n]+");
private static final Pattern MULTI_LINE_COMMENT_TODO = Pattern.compile("((TODO)|(todo)|(fixme)|(FIXME))[ \t]+[^\n(?!*/)]+");
public MagicWorkbenchController(MagicConfiguration configuration, String secretKey) {
private final String secretKey;
private final List<Plugin> plugins;
public MagicWorkbenchController(MagicConfiguration configuration, List<Plugin> plugins, String secretKey) {
super(configuration);
this.plugins = plugins;
this.secretKey = secretKey;
// 给前端添加代码提示
MagicScriptEngine.addScriptClass(SQLModule.class);
......@@ -143,6 +146,13 @@ public class MagicWorkbenchController extends MagicController implements MagicEx
return new JsonBean<>();
}
@GetMapping("/plugins")
@Valid(requireLogin = false)
@ResponseBody
public JsonBean<List<Plugin>> plugins(){
return new JsonBean<>(plugins);
}
@RequestMapping("/options")
@ResponseBody
......
......@@ -6,7 +6,7 @@
<parent>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-parent</artifactId>
<version>2.0.0-alpha.1</version>
<version>2.0.0-alpha.2</version>
</parent>
<artifactId>magic-editor</artifactId>
<packaging>jar</packaging>
......
因为 它太大了无法显示 source diff 。你可以改为 查看blob
因为 它太大了无法显示 source diff 。你可以改为 查看blob
import"./app.606db4d6.js";import"./vue.f3fe741d.js";import"./vendor.f140c5b8.js";import"./axios.23e7b955.js";const s=function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const e of document.querySelectorAll('link[rel="modulepreload"]'))i(e);new MutationObserver(e=>{for(const r of e)if(r.type==="childList")for(const o of r.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&i(o)}).observe(document,{childList:!0,subtree:!0});function n(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerpolicy&&(r.referrerPolicy=e.referrerpolicy),e.crossorigin==="use-credentials"?r.credentials="include":e.crossorigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function i(e){if(e.ep)return;e.ep=!0;const r=n(e);fetch(e.href,r)}};s();
import"./app.b70c1c3e.js";import"./vue.2ce67a83.js";import"./vendor.f140c5b8.js";import"./axios.23e7b955.js";const s=function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const e of document.querySelectorAll('link[rel="modulepreload"]'))i(e);new MutationObserver(e=>{for(const r of e)if(r.type==="childList")for(const o of r.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&i(o)}).observe(document,{childList:!0,subtree:!0});function n(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerpolicy&&(r.referrerPolicy=e.referrerpolicy),e.crossorigin==="use-credentials"?r.credentials="include":e.crossorigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function i(e){if(e.ep)return;e.ep=!0;const r=n(e);fetch(e.href,r)}};s();
此差异已折叠。
此差异已折叠。
......@@ -23,12 +23,12 @@
@keyframes stretch {0% {transform: scale(1);}25% {transform: scale(1.2);}50% {transform: scale(1);}100% {transform: scale(1);}}
@keyframes blink-loading {0% {opacity: 1;}50% {opacity: 0.5;}100% {opacity: 1;}}
</style>
<script type="module" crossorigin src="./assets/index.fbab38f6.js"></script>
<link rel="modulepreload" href="./assets/vue.f3fe741d.js">
<script type="module" crossorigin src="./assets/index.611c2146.js"></script>
<link rel="modulepreload" href="./assets/vue.2ce67a83.js">
<link rel="modulepreload" href="./assets/axios.23e7b955.js">
<link rel="modulepreload" href="./assets/vendor.f140c5b8.js">
<link rel="modulepreload" href="./assets/app.606db4d6.js">
<link rel="stylesheet" href="./assets/style.226f789e.css">
<link rel="modulepreload" href="./assets/app.b70c1c3e.js">
<link rel="stylesheet" href="./assets/style.b80c2317.css">
</head>
<body>
<div class="magic-loading-wrapper" id="magic-loading-wrapper">
......
......@@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-parent</artifactId>
<version>2.0.0-alpha.1</version>
<version>2.0.0-alpha.2</version>
<packaging>pom</packaging>
<name>magic-api-parent</name>
<description>auto generate http api</description>
......@@ -31,12 +31,10 @@
<properties>
<spring-boot.version>2.4.5</spring-boot.version>
<magic-script.version>1.6.4</magic-script.version>
<elasticsearch.version>7.15.0</elasticsearch.version>
<commons-compress.version>1.21</commons-compress.version>
<commons-io.version>2.7</commons-io.version>
<commons-text.version>1.6</commons-text.version>
<commons-beanutils.version>1.9.4</commons-beanutils.version>
<swagger.version>2.9.2</swagger.version>
<fastjson.version>1.2.75</fastjson.version>
<spring-boot-starter-log4j.version>1.3.8.RELEASE</spring-boot-starter-log4j.version>
<java.version>1.8</java.version>
......@@ -48,7 +46,8 @@
<module>magic-api</module>
<module>magic-editor</module>
<module>magic-api-spring-boot-starter</module>
</modules>
<module>magic-api-plugins</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
......@@ -98,16 +97,6 @@
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册