Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ RestProvider/
│ │ ├── java/com/restprovider/
│ │ │ ├── App.java # Application entry point
│ │ │ ├── controllers/ # One class per integration controller
│ │ │ │ └── JavadocController.java # Generates and serves Javadocs
│ │ │ ├── core/ # Server bootstrap, registry, dispatcher
│ │ │ ├── domain/ # DTOs and service layer (azure, business, common, security)
│ │ │ └── util/ # Shared utilities (JsonUtil)
Expand All @@ -34,6 +35,7 @@ RestProvider/
│ └── test/
│ └── java/com/restprovider/
│ └── integration/ # Integration tests per controller
│ └── JavadocControllerIntegrationTest.java
├── data_files/ # Sample properties and response templates
│ ├── variable.properties
│ ├── sample_var.properties
Expand Down Expand Up @@ -72,6 +74,7 @@ All controllers currently shipped in the Java server are implemented natively.
| BrowserStack | Complete |
| Jenkins | Complete |
| JMeter | Complete |
| K6 | Complete |
| Postman | Complete |
| SonarQube | Complete |

Expand All @@ -82,6 +85,7 @@ All controllers currently shipped in the Java server are implemented natively.
| MSD | Complete |
| Oracle | Complete |
| PowerBI | Complete |
| Grafana | Complete |
| Snowflake | Complete |
| SQLServer | Complete |

Expand All @@ -95,6 +99,7 @@ All controllers currently shipped in the Java server are implemented natively.
| Misc | Complete |
| Office | Complete |
| OS | Complete |
| Javadoc | Complete |
| Sequence | Complete |
| String | Complete |
| Wait | Complete |
Expand Down Expand Up @@ -183,6 +188,7 @@ Representative routes:
4. System and utility:
- `GET /api/business/health`
- `GET /api/file/exists`, `POST /api/file/upload/local`
- `GET /api/javadoc/generate`, `GET /api/javadoc/docs`
- `GET /api/loganalytics/message`, `GET /api/loganalytics/message/startswith`
- `GET /api/misc/check/vpn`, `GET /api/misc/account/names`
- `POST /api/os/session/schedule`, `GET /api/os/env/variable`
Expand All @@ -192,6 +198,18 @@ Representative routes:

Route details and controller-specific aliases are documented in [java-server/README.md](java-server/README.md).

## Generated API Docs

Generated Javadocs are published by the Java server at:

- `GET /api/javadoc/docs` (or `http://localhost:8080/api/javadoc/docs` when running locally)

Important:

1. The `Javadoc` controller is disabled by default at startup.
2. Enable it before using documentation routes:
- `PUT /admin/controllers/javadoc/enabled?value=true`

## Enable or Disable Controllers

