|
143 | 143 | * message classes that are generated later in the compile process. |
144 | 144 | */ |
145 | 145 | public class MessageTest { |
| 146 | + private static final String DEFAULT_CONNECT_TIMEOUT_PROPERTY = "sun.net.client.defaultConnectTimeout"; |
| 147 | + private static final String DEFAULT_READ_TIMEOUT_PROPERTY = "sun.net.client.defaultReadTimeout"; |
| 148 | + private static final int EXTERNAL_DTD_TIMEOUT_MILLIS = 5000; |
| 149 | + private static final int EXTERNAL_DTD_LOAD_RETRIES = 3; |
| 150 | + private static final int EXTERNAL_DTD_RETRY_DELAY_MILLIS = 250; |
146 | 151 |
|
147 | 152 | @Rule |
148 | 153 | public ExpectedException expectedException = ExpectedException.none(); |
@@ -1265,14 +1270,55 @@ public void testIfMessageHeaderIsOverwritten() { |
1265 | 1270 |
|
1266 | 1271 | @Test |
1267 | 1272 | public void shouldConvertToXmlWhenDataDictionaryLoadedWithExternalDTD() throws ConfigError { |
1268 | | - DataDictionary dataDictionary = new DataDictionary("FIX_External_DTD.xml", DocumentBuilderFactory::newInstance); |
| 1273 | + DataDictionary dataDictionary = loadDataDictionaryWithExternalDtdRetry(); |
1269 | 1274 | Message message = new Message(); |
1270 | 1275 | message.setString(Account.FIELD, "test-account"); |
1271 | 1276 |
|
1272 | 1277 | String xml = message.toXML(dataDictionary); |
1273 | 1278 | xml = xml.replace("\r", "").replace("\n", "").replaceAll(">\\s+<", "><"); |
1274 | 1279 | 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); |
1275 | 1280 | } |
| 1281 | + |
| 1282 | + private DataDictionary loadDataDictionaryWithExternalDtdRetry() throws ConfigError { |
| 1283 | + final String previousConnectTimeout = System.getProperty(DEFAULT_CONNECT_TIMEOUT_PROPERTY); |
| 1284 | + final String previousReadTimeout = System.getProperty(DEFAULT_READ_TIMEOUT_PROPERTY); |
| 1285 | + try { |
| 1286 | + final String timeout = String.valueOf(EXTERNAL_DTD_TIMEOUT_MILLIS); |
| 1287 | + System.setProperty(DEFAULT_CONNECT_TIMEOUT_PROPERTY, timeout); |
| 1288 | + System.setProperty(DEFAULT_READ_TIMEOUT_PROPERTY, timeout); |
| 1289 | + |
| 1290 | + ConfigError lastError = new ConfigError("Could not parse data dictionary file"); |
| 1291 | + for (int attempt = 1; attempt <= EXTERNAL_DTD_LOAD_RETRIES; attempt++) { |
| 1292 | + try { |
| 1293 | + return new DataDictionary("FIX_External_DTD.xml", DocumentBuilderFactory::newInstance); |
| 1294 | + } catch (ConfigError e) { |
| 1295 | + lastError = e; |
| 1296 | + if (attempt < EXTERNAL_DTD_LOAD_RETRIES) { |
| 1297 | + try { |
| 1298 | + Thread.sleep((1L << (attempt - 1)) * EXTERNAL_DTD_RETRY_DELAY_MILLIS); |
| 1299 | + } catch (InterruptedException interruptedException) { |
| 1300 | + Thread.currentThread().interrupt(); |
| 1301 | + throw new ConfigError("Interrupted while retrying FIX_External_DTD.xml load", interruptedException); |
| 1302 | + } |
| 1303 | + } |
| 1304 | + } |
| 1305 | + } |
| 1306 | + throw new ConfigError("Failed to load FIX_External_DTD.xml after " |
| 1307 | + + EXTERNAL_DTD_LOAD_RETRIES + " attempts", lastError); |
| 1308 | + } finally { |
| 1309 | + restoreSystemProperty(DEFAULT_CONNECT_TIMEOUT_PROPERTY, previousConnectTimeout); |
| 1310 | + restoreSystemProperty(DEFAULT_READ_TIMEOUT_PROPERTY, previousReadTimeout); |
| 1311 | + } |
| 1312 | + } |
| 1313 | + |
| 1314 | + private static void restoreSystemProperty(String key, String value) { |
| 1315 | + if (value == null) { |
| 1316 | + System.clearProperty(key); |
| 1317 | + } else { |
| 1318 | + System.setProperty(key, value); |
| 1319 | + } |
| 1320 | + } |
| 1321 | + |
1276 | 1322 | @Test |
1277 | 1323 | public void shouldConvertToXMLWithoutIndent() { |
1278 | 1324 | Message message = new Message(); |
|
0 commit comments