Skip to content

Bump org.json:json from 20230227 to 20231013 in /server/api-service/lowcoder-dependencies #768

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
New plugin system
* Add support for SUPER_ADMIN role
* Publish server log events
* Add handling for audit logs feature
* Add handling for geolocation data
* Add handling for api delays in case of rate limit
* Propagate plugin specific environment variables to plugins
* Add environment variable for controlling plugin location
* Implemented plugin endpoints security

---------

Co-authored-by: Abdul Qadir <abdul.qadir@ikhwatech.com>
  • Loading branch information
ludomikula and aq-ikhwa-tech committed Mar 5, 2024
commit 20f5bc87aa0f612908c1e1020489acd24c0abe16
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ client/node_modules/
client/packages/lowcoder-plugin-demo/.yarn/install-state.gz
client/packages/lowcoder-plugin-demo/yarn.lock
client/packages/lowcoder-plugin-demo/.yarn/cache/@types-node-npm-16.18.68-56f72825c0-094ae9ed80.zip
application-dev.yml
20 changes: 11 additions & 9 deletions deploy/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,14 @@
## Build Lowcoder api-service application
##
FROM maven:3.9-eclipse-temurin-17 AS build-api-service

# Build lowcoder-api
COPY ./server/api-service /lowcoder-server
WORKDIR /lowcoder-server
RUN --mount=type=cache,target=/root/.m2 mvn -f pom.xml clean package -DskipTests

# Create required folder structure
RUN mkdir -p /lowcoder/api-service/plugins /lowcoder/api-service/config /lowcoder/api-service/logs

# Define lowcoder main jar and plugin jars
ARG JAR_FILE=/lowcoder-server/lowcoder-server/target/lowcoder-server-*.jar
ARG PLUGIN_JARS=/lowcoder-server/lowcoder-plugins/*/target/*.jar

# Copy lowcoder server application and plugins
RUN cp ${JAR_FILE} /lowcoder/api-service/server.jar \
&& cp ${PLUGIN_JARS} /lowcoder/api-service/plugins/
RUN mkdir -p /lowcoder/api-service/config /lowcoder/api-service/logs /lowcoder/plugins

# Copy lowcoder server configuration
COPY server/api-service/lowcoder-server/src/main/resources/selfhost/ce/application.yml /lowcoder/api-service/config/
Expand Down Expand Up @@ -43,6 +37,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends gosu \
# Copy lowcoder server configuration
COPY --chown=lowcoder:lowcoder --from=build-api-service /lowcoder/api-service /lowcoder/api-service

# Copy lowcoder api service app, dependencies and libs
COPY --chown=lowcoder:lowcoder --from=build-api-service /lowcoder-server/distribution/target/lowcoder-api-service-bin/app /lowcoder/api-service/app
COPY --chown=lowcoder:lowcoder --from=build-api-service /lowcoder-server/distribution/target/lowcoder-api-service-bin/dependencies /lowcoder/api-service/dependencies
COPY --chown=lowcoder:lowcoder --from=build-api-service /lowcoder-server/distribution/target/lowcoder-api-service-bin/libs /lowcoder/api-service/libs
COPY --chown=lowcoder:lowcoder --from=build-api-service /lowcoder-server/distribution/target/lowcoder-api-service-bin/plugins /lowcoder/api-service/plugins
COPY --chown=lowcoder:lowcoder --from=build-api-service /lowcoder-server/distribution/target/lowcoder-api-service-bin/set-classpath.sh /lowcoder/api-service/set-classpath.sh

EXPOSE 8080
CMD [ "sh" , "/lowcoder/api-service/entrypoint.sh" ]

Expand Down Expand Up @@ -202,6 +203,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-instal

# Add lowcoder api-service
COPY --chown=lowcoder:lowcoder --from=lowcoder-ce-api-service /lowcoder/api-service /lowcoder/api-service
RUN mkdir -p /lowcoder/plugins/ && chown lowcoder:lowcoder /lowcoder/plugins/

# Add lowcoder node-service
COPY --chown=lowcoder:lowcoder --from=lowcoder-ce-node-service /lowcoder/node-service /lowcoder/node-service
Expand Down
6 changes: 5 additions & 1 deletion deploy/docker/api-service/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@ ${JAVA_HOME}/bin/java -version
echo

cd /lowcoder/api-service
source set-classpath.sh

exec gosu ${USER_ID}:${GROUP_ID} ${JAVA_HOME}/bin/java \
-Djava.util.prefs.userRoot=/tmp \
-Djava.security.egd=file:/dev/./urandom \
-Dhttps.protocols=TLSv1.1,TLSv1.2 \
-Dlog4j2.formatMsgNoLookups=true \
-Dspring.config.location="file:///lowcoder/api-service/config/application.yml,file:///lowcoder/api-service/config/application-selfhost.yml" \
--add-opens java.base/java.nio=ALL-UNNAMED \
-cp "${LOWCODER_CLASSPATH:=.}" \
${JAVA_OPTS} \
-jar "${APP_JAR}" --spring.webflux.base-path=${CONTEXT_PATH} ${CUSTOM_APP_PROPERTIES}
org.lowcoder.api.ServerApplication --spring.webflux.base-path=${CONTEXT_PATH} ${CUSTOM_APP_PROPERTIES}

6 changes: 3 additions & 3 deletions server/api-service/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ dependency-reduced-pom.xml
.run/**
logs/**
tmp/**
/openblocks-server/logs/

# Ignore plugin.properties which are generated dynamically
**/plugin.properties

