Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*******************************************************************************
* Copyright (c) quickfixengine.org All rights reserved.
*
* This file is part of the QuickFIX FIX Engine
*
* This file may be distributed under the terms of the quickfixengine.org
* license as defined by quickfixengine.org and appearing in the file
* LICENSE included in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* See http://www.quickfixengine.org/LICENSE for licensing information.
*
* Contact ask@quickfixengine.org if any conditions of this licensing
* are not clear to you.
******************************************************************************/

package quickfix;

import javax.xml.parsers.DocumentBuilderFactory;

final class ExternalDtdDataDictionaryLoader {
private static final String DEFAULT_CONNECT_TIMEOUT_PROPERTY = "sun.net.client.defaultConnectTimeout";
private static final String DEFAULT_READ_TIMEOUT_PROPERTY = "sun.net.client.defaultReadTimeout";
private static final int EXTERNAL_DTD_TIMEOUT_MILLIS = 5000;
private static final int EXTERNAL_DTD_LOAD_RETRIES = 3;
private static final int EXTERNAL_DTD_RETRY_DELAY_MILLIS = 250;

private ExternalDtdDataDictionaryLoader() {
}

static DataDictionary load(String location) throws ConfigError {
final String previousConnectTimeout = System.getProperty(DEFAULT_CONNECT_TIMEOUT_PROPERTY);
final String previousReadTimeout = System.getProperty(DEFAULT_READ_TIMEOUT_PROPERTY);
try {
final String timeout = String.valueOf(EXTERNAL_DTD_TIMEOUT_MILLIS);
System.setProperty(DEFAULT_CONNECT_TIMEOUT_PROPERTY, timeout);
System.setProperty(DEFAULT_READ_TIMEOUT_PROPERTY, timeout);

ConfigError lastError = new ConfigError("Could not parse data dictionary file");
for (int attempt = 1; attempt <= EXTERNAL_DTD_LOAD_RETRIES; attempt++) {
try {
return new DataDictionary(location, DocumentBuilderFactory::newInstance);
} catch (ConfigError e) {
lastError = e;
if (attempt < EXTERNAL_DTD_LOAD_RETRIES) {
try {
Thread.sleep((1L << (attempt - 1)) * EXTERNAL_DTD_RETRY_DELAY_MILLIS);
} catch (InterruptedException interruptedException) {
Thread.currentThread().interrupt();
throw new ConfigError("Interrupted while retrying " + location + " load",
interruptedException);
}
}
}
}
throw new ConfigError("Failed to load " + location + " after " + EXTERNAL_DTD_LOAD_RETRIES
+ " attempts", lastError);
} finally {
restoreSystemProperty(DEFAULT_CONNECT_TIMEOUT_PROPERTY, previousConnectTimeout);
restoreSystemProperty(DEFAULT_READ_TIMEOUT_PROPERTY, previousReadTimeout);
}
}

private static void restoreSystemProperty(String key, String value) {
if (value == null) {
System.clearProperty(key);
} else {
System.setProperty(key, value);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
import java.net.URLClassLoader;
import java.util.Locale;

import javax.xml.parsers.DocumentBuilderFactory;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
Expand Down Expand Up @@ -673,7 +671,7 @@ public void testValidateFieldsOutOfOrderForGroups() throws Exception {

@Test
public void shouldLoadDictionaryWhenExternalDTDisEnabled() throws ConfigError {
new DataDictionary("FIX_External_DTD.xml", DocumentBuilderFactory::newInstance);
ExternalDtdDataDictionaryLoader.load("FIX_External_DTD.xml");
}

@Test
Expand Down
50 changes: 1 addition & 49 deletions quickfixj-core/src/test/java/quickfix/MessageTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
import java.time.LocalDateTime;
import java.time.ZoneOffset;

import javax.xml.parsers.DocumentBuilderFactory;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
Expand Down Expand Up @@ -143,12 +141,6 @@
* message classes that are generated later in the compile process.
*/
public class MessageTest {
private static final String DEFAULT_CONNECT_TIMEOUT_PROPERTY = "sun.net.client.defaultConnectTimeout";
private static final String DEFAULT_READ_TIMEOUT_PROPERTY = "sun.net.client.defaultReadTimeout";
private static final int EXTERNAL_DTD_TIMEOUT_MILLIS = 5000;
private static final int EXTERNAL_DTD_LOAD_RETRIES = 3;
private static final int EXTERNAL_DTD_RETRY_DELAY_MILLIS = 250;

@Rule
public ExpectedException expectedException = ExpectedException.none();

Expand Down Expand Up @@ -1270,7 +1262,7 @@ public void testIfMessageHeaderIsOverwritten() {

@Test
public void shouldConvertToXmlWhenDataDictionaryLoadedWithExternalDTD() throws ConfigError {
DataDictionary dataDictionary = loadDataDictionaryWithExternalDtdRetry();
DataDictionary dataDictionary = ExternalDtdDataDictionaryLoader.load("FIX_External_DTD.xml");
Message message = new Message();
message.setString(Account.FIELD, "test-account");

Expand All @@ -1279,46 +1271,6 @@ public void shouldConvertToXmlWhenDataDictionaryLoadedWithExternalDTD() throws C
assertEquals("<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"no\"?><message><header/><body><field name=\"Account\" tag=\"1\"><![CDATA[test-account]]></field></body><trailer/></message>", xml);
}

private DataDictionary loadDataDictionaryWithExternalDtdRetry() throws ConfigError {
final String previousConnectTimeout = System.getProperty(DEFAULT_CONNECT_TIMEOUT_PROPERTY);
final String previousReadTimeout = System.getProperty(DEFAULT_READ_TIMEOUT_PROPERTY);
try {
final String timeout = String.valueOf(EXTERNAL_DTD_TIMEOUT_MILLIS);
System.setProperty(DEFAULT_CONNECT_TIMEOUT_PROPERTY, timeout);
System.setProperty(DEFAULT_READ_TIMEOUT_PROPERTY, timeout);

ConfigError lastError = new ConfigError("Could not parse data dictionary file");
for (int attempt = 1; attempt <= EXTERNAL_DTD_LOAD_RETRIES; attempt++) {
try {
return new DataDictionary("FIX_External_DTD.xml", DocumentBuilderFactory::newInstance);
} catch (ConfigError e) {
lastError = e;
if (attempt < EXTERNAL_DTD_LOAD_RETRIES) {
try {
Thread.sleep((1L << (attempt - 1)) * EXTERNAL_DTD_RETRY_DELAY_MILLIS);
} catch (InterruptedException interruptedException) {
Thread.currentThread().interrupt();
throw new ConfigError("Interrupted while retrying FIX_External_DTD.xml load", interruptedException);
}
}
}
}
throw new ConfigError("Failed to load FIX_External_DTD.xml after "
+ EXTERNAL_DTD_LOAD_RETRIES + " attempts", lastError);
} finally {
restoreSystemProperty(DEFAULT_CONNECT_TIMEOUT_PROPERTY, previousConnectTimeout);
restoreSystemProperty(DEFAULT_READ_TIMEOUT_PROPERTY, previousReadTimeout);
}
}

private static void restoreSystemProperty(String key, String value) {
if (value == null) {
System.clearProperty(key);
} else {
System.setProperty(key, value);
}
}

@Test
public void shouldConvertToXMLWithoutIndent() {
Message message = new Message();
Expand Down
Loading