content: /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You 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 org.apache.camel.component.mina;
  
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.net.InetSocketAddress;
  import java.net.Socket;
  
  import org.apache.camel.builder.RouteBuilder;
  import org.apache.camel.util.IOHelper;
  import org.junit.jupiter.api.Test;
  
  import static org.junit.jupiter.api.Assertions.assertEquals;
  import static org.junit.jupiter.api.Assertions.assertNotEquals;
  import static org.junit.jupiter.api.Assertions.assertNotNull;
  import static org.junit.jupiter.api.Assertions.assertNull;
  
  /**
   * To test camel-mina component using a TCP client that communicates using TCP socket communication.
   */
  public class MinaTcpLineDelimiterUsingPlainSocketTest extends BaseMinaTest {
  
      @Test
      public void testSendAndReceiveOnce() throws Exception {
          String response = sendAndReceive("World");
  
          assertNotNull(response, "Nothing received from Mina");
          assertEquals("Hello World", response);
      }
  
      @Test
      public void testSendAndReceiveTwice() throws Exception {
          String london = sendAndReceive("London");
          String paris = sendAndReceive("Paris");
  
          assertNotNull(london, "Nothing received from Mina");
          assertNotNull(paris, "Nothing received from Mina");
          assertEquals("Hello London", london);
          assertEquals("Hello Paris", paris);
      }
  
      @Test
      public void testReceiveNoResponseSinceOutBodyIsNull() throws Exception {
          String out = sendAndReceive("force-null-out-body");
          assertNull(out, "no data should be received");
      }
  
      @Test
      public void testReceiveNoResponseSinceOutBodyIsNullTwice() throws Exception {
          String out = sendAndReceive("force-null-out-body");
          assertNull(out, "no data should be received");
  
          out = sendAndReceive("force-null-out-body");
          assertNull(out, "no data should be received");
      }
  
      @Test
      public void testExchangeFailedOutShouldBeNull() throws Exception {
          String out = sendAndReceive("force-exception");
          assertNotEquals("force-exception", out, "out should not be the same as in when the exchange has failed");
          assertEquals("java.lang.IllegalArgumentException: Forced exception", out, "should get the exception here");
      }
  
      private String sendAndReceive(String input) throws IOException {
          byte[] buf = new byte[128];
  
          Socket soc = new Socket();
          soc.connect(new InetSocketAddress("localhost", getPort()));
  
          // Send message using plain Socket to test if this works
          OutputStream os = null;
          InputStream is = null;
          try {
              os = soc.getOutputStream();
              // must append MAC newline at the end to flag end of textline to camel-mina
              os.write((input + "\r").getBytes());
  
              is = soc.getInputStream();
              int len = is.read(buf);
              if (len == -1) {
                  // no data received
                  return null;
              }
          } finally {
              IOHelper.close(is, os);
              soc.close();
          }
  
          // convert the buffer to chars
          StringBuilder sb = new StringBuilder();
          for (byte b : buf) {
              char ch = (char) b;
              if (ch == '\r' || ch == 0) {
                  // use MAC delimiter denotes end of text (added in the end in the processor below)
                  break;
              } else {
                  sb.append(ch);
              }
          }
  
          return sb.toString();
      }
  
      @Override
      protected RouteBuilder createRouteBuilder() {
          return new RouteBuilder() {
  
              public void configure() {
                  // use no delay for fast unit testing
                  errorHandler(defaultErrorHandler().maximumRedeliveries(2));
  
                  fromF("mina:tcp://localhost:%1$s?textline=true&minaLogger=true&textlineDelimiter=MAC&sync=true",
                          getPort())
                          .process(e -> {
                              String in = e.getIn().getBody(String.class);
                              if ("force-null-out-body".equals(in)) {
                                  // forcing a null out body
                                  e.getMessage().setBody(null);
                              } else if ("force-exception".equals(in)) {
                                  // clear out before throwing exception
                                  e.getMessage().setBody(null);
                                  throw new IllegalArgumentException("Forced exception");
                              } else {
                                  e.getMessage().setBody("Hello " + in);
                              }
                          });
              }
          };
      }
  }
  