From 909c86863cd9a2d9f47a47a485180eee4cf3c520 Mon Sep 17 00:00:00 2001 From: Richard L King Date: Wed, 10 May 2023 23:44:50 +0100 Subject: [PATCH] Make FIX handling work properly (issue #207) --- resources/config.ini | 33 +++++-- src/ibcalpha/ibc/AbstractLoginHandler.java | 2 +- src/ibcalpha/ibc/CommandChannel.java | 2 - src/ibcalpha/ibc/CommandDispatcher.java | 12 +++ src/ibcalpha/ibc/DefaultLoginManager.java | 85 +++++++++---------- .../ExistingSessionDetectedDialogHandler.java | 7 +- .../ibc/GatewayLoginFrameHandler.java | 12 ++- src/ibcalpha/ibc/IbcTws.java | 71 ++++++++++++---- src/ibcalpha/ibc/JtsIniManager.java | 40 ++++++--- src/ibcalpha/ibc/LoginFrameHandler.java | 2 +- src/ibcalpha/ibc/LoginManager.java | 7 ++ ...condFactorAuthenticationDialogHandler.java | 5 +- src/ibcalpha/ibc/SessionManager.java | 22 +++-- src/ibcalpha/ibc/Utils.java | 2 +- 14 files changed, 204 insertions(+), 98 deletions(-) diff --git a/resources/config.ini b/resources/config.ini index 28f8af9..17425e8 100644 --- a/resources/config.ini +++ b/resources/config.ini @@ -329,13 +329,16 @@ ExistingSessionDetectedAction=manual # Override TWS API Port Number # ---------------------------- # -# If OverrideTwsApiPort is set to an integer, IBC changes the -# 'Socket port' in TWS's API configuration to that number shortly -# after startup. Leaving the setting blank will make no change to -# the current setting. This setting is only intended for use in -# certain specialized situations where the port number needs to -# be set dynamically at run-time: most users will never need it, -# so don't use it unless you know you need it. +# If OverrideTwsApiPort is set to an integer, IBC changes the +# 'Socket port' in TWS's API configuration to that number shortly +# after startup (but note that for the FIX Gateway, this setting is +# actually stored in jts.ini rather than the Gateway's settings +# file). Leaving the setting blank will make no change to +# the current setting. This setting is only intended for use in +# certain specialized situations where the port number needs to +# be set dynamically at run-time, and for the FIX Gateway: most +# non-FIX users will never need it, so don't use it unless you know +# you need it. OverrideTwsApiPort= @@ -428,6 +431,22 @@ AcceptBidAskLastSizeDisplayUpdateNotification= SendMarketDataInLotsForUSstocks= +# Trusted API Client IPs +# ---------------------- +# +# NB: THIS SETTING IS ONLY RELEVANT FOR THE GATEWAY, AND ONLY WHEN FIX=yes. +# In all other cases it is ignored. +# +# This is a list of IP addresses separated by commas. API clients with IP +# addresses in this list are able to connect to the API without Gateway +# generating the 'Incoming connection' popup. +# +# Note that 127.0.0.1 is always permitted to connect, so do not include it +# in this setting. + +TrustedTwsApiClientIPs= + + # ============================================================================= # 4. TWS Auto-Logoff and Auto-Restart diff --git a/src/ibcalpha/ibc/AbstractLoginHandler.java b/src/ibcalpha/ibc/AbstractLoginHandler.java index 8678795..0226892 100644 --- a/src/ibcalpha/ibc/AbstractLoginHandler.java +++ b/src/ibcalpha/ibc/AbstractLoginHandler.java @@ -57,7 +57,7 @@ public final void handleWindow(Window window, int eventID) { switch (LoginManager.loginManager().getLoginState()){ case LOGGED_OUT: // don't initiate login if we're auto-restarting - if (! SessionManager.IsRestart()) initiateLogin(window); + if (! SessionManager.isRestart()) initiateLogin(window); } } diff --git a/src/ibcalpha/ibc/CommandChannel.java b/src/ibcalpha/ibc/CommandChannel.java index 10be3da..0d3cc3b 100644 --- a/src/ibcalpha/ibc/CommandChannel.java +++ b/src/ibcalpha/ibc/CommandChannel.java @@ -41,8 +41,6 @@ final class CommandChannel { if (! setupStreams()) return; writeInfo("IBC Command Server"); - writePrompt(); - } void close() { diff --git a/src/ibcalpha/ibc/CommandDispatcher.java b/src/ibcalpha/ibc/CommandDispatcher.java index 1381780..5adefa3 100644 --- a/src/ibcalpha/ibc/CommandDispatcher.java +++ b/src/ibcalpha/ibc/CommandDispatcher.java @@ -72,6 +72,10 @@ private void handleEnableAPICommand() { } private void handleReconnectDataCommand() { + if (SessionManager.isFIX()) { + mChannel.writeNack("RECONNECTDATA is not valid for the FIX Gateway"); + return; + } JFrame jf = MainWindowManager.mainWindowManager().getMainWindow(1, TimeUnit.MILLISECONDS); int modifiers = KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK; @@ -86,6 +90,10 @@ private void handleReconnectDataCommand() { } private void handleReconnectAccountCommand() { + if (SessionManager.isFIX()) { + mChannel.writeNack("RECONNECTACCOUNT is not valid for the FIX Gateway"); + return; + } JFrame jf = MainWindowManager.mainWindowManager().getMainWindow(); int modifiers = KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK; @@ -104,6 +112,10 @@ private void handleStopCommand() { } private void handleRestartCommand() { + if (SessionManager.isFIX()) { + mChannel.writeNack("RESTART is not valid for the FIX Gateway"); + return; + } (new RestartTask(mChannel)).run(); // run on the current thread } diff --git a/src/ibcalpha/ibc/DefaultLoginManager.java b/src/ibcalpha/ibc/DefaultLoginManager.java index 9d690d7..68cfa0c 100644 --- a/src/ibcalpha/ibc/DefaultLoginManager.java +++ b/src/ibcalpha/ibc/DefaultLoginManager.java @@ -26,28 +26,25 @@ public DefaultLoginManager() { /* don't actually get the credentials yet because the settings * provider might be changed */ - fromSettings = true; - message = "getting username and password from settings"; + ibapiCredentialsFromArgs = false; + fixCredentialsFromArgs = false; + message = "will get username and password from settings"; } public DefaultLoginManager(String[] args) { - if (isFIX()) { - getTWSUserNameAndPasswordFromArguments(args); - fromSettings = !getFIXUserNameAndPasswordFromArguments(args); - } else { - fromSettings = !getTWSUserNameAndPasswordFromArguments(args); - } - if (fromSettings) { - message = "getting username and password from args but not found. Will get from settings"; - } else { - message = "getting username and password from args"; - } + ibapiCredentialsFromArgs = getTWSUserNameAndPasswordFromArguments(args); + fixCredentialsFromArgs = getFIXUserNameAndPasswordFromArguments(args); + message = "will get username and password from " + + (fixCredentialsFromArgs ? "args" : "settings") + + "; FIX username and password (if required) from " + + (fixCredentialsFromArgs ? "args" : "settings"); } public DefaultLoginManager(String username, String password) { IBAPIUserName = username; IBAPIPassword = password; - fromSettings = false; + ibapiCredentialsFromArgs = true; + fixCredentialsFromArgs = false; message = "getting username and password from constructor"; } @@ -56,7 +53,8 @@ public DefaultLoginManager(String FIXUsername, String FIXPassword, String IBAPIU this.FIXPassword = FIXPassword; this.IBAPIUserName = IBAPIUsername; this.IBAPIPassword = IBAPIPassword; - fromSettings = false; + ibapiCredentialsFromArgs = true; + fixCredentialsFromArgs = true; message = "getting username and password from constructor (including FIX)"; } @@ -64,7 +62,8 @@ public DefaultLoginManager(String FIXUsername, String FIXPassword, String IBAPIU private volatile AbstractLoginHandler loginHandler = null; - private final boolean fromSettings; + private final boolean ibapiCredentialsFromArgs; + private final boolean fixCredentialsFromArgs; /** * IBAPI username - can either be supplied from the .ini file or as args[1] @@ -101,26 +100,26 @@ public void logDiagnosticMessage(){ @Override public String FIXPassword() { - if (fromSettings) return getFIXPasswordFromSettings(); - return FIXPassword; + if (fixCredentialsFromArgs) return FIXPassword; + return getFIXPasswordFromSettings(); } @Override public String FIXUserName() { - if (fromSettings) return getFIXUserNameFromSettings(); - return FIXUserName; + if (fixCredentialsFromArgs) return FIXUserName; + return getFIXUserNameFromSettings(); } @Override public String IBAPIPassword() { - if (fromSettings) return getTWSPasswordFromSettings(); - return IBAPIPassword; + if (ibapiCredentialsFromArgs) return IBAPIPassword; + return getTWSPasswordFromSettings(); } @Override public String IBAPIUserName() { - if (fromSettings) return getTWSUserNameFromSettings(); - return IBAPIUserName; + if (ibapiCredentialsFromArgs) return IBAPIUserName; + return getTWSUserNameFromSettings(); } @Override @@ -172,33 +171,27 @@ private static String getTWSUserNameFromSettings() { } private boolean getTWSUserNameAndPasswordFromArguments(String[] args) { - if (isFIX()) { - if (args.length == 5 || args.length == 6) { - IBAPIUserName = args[3]; - IBAPIPassword = args[4]; - return true; - } else { - return false; - } - } else if (args.length == 3 || args.length == 4) { + if (args.length == 5 || args.length == 6) { + IBAPIUserName = args[3]; + IBAPIPassword = args[4]; + return true; + + } + if (args.length == 3 || args.length == 4) { IBAPIUserName = args[1]; IBAPIPassword = args[2]; return true; - } else if (args.length == 5 || args.length == 6) { - Utils.logError("Incorrect number of arguments passed. quitting..."); - Utils.logRawToConsole("Number of arguments = " +args.length + " which is only permitted if FIX=yes"); - for (String arg : args) { - Utils.logRawToConsole(arg); - } - Utils.exitWithError(ErrorCodes.ERROR_CODE_INCORRECT_NUMBER_OF_ARGUMENTS); - return false; - } else { + } + if (args.length <= 2) { return false; } - } - - private static boolean isFIX() { - return Settings.settings().getBoolean("FIX", false); + Utils.logError("Incorrect number of arguments passed. quitting..."); + Utils.logRawToConsole("Number of arguments = " +args.length); + for (int i = 0; i < args.length; i++) { + Utils.logRawToConsole("arg[" + i + "]=" + args[i]); + } + Utils.exitWithError(ErrorCodes.ERROR_CODE_INCORRECT_NUMBER_OF_ARGUMENTS); + return false; } } diff --git a/src/ibcalpha/ibc/ExistingSessionDetectedDialogHandler.java b/src/ibcalpha/ibc/ExistingSessionDetectedDialogHandler.java index 4bc8f72..6516727 100644 --- a/src/ibcalpha/ibc/ExistingSessionDetectedDialogHandler.java +++ b/src/ibcalpha/ibc/ExistingSessionDetectedDialogHandler.java @@ -46,9 +46,10 @@ public void handleWindow(Window window, int eventID) { if (setting.equalsIgnoreCase("secondary")) { Utils.logToConsole("End this session and let the other session proceed (scenario 2)"); - if (!SwingUtils.clickButton(window, "Cancel") && !SwingUtils.clickButton(window, "Exit Application")) { - Utils.logError("could not handle 'Existing session detected' dialog because the 'Cancel' or 'Exit Application' button wasn't found."); - } + if (!SwingUtils.clickButton(window, "Cancel") && !SwingUtils.clickButton(window, "Exit Application")) { + Utils.logError("could not handle 'Existing session detected' dialog because the 'Cancel' or 'Exit Application' button wasn't found."); + } + return; } /* The handling of this dialog is based on the following observed diff --git a/src/ibcalpha/ibc/GatewayLoginFrameHandler.java b/src/ibcalpha/ibc/GatewayLoginFrameHandler.java index 182aa82..3a65cec 100644 --- a/src/ibcalpha/ibc/GatewayLoginFrameHandler.java +++ b/src/ibcalpha/ibc/GatewayLoginFrameHandler.java @@ -48,7 +48,7 @@ protected final boolean initialise(final Window window, int eventID) throws IbcE @Override protected final boolean preLogin(final Window window, int eventID) throws IbcException { boolean result; - if (Settings.settings().getBoolean("FIX", false)) { + if (SessionManager.isFIX()) { result = setMissingFIXCredentials(window); } else { result = setMissingIBAPICredentials(window); @@ -90,20 +90,26 @@ private boolean setMissingIBAPICredentials(Window window) { @Override protected final boolean setFields(Window window, int eventID) throws IbcException { - if (Settings.settings().getBoolean("FIX", false)) { + if (SessionManager.isFIX()) { + Utils.logToConsole("Setting FIX user name"); setCredential(window, "FIX user name", 0, LoginManager.loginManager().FIXUserName()); + Utils.logToConsole("Setting FIX password"); setCredential(window, "FIX password", 1, LoginManager.loginManager().FIXPassword()); + Utils.logToConsole("Setting API user name"); setCredential(window, "IBAPI user name", 2, LoginManager.loginManager().IBAPIUserName()); + Utils.logToConsole("Setting API password"); setCredential(window, "IBAPI password", 3, LoginManager.loginManager().IBAPIPassword()); } else { + Utils.logToConsole("Setting user name"); setCredential(window, "IBAPI user name", 0, LoginManager.loginManager().IBAPIUserName()); + Utils.logToConsole("Setting password"); setCredential(window, "IBAPI password", 1, LoginManager.loginManager().IBAPIPassword()); } return true; } private void selectGatewayMode(Window window) throws IbcException { - if (Settings.settings().getBoolean("FIX", false)) { + if (SessionManager.isFIX()) { switchToFIX(window); } else { switchToIBAPI(window); diff --git a/src/ibcalpha/ibc/IbcTws.java b/src/ibcalpha/ibc/IbcTws.java index 1dca409..d187cdf 100644 --- a/src/ibcalpha/ibc/IbcTws.java +++ b/src/ibcalpha/ibc/IbcTws.java @@ -434,10 +434,9 @@ private static void startGateway() { twsArgs[0] = getTWSSettingsDirectory(); try { Utils.logToConsole("Starting Gateway"); - SessionManager.startSession(); ibgateway.GWClient.main(twsArgs); } catch (Throwable t) { - Utils.logError("Can't find the Gateway entry point: ibgateway.GWClient.main. Gateway is not correctly installed."); + Utils.logError("Exception occurred at Gateway entry point: ibgateway.GWClient.main"); t.printStackTrace(Utils.getErrStream()); Utils.exitWithError(ErrorCodes.ERROR_CODE_CANT_FIND_ENTRYPOINT); } @@ -468,10 +467,9 @@ private static void startTws() { twsArgs[0] = getTWSSettingsDirectory(); try { Utils.logToConsole("Starting TWS"); - SessionManager.startSession(); jclient.LoginFrame.main(twsArgs); } catch (Throwable t) { - Utils.logError("Can't find the TWS entry point: jclient.LoginFrame.main; TWS is not correctly installed."); + Utils.logError("Exception occurred at TWS entry point: jclient.LoginFrame.main"); t.printStackTrace(Utils.getErrStream()); Utils.exitWithError(ErrorCodes.ERROR_CODE_CANT_FIND_ENTRYPOINT); } @@ -479,6 +477,7 @@ private static void startTws() { private static void startTwsOrGateway() { Utils.logToConsole("TWS Settings directory is: " + getTWSSettingsDirectory()); + SessionManager.startSession(); JtsIniManager.initialise(getJtsIniFilePath()); if (SessionManager.isGateway()) { startGateway(); @@ -486,20 +485,36 @@ private static void startTwsOrGateway() { startTws(); } - int portNumber = Settings.settings().getInt("OverrideTwsApiPort", 0); - if (portNumber != 0) (new ConfigurationTask(new ConfigureTwsApiPortTask(portNumber))).executeAsync(); - - if (!Settings.settings().getString("ReadOnlyApi", "").equals("")) { - (new ConfigurationTask(new ConfigureReadOnlyApiTask(Settings.settings().getBoolean("ReadOnlyApi",true)))).executeAsync(); - } - - String sendMarketDataInLots = Settings.settings().getString("SendMarketDataInLotsForUSstocks", ""); - if (!sendMarketDataInLots.equals("")) { - (new ConfigurationTask(new ConfigureSendMarketDataInLotsForUSstocksTask(Settings.settings().getBoolean("SendMarketDataInLotsForUSstocks", true)))).executeAsync(); - } + configureApiPort(); + configureReadOnlyApi(); + configureSendMarketDataInLotsForUSstocks(); + configureAutoLogoffOrRestart(); + Utils.sendConsoleOutputToTwsLog(!Settings.settings().getBoolean("LogToConsole", false)); + } + + private static void configureApiPort() { + String configName = "OverrideTwsApiPort"; + int portNumber = Settings.settings().getInt(configName, 0); + if (portNumber != 0) { + if (SessionManager.isFIX()){ + Utils.logToConsole(configName + " - ignored for FIX"); + return; + } + (new ConfigurationTask(new ConfigureTwsApiPortTask(portNumber))).executeAsync(); + } + } + + private static void configureAutoLogoffOrRestart() { + String configName = "AutoLogoffTime Or AutoRestartTime"; String autoLogoffTime = Settings.settings().getString("AutoLogoffTime", ""); String autoRestartTime = Settings.settings().getString("AutoRestartTime", ""); + if (autoRestartTime.length() != 0 || autoLogoffTime.length() != 0) { + if (SessionManager.isFIX()){ + Utils.logToConsole(configName + " - ignored for FIX"); + return; + } + } if (autoRestartTime.length() != 0) { (new ConfigurationTask(new ConfigureAutoLogoffOrRestartTimeTask("Auto restart", autoRestartTime))).executeAsync(); if (autoLogoffTime.length() != 0) { @@ -508,9 +523,31 @@ private static void startTwsOrGateway() { } else if (autoLogoffTime.length() != 0) { (new ConfigurationTask(new ConfigureAutoLogoffOrRestartTimeTask("Auto logoff", autoLogoffTime))).executeAsync(); } - - Utils.sendConsoleOutputToTwsLog(!Settings.settings().getBoolean("LogToConsole", false)); } + + private static void configureReadOnlyApi() { + String configName = "ReadOnlyApi"; + if (!Settings.settings().getString(configName, "").equals("")) { + if (SessionManager.isFIX()){ + Utils.logToConsole(configName + " - ignored for FIX"); + return; + } + (new ConfigurationTask(new ConfigureReadOnlyApiTask(Settings.settings().getBoolean(configName,true)))).executeAsync(); + } + } + + private static void configureSendMarketDataInLotsForUSstocks(){ + String configName = "SendMarketDataInLotsForUSstocks"; + String sendMarketDataInLots = Settings.settings().getString(configName, ""); + if (!sendMarketDataInLots.equals("")) { + if (SessionManager.isFIX()){ + Utils.logToConsole(configName + " - ignored for FIX"); + return; + } + (new ConfigurationTask(new ConfigureSendMarketDataInLotsForUSstocksTask(Settings.settings().getBoolean(configName, true)))).executeAsync(); + } + } + private static void startSavingTwsSettingsAutomatically() { TwsSettingsSaver.getInstance().initialise(); diff --git a/src/ibcalpha/ibc/JtsIniManager.java b/src/ibcalpha/ibc/JtsIniManager.java index 6bf6ba6..d71070b 100644 --- a/src/ibcalpha/ibc/JtsIniManager.java +++ b/src/ibcalpha/ibc/JtsIniManager.java @@ -43,6 +43,9 @@ class JtsIniManager { final static String USESSL_SETTING_TRUE = USESSL_SETTING + "=true"; final static String APIONLY_SETTING = "ApiOnly"; final static String APIONLY_SETTING_TRUE = APIONLY_SETTING + "=true"; + final static String APIONLY_SETTING_FALSE = APIONLY_SETTING + "=false"; + final static String TRUSTED_IPS_SETTING = "TrustedIPs"; + final static String LOCAL_SERVER_PORT = "LocalServerPort"; private static String jtsIniFilePath; private static File jtsIniFile; @@ -180,21 +183,36 @@ private static void updateExistingFile() { private static List getMissingSettings() { List missingSettings = new ArrayList<>(); - if (! findSettingAndLog(LOGON_SECTION_HEADER, S3STORE_SETTING, "true", false)) - missingSettings.add(new JtsIniSectionSetting(LOGON_SECTION_HEADER, S3STORE_SETTING_TRUE)); - - if (! findSettingAndLog(LOGON_SECTION_HEADER, LOCALE_SETTING, "en", true)) - missingSettings.add(new JtsIniSectionSetting(LOGON_SECTION_HEADER, LOCALE_SETTING_EN)); + if (SessionManager.isFIX()) { + if (! findSettingAndLog(IBGATEWAY_SECTION_HEADER, APIONLY_SETTING, "true", true)) + missingSettings.add(new JtsIniSectionSetting(IBGATEWAY_SECTION_HEADER, APIONLY_SETTING_FALSE)); + + String trustedIPs = Settings.settings().getString("TrustedTwsApiClientIPs", ""); + trustedIPs = "127.0.0.1" + (trustedIPs.equals("") ? "" : "," + trustedIPs); + if (! findSettingAndLog(IBGATEWAY_SECTION_HEADER, TRUSTED_IPS_SETTING, trustedIPs, true)) + missingSettings.add(new JtsIniSectionSetting(IBGATEWAY_SECTION_HEADER, TRUSTED_IPS_SETTING + "=" + trustedIPs)); + + String apiPort = Settings.settings().getString("OverrideTwsApiPort", ""); + if (! "".equals(apiPort)) { + if (! findSettingAndLog(IBGATEWAY_SECTION_HEADER, LOCAL_SERVER_PORT, apiPort, true)) + missingSettings.add(new JtsIniSectionSetting(IBGATEWAY_SECTION_HEADER, TRUSTED_IPS_SETTING + "=" + apiPort)); + } + } else { + if (! findSettingAndLog(LOGON_SECTION_HEADER, S3STORE_SETTING, "true", false)) + missingSettings.add(new JtsIniSectionSetting(LOGON_SECTION_HEADER, S3STORE_SETTING_TRUE)); - if (! findSettingAndLog(LOGON_SECTION_HEADER, DISPLAYEDPROXYMSG_SETTING, "1", true)) - missingSettings.add(new JtsIniSectionSetting(LOGON_SECTION_HEADER, DISPLAYEDPROXYMSG_SETTING_1)); + if (! findSettingAndLog(LOGON_SECTION_HEADER, LOCALE_SETTING, "en", true)) + missingSettings.add(new JtsIniSectionSetting(LOGON_SECTION_HEADER, LOCALE_SETTING_EN)); - if (! findSettingAndLog(LOGON_SECTION_HEADER, USESSL_SETTING, "true", true)) - missingSettings.add(new JtsIniSectionSetting(LOGON_SECTION_HEADER, USESSL_SETTING_TRUE)); + if (! findSettingAndLog(LOGON_SECTION_HEADER, DISPLAYEDPROXYMSG_SETTING, "1", true)) + missingSettings.add(new JtsIniSectionSetting(LOGON_SECTION_HEADER, DISPLAYEDPROXYMSG_SETTING_1)); - if (! findSettingAndLog(IBGATEWAY_SECTION_HEADER, APIONLY_SETTING, "true", true)) - missingSettings.add(new JtsIniSectionSetting(IBGATEWAY_SECTION_HEADER, APIONLY_SETTING_TRUE)); + if (! findSettingAndLog(LOGON_SECTION_HEADER, USESSL_SETTING, "true", true)) + missingSettings.add(new JtsIniSectionSetting(LOGON_SECTION_HEADER, USESSL_SETTING_TRUE)); + if (! findSettingAndLog(IBGATEWAY_SECTION_HEADER, APIONLY_SETTING, "true", true)) + missingSettings.add(new JtsIniSectionSetting(IBGATEWAY_SECTION_HEADER, APIONLY_SETTING_TRUE)); + } return missingSettings; } diff --git a/src/ibcalpha/ibc/LoginFrameHandler.java b/src/ibcalpha/ibc/LoginFrameHandler.java index ae5a268..d95de5a 100644 --- a/src/ibcalpha/ibc/LoginFrameHandler.java +++ b/src/ibcalpha/ibc/LoginFrameHandler.java @@ -39,7 +39,7 @@ public boolean recogniseWindow(Window window) { SwingUtils.titleEquals(window, "Login")) && (SwingUtils.findButton(window, "Log In") != null || SwingUtils.findButton(window, "Paper Log In") != null || - SessionManager.IsRestart())); + SessionManager.isRestart())); } private boolean listeningForUsernameChange; diff --git a/src/ibcalpha/ibc/LoginManager.java b/src/ibcalpha/ibc/LoginManager.java index 435902f..ef17c16 100644 --- a/src/ibcalpha/ibc/LoginManager.java +++ b/src/ibcalpha/ibc/LoginManager.java @@ -124,6 +124,13 @@ void secondFactorAuthenticationDialogClosed() { if (d.getSeconds() < SecondFactorAuthenticationTimeout) { // The 2FA prompt must have been handled by the user, so authentication // should be under way + + if (SessionManager.isFIX()) { + // no Splash screen is dislayed for FIX Gateway - just let things run + LoginManager.loginManager().setLoginState(LoginManager.LoginState.LOGGED_IN); + return; + } + Utils.logToConsole("If login has not completed, IBC will exit in " + exitInterval + " seconds"); restartAfterTime(exitInterval, "IBC closing because login has not completed after Second Factor Authentication"); return; diff --git a/src/ibcalpha/ibc/SecondFactorAuthenticationDialogHandler.java b/src/ibcalpha/ibc/SecondFactorAuthenticationDialogHandler.java index bddcd39..02a8ab8 100644 --- a/src/ibcalpha/ibc/SecondFactorAuthenticationDialogHandler.java +++ b/src/ibcalpha/ibc/SecondFactorAuthenticationDialogHandler.java @@ -57,7 +57,10 @@ public void handleWindow(Window window, int eventID) { LoginManager.loginManager().setLoginState(LoginManager.LoginState.TWO_FA_IN_PROGRESS); } } else if (eventID == WindowEvent.WINDOW_CLOSED) { - if (LoginManager.loginManager().readonlyLoginRequired()) return; + if (LoginManager.loginManager().readonlyLoginRequired()) { + LoginManager.loginManager().setLoginState(LoginManager.LoginState.LOGGED_IN); + return; + } LoginManager.loginManager().secondFactorAuthenticationDialogClosed(); } } diff --git a/src/ibcalpha/ibc/SessionManager.java b/src/ibcalpha/ibc/SessionManager.java index 5e48e80..26bed90 100644 --- a/src/ibcalpha/ibc/SessionManager.java +++ b/src/ibcalpha/ibc/SessionManager.java @@ -34,17 +34,29 @@ public static void initialise(boolean isGateway) { public static boolean isGateway() { return _isGateway; }; + + private static boolean _isFIX = false; + public static boolean isFIX() { + if (!_isSessionStarted) Utils.exitWithError(ErrorCodes.ERROR_CODE_INVALID_STATE, "isFix() called before session has started"); + return _isFIX; + } - private static boolean isRestart; - static boolean IsRestart() { - return isRestart; + private static boolean _isRestart; + static boolean isRestart() { + if (!_isSessionStarted) Utils.exitWithError(ErrorCodes.ERROR_CODE_INVALID_STATE, "isRestart() called before session has started"); + return _isRestart; } + private static boolean _isSessionStarted = false; static void startSession() { + _isSessionStarted = true; + + _isFIX = Settings.settings().getBoolean("FIX", false); + // test to see if the -Drestart VM option has been supplied - isRestart = ! (System.getProperties().getProperty("restart", "").isEmpty()); + _isRestart = ! (System.getProperties().getProperty("restart", "").isEmpty()); int loginDialogDisplayTimeout = Settings.settings().getInt("LoginDialogDisplayTimeout", 60); - if (isRestart){ + if (_isRestart){ Utils.logToConsole("Re-starting session"); // TWS/Gateway will re-establish the session with no intervention from IBC needed } else { diff --git a/src/ibcalpha/ibc/Utils.java b/src/ibcalpha/ibc/Utils.java index 0b5d27e..5929d4d 100644 --- a/src/ibcalpha/ibc/Utils.java +++ b/src/ibcalpha/ibc/Utils.java @@ -163,7 +163,7 @@ static String formatDate(LocalDateTime date) { } private static String formatMessage(String message) { - return _dateFormatter.format(LocalDateTime.now()) + " IBC: " + message.substring(0,1).toUpperCase() + message.substring(1); + return _dateFormatter.format(LocalDateTime.now()) + " IBC: " + message; } /**