# to ignore the node_modeules folder
node_modules
Expand All @@ -34,5 +35,4 @@ package-lock.json
# test coverage
coverage-summary.json
app/client/cypress/locators/Widgets.json
/openblocks-domain/logs/
application-lowcoder.yml
application-lowcoder.yml
122 changes: 122 additions & 0 deletions server/api-service/PLUGIN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Lowcoder plugin system (WIP)

This is an ongoing effort to refactor current plugin system based on pf4j library.

## Reasoning

1. create a cleaner and simpler plugin system with clearly defined purpose(s) (new endpoints, new datasource types, etc..)
2. lowcoder does not need live plugin loading/reloading/unloading/updates, therefore the main feature of pf4j is rendered useless, in fact it adds a lot of complexity due to classloaders used for managing plugins (especially in spring/boot applications)
3. simpler and easier plugin detection - just a jar with a class implementing a common interface (be it a simple pojo project or a complex spring/boot implementation)

## How it works

The main entrypoint for plugin system is in **lowcoder-server** module with class **org.lowcoder.api.framework.configuration.PluginConfiguration**
It creates:
- LowcoderPluginManager bean which is responsible for plugin lifecycle management
- Adds plugin defined endpoints to lowcoder by creating **pluginEndpoints** bean
- TODO: Adds plugin defined datasources to lowcoder by creating **pluginDatasources** bean

### lowcoder-plugin-api library

This library contains APIs for plugin implementations.
It is used by both, lowcoder API server as well as all plugins.

### PluginLoader

The sole purpose of a PluginLoader is to find plugin candidates and load them into VM.
There is currently one implementation that based on paths - **PathBasedPluginLoader**, it:
- looks in folders and subfolders defined in **application.yaml** - entries can point to a folder or specific jar file. If a relative path is supplied, the location of lowcoder API server application jar is used as parent folder (when run in non-packaged state, eg. in IDE, it uses the folder where ServerApplication.class is generated)

```yaml
common:
plugin-dirs:
- plugins
- /some/custom/path/myGreatPlugin.jar
```
- finds all **jar**(s) and inspects them for classes implementing **LowcoderPlugin** interface
- instantiates all LowcoderPlugin implementations

### LowcoderPluginManager

The main job of plugin manager is to:
- register plugins found and instantiated by **PluginLoader**
- start registered plugins by calling **LowcoderPlugin.load()** method
- create and register **RouterFunction**(s) for all loaded plugin endpoints
- TODO: create and register datasources for all loaded plugin datasources

## Plugin project structure

Plugin jar can be structured in any way you like. It can be a plain java project, but also a spring/boot based project or based on any other framework.

It is composed from several parts:
- class(es) implementing **LowcoderPlugin** interface
- class(es) implementing **LowcoderEndpoint** interface, containing endpoint handler functions marked with **@EndpointExtension** annotation. These functions must obey following format:

```java
@EndpointExtension(uri = <endpoint uri>, method = <HTTP method>)
public Mono<ServerResponse> <handler name>(ServerRequest request)
{
... your endpoint logic implementation
}

for example:

@EndpointExtension(uri = "/hello-world", method = Method.GET)
public Mono<ServerResponse> helloWorld(ServerRequest request)
{
return ServerResponse.ok().body(Mono.just(Hello.builder().message("Hello world!").build()), Hello.class);
}
```
- TODO: class(es) impelemting **LowcoderDatasource** interface

### LowcoderPlugin implementations

Methods of interest:
- **pluginId()** - unique plugin ID - if a plugin with such ID is already loaded, subsequent plugins whith this ID will be ignored
- **description()** - short plugin description
- **load(ApplicationContext parentContext)** - is called during plugin startup - this is the place where you should completely initialize your plugin. If initialization fails, return false
- **unload()** - is called during lowcoder API server shutdown - this is the place where you should release all resources
- **endpoints()** - needs to contain all initialized **PluginEndpoints** you want to expose, for example:

