protected void logoutAllSessions(boolean forceDisconnect) {
    log.info("Logging out all sessions");
    if (sessions == null) {
      log.error("Attempt to logout all sessions before initialization is complete.");
      return;
    }
    for (Session session : sessions.values()) {
      try {
        session.logout();
      } catch (Throwable e) {
        logError(session.getSessionID(), null, "Error during logout", e);
      }
    }

    if (forceDisconnect && isLoggedOn()) {
      for (Session session : sessions.values()) {
        try {
          if (session.isLoggedOn()) {
            session.disconnect("Forcibly disconnecting session", false);
          }
        } catch (Throwable e) {
          logError(session.getSessionID(), null, "Error during disconnect", e);
        }
      }
    }

    if (!forceDisconnect) {
      waitForLogout();
    }
  }
 protected void waitForLogout() {
   long start = System.currentTimeMillis();
   Set<Session> loggedOnSessions;
   while (!(loggedOnSessions = getLoggedOnSessions()).isEmpty()) {
     try {
       Thread.sleep(100L);
     } catch (InterruptedException e) {
       log.error(e.getMessage(), e);
     }
     final long elapsed = System.currentTimeMillis() - start;
     Iterator<Session> sessionItr = loggedOnSessions.iterator();
     while (sessionItr.hasNext()) {
       Session session = sessionItr.next();
       if (elapsed >= session.getLogoutTimeout() * 1000L) {
         try {
           session.disconnect("Logout timeout, force disconnect", false);
         } catch (IOException e) {
           log.error(e.getMessage(), e);
         }
         sessionItr.remove();
       }
     }
     // Be sure we don't look forever
     if (elapsed > 60000L) {
       log.warn("Stopping session logout wait after 1 minute");
       break;
     }
   }
 }
  @Override
  public boolean send(String data) {
    // Check for and disconnect slow consumers.
    if (maxScheduledWriteRequests > 0
        && ioSession.getScheduledWriteMessages() >= maxScheduledWriteRequests) {
      Session qfjSession = (Session) ioSession.getAttribute(SessionConnector.QF_SESSION);
      try {
        qfjSession.disconnect("Slow consumer", true);
      } catch (IOException e) {
      }
      return false;
    }

    // The data is written asynchronously in a MINA thread
    WriteFuture future = ioSession.write(data);
    if (synchronousWrites) {
      try {
        if (!future.awaitUninterruptibly(synchronousWriteTimeout)) {
          log.error("Synchronous write timed out after " + synchronousWriteTimeout + "ms");
          return false;
        }
      } catch (RuntimeException e) {
        log.error("Synchronous write failed: " + e.getMessage());
        return false;
      }
    }
    return true;
  }
 private Set<quickfix.Session> getLoggedOnSessions() {
   Set<quickfix.Session> loggedOnSessions = new HashSet<quickfix.Session>(sessions.size());
   for (Session session : sessions.values()) {
     if (session.isLoggedOn()) {
       loggedOnSessions.add(session);
     }
   }
   return loggedOnSessions;
 }
 /**
  * Check if we have at least one session and that all the sessions are logged on
  *
  * @return false if no session or at least one session is not logged on
  */
 public boolean isLoggedOn() {
   // if no session, not logged on
   if (sessions.isEmpty()) return false;
   for (Session session : sessions.values()) {
     // at least one session not logged on
     if (!session.isLoggedOn()) return false;
   }
   // all the sessions are logged on
   return true;
 }
 public void run() {
   try {
     for (Session session : sessions.values()) {
       try {
         session.next();
       } catch (IOException e) {
         logError(session.getSessionID(), null, "Error in session timer processing", e);
       }
     }
   } catch (Throwable e) {
     log.error("Error during timer processing", e);
   }
 }
 @Override
 public void exceptionCaught(IoSession ioSession, Throwable cause) throws Exception {
   boolean disconnectNeeded = false;
   Session quickFixSession = findQFSession(ioSession);
   Throwable realCause = cause;
   if (cause instanceof ProtocolDecoderException && cause.getCause() != null) {
     realCause = cause.getCause();
   } else {
     Throwable chain = cause;
     while (chain != null && chain.getCause() != null) {
       chain = chain.getCause();
       if (chain instanceof IOException) {
         realCause = chain;
         break;
       }
     }
   }
   String reason;
   if (realCause instanceof IOException) {
     if (quickFixSession != null && quickFixSession.isEnabled()) {
       reason = "Socket exception (" + ioSession.getRemoteAddress() + "): " + cause;
     } else {
       reason = "Socket (" + ioSession.getRemoteAddress() + "): " + cause;
     }
     disconnectNeeded = true;
   } else if (realCause instanceof CriticalProtocolCodecException) {
     reason = "Critical protocol codec error: " + cause;
     disconnectNeeded = true;
   } else if (realCause instanceof ProtocolCodecException) {
     reason = "Protocol handler exception: " + cause;
   } else {
     reason = cause.toString();
   }
   if (disconnectNeeded) {
     try {
       if (quickFixSession != null) {
         quickFixSession.disconnect(reason, true);
       } else {
         log.error(reason, cause);
         ioSession.closeNow();
       }
     } finally {
       ioSession.setAttribute("QFJ_RESET_IO_CONNECTOR", Boolean.TRUE);
     }
   } else {
     log.error(reason, cause);
   }
 }
  public void testOneSessionLoggedOnOneSessionNotLoggedOne() throws Exception {
    SessionID sessionID1 = new SessionID(FixVersions.BEGINSTRING_FIX40, "TW", "ISLD");
    SessionSettings settings = setUpSessionSettings(sessionID1);
    DefaultSessionFactory sessionFactory =
        new DefaultSessionFactory(
            new UnitTestApplication(),
            new MemoryStoreFactory(),
            new ScreenLogFactory(true, true, true));

    SessionConnector connector = new SessionConnectorUnderTest(settings, sessionFactory);

    Session session1 = connector.createSession(sessionID1);
    assertNotNull(session1);

    // test add/remove
    SessionConnectorListener connectorListener = new SessionConnectorListener();
    connector.addPropertyChangeListener(connectorListener);
    connector.removePropertyChangeListener(connectorListener);

    Map<SessionID, Session> sessions = new HashMap<>();
    sessions.put(session1.getSessionID(), session1);
    connector.setSessions(sessions);

    assertEquals(0, propertyChangeEvents.size());

    assertEquals(1, connector.getManagedSessions().size());
    assertEquals(session1, connector.getManagedSessions().get(0));

    assertFalse(connector.isLoggedOn());

    Field stateField = session1.getClass().getDeclaredField("state");
    stateField.setAccessible(true);
    SessionState state = (SessionState) stateField.get(session1);

    state.setLogonSent(true);
    state.setLogonReceived(true);
    assertTrue(connector.isLoggedOn());

    SessionID sessionID2 = new SessionID(FixVersions.BEGINSTRING_FIX40, "TW", "ISLD1");
    settings.setString(
        sessionID2,
        SessionFactory.SETTING_CONNECTION_TYPE,
        SessionFactory.ACCEPTOR_CONNECTION_TYPE);
    Session session2 = connector.createSession(sessionID2);
    assertNotNull(session2);
    sessions.put(session2.getSessionID(), session2);
    assertFalse(connector.isLoggedOn());
  }
