adminInterfaceHandlers() {
return emptyMap();
}
-}
\ No newline at end of file
+}
diff --git a/plugin-examples/src/main/java/com/hotels/styx/ExamplePluginConfig.java b/plugin-examples/src/main/java/com/hotels/styx/ModifyHeadersExamplePluginConfig.java
similarity index 95%
rename from plugin-examples/src/main/java/com/hotels/styx/ExamplePluginConfig.java
rename to plugin-examples/src/main/java/com/hotels/styx/ModifyHeadersExamplePluginConfig.java
index 9dabf4ac03..0487220551 100644
--- a/plugin-examples/src/main/java/com/hotels/styx/ExamplePluginConfig.java
+++ b/plugin-examples/src/main/java/com/hotels/styx/ModifyHeadersExamplePluginConfig.java
@@ -23,7 +23,7 @@
*
* You should rename it to something relevant to your project.
*/
-public class ExamplePluginConfig {
+public class ModifyHeadersExamplePluginConfig {
private final String requestHeaderValue;
private final String responseHeaderValue;
@@ -33,7 +33,7 @@ public class ExamplePluginConfig {
* @param requestHeaderValue value from config
* @param responseHeaderValue value from config
*/
- public ExamplePluginConfig(
+ public ModifyHeadersExamplePluginConfig(
@JsonProperty("requestHeaderValue") String requestHeaderValue,
@JsonProperty("responseHeaderValue") String responseHeaderValue) {
this.requestHeaderValue = requestHeaderValue;
diff --git a/plugin-examples/src/main/java/com/hotels/styx/ExamplePluginFactory.java b/plugin-examples/src/main/java/com/hotels/styx/ModifyHeadersExamplePluginFactory.java
similarity index 86%
rename from plugin-examples/src/main/java/com/hotels/styx/ExamplePluginFactory.java
rename to plugin-examples/src/main/java/com/hotels/styx/ModifyHeadersExamplePluginFactory.java
index c75f32e124..d098beae54 100644
--- a/plugin-examples/src/main/java/com/hotels/styx/ExamplePluginFactory.java
+++ b/plugin-examples/src/main/java/com/hotels/styx/ModifyHeadersExamplePluginFactory.java
@@ -21,7 +21,7 @@
/**
* The factory is used to construct your plugin. You can do this however you like.
*/
-public class ExamplePluginFactory implements PluginFactory {
+public class ModifyHeadersExamplePluginFactory implements PluginFactory {
/**
* The environment object will provide this plugin with the configuration you created in the YAML file.
*
@@ -37,8 +37,8 @@ public Plugin create(PluginFactory.Environment environment) {
* However, using a separate config object has the advantage that your PluginFactory is
* free to select a Plugin implementation at runtime.
*/
- ExamplePluginConfig config = environment.pluginConfig(ExamplePluginConfig.class);
+ ModifyHeadersExamplePluginConfig config = environment.pluginConfig(ModifyHeadersExamplePluginConfig.class);
- return new ExamplePlugin(config);
+ return new ModifyHeadersExamplePlugin(config);
}
}
diff --git a/plugin-examples/src/main/java/com/hotels/styx/ReplaceLiveContentExampleConfig.java b/plugin-examples/src/main/java/com/hotels/styx/ReplaceLiveContentExampleConfig.java
new file mode 100644
index 0000000000..7f1f0cb647
--- /dev/null
+++ b/plugin-examples/src/main/java/com/hotels/styx/ReplaceLiveContentExampleConfig.java
@@ -0,0 +1,33 @@
+/*
+ Copyright (C) 2013-2019 Expedia Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+package com.hotels.styx;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Config for example plugin.
+ */
+public class ReplaceLiveContentExampleConfig {
+ private String replacement;
+
+ public ReplaceLiveContentExampleConfig(String replacement) {
+ this.replacement = requireNonNull(replacement);
+ }
+
+ public String replacement() {
+ return replacement;
+ }
+}
diff --git a/plugin-examples/src/main/java/com/hotels/styx/ReplaceLiveContentExamplePlugin.java b/plugin-examples/src/main/java/com/hotels/styx/ReplaceLiveContentExamplePlugin.java
new file mode 100644
index 0000000000..159373e959
--- /dev/null
+++ b/plugin-examples/src/main/java/com/hotels/styx/ReplaceLiveContentExamplePlugin.java
@@ -0,0 +1,53 @@
+/*
+ Copyright (C) 2013-2019 Expedia Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+package com.hotels.styx;
+
+import com.hotels.styx.api.ByteStream;
+import com.hotels.styx.api.Eventual;
+import com.hotels.styx.api.LiveHttpRequest;
+import com.hotels.styx.api.LiveHttpResponse;
+import com.hotels.styx.api.plugins.spi.Plugin;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * You can replace without aggregating it first, if the replacement does not depend on the original contents.
+ * For example, if you need to replace a message body based on information in the message headers , regardless of
+ * the original message body. (E.g you need to add a HTTP message body based on a HTTP error code)
+ *
+ * You can transform a live HTTP message body using the `replaceWith` Bytestream operator such as shown in the example below.
+ *
+ * This can be used to replace a message body without having to look into it, which will also save heap space as the
+ * live upstream response body is never stored in the heap in full.
+ */
+
+public class ReplaceLiveContentExamplePlugin implements Plugin {
+ private final ReplaceLiveContentExampleConfig config;
+
+ public ReplaceLiveContentExamplePlugin(ReplaceLiveContentExampleConfig config) {
+ this.config = requireNonNull(config);
+ }
+
+ @Override
+ public Eventual intercept(LiveHttpRequest request, Chain chain) {
+ return chain.proceed(request)
+ .map(response -> response.newBuilder()
+ .body(body -> body.replaceWith(ByteStream.from(config.replacement(), UTF_8)))
+ .build());
+ }
+}
+
diff --git a/plugin-examples/src/test/java/com/hotels/styx/EarlyReturnExamplePluginTest.java b/plugin-examples/src/test/java/com/hotels/styx/EarlyReturnExamplePluginTest.java
new file mode 100644
index 0000000000..374112096e
--- /dev/null
+++ b/plugin-examples/src/test/java/com/hotels/styx/EarlyReturnExamplePluginTest.java
@@ -0,0 +1,52 @@
+/*
+ Copyright (C) 2013-2019 Expedia Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+package com.hotels.styx;
+
+import com.hotels.styx.api.*;
+import org.testng.annotations.Test;
+import reactor.core.publisher.Mono;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+
+/**
+ * This tests the behaviours added in the EarlyReturnExamplePlugin.
+ */
+
+public class EarlyReturnExamplePluginTest {
+
+ @Test
+ public void returnsEarlyWhenHeaderIsPresent() {
+
+ EarlyReturnExamplePlugin plugin = new EarlyReturnExamplePlugin();
+
+ LiveHttpRequest request = LiveHttpRequest.get("/")
+ .header("X-Respond", "foo")
+ .build();
+
+ HttpInterceptor.Chain chain = request1 -> Eventual.of(LiveHttpResponse.response().build());
+
+ Eventual eventualLive = plugin.intercept(request, chain);
+ Eventual eventual = eventualLive.flatMap(response -> response.aggregate(100));
+
+ HttpResponse response = Mono.from(eventual).block();
+
+ assertThat(response.bodyAs(UTF_8), is("Responding from plugin"));
+ }
+
+}
diff --git a/plugin-examples/src/test/java/com/hotels/styx/ModifyContentByAggregationExamplePluginTest.java b/plugin-examples/src/test/java/com/hotels/styx/ModifyContentByAggregationExamplePluginTest.java
new file mode 100644
index 0000000000..472060fe03
--- /dev/null
+++ b/plugin-examples/src/test/java/com/hotels/styx/ModifyContentByAggregationExamplePluginTest.java
@@ -0,0 +1,54 @@
+/*
+ Copyright (C) 2013-2019 Expedia Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+package com.hotels.styx;
+
+import com.hotels.styx.ModifyContentByAggregationExamplePlugin.Config;
+import com.hotels.styx.api.*;
+import org.testng.annotations.Test;
+import reactor.core.publisher.Mono;
+
+import static com.hotels.styx.api.HttpResponse.response;
+import static com.hotels.styx.api.LiveHttpRequest.get;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+
+public class ModifyContentByAggregationExamplePluginTest {
+
+ @Test
+ public void modifiesContent() {
+ // Set up
+ Config config = new Config("MyExtraText");
+ ModifyContentByAggregationExamplePlugin plugin = new ModifyContentByAggregationExamplePlugin(config);
+
+ LiveHttpRequest request = get("/").build();
+
+ HttpInterceptor.Chain chain = anyRequest -> Eventual.of(response()
+ .body("OriginalBody", UTF_8)
+ .build()
+ .stream());
+
+ // Execution
+
+ HttpResponse response = Mono.from(plugin.intercept(request, chain)
+ .flatMap(liveResponse -> liveResponse.aggregate(100)))
+ .block();
+
+ // Assertion
+ assertThat(response.bodyAs(UTF_8), is("OriginalBodyMyExtraText"));
+ }
+}
diff --git a/plugin-examples/src/test/java/com/hotels/styx/ExamplePluginTest.java b/plugin-examples/src/test/java/com/hotels/styx/ModifyHeadersExamplePluginTest.java
similarity index 75%
rename from plugin-examples/src/test/java/com/hotels/styx/ExamplePluginTest.java
rename to plugin-examples/src/test/java/com/hotels/styx/ModifyHeadersExamplePluginTest.java
index e8c072be0c..77a816d9b8 100644
--- a/plugin-examples/src/test/java/com/hotels/styx/ExamplePluginTest.java
+++ b/plugin-examples/src/test/java/com/hotels/styx/ModifyHeadersExamplePluginTest.java
@@ -20,6 +20,7 @@
import com.hotels.styx.api.LiveHttpRequest;
import com.hotels.styx.api.LiveHttpResponse;
import org.testng.annotations.Test;
+import reactor.core.publisher.Mono;
import static com.hotels.styx.api.HttpResponseStatus.OK;
import static com.hotels.styx.api.LiveHttpRequest.get;
@@ -30,15 +31,15 @@
/**
* This is a unit test for your plugin. Please change it to test the behaviour you expect your plugin to exhibit.
*/
-public class ExamplePluginTest {
- private final ExamplePluginConfig config = new ExamplePluginConfig("foo", "bar");
- private final ExamplePlugin plugin = new ExamplePlugin(config);
+public class ModifyHeadersExamplePluginTest {
+ private final ModifyHeadersExamplePluginConfig config = new ModifyHeadersExamplePluginConfig("foo", "bar");
+ private final ModifyHeadersExamplePlugin plugin = new ModifyHeadersExamplePlugin(config);
/**
- * This tests the behaviours added in the example plugin.
+ * This tests the behaviours added in the ModifyHeadersExamplePlugin.
*/
@Test
- public void addsExtraHeaders() throws Exception {
+ public void addsExtraHeaders() {
// a simple way to mock the downstream system
HttpInterceptor.Chain chain = request -> {
assertThat(request.header("myRequestHeader").orElse(null), is("foo"));
@@ -51,9 +52,9 @@ public void addsExtraHeaders() throws Exception {
.build();
- // since this is a test, we want to wait for the response, so we call CompletableFuture.get
- LiveHttpResponse response = plugin.intercept(request, chain).asCompletableFuture().get();
+ // since this is a test, we want to wait for the response
+ LiveHttpResponse response = Mono.from(plugin.intercept(request, chain)).block();
- assertThat(response.header("myResponseheader").orElse(null), is("bar"));
+ assertThat(response.header("myResponseHeader").orElse(null), is("bar"));
}
}
diff --git a/plugin-examples/src/test/java/com/hotels/styx/ReplaceLiveContentExamplePluginTest.java b/plugin-examples/src/test/java/com/hotels/styx/ReplaceLiveContentExamplePluginTest.java
new file mode 100644
index 0000000000..baf92935ef
--- /dev/null
+++ b/plugin-examples/src/test/java/com/hotels/styx/ReplaceLiveContentExamplePluginTest.java
@@ -0,0 +1,48 @@
+/*
+ Copyright (C) 2013-2019 Expedia Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+package com.hotels.styx;
+
+import com.hotels.styx.api.*;
+import org.testng.annotations.Test;
+import reactor.core.publisher.Mono;
+
+import static com.hotels.styx.api.LiveHttpRequest.get;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+
+public class ReplaceLiveContentExamplePluginTest {
+
+ @Test
+ public void replacesLiveContent() {
+ // Set up
+ ReplaceLiveContentExampleConfig config = new ReplaceLiveContentExampleConfig("myNewContent");
+
+ ReplaceLiveContentExamplePlugin plugin = new ReplaceLiveContentExamplePlugin(config);
+
+ LiveHttpRequest request = get("/").build();
+ HttpInterceptor.Chain chain = request1 -> Eventual.of(LiveHttpResponse.response().build());
+
+ // Execution
+ HttpResponse response = Mono.from(plugin.intercept(request, chain)
+ .flatMap(liveResponse -> liveResponse.aggregate(100)))
+ .block();
+
+ // Assertion
+ assertThat(response.bodyAs(UTF_8), is("myNewContent"));
+ }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 8af165b935..b0156356a3 100755
--- a/pom.xml
+++ b/pom.xml
@@ -67,6 +67,7 @@
components
support
system-tests
+ plugin-examples