Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7a3b3e5

Browse files
committed
new: extend new plugin system
1 parent 63d5dde commit 7a3b3e5

File tree

6 files changed

+18
-479
lines changed

6 files changed

+18
-479
lines changed

server/api-service/lowcoder-server/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@
215215
<version>0.11.5</version>
216216
<scope>runtime</scope>
217217
</dependency>
218+
<dependency>
218219
<groupId>org.springframework</groupId>
219220
<artifactId>spring-aspects</artifactId>
220221
</dependency>

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/configuration/PluginConfiguration.java

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
import java.util.ArrayList;
44

55
import org.lowcoder.api.framework.plugin.LowcoderPluginManager;
6-
import org.lowcoder.api.framework.plugin.PluginLoader;
7-
import org.springframework.context.ApplicationContext;
6+
import org.lowcoder.api.framework.plugin.endpoint.PluginEndpointHandler;
87
import org.springframework.context.annotation.Bean;
98
import org.springframework.context.annotation.Configuration;
109
import org.springframework.context.annotation.DependsOn;
@@ -20,24 +19,17 @@
2019
@Configuration
2120
public class PluginConfiguration
2221
{
23-
// private final ApplicationContext applicationContext;
24-
// private final PluginLoader pluginLoader;
25-
//
26-
// public LowcoderPluginManager lowcoderPluginManager()
27-
// {
28-
// return new LowcoderPluginManager(applicationContext, pluginLoader);
29-
// }
3022

3123
@SuppressWarnings("unchecked")
3224
@Bean
3325
@DependsOn("lowcoderPluginManager")
34-
RouterFunction<?> pluginEndpoints(LowcoderPluginManager pluginManager)
26+
RouterFunction<?> pluginEndpoints(LowcoderPluginManager pluginManager, PluginEndpointHandler pluginEndpointHandler)
3527
{
3628
RouterFunction<?> pluginsList = RouterFunctions.route()
3729
.GET(RequestPredicates.path("/plugins"), req -> ServerResponse.ok().body(Mono.just(pluginManager.getLoadedPluginsInfo()), ArrayList.class))
3830
.build();
3931

40-
RouterFunction<?> endpoints = pluginManager.getEndpoints().stream()
32+
RouterFunction<?> endpoints = pluginEndpointHandler.registeredEndpoints().stream()
4133
.map(r-> (RouterFunction<ServerResponse>)r)
4234
.reduce((o, r )-> (RouterFunction<ServerResponse>) o.andOther(r))
4335
.orElse(null);

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/plugin/LowcoderPluginManager.java

Lines changed: 2 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,20 @@
11
package org.lowcoder.api.framework.plugin;
22

3-
import static org.springframework.web.reactive.function.server.RequestPredicates.DELETE;
4-
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
5-
import static org.springframework.web.reactive.function.server.RequestPredicates.OPTIONS;
6-
import static org.springframework.web.reactive.function.server.RequestPredicates.PATCH;
7-
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
8-
import static org.springframework.web.reactive.function.server.RequestPredicates.PUT;
9-
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
10-
11-
import java.lang.reflect.InvocationTargetException;
12-
import java.lang.reflect.Method;
133
import java.util.ArrayList;
144
import java.util.Comparator;
155
import java.util.LinkedHashMap;
166
import java.util.List;
177
import java.util.Map;
188

199
import org.apache.commons.collections4.CollectionUtils;
20-
import org.apache.commons.lang3.StringUtils;
21-
import org.lowcoder.api.framework.plugin.data.PluginServerRequest;
22-
import org.lowcoder.plugin.api.EndpointExtension;
2310
import org.lowcoder.plugin.api.LowcoderPlugin;
2411
import org.lowcoder.plugin.api.LowcoderServices;
25-
import org.lowcoder.plugin.api.PluginEndpoint;
26-
import org.lowcoder.plugin.api.data.EndpointRequest;
27-
import org.lowcoder.plugin.api.data.EndpointResponse;
28-
import org.lowcoder.sdk.exception.BaseException;
29-
import org.springframework.core.ResolvableType;
30-
import org.springframework.http.ResponseCookie;
3112
import org.springframework.stereotype.Component;
32-
import org.springframework.web.reactive.function.server.RequestPredicate;
33-
import org.springframework.web.reactive.function.server.RouterFunction;
34-
import org.springframework.web.reactive.function.server.ServerResponse;
35-
import org.springframework.web.reactive.function.server.ServerResponse.BodyBuilder;
3613

3714
import jakarta.annotation.PostConstruct;
3815
import jakarta.annotation.PreDestroy;
3916
import lombok.RequiredArgsConstructor;
4017
import lombok.extern.slf4j.Slf4j;
41-
import reactor.core.publisher.Mono;
4218

4319
@RequiredArgsConstructor
4420
@Component
@@ -49,7 +25,6 @@ public class LowcoderPluginManager
4925
private final PluginLoader pluginLoader;
5026

5127
private Map<String, LowcoderPlugin> plugins = new LinkedHashMap<>();
52-
private List<RouterFunction<ServerResponse>> routes = new ArrayList<>();
5328

5429
@PostConstruct
5530
private void loadPlugins()
@@ -60,11 +35,8 @@ private void loadPlugins()
6035

6136
for (LowcoderPlugin plugin : sorted)
6237
{
63-
if (plugin.load(lowcoderServices))
64-
{
65-
log.info("Plugin [{}] loaded successfully.", plugin.pluginId());
66-
registerEndpoints(plugin);
67-
}
38+
PluginExecutor executor = new PluginExecutor(plugin, lowcoderServices);
39+
executor.start();
6840
}
6941
}
7042

@@ -84,11 +56,6 @@ public void unloadPlugins()
8456
}
8557
}
8658