Example #9
0
  private void doLogonTest(String keyStoreName, String keyStorePassword)
      throws InterruptedException, ConfigError {
    ServerThread serverThread = new ServerThread(keyStoreName, keyStorePassword);
    try {
      serverThread.setDaemon(true);
      serverThread.start();
      serverThread.waitForInitialization();

      SessionID clientSessionID = new SessionID(FixVersions.BEGINSTRING_FIX42, "TW", "ISLD");
      SessionSettings settings = getClientSessionSettings(clientSessionID);
      ClientApplication clientApplication = new ClientApplication();
      ThreadedSocketInitiator initiator =
          new ThreadedSocketInitiator(
              clientApplication, new MemoryStoreFactory(), settings, new DefaultMessageFactory());

      try {
        log.info("Do login");
        clientApplication.setUpLogonExpectation();
        initiator.start();
        Session clientSession = Session.lookupSession(clientSessionID);
        assertLoggedOn(clientApplication, clientSession);
      } finally {
        initiator.stop();
      }
    } finally {
      serverThread.interrupt();
      serverThread.join();
    }
  }
 protected Session findQFSession(IoSession ioSession, SessionID sessionID) {
   Session quickfixSession = findQFSession(ioSession);
   if (quickfixSession == null) {
     quickfixSession = Session.lookupSession(sessionID);
   }
   return quickfixSession;
 }
 public void processMessage() {
   try {
     if (m_session.hasResponder()) {
       m_session.next(m_message);
     } else {
       try {
         final String msgType = m_message.getHeader().getString(MsgType.FIELD);
         if (msgType.equals(MsgType.LOGOUT)) {
           m_session.next(m_message);
         }
       } catch (FieldNotFound ex) {
       }
     }
   } catch (Throwable e) {
     LogUtil.logThrowable(m_session, e.getMessage(), e);
   }
 }
