// Copyright 2015-2018 The NATS Authors // 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 io.nats.client; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; import org.junit.Test; public class PublishTests { @Test(expected = IllegalStateException.class) public void throwsIfClosedOnPublish() throws IOException, InterruptedException { try (NatsTestServer ts = new NatsTestServer(false); Connection nc = Nats.connect(ts.getURI())) { nc.close(); nc.publish("subject", "replyto", null); assertFalse(true); } } @Test(expected = TimeoutException.class) public void throwsIfClosedOnFlush() throws IOException, TimeoutException, InterruptedException { try (NatsTestServer ts = new NatsTestServer(false); Connection nc = Nats.connect(ts.getURI())) { nc.close(); nc.flush(null); assertFalse(true); } } @Test(expected = IllegalArgumentException.class) public void testThrowsWithoutSubject() throws IOException, InterruptedException { try (NatsTestServer ts = new NatsTestServer(false); Connection nc = Nats.connect(ts.getURI())) { nc.publish(null, null); assertFalse(true); } } @Test(expected = IllegalArgumentException.class) public void testThrowsWithoutReplyTo() throws IOException, InterruptedException { try (NatsTestServer ts = new NatsTestServer(false); Connection nc = Nats.connect(ts.getURI())) { nc.publish("subject", "", null); assertFalse(true); } } @Test(expected = IllegalArgumentException.class) public void testThrowsIfTooBig() throws IOException, InterruptedException { String customInfo = "{\"server_id\":\"myid\",\"max_payload\": 1000}"; try (NatsServerProtocolMock ts = new NatsServerProtocolMock(null, customInfo); Connection nc = Nats.connect(ts.getURI())) { assertTrue("Connected Status", Connection.Status.CONNECTED == nc.getStatus()); byte[] body = new byte[1001]; nc.publish("subject", null, body); assertFalse(true); } } @Test public void testEmptyPublish() throws IOException, InterruptedException,ExecutionException { runSimplePublishTest("testsubemptybody", null, ""); } @Test public void testEmptyByDefaultPublish() throws IOException, InterruptedException,ExecutionException { runSimplePublishTest("testsubemptybody", null, null); } @Test public void testNoReplyPublish() throws IOException, InterruptedException,ExecutionException { runSimplePublishTest("testsub", null, "This is the message."); } @Test public void testReplyToInPublish() throws IOException, InterruptedException,ExecutionException { runSimplePublishTest("testsubforreply", "replyTo", "This is the message to reply to."); } public void runSimplePublishTest(String subject, String replyTo, String bodyString) throws IOException, InterruptedException,ExecutionException { CompletableFuture<Boolean> gotPub = new CompletableFuture<>(); AtomicReference<String> body = new AtomicReference<>(""); AtomicReference<String> protocol = new AtomicReference<>(""); NatsServerProtocolMock.Customizer receiveMessageCustomizer = (ts, r,w) -> { String pubLine = ""; String bodyLine = ""; System.out.println("*** Mock Server @" + ts.getPort() + " waiting for PUB ..."); try { pubLine = r.readLine(); bodyLine = r.readLine(); // Ignores encoding, but ok for test } catch(Exception e) { gotPub.cancel(true); return; } if (pubLine.startsWith("PUB")) { System.out.println("*** Mock Server @" + ts.getPort() + " got PUB ..."); protocol.set(pubLine); body.set(bodyLine); gotPub.complete(Boolean.TRUE); } }; try (NatsServerProtocolMock ts = new NatsServerProtocolMock(receiveMessageCustomizer); Connection nc = Nats.connect(ts.getURI())) { byte[] bodyBytes = (bodyString != null) ? bodyString.getBytes(StandardCharsets.UTF_8) : null; assertTrue("Connected Status", Connection.Status.CONNECTED == nc.getStatus()); nc.publish(subject, replyTo, bodyBytes); // This is used for the default test if (bodyString == null) { bodyBytes = new byte[0]; bodyString = ""; } assertTrue("Got pub.", gotPub.get().booleanValue()); //wait for receipt to close up nc.close(); assertTrue("Closed Status", Connection.Status.CLOSED == nc.getStatus()); String expectedProtocol = null; if (replyTo == null) { expectedProtocol = "PUB "+subject+" "+bodyBytes.length; } else { expectedProtocol = "PUB "+subject+" "+replyTo+" "+bodyBytes.length; } assertEquals("Protocol matches", expectedProtocol, protocol.get()); assertEquals("Body matches", bodyString, body.get()); } } }