87-
public List<RouterFunction<ServerResponse>> getEndpoints()
88-
{
89-
return this.routes;
90-
}
91-
9259
public List<PluginInfo> getLoadedPluginsInfo()
9360
{
9461
List<PluginInfo> infos = new ArrayList<>();
@@ -121,130 +88,6 @@ private void registerPlugins()
12188
}
12289
}
12390

124-
125-
private void registerEndpoints(LowcoderPlugin plugin)
126-
{
127-
if (CollectionUtils.isNotEmpty(plugin.endpoints()))
128-
{
129-
for (PluginEndpoint endpoint : plugin.endpoints())
130-
{
131-
Method[] handlers = endpoint.getClass().getDeclaredMethods();
132-
if (handlers != null && handlers.length > 0)
133-
{
134-
for (Method handler : handlers)
135-
{
136-
registerEndpointHandler(plugin, endpoint, handler);
137-
}
138-
}
139-
}
140-
}
141-
}
142-
143-
private void registerEndpointHandler(LowcoderPlugin plugin, PluginEndpoint endpoint, Method handler)
144-
{
145-
if (handler.isAnnotationPresent(EndpointExtension.class))
146-
{
147-
if (checkHandlerMethod(handler))
148-
{
149-
150-
EndpointExtension endpointMeta = handler.getAnnotation(EndpointExtension.class);
151-
routes.add(route(createRequestPredicate(plugin, endpointMeta), req -> {
152-
Mono<ServerResponse> result = null;
153-
try
154-
{
155-
EndpointResponse response = (EndpointResponse)handler.invoke(endpoint, PluginServerRequest.fromServerRequest(req));
156-
result = createServerResponse(response);
157-
}
158-
catch (IllegalAccessException | InvocationTargetException cause)
159-
{
160-
throw new BaseException("Error running handler for [ " + endpointMeta.method() + ": " + endpointMeta.uri() + "] !");
161-
}
162-
return result;
163-
})
164-
);
165-
log.info("Registered plugin endpoint: {} -> {} -> {}: {}", plugin.pluginId(), endpoint.getClass().getSimpleName(), endpointMeta.method(), endpointMeta.uri());
166-
}
167-
else
168-
{
169-
log.error("Cannot register plugin endpoint: {} -> {} -> {}! Handler method must be defined as: public Mono<ServerResponse> {}(ServerRequest request)", plugin.pluginId(), endpoint.getClass().getSimpleName(), handler.getName(), handler.getName());
170-
}
171-
}
172-
}
173-
174-
private Mono<ServerResponse> createServerResponse(EndpointResponse pluginResponse)
175-
{
176-
/** Create response with given status **/
177-
BodyBuilder builder = ServerResponse.status(pluginResponse.statusCode());
178-
179-
/** Set response headers **/
180-
if (pluginResponse.headers() != null && !pluginResponse.headers().isEmpty())
181-
{
182-
pluginResponse.headers().entrySet()
183-
.forEach(entry -> {
184-
builder.header(entry.getKey(), entry.getValue().toArray(new String[] {}));
185-
});
186-
187-
}
188-
189-
/** Set cookies if available **/
190-
if (pluginResponse.cookies() != null && !pluginResponse.cookies().isEmpty())
191-
{
192-
pluginResponse.cookies().values()
193-
.forEach(cookies -> {
194-
cookies.forEach(cookie -> {
195-
builder.cookie(ResponseCookie.from(cookie.getKey(), cookie.getValue()).build());
196-
});
197-
198-
});
199-
}
200-
201-
/** Set response body if available **/
202-
if (pluginResponse.body() != null)
203-
{
204-
return builder.bodyValue(pluginResponse.body());
205-
}
206-
207-
return builder.build();
208-
}
209-
210-
private boolean checkHandlerMethod(Method method)
211-
{
212-
ResolvableType returnType = ResolvableType.forMethodReturnType(method);
213-
214-
return (returnType.getRawClass().isAssignableFrom(EndpointResponse.class)
215-
&& method.getParameterCount() == 1
216-
&& method.getParameterTypes()[0].isAssignableFrom(EndpointRequest.class)
217-
);
218-
}
219-
220-
private RequestPredicate createRequestPredicate(LowcoderPlugin plugin, EndpointExtension endpoint)
221-
{
222-
String basePath = "/plugins/" + plugin.pluginId();
223-
224-
switch(endpoint.method())
225-
{
226-
case GET:
227-
return GET(pluginEndpointUri(basePath, endpoint.uri()));
228-
case POST:
229-
return POST(pluginEndpointUri(basePath, endpoint.uri()));
230-
case PUT:
231-
return PUT(pluginEndpointUri(basePath, endpoint.uri()));
232-
case PATCH:
233-
return PATCH(pluginEndpointUri(basePath, endpoint.uri()));
234-
case DELETE:
235-
return DELETE(pluginEndpointUri(basePath, endpoint.uri()));
236-
case OPTIONS:
237-
return OPTIONS(pluginEndpointUri(basePath, endpoint.uri()));
238-
}
239-
return null;
240-
}
241-
242-
private String pluginEndpointUri(String basePath, String uri)
243-
{
244-
return StringUtils.join(basePath, StringUtils.prependIfMissing(uri, "/"));
245-
}
246-
247-
24891
private record PluginInfo(
24992
String id,
25093
String description,

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/framework/plugin/PathBasedPluginLoader.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,12 @@ protected List<String> findPluginCandidates(Path pluginsDir)
9797
protected List<LowcoderPlugin> loadPluginCandidates(String pluginJar)
9898
{
9999
List<LowcoderPlugin> pluginCandidates = new ArrayList<>();
100-
101-
PluginJarClassLoader pluginClassLoader = null;
100+
102101
try
103102
{
104-
pluginClassLoader = new PluginJarClassLoader(getClass().getClassLoader(), Path.of(pluginJar));
103+
Path pluginPath = Path.of(pluginJar);
104+
PluginClassLoader pluginClassLoader = new PluginClassLoader(pluginPath.getFileName().toString(), pluginPath);
105105

106-
107106
ServiceLoader<LowcoderPlugin> pluginServices = ServiceLoader.load(LowcoderPlugin.class, pluginClassLoader);
108107
if (pluginServices != null )
109108
{

0 commit comments

Comments
 (0)