Example #12
0
 public void onMessage(quickfix.fix43.SecurityDefinition message, SessionID sessionID)
     throws FieldNotFound, UnsupportedMessageType, IncorrectTagValue {
   quickfix.fix43.SecurityDefinition echo = message;
   try {
     Session.sendToTarget(echo, sessionID);
   } catch (SessionNotFound snf) {
     snf.printStackTrace();
   }
 }
  private void sendOutMessage(Exchange exchange) throws QFJException {
    Message camelMessage = exchange.getOut();
    quickfix.Message quickfixjMessage = camelMessage.getBody(quickfix.Message.class);

    log.debug("Sending FIX message reply: {}", quickfixjMessage);

    SessionID messageSessionID = exchange.getIn().getHeader("SessionID", SessionID.class);

    Session session = getSession(messageSessionID);
    if (session == null) {
      throw new IllegalStateException("Unknown session: " + messageSessionID);
    }

    if (!session.send(quickfixjMessage)) {
      throw new CannotSendException(
          "Could not send FIX message reply: " + quickfixjMessage.toString());
    }
  }
  public void testConnector() throws Exception {
    SessionID sessionID = new SessionID(FixVersions.BEGINSTRING_FIX40, "TW", "ISLD");
    SessionSettings settings = setUpSessionSettings(sessionID);
    DefaultSessionFactory sessionFactory =
        new DefaultSessionFactory(
            new UnitTestApplication(),
            new MemoryStoreFactory(),
            new ScreenLogFactory(true, true, true));

    SessionConnector connector = new SessionConnectorUnderTest(settings, sessionFactory);

    connector.addPropertyChangeListener(new SessionConnectorListener());

    Session session = connector.createSession(sessionID);
    assertNotNull(session);

    Map<SessionID, Session> sessions = Collections.singletonMap(session.getSessionID(), session);
    connector.setSessions(sessions);

    assertEquals(1, propertyChangeEvents.size());

    assertEquals(1, connector.getManagedSessions().size());
    assertEquals(session, connector.getManagedSessions().get(0));

    assertFalse(connector.isLoggedOn());

    Field stateField = session.getClass().getDeclaredField("state");
    stateField.setAccessible(true);
    SessionState state = (SessionState) stateField.get(session);

    state.setLogonSent(true);
    state.setLogonReceived(true);
    assertTrue(connector.isLoggedOn());

    assertTrue(session.isEnabled());
    connector.logoutAllSessions(true);
    assertFalse(session.isEnabled());

    assertEquals(9999, connector.getIntSetting(Acceptor.SETTING_SOCKET_ACCEPT_PORT));

    assertNotNull(connector.getScheduledExecutorService());
    assertEquals(settings, connector.getSettings());
  }
 @Override
 public void messageReceived(IoSession ioSession, Object message) throws Exception {
   String messageString = (String) message;
   SessionID remoteSessionID = MessageUtils.getReverseSessionID(messageString);
   Session quickFixSession = findQFSession(ioSession, remoteSessionID);
   if (quickFixSession != null) {
     quickFixSession.getLog().onIncoming(messageString);
     try {
       Message fixMessage = parse(quickFixSession, messageString);
       processMessage(ioSession, fixMessage);
     } catch (InvalidMessage e) {
       if (MsgType.LOGON.equals(MessageUtils.getMessageType(messageString))) {
         log.error("Invalid LOGON message, disconnecting: " + e.getMessage());
         ioSession.closeNow();
       } else {
         log.error("Invalid message: " + e.getMessage());
       }
     }
   } else {
     log.error("Disconnecting; received message for unknown session: " + messageString);
     ioSession.closeNow();
   }
 }