```java
@Override
public List<PluginEndpoint> endpoints()
{
List<PluginEndpoint> endpoints = new ArrayList<>();

endpoints.add(new HelloWorldEndpoint());

return endpoints;
}
```
- **pluginInfo()** - should return a record object with additional information about your plugin. It is serialized to JSON as part of the **/plugins** listing (see **"info"** object in this example):

```json
[
{
"id": "example-plugin",
"description": "Example plugin for lowcoder platform",
"info": {}
},
{
"id": "enterprise",
"description": "Lowcoder enterprise plugin",
"info": {
"enabledFeatures": [
"endpointApiUsage"
]
}
}
]
```

## TODOs

1. Implement endpoint security - currently all plugin endpoints are public (probably by adding **security** attribute to **@EndpointExtension** and enforcing it)


## QUESTIONS / CONSIDERATIONS

1. currently the plugin endpoints are prefixed with **/plugin/{pluginId}/** - this is hardcoded, do we want to make it configurable?


84 changes: 84 additions & 0 deletions server/api-service/distribution/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<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>
<parent>
<groupId>org.lowcoder</groupId>
<artifactId>lowcoder-root</artifactId>
<version>${revision}</version>
</parent>

<artifactId>distribution</artifactId>
<packaging>pom</packaging>

<properties>
<assembly.lib.directory>${project.build.directory}/dependencies</assembly.lib.directory>
</properties>


<!-- Dependency added here only to make sure this module is built after
everything alse was built -->
<dependencies>
<dependency>
<groupId>org.lowcoder</groupId>
<artifactId>lowcoder-sdk</artifactId>
</dependency>
<dependency>
<groupId>org.lowcoder</groupId>
<artifactId>lowcoder-infra</artifactId>
</dependency>
<dependency>
<groupId>org.lowcoder</groupId>
<artifactId>lowcoder-domain</artifactId>
</dependency>
<dependency>
<groupId>org.lowcoder</groupId>
<artifactId>lowcoder-server</artifactId>
</dependency>
</dependencies>

<build>
<finalName>lowcoder-api-service</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${assembly.lib.directory}</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<prependGroupId>true</prependGroupId>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>distro-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<attach>false</attach>
<descriptors>
<descriptor>src/assembly/bin.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
72 changes: 72 additions & 0 deletions server/api-service/distribution/src/assembly/bin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.2.0 http://maven.apache.org/xsd/assembly-2.2.0.xsd">
<id>bin</id>
<formats>
<format>dir</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>

<files>
<file>
<source>src/assembly/set-classpath.sh</source>
<outputDirectory></outputDirectory>
</file>
</files>
<fileSets>
<fileSet>
<directory>${assembly.lib.directory}</directory>
<outputDirectory>dependencies</outputDirectory>
<excludes>
<exclude>${project.groupId}:*</exclude>
</excludes>
</fileSet>
</fileSets>

<moduleSets>
<!-- Main lowcoder API server application -->
<moduleSet>
<useAllReactorProjects>true</useAllReactorProjects>
<includes>
<include>org.lowcoder:lowcoder-server</include>
</includes>
<binaries>
<outputDirectory>app</outputDirectory>
<includeDependencies>false</includeDependencies>
<unpack>false</unpack>
</binaries>
</moduleSet>

<!-- Lowcoder API server dependencies -->
<moduleSet>
<useAllReactorProjects>true</useAllReactorProjects>
<includes>
<include>org.lowcoder:lowcoder-domain</include>
<include>org.lowcoder:lowcoder-infra</include>
<include>org.lowcoder:lowcoder-sdk</include>
</includes>
<binaries>
<outputDirectory>libs</outputDirectory>
<includeDependencies>false</includeDependencies>
<unpack>false</unpack>
</binaries>
</moduleSet>

<!-- Lowcoder plugins -->
<moduleSet>
<useAllReactorProjects>true</useAllReactorProjects>
<includeSubModules>true</includeSubModules>
<includes>
<include>org.lowcoder:*Plugin</include>
</includes>
<excludes>
<exclude>org.lowcoder:sqlBasedPlugin</exclude>
</excludes>
<binaries>
<outputDirectory>plugins</outputDirectory>
<includeDependencies>false</includeDependencies>
<unpack>false</unpack>
</binaries>
</moduleSet>
</moduleSets>
</assembly>
11 changes: 11 additions & 0 deletions server/api-service/distribution/src/assembly/set-classpath.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

#
# Set lowcoder api service classpath for use in startup script
#
export LOWCODER_CLASSPATH="`find libs/ dependencies/ app/ -type f -name "*.jar" | tr '\n' ':' | sed -e 's/:$//'`"

#
# Example usage:
#
# java -cp "${LOWCODER_CLASSPATH}" org.lowcoder.api.ServerApplication
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy