Skip to content

Commit

Permalink
Merge pull request #4 from rollno748/ver1
Browse files Browse the repository at this point in the history
updated ver 2.1 changes
  • Loading branch information
rollno748 committed Sep 8, 2023
2 parents 6905b86 + d802a11 commit 4f431fc
Show file tree
Hide file tree
Showing 16 changed files with 237 additions and 123 deletions.
53 changes: 34 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ In situations where specific hosts lack internet access, this tool enables the t
## Required Components
1. Java 8 or above

## Features
1. Downloads plugins and their associated dependent libraries to local storage.
2. Stores all information in an SQLITE DB.
3. Provides a UI to upload custom plugins restricted to sharing within the organization.
4. Creates and exposes a modified API to retrieve plugin info for JMeter Plugin Manager.
5. Easily configurable scheduler to check for newly available plugins/versions in the market.

## Available APIs

| Service | HTTP Method | URI |
|:----------------------|:-----------:|:------------------------------------------|
| App Running Status | GET | http://<hostname/IP>:\<port>/v1/status |
| Get Plugins | GET | http://<hostname/IP>:\<port>/v1/plugins |
| Upload Custom Plugin | GET | http://<hostname/IP>:\<port>/v1/upload |
| View Plugins in table | GET | http://<hostname/IP>:\<port>/v1/dashboard |

## Creating Properties file
create a properties file with the below contents.

Expand All @@ -26,39 +42,33 @@ db.timeout.secs=300
jmeter.plugins.url=https://jmeter-plugins.org/repo/
mvn.repo.url=https://mvnrepository.com/search?q=

# DB Connection Pool configuration
db.min.threads=2
db.max.threads=10
db.timeout.secs=300

# External APIs
jmeter.plugins.url=https://jmeter-plugins.org/repo/
mvn.repo.url=https://mvnrepository.com/search?q=

# Directory Configs
local.repo.path=/app/plugins-manager/

# Uncomment the below if you are running this on Windows
local.repo.path=C:\\Temp\\plugins-manager\\
# local.repo.path=C:\\Temp\\plugins-manager\\
```

## Available APIs

| Service | HTTP Method | URI |
|:-------------------|:-----------:|:----------------------------------------|
| App Running Status | GET | http://<hostname/IP>:\<port>/v1/ |
| Get Plugins | GET | http://<hostname/IP>:\<port>/v1/plugins |
| Upload Custom Plugin | GET | http://<hostname/IP>:\<port>/v1/upload |



## How to Set up

* Download the Latest release from [here](https://github.com/rollno748/Jmeter-local-plugins-manager/tags)
* Create `configuration.properties` file
* Run the JAR (java -jar jmeter-local-plugins-manager-2.0.jar -c configuration.properties)
* Go to the JMeter installed directory and set `jpgc.repo.address` (this should be the local plugins manager API) in the jmeter.properties

## Features
1. Downloads plugins and their associated dependent libraries to local storage.
2. Stores all information in an SQLITE DB.
3. Provides a UI to upload custom plugins restricted to sharing within the organization.
4. Creates and exposes a modified API to retrieve plugin info for JMeter Plugin Manager.
5. Easily configurable scheduler to check for newly available plugins/versions in the market.

## Uploading Custom plugin
![Custom Upload Form](/img/upload-form.jpg)


## How it works ?

* Acts as an independent server that polls the plugins manager for updates (configurable).
Expand All @@ -69,6 +79,11 @@ local.repo.path=C:\\Temp\\plugins-manager\\
- Custom Plugins API
- Merged (Public and Custom) Plugins API

## Detailed Instructions

* Detailed instructions is available at [Medium](https://rollno748.medium.com/creating-your-own-jmeter-plugin-manager-a-comprehensive-guide-aaa57021dda9)


## Tools used
- Spark java framework
- Sqlite DB
Expand All @@ -83,4 +98,4 @@ If this project help you reduce time to develop, you can give me a cup of coffee
Please rate a star(:star2:) - If you like it.

Please open up a bug(:beetle:) - If you experience abnormalities.

4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>io.perfwise.local.pluginsmanager</groupId>
<artifactId>jmeter-local-plugins-manager</artifactId>
<version>2.0</version>
<version>2.1</version>

<properties>
<spark-java>2.9.4</spark-java>
Expand All @@ -13,7 +13,7 @@
<httpclient-version>4.5.14</httpclient-version>
<json-version>20230618</json-version>
<gson-version>2.8.9</gson-version>
<jackson-databind-version>2.12.5</jackson-databind-version>
<jackson-databind-version>2.12.7.1</jackson-databind-version>
<jsoup-version>1.16.1</jsoup-version>
<logback-version>1.2.6</logback-version>
<commons-fileupload>1.5</commons-fileupload>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ public void loadRestApiServices() {
"</div></body></html>";
});

get("/dashboard", (req, res) -> {
res.type("text/html");
res.redirect("/dashboard.html");
return null;
});

get("/upload", (req, res) -> {
res.type("text/html");
res.redirect("/");
Expand All @@ -129,6 +135,13 @@ public void loadRestApiServices() {
}
});

get("/plugins-table", (req, res) -> {
res.type("application/json");
String type = req.queryParams("type");
PluginService pluginService = new PluginServiceImpl();
return pluginService.getPluginTable();
});

post("/upload", (req, res) -> {
req.attribute("org.eclipse.jetty.multipartConfig", new MultipartConfigElement("/temp"));
UploadService uploadService = new UploadServiceImpl(this.customPluginsPath, this.libPath);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package io.perfwise.local.pluginsmanager.model;


import com.fasterxml.jackson.annotation.JsonProperty;
import org.json.JSONObject;

public class MetadataModel {
@JsonProperty("id")
Expand Down
97 changes: 0 additions & 97 deletions src/main/java/io/perfwise/local/pluginsmanager/model/Plugin.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public class HttpRequest {
private static final String INSERT_PLUGIN_INFO = "INSERT INTO plugins (id, name, type, description, helpUrl, markerClass, screenshotUrl, vendor, versions_count) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static final String SELECT_PLUGIN_VERSION_METADATA = "SELECT COUNT(*) AS COUNT FROM METADATA WHERE ID = ? AND VERSION = ?";
private static final String SELECT_PLUGINS = "SELECT ID, NAME, DESCRIPTION, HELPURL, MARKERCLASS, SCREENSHOTURL, VENDOR FROM plugins";
private static final String SELECT_PLUGINS_TABLE_DATA = "SELECT ID, NAME, TYPE, DESCRIPTION, HELPURL, MARKERCLASS, SCREENSHOTURL, VENDOR, VERSIONS_COUNT FROM plugins";
private static final String SELECT_PLUGINS_WITH_FILTER = "SELECT ID, NAME, DESCRIPTION, HELPURL, MARKERCLASS, SCREENSHOTURL, VENDOR FROM plugins WHERE type = ?";
private static final String SELECT_METADATA_BY_ID = "SELECT ID, VERSION, DOWNLOADURL, LIBS FROM metadata WHERE ID = ?";

Expand Down Expand Up @@ -226,6 +227,43 @@ public JSONArray getCustomPlugins() {
return fetchPluginsFromLocalDB(SELECT_PLUGINS_WITH_FILTER, "custom");
}

public JSONArray getAllPluginsTableData() {
return fetchAllPluginsTableData();
}

private JSONArray fetchAllPluginsTableData() {
JSONArray jsonArray = new JSONArray();
try{
if(conn == null || conn.isClosed()){
conn = SQLiteConnectionPool.getConnection();
}
PreparedStatement preparedStatement = conn.prepareStatement(HttpRequest.SELECT_PLUGINS_TABLE_DATA);
ResultSet rs = preparedStatement.executeQuery();

while (rs.next()) {
JSONObject pluginObject = new JSONObject();
JSONObject libraryObj;

pluginObject.put("id", rs.getString("id"));
pluginObject.put("name", rs.getString("name"));
pluginObject.put("type", rs.getString("type"));
pluginObject.put("description", rs.getString("description"));
pluginObject.put("helpUrl", rs.getString("helpUrl"));
pluginObject.put("markerClass", rs.getString("markerClass"));
pluginObject.put("screenshotUrl", rs.getString("screenshotUrl"));
pluginObject.put("vendor", rs.getString("vendor"));
pluginObject.put("versions_count", rs.getString("versions_count"));
jsonArray.put(pluginObject);
}
preparedStatement.close();
}catch(SQLException | InterruptedException e){
LOGGER.error("Exception occurred while fetching plugins information");
} finally {
SQLiteConnectionPool.releaseConnection(conn);
}
return jsonArray;
}

private JSONObject getDependentLibraryObj(String id, String type) throws UnknownHostException {

String host = InetAddress.getLocalHost().getHostAddress();
Expand Down Expand Up @@ -404,5 +442,4 @@ public Properties getProps() {
public void setProps(Properties props) {
this.props = props;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ public static JSONArray getCustomPlugins() {
return httpRequest.getCustomPlugins();
}

public static JSONArray getPluginsTableData() {
return httpRequest.getAllPluginsTableData();
}

public void downloadMissingPlugins(JSONArray missingPluginsList) throws URISyntaxException, IOException {
for (int i = 0; i < missingPluginsList.length(); i++) {
httpRequest.downloadMissingPlugins(missingPluginsList.getJSONObject(i));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ public interface PluginService {
JSONArray getAllPlugins();
JSONArray getPublicPlugins();
JSONArray getCustomPlugins();
JSONArray getPluginTable();
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,11 @@ public JSONArray getPublicPlugins() {
public JSONArray getCustomPlugins() {
return Parse.getCustomPlugins();
}

@Override
public JSONArray getPluginTable() {
return Parse.getPluginsTableData();
}


}
30 changes: 30 additions & 0 deletions src/main/resources/public/assets/css/dashboard.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#tableInput {
background-image: url('./../ico/search.png');
background-position: 10px 12px;
background-repeat: no-repeat;
width: 97%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}

#pluginTable {
border-collapse: collapse;
width: 100%;
border: 1px solid #ddd;
font-size: 18px;
}

#pluginTable th, #pluginTable td {
text-align: left;
padding: 12px;
}

#pluginTable tr {
border-bottom: 1px solid #ddd;
}

#pluginTable tr.header, #pluginTable tr:hover {
background-color: #f1f1f1;
}
File renamed without changes.
Binary file added src/main/resources/public/assets/ico/search.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 4f431fc

Please sign in to comment.