Example #16
0
  private void doApplicationMessageEventsTest(
      SessionID acceptorSessionID, SessionID initiatorSessionID, QuickfixjEngine quickfixjEngine)
      throws SessionNotFound, InterruptedException, FieldNotFound {

    final List<EventRecord> events = new ArrayList<EventRecord>();
    final CountDownLatch messageLatch = new CountDownLatch(1);

    QuickfixjEventListener messageListener =
        new QuickfixjEventListener() {
          @Override
          public synchronized void onEvent(
              QuickfixjEventCategory eventCategory, SessionID sessionID, Message message) {
            EventRecord event = new EventRecord(eventCategory, sessionID, message);
            events.add(event);
            if (eventCategory == QuickfixjEventCategory.AppMessageReceived) {
              messageLatch.countDown();
            }
          }
        };

    quickfixjEngine.addEventListener(messageListener);
    Email email = TestSupport.createEmailMessage("Test");
    Session.sendToTarget(email, initiatorSessionID);

    assertTrue("Application message not received", messageLatch.await(5000, TimeUnit.MILLISECONDS));
    quickfixjEngine.removeEventListener(messageListener);

    assertThat(events.size(), is(2));

    EventRecord sendEvent =
        new EventRecord(QuickfixjEventCategory.AppMessageSent, initiatorSessionID, new Message());
    assertTrue(events.contains(sendEvent));
    int sendEventIndex = events.indexOf(sendEvent);
    assertThat(
        events.get(sendEventIndex).message.getHeader().getString(MsgType.FIELD), is(MsgType.EMAIL));

    EventRecord receiveEvent =
        new EventRecord(
            QuickfixjEventCategory.AppMessageReceived, acceptorSessionID, new Message());
    assertTrue(events.contains(receiveEvent));
    int receiveEventIndex = events.indexOf(receiveEvent);
    assertThat(
        events.get(receiveEventIndex).message.getHeader().getString(MsgType.FIELD),
        is(MsgType.EMAIL));
  }
  /** Test that adding/removing dynamic sessions works correctly */
  public void testAddingRemovingDymaicSessions() throws Exception {
    SessionID sessionID = new SessionID(FixVersions.BEGINSTRING_FIX40, "TW", "ISLD");
    SessionID sessionID2 = new SessionID(FixVersions.BEGINSTRING_FIX40, "me", "you");
    SessionSettings settings = setUpSessionSettings(sessionID);
    DefaultSessionFactory sessionFactory =
        new DefaultSessionFactory(
            new UnitTestApplication(),
            new MemoryStoreFactory(),
            new ScreenLogFactory(true, true, true));

    SessionConnector connector = new SessionConnectorUnderTest(settings, sessionFactory);
    connector.setSessions(new HashMap<>());
    Session session = connector.createSession(sessionID);

    // one-time use connector to create a slightly different session
    SessionSettings settings2 = setUpSessionSettings(sessionID2);
    SessionConnector connector2 = new SessionConnectorUnderTest(settings2, sessionFactory);
    connector.setSessions(new HashMap<>());
    Session session2 = connector2.createSession(sessionID2);
    assertNotNull(session);
    assertNotNull(session2);

    assertEquals(0, connector.getManagedSessions().size());
    connector.addDynamicSession(session);
    assertEquals(1, connector.getManagedSessions().size());
    connector.addDynamicSession(session2);
    assertEquals(2, connector.getManagedSessions().size());
    // the list can be in arbitrary order so let's make sure that we get both
    HashMap<SessionID, Session> map = new HashMap<>();
    for (Session s : connector.getManagedSessions()) {
      map.put(s.getSessionID(), s);
    }
    assertEquals(session, map.get(session.getSessionID()));
    assertEquals(session2, map.get(session2.getSessionID()));

    connector.removeDynamicSession(session.getSessionID());
    assertEquals(1, connector.getManagedSessions().size());
    assertEquals(session2, connector.getManagedSessions().get(0));
    connector.removeDynamicSession(session2.getSessionID());
    assertEquals(0, connector.getManagedSessions().size());
  }
Example #18
0
  public void process(Message message, SessionID sessionID) throws FieldNotFound {
    quickfix.Message echo = (quickfix.Message) message.clone();
    PossResend possResend = new PossResend(false);
    if (message.getHeader().isSetField(possResend)) message.getHeader().getField(possResend);

    ClOrdID clOrdID = new ClOrdID();
    message.getField(clOrdID);

    Pair pair = new Pair(clOrdID, sessionID);

    if (possResend.getValue() == true) {
      if (orderIDs.contains(pair)) return;
    }
    orderIDs.add(pair);
    try {
      Session.sendToTarget(echo, sessionID);
    } catch (SessionNotFound snf) {
    }
  }
Example #19
0
 private void assertLoggedOn(ClientApplication clientApplication, Session clientSession)
     throws InterruptedException {
   assertNotNull("no client session", clientSession);
   clientApplication.logonLatch.await(20, TimeUnit.SECONDS);
   assertTrue("client session not logged in", clientSession.isLoggedOn());
 }
 Session getSession(SessionID messageSessionID) {
   return Session.lookupSession(messageSessionID);
 }
Example #21
0
 public void addDynamicSession(Session inSession) {
   sessions.put(inSession.getSessionID(), inSession);
   log.debug("adding session for " + inSession.getSessionID());
   propertyChangeSupport.firePropertyChange(SESSIONS_PROPERTY, null, sessions);
 }