The Java server includes one central control method in [java-server/src/main/java/com/restprovider/core/ControllerRegistry.java](java-server/src/main/java/com/restprovider/core/ControllerRegistry.java):
Expand Down
3 changes: 3 additions & 0 deletions java-server/MIGRATION_STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ This file tracks the Java implementation status for each controller.
| Dataverse | 4 | Native | Native Dataverse route set implemented via SQL CLI with GET and POST query support, route aliases, runtime credential overrides, and required-field validation |
| FHIR | 4 | Native | Authenticated FHIR GET/POST/PUT/DELETE operations implemented via native HTTP with route-based resource paths, query aliases, token override support, and required-field validation |
| File | 31 | Native | Full file route set implemented including sorting, archive, sftp, local transfer, diff, and template-copy flows, with common routes accepting query-param aliases and required-file validation |
| Grafana | 4 | Native | Native authenticated Grafana GET, POST, PUT, and DELETE pass-through implemented with request alias routes, runtime token and base-URL overrides, and required-field validation |
| Jenkins | 4 | Native | Native Jenkins GET/POST/PUT/DELETE pass-through with auth implemented |
| Javadoc | 3 | Native | Native documentation generation and publish endpoints for building Javadocs and serving generated docs through HTTP |
| JMeter | 3 | Native | Native process-based jmeter version/server/script-run endpoints |
| K6 | 2 | Native | Native process-based k6 version and script-run endpoints |
| LogAnalytics | 3 | Native | Native log analytics message matching routes implemented with route aliases plus query/header aliases for run, workspace, and expected-message inputs |
| Misc | 15 | Native | Native misc route set implemented for VPN, heartbeat, time, process, variables, random, and credential flows, with tested routes accepting query/header aliases and required-field validation |
| MSD | 1 | Native | Native sqlcmd-backed MSD query execution implemented |
Expand Down
13 changes: 12 additions & 1 deletion java-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Java implementation of RestProvider controllers using Apache HttpComponents (Htt

## What this contains

- 31 Java controllers mirroring the existing controller names.
- 32 Java controllers mirroring the existing controller names.
- Apache HTTP server bootstrap using `ServerBootstrap`.
- Native controller implementations for every route-bearing domain.
- DTO and service layer split for cleaner domain boundaries.
Expand Down Expand Up @@ -83,6 +83,14 @@ Java implementation of RestProvider controllers using Apache HttpComponents (Htt
- `GET /api/jmeter/servers` (alias: `/api/jmeter/server/list`)
- `GET|POST /api/jmeter` (alias: `/api/jmeter/run`)
- Script execution accepts aliases for script and output settings (`scriptName`, `resultFile`, `jmeterLogFile`)
- Javadoc routes:
- `GET /api/javadoc/generate` (aliases: `/api/javadoc`, `/api/javadoc/build`) to generate project Javadocs via Maven
- `GET /api/javadoc/docs` serves generated `target/reports/apidocs/index.html`
- `GET /api/javadoc/docs/{relativePath}` serves generated documentation assets and pages
- K6 routes (headers or query params supported):
- `GET /api/k6/version` (alias: `/api/k6/info/version`)
- `GET|POST /api/k6` (alias: `/api/k6/run`)
- Script execution accepts aliases for script and output settings (`scriptName`, `resultFile`)
- LogAnalytics routes (headers or query params supported):
- `GET /api/loganalytics/message`
- `GET /api/loganalytics/message/startswith` (alias: `/api/loganalytics/message/starts-with`)
Expand Down Expand Up @@ -110,6 +118,9 @@ Java implementation of RestProvider controllers using Apache HttpComponents (Htt
- PowerBI routes (headers or query params supported):
- `GET|POST|PUT|DELETE /api/powerbi` (alias: `/api/powerbi/request`)
- Supports aliases for request path, organization, API version, base URL, and access token override
- Grafana routes (headers or query params supported):
- `GET|POST|PUT|DELETE /api/grafana` (alias: `/api/grafana/request`)
- Supports aliases for request path, API version, base URL, and API token override
- Snowflake routes (headers or query params supported):
- `GET|POST /api/snowflake/token` (alias: `/api/snowflake/oauth/token`)
- Supports aliases for token endpoint, scope, client credentials, and runtime user/password overrides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,44 @@
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.io.entity.StringEntity;

/**
* Controller for the AZPipeline integration endpoints.
*
* <p>This class maps controller routes, validates request input aliases, and
* returns API responses aligned with RestProvider automation behavior.</p>
*/
public class AZPipelineController extends BaseController {
private static final Pattern RESULT_PATTERN = Pattern.compile("\\\"result\\\"\\s*:\\s*\\\"([^\\\"]*)\\\"");
private static final Pattern STATUS_PATTERN = Pattern.compile("\\\"status\\\"\\s*:\\s*\\\"([^\\\"]*)\\\"");

private final PasscodeValidator passcodeValidator;
private final CommandRunner commandRunner;

/**
* Creates a controller with default runtime dependencies.
*/
public AZPipelineController() {
this(new EnvPasscodeValidator(), ProcessUtil::run);
}

/**
* Creates a controller with injected dependencies for testability and customization.
*/
public AZPipelineController(PasscodeValidator passcodeValidator, CommandRunner commandRunner) {
super("AZPipeline");
this.passcodeValidator = passcodeValidator;
this.commandRunner = commandRunner;
}

/**
* Handles incoming HTTP requests for this controller's route surface.
*
* @param request inbound HTTP request
* @param response outbound HTTP response
* @param subPath controller-specific route segment after /api/{controller}/
* @throws IOException when I/O work fails
* @throws HttpException when request handling fails at HTTP protocol level
*/
@Override
public void handle(ClassicHttpRequest request, ClassicHttpResponse response, String subPath)
throws IOException, HttpException {
Expand Down Expand Up @@ -287,9 +308,14 @@ private static void respondJson(ClassicHttpResponse response, int code, String b
response.setEntity(new StringEntity(body, ContentType.APPLICATION_JSON));
}

/**
* Functional contract used to abstract external operations for this controller.
*/
@FunctionalInterface
public interface CommandRunner {
String run(String command, String args);
}
}



Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,27 @@
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.io.entity.StringEntity;

/**
* Controller for the Azure integration endpoints.
*
* <p>This class maps controller routes, validates request input aliases, and
* returns API responses aligned with RestProvider automation behavior.</p>
*/
public class AzureController implements BridgeController {
private static final Logger logger = LogManager.getLogger(AzureController.class);
private final AzureService azureService;
private final PasscodeValidator passcodeValidator;

/**
* Creates a controller with default runtime dependencies.
*/
public AzureController() {
this(new AzureCliService(new ShellProcessExecutionService()), new EnvPasscodeValidator());
}

/**
* Creates a controller with injected dependencies for testability and customization.
*/
public AzureController(AzureService azureService, PasscodeValidator passcodeValidator) {
this.azureService = azureService;
this.passcodeValidator = passcodeValidator;
Expand All @@ -41,6 +53,15 @@ public String getName() {
return "Azure";
}

/**
* Handles incoming HTTP requests for this controller's route surface.
*
* @param request inbound HTTP request
* @param response outbound HTTP response
* @param subPath controller-specific route segment after /api/{controller}/
* @throws IOException when I/O work fails
* @throws HttpException when request handling fails at HTTP protocol level
*/
@Override
public void handle(ClassicHttpRequest request, ClassicHttpResponse response, String subPath)
throws IOException, HttpException {
Expand Down Expand Up @@ -121,3 +142,5 @@ private void respondWithResult(ClassicHttpResponse response, AzureCommandRespons
ContentType.APPLICATION_JSON));
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,41 @@
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.io.entity.StringEntity;

/**
* Controller for the BrowserStack integration endpoints.
*
* <p>This class maps controller routes, validates request input aliases, and
* returns API responses aligned with RestProvider automation behavior.</p>
*/
public class BrowserStackController extends BaseController {
private final PasscodeValidator passcodeValidator;
private final HttpInvoker httpInvoker;

/**
* Creates a controller with default runtime dependencies.
*/
public BrowserStackController() {
this(new EnvPasscodeValidator(), BrowserStackController::invoke);
}

/**
* Creates a controller with injected dependencies for testability and customization.
*/
public BrowserStackController(PasscodeValidator passcodeValidator, HttpInvoker httpInvoker) {
super("BrowserStack");
this.passcodeValidator = passcodeValidator;
this.httpInvoker = httpInvoker;
}

/**
* Handles incoming HTTP requests for this controller's route surface.
*
* @param request inbound HTTP request
* @param response outbound HTTP response
* @param subPath controller-specific route segment after /api/{controller}/
* @throws IOException when I/O work fails
* @throws HttpException when request handling fails at HTTP protocol level
*/
@Override
public void handle(ClassicHttpRequest request, ClassicHttpResponse response, String subPath)
throws IOException, HttpException {
Expand Down Expand Up @@ -154,6 +175,7 @@ public void handle(ClassicHttpRequest request, ClassicHttpResponse response, Str
private String call(ClassicHttpRequest request, Map<String, String> query, String endpoint) {
String user = defaultValue(readValue(request, query, "browserstackUser", "username", "user"), env("browserstack_user"));
String key = defaultValue(readValue(request, query, "browserstackAccessKey", "accessKey", "key"), env("browserstack_accesskey"));
// Outbound REST call to the target service endpoint.
return httpInvoker.call("GET", endpoint, user, key);
}

Expand Down Expand Up @@ -252,6 +274,7 @@ private static String invoke(String method, String endpoint, String user, String
.header("Authorization", "Basic " + auth)
.method(method, HttpRequest.BodyPublishers.noBody())
.build();
// Outbound REST call to the target service endpoint.
HttpResponse<String> res = HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString());
return res.body();
} catch (Exception ex) {
Expand All @@ -264,9 +287,14 @@ private static void respondJson(ClassicHttpResponse response, int code, String b
response.setEntity(new StringEntity(body, ContentType.APPLICATION_JSON));
}

/**
* Functional contract used to abstract external operations for this controller.
*/
@FunctionalInterface
public interface HttpInvoker {
String call(String method, String endpoint, String user, String accessKey);
}
}



Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,26 @@
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.io.entity.StringEntity;

/**
* Controller for the Business integration endpoints.
*
* <p>This class maps controller routes, validates request input aliases, and
* returns API responses aligned with RestProvider automation behavior.</p>
*/
public class BusinessController implements BridgeController {
private static final Logger logger = LogManager.getLogger(BusinessController.class);
private final BusinessService businessService;

/**
* Creates a controller with default runtime dependencies.
*/
public BusinessController() {
this(new DefaultBusinessService());
}

/**
* Creates a controller with injected dependencies for testability and customization.
*/
public BusinessController(BusinessService businessService) {
this.businessService = businessService;
}
Expand All @@ -32,6 +44,15 @@ public String getName() {
return "Business";
}

/**
* Handles incoming HTTP requests for this controller's route surface.
*
* @param request inbound HTTP request
* @param response outbound HTTP response
* @param subPath controller-specific route segment after /api/{controller}/
* @throws IOException when I/O work fails
* @throws HttpException when request handling fails at HTTP protocol level
*/
@Override
public void handle(ClassicHttpRequest request, ClassicHttpResponse response, String subPath)
throws IOException, HttpException {
Expand Down Expand Up @@ -75,3 +96,5 @@ private static void respondJson(ClassicHttpResponse response, int code, String b
response.setEntity(new StringEntity(body, ContentType.APPLICATION_JSON));
}
}


Loading
Loading