Skip to content

Commit f6aa1c1

Browse files
authored
Rest plugins plugin+Fixes (#74)
* Added creation of plugins in -any- language (rest-plugins-plugin) * Allow insecure websites on selenium * One JdbcExecutor for JdbcProtocol
1 parent da14474 commit f6aa1c1

File tree

117 files changed

+6671
-250
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+6671
-250
lines changed

.idea/compiler.xml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/encodings.xml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ various languages and environments
2626
* Java/Spring/MySQL/MQTT
2727
* Intercept a phone with pre-setup VPN container
2828

29+
![generic.png](docs/ui/generic.png)
30+
2931
### How it works
3032

3133
It's simple it's a `multiprotocol` proxy on your box (or whatever you want)

docs/rest-plugins-plugin.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# The Rest-Plugins plugin
2+
3+
This plugin allows to intercept every call made to every protocol and to modify
4+
it within your preferred environment
5+
6+
You write your server code, setup it on TPM and that's it
7+
8+
An example is in `UiSeleniumTest::httpRestPluginsPlugin` where the server handler is
9+
into the `handleMessage` function. It simply replaces the Google logo with the Bing's one
10+
11+
## Your server
12+
13+
* Create a REST api able to answer to POST request. e.g. 'http://host:91/callinterceptor'
14+
* Deserialize the JSON of the request and parse input and proposed output (when present)
15+
* Do your operations and eventually modify the output
16+
* Respond with the output, error and blocking flags as needed
17+
18+
### Request
19+
* The request will be in the following format
20+
21+
```
22+
{
23+
"inputType":"",
24+
"outputType":"",
25+
"phase":"",
26+
"input":"",
27+
"output:""
28+
}
29+
```
30+
31+
Where
32+
33+
* inputType: The simple class name of the input object, Object for any (included null). For DB calls can use `JdbcCall`, for Http/s `Request`
34+
* outputType: The simple class name of the output object, Object for any (included null). For DB calls can use `SelectResult`, for Http/s `Response`
35+
* phase: the protocol phase
36+
37+
### Response
38+
39+
And the response
40+
41+
* blocking: If the protocol should respond directly with the response given
42+
* message: The JSON serialized object of the response. For DB calls can use `SelectResult`, for Http/s `Response`
43+
* withError: True when there is an error
44+
* error: The error message
45+
46+
```
47+
{
48+
"blocking":true,
49+
"message":"",
50+
"error":"",
51+
"withError":false
52+
}
53+
```
54+
55+
### An example with Http/s
56+
57+
* The inputType would be Request, the output Response
58+
* The phase will be `POST_CALL`, that means the original server had been called already
59+
* Then we can deserialize the Request json (simplified)
60+
* If it's from google (in pseudocode `input.host contains google`)
61+
* Then change int the `output.responseText` all the "google.png" into "bing.png"
62+
* Re-serialize the output to JSON and send it into `message` field
63+
64+
```
65+
{
66+
"input": {
67+
"host": "www.google.com",
68+
...
69+
},
70+
"outuput:{
71+
"responseText": "<html><body><img src='google.png'/></body></html>
72+
},
73+
"inputType": "Request",
74+
"outputType": "Response",
75+
"phase":"POST_CALL"
76+
...
77+
}
78+
```
79+
80+
## TPM Side
81+
82+
Just set in the settings file the relative interceptor where
83+
84+
* name: Mnemonic for the interceptor
85+
* phase: The phase (`POST_CALL` in this case)
86+
* destinationAddress: The API to call
87+
* inputType: `Request`
88+
* outputType: `Response`
89+
* inMatcher: The matcher for the input content, can be a
90+
* regexp, prepend `@`
91+
* [tpmQl](tpmql.md), prepend `!`
92+
* contains, just the string that should be founded
93+
94+
If you need it exists even the outputMatcher that follows the same rules
95+
96+
```
97+
{
98+
"protocols":{
99+
"http-01":{
100+
"plugins":{
101+
"rest-plugins-plugin": {
102+
"interceptors": [
103+
{
104+
"name": "MyInterceptor",
105+
"phase": "POST_CALL",
106+
"destinationAddress": "http://host:91/callinterceptor",
107+
"inputType": "Request",
108+
"outputType": "Response",
109+
"inMatcher": "!CONTAINS(host,'google')"
110+
}
111+
]
112+
},
113+
114+
}
115+
}
116+
}
117+
118+
```

docs/ui/generic.png

138 KB
Loading

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
</modules>
2626

2727
<properties>
28-
<revision>4.2.0</revision>
28+
<revision>4.3.0</revision>
2929
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
3030
<maven.compiler.target>17</maven.compiler.target>
3131
<maven.compiler.source>17</maven.compiler.source>

protocol-amqp-091/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,20 @@ Introduce random latency. Not applicable to async calls
7676
* minMs: Minimum latency added (default 0)
7777
* maxMs: Max latency added (default 0)
7878

79+
### rest-plugins-plugin
80+
81+
This plugin is used to intercept protocol calls and forward the request to a REST API
82+
that will need to respond with the correct response data. Contains a list of "interceptors"
83+
definitions. For details on the implementation [here](../docs/rest-plugins-plugin.md)
84+
85+
* name: The name of the interceptor
86+
* destinationAddress: The api to call (POST)
87+
* inputType: The expected input type (simple class name), Object for any
88+
* inMatcher: The matcher for the in content, `@` for Java regexp, `!` for [tpmql](../docs/tpmql.md), generic string from contains
89+
* outputType: The expected output type (simple class name), Object for any
90+
* outMatcher: The matcher for the out content, `@` for Java regexp, `!` for [tpmql](../docs/tpmql.md), generic string from contains
91+
* blockOnException: If there is an exception return the error and stop the filtering
92+
7993
## Documentation used
8094

8195
* https://www.rabbitmq.com/resources/specs/amqp0-9-1.pdf (page 31)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.kendar.amqp.v09.plugins;
2+
3+
import org.kendar.di.annotations.TpmService;
4+
import org.kendar.plugins.BasicRestPluginsPlugin;
5+
import org.kendar.utils.JsonMapper;
6+
7+
@TpmService(tags = "amqp091")
8+
public class AmqpRestPluginsPlugin extends BasicRestPluginsPlugin {
9+
public AmqpRestPluginsPlugin(JsonMapper mapper) {
10+
super(mapper);
11+
}
12+
13+
@Override
14+
public String getProtocol() {
15+
return "amqp091";
16+
}
17+
}

protocol-amqp-091/src/main/java/org/kendar/amqp/v09/plugins/apis/dtos/PublishAmqpMessage.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ public class PublishAmqpMessage {
77
private int propertyFlag = -28664;
88
private int deliveryMode = 1;
99
private long deliveryTag = 1;
10+
1011
public PublishAmqpMessage() {
1112

1213
}

protocol-amqp-091/src/main/resources/jte/amqp091/record_plugin/index.jte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
function updateData() {
1515
var data = retrieveValues({
1616
active:${data.isActive()},
17-
ignoreTrivialCalls:true,
18-
resetConnectionsOnStart:true
17+
ignoreTrivialCalls: true,
18+
resetConnectionsOnStart: true
1919
});
2020
console.log(data);
2121
sendData('/api/protocols/${data.getInstanceId()}/plugins/${data.getId()}/settings', 'PUT', JSON.stringify(data), 'application/json', (status, response) => {

protocol-amqp-091/src/test/java/org/kendar/amqp/v09/ExchangeTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,6 @@ void testExchange() throws URISyntaxException, NoSuchAlgorithmException, KeyMana
8383
var events = getEvents().stream().collect(Collectors.toList());
8484
assertEquals(5, events.stream().filter(e -> e.getQuery().startsWith("RECEIVE")).count());
8585
assertEquals(5, events.stream().filter(e -> e.getQuery().startsWith("SEND")).count());
86-
assertTrue(events.stream().filter(e -> e.getQuery().equalsIgnoreCase("CONNECT")).count()>=2);
86+
assertTrue(events.stream().filter(e -> e.getQuery().equalsIgnoreCase("CONNECT")).count() >= 2);
8787
}
8888
}

protocol-common-jdbc/src/main/java/org/kendar/plugins/JdbcMockPlugin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public abstract class JdbcMockPlugin extends BasicMockPlugin<JdbcCall, SelectRes
2121

2222

2323
public JdbcMockPlugin(JsonMapper mapper, StorageRepository repository, MultiTemplateEngine resolversFactory) {
24-
super(mapper, repository,resolversFactory);
24+
super(mapper, repository, resolversFactory);
2525
}
2626

2727
@Override

protocol-common-jdbc/src/main/java/org/kendar/plugins/JdbcRecordPlugin.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public abstract class JdbcRecordPlugin extends BasicRecordPlugin<BasicRecordPlug
2525

2626
public JdbcRecordPlugin(JsonMapper mapper, StorageRepository storage,
2727
MultiTemplateEngine resolversFactory, SimpleParser parser) {
28-
super(mapper, storage,resolversFactory,parser);
28+
super(mapper, storage, resolversFactory, parser);
2929
}
3030

3131
@Override
@@ -57,10 +57,10 @@ protected void postCall(PluginContext pluginContext, Object obIn, Object obOUt)
5757
if (!shouldNotSaveJdbc(storageItem, compactLine) || !shouldIgnoreTrivialCalls()) {
5858
EventsQueue.send(new WriteItemEvent(new LineToWrite(getInstanceId(), storageItem, compactLine, id)));
5959
} else {
60-
if(!shouldIgnoreTrivialCalls()){
60+
if (!shouldIgnoreTrivialCalls()) {
6161
storageItem.setTrivial(true);
6262
EventsQueue.send(new WriteItemEvent(new LineToWrite(getInstanceId(), storageItem, compactLine, id)));
63-
}else {
63+
} else {
6464
EventsQueue.send(new WriteItemEvent(new LineToWrite(getInstanceId(), compactLine, id)));
6565
}
6666
}

protocol-common-jdbc/src/main/java/org/kendar/plugins/JdbcRewritePlugin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
public abstract class JdbcRewritePlugin extends BasicRewritePlugin<JdbcCall, SelectResult, RewritePluginSettings, String> {
1515
public JdbcRewritePlugin(JsonMapper mapper, StorageRepository repository, MultiTemplateEngine resolversFactory) {
16-
super(mapper, repository,resolversFactory);
16+
super(mapper, repository, resolversFactory);
1717
}
1818

1919
@Override

protocol-common-jdbc/src/main/java/org/kendar/sql/jdbc/JdbcProxy.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public JdbcProxy(String driver) {
5252

5353
public JdbcProxy(String driver, String connectionString, String forcedSchema, String login, String password) {
5454
super();
55-
this.driver = (driver!=null && !driver.isEmpty()) ? driver : getDefaultDriver();
55+
this.driver = (driver != null && !driver.isEmpty()) ? driver : getDefaultDriver();
5656
this.connectionString = connectionString;
5757
this.forcedSchema = forcedSchema;
5858
this.login = login;
@@ -404,7 +404,7 @@ public ProxyConnection connect(NetworkProtoContext context) {
404404
public void initialize() {
405405
if (replayer) return;
406406
try {
407-
if(driver!=null && !driver.isEmpty()) {
407+
if (driver != null && !driver.isEmpty()) {
408408
Class.forName(driver);
409409
}
410410
} catch (ClassNotFoundException e) {

protocol-common/src/main/java/org/kendar/apis/FilterDescriptor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ private String replaceFilterSpecific(String pathPatternOri, FilteringClass filte
292292
pathPattern = pathPattern.replaceAll(
293293
Pattern.quote("{#plugin}"),
294294
Matcher.quoteReplacement(ppah.getPluginId()));
295-
}else if (ProtocolApiHandler.class.isAssignableFrom(filterClass.getClass())) {
295+
} else if (ProtocolApiHandler.class.isAssignableFrom(filterClass.getClass())) {
296296
var ppah = (ProtocolApiHandler) filterClass;
297297
pathPattern = pathPattern.replaceAll(
298298
Pattern.quote("{#protocolInstanceId}"),

protocol-common/src/main/java/org/kendar/apis/ProtocolStaticWebFilter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public ProtocolStaticWebFilter(FileResourcesUtils fileResourcesUtils, String pro
2121
try {
2222
loadAllStuffs();
2323
} catch (IOException e) {
24-
throw new ApiException("Unable to load data for protocol "+protocolInstanceId,e);
24+
throw new ApiException("Unable to load data for protocol " + protocolInstanceId, e);
2525
}
2626
}
2727

protocol-common/src/main/java/org/kendar/di/DiService.java

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,27 @@ public static List<String> getTags(Object instance) {
8282
return result;
8383
}
8484

85+
private static Constructor retrieveConstructor(Constructor<?>[] constructors) {
86+
Constructor constructor = null;
87+
if (constructors.length == 1) {
88+
constructor = constructors[0];
89+
} else {
90+
for (var constr : constructors) {
91+
if (null != constr.getAnnotation(TpmConstructor.class)) {
92+
if (constructor != null) {
93+
throw new DiException("Duplicate TpmConstructor constructor found");
94+
}
95+
constructor = constr;
96+
}
97+
}
98+
}
99+
100+
if (constructor == null) {
101+
throw new DiException("No TpmConstructor found");
102+
}
103+
return constructor;
104+
}
105+
85106
private void destroy() {
86107
for (var item : children) {
87108
try {
@@ -237,7 +258,6 @@ public <T> List<T> getInstances(Class<T> clazz, String... tags) {
237258
return getInstancesInternal(null, clazz, this, clazz, tags);
238259
}
239260

240-
241261
private Object createInstance(DiService context, Class<?> clazz, boolean transi) {
242262
try {
243263
if (!transi) {
@@ -310,27 +330,6 @@ private Object createInstance(DiService context, Class<?> clazz, boolean transi)
310330
}
311331
}
312332

313-
private static Constructor retrieveConstructor(Constructor<?>[] constructors) {
314-
Constructor constructor = null;
315-
if (constructors.length == 1) {
316-
constructor = constructors[0];
317-
} else {
318-
for (var constr : constructors) {
319-
if (null != constr.getAnnotation(TpmConstructor.class)) {
320-
if (constructor != null) {
321-
throw new DiException("Duplicate TpmConstructor constructor found");
322-
}
323-
constructor = constr;
324-
}
325-
}
326-
}
327-
328-
if (constructor == null) {
329-
throw new DiException("No TpmConstructor found");
330-
}
331-
return constructor;
332-
}
333-
334333
private Object destroy(Object o) {
335334
var ms = o.getClass().getMethods();
336335
for (var m : ms) {

protocol-common/src/main/java/org/kendar/exceptions/ApiException.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ public class ApiException extends TPMException {
55
public ApiException(String message) {
66
super(message);
77
}
8+
89
public ApiException(String message, Throwable cause) {
910
super(message, cause);
1011
}
12+
1113
public ApiException(Throwable cause) {
1214
super(cause);
1315
}
16+
1417
protected ApiException(String message, Throwable cause,
1518
boolean enableSuppression,
1619
boolean writableStackTrace) {

protocol-common/src/main/java/org/kendar/exceptions/CliException.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ public class CliException extends TPMException {
55
public CliException(String message) {
66
super(message);
77
}
8+
89
public CliException(String message, Throwable cause) {
910
super(message, cause);
1011
}
12+
1113
public CliException(Throwable cause) {
1214
super(cause);
1315
}
16+
1417
protected CliException(String message, Throwable cause,
1518
boolean enableSuppression,
1619
boolean writableStackTrace) {

0 commit comments

Comments
 (0)