diff options
author | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2022-07-20 16:01:16 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-20 16:01:16 +0200 |
commit | 37b82350dd673de1d7375c01838123bf0b1e1a91 (patch) | |
tree | d57a651f4c11589a5acefd26f70b612766857f3f /jrt | |
parent | 02c4a8fff7668971d0b82581081c1ea9466d5fc8 (diff) | |
parent | 4dcb1c83c96b51ec9a1770c269e75a94debebb9d (diff) |
Merge pull request #23528 from vespa-engine/bjorncs/capabilities
Bjorncs/capabilities [run-systemtest]
Diffstat (limited to 'jrt')
-rw-r--r-- | jrt/src/com/yahoo/jrt/Connection.java | 17 | ||||
-rw-r--r-- | jrt/src/com/yahoo/jrt/CryptoSocket.java | 12 | ||||
-rw-r--r-- | jrt/src/com/yahoo/jrt/ErrorCode.java | 3 | ||||
-rw-r--r-- | jrt/src/com/yahoo/jrt/InvocationServer.java | 6 | ||||
-rw-r--r-- | jrt/src/com/yahoo/jrt/MaybeTlsCryptoSocket.java | 7 | ||||
-rw-r--r-- | jrt/src/com/yahoo/jrt/Method.java | 6 | ||||
-rw-r--r-- | jrt/src/com/yahoo/jrt/RequestAccessFilter.java | 17 | ||||
-rw-r--r-- | jrt/src/com/yahoo/jrt/RequireCapabilitiesFilter.java | 54 | ||||
-rw-r--r-- | jrt/src/com/yahoo/jrt/Target.java | 12 | ||||
-rw-r--r-- | jrt/src/com/yahoo/jrt/TlsCryptoSocket.java | 12 | ||||
-rw-r--r-- | jrt/tests/com/yahoo/jrt/CryptoUtils.java | 8 | ||||
-rw-r--r-- | jrt/tests/com/yahoo/jrt/EchoTest.java | 7 | ||||
-rw-r--r-- | jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java | 22 | ||||
-rw-r--r-- | jrt/tests/com/yahoo/jrt/InvokeErrorTest.java | 59 | ||||
-rw-r--r-- | jrt/tests/com/yahoo/jrt/InvokeSyncTest.java | 19 | ||||
-rw-r--r-- | jrt/tests/com/yahoo/jrt/SimpleRequestAccessFilter.java | 9 |
16 files changed, 212 insertions, 58 deletions
diff --git a/jrt/src/com/yahoo/jrt/Connection.java b/jrt/src/com/yahoo/jrt/Connection.java index 644e2ef4ff3..1e4092efb75 100644 --- a/jrt/src/com/yahoo/jrt/Connection.java +++ b/jrt/src/com/yahoo/jrt/Connection.java @@ -1,9 +1,10 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.jrt; -import com.yahoo.security.tls.authz.ConnectionAuthContext; +import com.yahoo.security.tls.ConnectionAuthContext; import java.io.IOException; +import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; @@ -11,7 +12,6 @@ import java.nio.channels.SocketChannel; import java.util.HashMap; import java.util.IdentityHashMap; import java.util.Map; -import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import java.util.logging.Logger; @@ -438,9 +438,16 @@ class Connection extends Target { } @Override - public Optional<ConnectionAuthContext> getConnectionAuthContext() { - return Optional.ofNullable(socket) - .flatMap(CryptoSocket::getConnectionAuthContext); + public ConnectionAuthContext connectionAuthContext() { + if (socket == null) throw new IllegalStateException("Not connected"); + return socket.connectionAuthContext(); + } + + @Override + public Spec peerSpec() { + if (socket == null) throw new IllegalStateException("Not connected"); + InetSocketAddress addr = (InetSocketAddress) socket.channel().socket().getRemoteSocketAddress(); + return new Spec(addr.getHostString(), addr.getPort()); } public boolean isClient() { diff --git a/jrt/src/com/yahoo/jrt/CryptoSocket.java b/jrt/src/com/yahoo/jrt/CryptoSocket.java index aac91362405..e30579d2bdc 100644 --- a/jrt/src/com/yahoo/jrt/CryptoSocket.java +++ b/jrt/src/com/yahoo/jrt/CryptoSocket.java @@ -2,12 +2,11 @@ package com.yahoo.jrt; -import com.yahoo.security.tls.authz.ConnectionAuthContext; +import com.yahoo.security.tls.ConnectionAuthContext; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; -import java.util.Optional; /** @@ -104,11 +103,6 @@ public interface CryptoSocket { **/ public void dropEmptyBuffers(); - /** - * Returns the auth context for the current connection (given handshake completed), - * or empty if the current connection is not secure. - */ - default public Optional<ConnectionAuthContext> getConnectionAuthContext() { - return Optional.empty(); - } + /** Returns the auth context for the current connection (given handshake completed) */ + default ConnectionAuthContext connectionAuthContext() { return ConnectionAuthContext.defaultAllCapabilities(); } } diff --git a/jrt/src/com/yahoo/jrt/ErrorCode.java b/jrt/src/com/yahoo/jrt/ErrorCode.java index beaabcea316..8e129cfef98 100644 --- a/jrt/src/com/yahoo/jrt/ErrorCode.java +++ b/jrt/src/com/yahoo/jrt/ErrorCode.java @@ -49,4 +49,7 @@ public class ErrorCode /** Method failed (111) **/ public static final int METHOD_FAILED = 111; + + /** Permission denied (112) **/ + public static final int PERMISSION_DENIED = 112; } diff --git a/jrt/src/com/yahoo/jrt/InvocationServer.java b/jrt/src/com/yahoo/jrt/InvocationServer.java index 9df92eb20a6..7704c0019ed 100644 --- a/jrt/src/com/yahoo/jrt/InvocationServer.java +++ b/jrt/src/com/yahoo/jrt/InvocationServer.java @@ -31,7 +31,11 @@ class InvocationServer { public void invoke() { if (method != null) { if (method.checkParameters(request)) { - method.invoke(request); + if (method.requestAccessFilter().allow(request)) { + method.invoke(request); + } else { + request.setError(ErrorCode.PERMISSION_DENIED, "Permission denied"); + } } else { request.setError(ErrorCode.WRONG_PARAMS, "Parameters in " + request + " does not match " + method); } diff --git a/jrt/src/com/yahoo/jrt/MaybeTlsCryptoSocket.java b/jrt/src/com/yahoo/jrt/MaybeTlsCryptoSocket.java index 42442289cd1..ab9d78d2676 100644 --- a/jrt/src/com/yahoo/jrt/MaybeTlsCryptoSocket.java +++ b/jrt/src/com/yahoo/jrt/MaybeTlsCryptoSocket.java @@ -1,12 +1,11 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.jrt; -import com.yahoo.security.tls.authz.ConnectionAuthContext; +import com.yahoo.security.tls.ConnectionAuthContext; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; -import java.util.Optional; /** * A crypto socket for the server side of a connection that @@ -132,7 +131,5 @@ public class MaybeTlsCryptoSocket implements CryptoSocket { @Override public int write(ByteBuffer src) throws IOException { return socket.write(src); } @Override public FlushResult flush() throws IOException { return socket.flush(); } @Override public void dropEmptyBuffers() { socket.dropEmptyBuffers(); } - @Override public Optional<ConnectionAuthContext> getConnectionAuthContext() { - return Optional.ofNullable(socket).flatMap(CryptoSocket::getConnectionAuthContext); - } + @Override public ConnectionAuthContext connectionAuthContext() { return socket.connectionAuthContext(); } } diff --git a/jrt/src/com/yahoo/jrt/Method.java b/jrt/src/com/yahoo/jrt/Method.java index 4fc9f0714da..89c66747e0b 100644 --- a/jrt/src/com/yahoo/jrt/Method.java +++ b/jrt/src/com/yahoo/jrt/Method.java @@ -40,6 +40,8 @@ public class Method { private String[] returnName; private String[] returnDesc; + private RequestAccessFilter filter = RequestAccessFilter.ALLOW_ALL; + private static final String undocumented = "???"; @@ -147,6 +149,10 @@ public class Method { return this; } + public Method requestAccessFilter(RequestAccessFilter filter) { this.filter = filter; return this; } + + public RequestAccessFilter requestAccessFilter() { return filter; } + /** * Obtain the name of a parameter * diff --git a/jrt/src/com/yahoo/jrt/RequestAccessFilter.java b/jrt/src/com/yahoo/jrt/RequestAccessFilter.java new file mode 100644 index 00000000000..6701436d6ce --- /dev/null +++ b/jrt/src/com/yahoo/jrt/RequestAccessFilter.java @@ -0,0 +1,17 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.jrt; + +/** + * Request access filter is invoked before any call to {@link Method#invoke(Request)}. + * If {@link #allow(Request)} returns false, the method is not invoked, and the request is failed with error + * {@link ErrorCode#PERMISSION_DENIED}. + * + * @author bjorncs + */ +public interface RequestAccessFilter { + + RequestAccessFilter ALLOW_ALL = __ -> true; + + boolean allow(Request r); + +} diff --git a/jrt/src/com/yahoo/jrt/RequireCapabilitiesFilter.java b/jrt/src/com/yahoo/jrt/RequireCapabilitiesFilter.java new file mode 100644 index 00000000000..bb2eafcf711 --- /dev/null +++ b/jrt/src/com/yahoo/jrt/RequireCapabilitiesFilter.java @@ -0,0 +1,54 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.jrt; + +import com.yahoo.security.tls.Capability; +import com.yahoo.security.tls.CapabilityMode; +import com.yahoo.security.tls.CapabilitySet; +import com.yahoo.security.tls.ConnectionAuthContext; +import com.yahoo.security.tls.TransportSecurityUtils; + +import java.util.logging.Logger; + +import static com.yahoo.security.tls.CapabilityMode.DISABLE; +import static com.yahoo.security.tls.CapabilityMode.LOG_ONLY; + +/** + * @author bjorncs + */ +public class RequireCapabilitiesFilter implements RequestAccessFilter { + + private static final Logger log = Logger.getLogger(RequireCapabilitiesFilter.class.getName()); + private static final CapabilityMode MODE = TransportSecurityUtils.getCapabilityMode(); + + private final CapabilitySet requiredCapabilities; + + public RequireCapabilitiesFilter(CapabilitySet requiredCapabilities) { + this.requiredCapabilities = requiredCapabilities; + } + + public RequireCapabilitiesFilter(Capability... requiredCapabilities) { + this(CapabilitySet.from(requiredCapabilities)); + } + + @Override + public boolean allow(Request r) { + if (MODE == DISABLE) return true; + ConnectionAuthContext ctx = r.target().connectionAuthContext(); + CapabilitySet peerCapabilities = ctx.capabilities(); + boolean authorized = peerCapabilities.has(requiredCapabilities); + if (!authorized) { + String msg = "%sPermission denied for RPC method '%s'. Peer at %s with %s. Call requires %s, but peer has %s" + .formatted(MODE == LOG_ONLY ? "Dry-run: " : "", r.methodName(), r.target().peerSpec(), ctx.peerCertificateString().orElseThrow(), + requiredCapabilities.toNames(), peerCapabilities.toNames()); + if (MODE == LOG_ONLY) { + log.info(msg); + return true; + } else { + log.warning(msg); + return false; + } + } + return true; + } + +} diff --git a/jrt/src/com/yahoo/jrt/Target.java b/jrt/src/com/yahoo/jrt/Target.java index 239a71f53b3..0e8c27deac5 100644 --- a/jrt/src/com/yahoo/jrt/Target.java +++ b/jrt/src/com/yahoo/jrt/Target.java @@ -1,9 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.jrt; -import com.yahoo.security.tls.authz.ConnectionAuthContext; - -import java.util.Optional; +import com.yahoo.security.tls.ConnectionAuthContext; /** * A Target represents a connection endpoint with RPC @@ -71,9 +69,13 @@ public abstract class Target { public Exception getConnectionLostReason() { return null; } /** - * Returns the connection auth context associated with this target, or empty if no connection or is insecure. + * Returns the connection auth context associated with this target. */ - public abstract Optional<ConnectionAuthContext> getConnectionAuthContext(); + public abstract ConnectionAuthContext connectionAuthContext(); + + + /** @return address spec of socket peer */ + public abstract Spec peerSpec(); /** * Check if this target represents the client side of a diff --git a/jrt/src/com/yahoo/jrt/TlsCryptoSocket.java b/jrt/src/com/yahoo/jrt/TlsCryptoSocket.java index ecd76e1eb17..13274dc3ba5 100644 --- a/jrt/src/com/yahoo/jrt/TlsCryptoSocket.java +++ b/jrt/src/com/yahoo/jrt/TlsCryptoSocket.java @@ -1,8 +1,8 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.jrt; -import com.yahoo.security.tls.authz.ConnectionAuthContext; -import com.yahoo.security.tls.authz.PeerAuthorizerTrustManager; +import com.yahoo.security.tls.ConnectionAuthContext; +import com.yahoo.security.tls.PeerAuthorizerTrustManager; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult; @@ -14,7 +14,7 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.ClosedChannelException; import java.nio.channels.SocketChannel; -import java.util.Optional; +import java.util.Objects; import java.util.logging.Logger; import static javax.net.ssl.SSLEngineResult.Status; @@ -219,9 +219,9 @@ public class TlsCryptoSocket implements CryptoSocket { } @Override - public Optional<ConnectionAuthContext> getConnectionAuthContext() { - if (handshakeState != HandshakeState.COMPLETED) return Optional.empty(); - return Optional.ofNullable(authContext); + public ConnectionAuthContext connectionAuthContext() { + if (handshakeState != HandshakeState.COMPLETED) throw new IllegalStateException("Handshake not complete"); + return Objects.requireNonNull(authContext); } private boolean handshakeWrap() throws IOException { diff --git a/jrt/tests/com/yahoo/jrt/CryptoUtils.java b/jrt/tests/com/yahoo/jrt/CryptoUtils.java index d5ce32ee5ee..cef138ffba1 100644 --- a/jrt/tests/com/yahoo/jrt/CryptoUtils.java +++ b/jrt/tests/com/yahoo/jrt/CryptoUtils.java @@ -4,14 +4,14 @@ package com.yahoo.jrt; import com.yahoo.security.KeyUtils; import com.yahoo.security.X509CertificateBuilder; import com.yahoo.security.tls.AuthorizationMode; +import com.yahoo.security.tls.AuthorizedPeers; import com.yahoo.security.tls.DefaultTlsContext; import com.yahoo.security.tls.HostnameVerification; import com.yahoo.security.tls.PeerAuthentication; +import com.yahoo.security.tls.PeerPolicy; +import com.yahoo.security.tls.RequiredPeerCredential; +import com.yahoo.security.tls.RequiredPeerCredential.Field; import com.yahoo.security.tls.TlsContext; -import com.yahoo.security.tls.policy.AuthorizedPeers; -import com.yahoo.security.tls.policy.PeerPolicy; -import com.yahoo.security.tls.policy.RequiredPeerCredential; -import com.yahoo.security.tls.policy.RequiredPeerCredential.Field; import javax.security.auth.x500.X500Principal; import java.security.KeyPair; diff --git a/jrt/tests/com/yahoo/jrt/EchoTest.java b/jrt/tests/com/yahoo/jrt/EchoTest.java index e6243eaf4da..47c6e806635 100644 --- a/jrt/tests/com/yahoo/jrt/EchoTest.java +++ b/jrt/tests/com/yahoo/jrt/EchoTest.java @@ -2,7 +2,7 @@ package com.yahoo.jrt; -import com.yahoo.security.tls.authz.ConnectionAuthContext; +import com.yahoo.security.tls.ConnectionAuthContext; import org.junit.After; import org.junit.Before; import org.junit.runner.RunWith; @@ -16,7 +16,6 @@ import java.util.List; import static com.yahoo.jrt.CryptoUtils.createTestTlsContext; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @RunWith(Parameterized.class) @@ -147,7 +146,7 @@ public class EchoTest { for (int i = 0; i < p.size(); i++) { r.add(p.get(i)); } - connAuthCtx = req.target().getConnectionAuthContext().orElse(null); + connAuthCtx = req.target().connectionAuthContext(); } @org.junit.Test @@ -168,8 +167,6 @@ public class EchoTest { if (connAuthCtxAssertion != null) { assertNotNull(connAuthCtx); connAuthCtxAssertion.assertConnectionAuthContext(connAuthCtx); - } else { - assertNull(connAuthCtx); } } } diff --git a/jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java b/jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java index 5e9f426bb17..436b650198e 100644 --- a/jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java +++ b/jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java @@ -16,6 +16,7 @@ public class InvokeAsyncTest { Supervisor client; Target target; Test.Barrier barrier; + SimpleRequestAccessFilter filter; @Before public void setUp() throws ListenFailedException { @@ -23,11 +24,13 @@ public class InvokeAsyncTest { client = new Supervisor(new Transport()); acceptor = server.listen(new Spec(0)); target = client.connect(new Spec("localhost", acceptor.port())); + filter = new SimpleRequestAccessFilter(); server.addMethod(new Method("concat", "ss", "s", this::rpc_concat) .methodDesc("Concatenate 2 strings") .paramDesc(0, "str1", "a string") .paramDesc(1, "str2", "another string") - .returnDesc(0, "ret", "str1 followed by str2")); + .returnDesc(0, "ret", "str1 followed by str2") + .requestAccessFilter(filter)); barrier = new Test.Barrier(); } @@ -65,4 +68,21 @@ public class InvokeAsyncTest { assertEquals("abcdef", req.returnValues().get(0).asString()); } + @org.junit.Test + public void testFilterIsInvoked() { + Request req = new Request("concat"); + req.parameters().add(new StringValue("abc")); + req.parameters().add(new StringValue("def")); + assertFalse(filter.invoked); + Test.Waiter w = new Test.Waiter(); + target.invokeAsync(req, 10, w); + assertFalse(w.isDone()); + barrier.breakIt(); + w.waitDone(); + assertTrue(w.isDone()); + assertFalse(req.isError()); + assertEquals("abcdef", req.returnValues().get(0).asString()); + assertTrue(filter.invoked); + } + } diff --git a/jrt/tests/com/yahoo/jrt/InvokeErrorTest.java b/jrt/tests/com/yahoo/jrt/InvokeErrorTest.java index a9a0b18b5a1..3b58ba2f42e 100644 --- a/jrt/tests/com/yahoo/jrt/InvokeErrorTest.java +++ b/jrt/tests/com/yahoo/jrt/InvokeErrorTest.java @@ -6,6 +6,7 @@ import org.junit.After; import org.junit.Before; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class InvokeErrorTest { @@ -16,6 +17,8 @@ public class InvokeErrorTest { Supervisor client; Target target; Test.Barrier barrier; + SimpleRequestAccessFilter filter; + RpcTestMethod testMethod; @Before public void setUp() throws ListenFailedException { @@ -23,7 +26,9 @@ public class InvokeErrorTest { client = new Supervisor(new Transport()); acceptor = server.listen(new Spec(0)); target = client.connect(new Spec("localhost", acceptor.port())); - server.addMethod(new Method("test", "iib", "i", this::rpc_test)); + filter = new SimpleRequestAccessFilter(); + testMethod = new RpcTestMethod(); + server.addMethod(new Method("test", "iib", "i", testMethod).requestAccessFilter(filter)); server.addMethod(new Method("test_barrier", "iib", "i", this::rpc_test_barrier)); barrier = new Test.Barrier(); } @@ -36,22 +41,8 @@ public class InvokeErrorTest { server.transport().shutdown().join(); } - private void rpc_test(Request req) { - int value = req.parameters().get(0).asInt32(); - int error = req.parameters().get(1).asInt32(); - int extra = req.parameters().get(2).asInt8(); - - req.returnValues().add(new Int32Value(value)); - if (extra != 0) { - req.returnValues().add(new Int32Value(value)); - } - if (error != 0) { - req.setError(error, "Custom error"); - } - } - private void rpc_test_barrier(Request req) { - rpc_test(req); + testMethod.invoke(req); barrier.waitFor(); } @@ -157,4 +148,40 @@ public class InvokeErrorTest { assertEquals(ErrorCode.CONNECTION, req1.errorCode()); } + @org.junit.Test + public void testFilterFailsRequest() { + Request r = new Request("test"); + r.parameters().add(new Int32Value(42)); + r.parameters().add(new Int32Value(0)); + r.parameters().add(new Int8Value((byte)0)); + filter.allowed = false; + assertFalse(filter.invoked); + target.invokeSync(r, timeout); + assertTrue(r.isError()); + assertTrue(filter.invoked); + assertFalse(testMethod.invoked); + assertEquals(ErrorCode.PERMISSION_DENIED, r.errorCode()); + assertEquals("Permission denied", r.errorMessage()); + } + + private static class RpcTestMethod implements MethodHandler { + boolean invoked = false; + + @Override public void invoke(Request req) { invoked = true; rpc_test(req); } + + void rpc_test(Request req) { + int value = req.parameters().get(0).asInt32(); + int error = req.parameters().get(1).asInt32(); + int extra = req.parameters().get(2).asInt8(); + + req.returnValues().add(new Int32Value(value)); + if (extra != 0) { + req.returnValues().add(new Int32Value(value)); + } + if (error != 0) { + req.setError(error, "Custom error"); + } + } + } + } diff --git a/jrt/tests/com/yahoo/jrt/InvokeSyncTest.java b/jrt/tests/com/yahoo/jrt/InvokeSyncTest.java index ca7d0db129d..ec196bea47c 100644 --- a/jrt/tests/com/yahoo/jrt/InvokeSyncTest.java +++ b/jrt/tests/com/yahoo/jrt/InvokeSyncTest.java @@ -12,6 +12,7 @@ import java.io.IOException; import java.io.PrintStream; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -21,6 +22,7 @@ public class InvokeSyncTest { Acceptor acceptor; Supervisor client; Target target; + SimpleRequestAccessFilter filter; @Before public void setUp() throws ListenFailedException { @@ -28,11 +30,13 @@ public class InvokeSyncTest { client = new Supervisor(new Transport()); acceptor = server.listen(new Spec(0)); target = client.connect(new Spec("localhost", acceptor.port())); + filter = new SimpleRequestAccessFilter(); server.addMethod(new Method("concat", "ss", "s", this::rpc_concat) .methodDesc("Concatenate 2 strings") .paramDesc(0, "str1", "a string") .paramDesc(1, "str2", "another string") - .returnDesc(0, "ret", "str1 followed by str2")); + .returnDesc(0, "ret", "str1 followed by str2") + .requestAccessFilter(filter)); server.addMethod(new Method("alltypes", "bhilfds", "s", this::rpc_alltypes) .methodDesc("Method taking all types of params")); } @@ -84,4 +88,17 @@ public class InvokeSyncTest { assertEquals(baos.toString(), "This was alltypes. The string param was: baz\n"); } + @org.junit.Test + public void testFilterIsInvoked() { + Request req = new Request("concat"); + req.parameters().add(new StringValue("abc")); + req.parameters().add(new StringValue("def")); + assertFalse(filter.invoked); + target.invokeSync(req, 10); + assertFalse(req.isError()); + assertEquals("abcdef", req.returnValues().get(0).asString()); + assertTrue(filter.invoked); + } + + } diff --git a/jrt/tests/com/yahoo/jrt/SimpleRequestAccessFilter.java b/jrt/tests/com/yahoo/jrt/SimpleRequestAccessFilter.java new file mode 100644 index 00000000000..38d59720848 --- /dev/null +++ b/jrt/tests/com/yahoo/jrt/SimpleRequestAccessFilter.java @@ -0,0 +1,9 @@ +package com.yahoo.jrt;// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +/** + * @author bjorncs + */ +class SimpleRequestAccessFilter implements RequestAccessFilter { + volatile boolean invoked = false, allowed = true; + @Override public boolean allow(Request r) { invoked = true; return allowed; } +} |