http://jira.mfd.msk:8088/browse/BKI-3191 fix concurrency bug in XmlProcessorStaxImpl
This commit is contained in:
parent
3fe63a93ec
commit
111d8b876b
5 changed files with 29 additions and 20 deletions
|
|
@ -14,6 +14,7 @@ import ru.nbch.credit_tracker.service.xml.stax.*;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class XmlConfig {
|
public class XmlConfig {
|
||||||
|
|
@ -30,11 +31,11 @@ public class XmlConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public StaxXmlProcessor staxXmlProcessor() {
|
public StaxXmlProcessor staxXmlProcessor() {
|
||||||
List<StaxReader<?>> staxReader = new ArrayList<>();
|
List<Supplier<StaxReader<?>>> staxReader = new ArrayList<>();
|
||||||
staxReader.add(new SgnlReportStatusStaxReader());
|
staxReader.add(SgnlReportStatusStaxReader::new);
|
||||||
staxReader.add(new MonitoringRequestStaxReader());
|
staxReader.add(MonitoringRequestStaxReader::new);
|
||||||
staxReader.add(new OnlineDownloadReportPersonsStaxReader());
|
staxReader.add(OnlineDownloadReportPersonsStaxReader::new);
|
||||||
staxReader.add(new MonitoringSignalResponseStaxXmlReader());
|
staxReader.add(MonitoringSignalResponseStaxXmlReader::new);
|
||||||
return new XmlProcessorStaxImpl(staxReader);
|
return new XmlProcessorStaxImpl(staxReader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package ru.nbch.credit_tracker.service.xml.stax;
|
package ru.nbch.credit_tracker.service.xml.stax;
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import ru.nbch.credit_tracker.entities.external_response.errors.Error;
|
import ru.nbch.credit_tracker.entities.external_response.errors.Error;
|
||||||
import ru.nbch.credit_tracker.entities.external_response.errors.InputParams;
|
import ru.nbch.credit_tracker.entities.external_response.errors.InputParams;
|
||||||
import ru.nbch.credit_tracker.entities.external_response.errors.SgnlReport;
|
import ru.nbch.credit_tracker.entities.external_response.errors.SgnlReport;
|
||||||
|
|
@ -8,7 +7,6 @@ import ru.nbch.credit_tracker.entities.external_response.errors.SgnlReport;
|
||||||
import javax.xml.stream.XMLStreamException;
|
import javax.xml.stream.XMLStreamException;
|
||||||
import javax.xml.stream.XMLStreamReader;
|
import javax.xml.stream.XMLStreamReader;
|
||||||
|
|
||||||
@Component
|
|
||||||
public class SgnlReportStatusStaxReader extends BaseStaxReader<SgnlReport> {
|
public class SgnlReportStatusStaxReader extends BaseStaxReader<SgnlReport> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,14 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class XmlProcessorStaxImpl implements StaxXmlProcessor {
|
public class XmlProcessorStaxImpl implements StaxXmlProcessor {
|
||||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
protected XMLInputFactory xmlInputFactory;
|
protected XMLInputFactory xmlInputFactory;
|
||||||
protected Map<Class<?>, StaxReader<?>> staxReaders = new HashMap<>();
|
protected Map<Class<?>, Supplier<StaxReader<?>>> staxReaders = new HashMap<>();
|
||||||
|
|
||||||
public XmlProcessorStaxImpl(List<StaxReader<?>> staxReaders) {
|
public XmlProcessorStaxImpl(List<Supplier<StaxReader<?>>> staxReaders) {
|
||||||
this.xmlInputFactory = XMLInputFactory.newInstance();
|
this.xmlInputFactory = XMLInputFactory.newInstance();
|
||||||
this.xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); // полностью выключить DOCTYPE Declaration
|
this.xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); // полностью выключить DOCTYPE Declaration
|
||||||
// или выключить особо опасные возможности (менее строгое ограничение XXE, но достаточное):
|
// или выключить особо опасные возможности (менее строгое ограничение XXE, но достаточное):
|
||||||
|
|
@ -32,10 +33,13 @@ public class XmlProcessorStaxImpl implements StaxXmlProcessor {
|
||||||
this.xmlInputFactory.setXMLResolver((publicID, systemID, baseURI, namespace) -> {
|
this.xmlInputFactory.setXMLResolver((publicID, systemID, baseURI, namespace) -> {
|
||||||
throw new XMLStreamException("External entities are disabled");
|
throw new XMLStreamException("External entities are disabled");
|
||||||
});
|
});
|
||||||
staxReaders.forEach(reader -> this.staxReaders.put(reader.type(), reader));
|
staxReaders.forEach(supplier -> {
|
||||||
|
Class<?> type = supplier.get().type();
|
||||||
|
this.staxReaders.put(type, supplier);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public XmlProcessorStaxImpl(StaxReader<?>... staxReaders) {
|
public XmlProcessorStaxImpl(Supplier<StaxReader<?>>... staxReaders) {
|
||||||
this(Arrays.asList(staxReaders));
|
this(Arrays.asList(staxReaders));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,8 +47,9 @@ public class XmlProcessorStaxImpl implements StaxXmlProcessor {
|
||||||
public <Z> Z read(String xml, Class<Z> clazz) {
|
public <Z> Z read(String xml, Class<Z> clazz) {
|
||||||
try {
|
try {
|
||||||
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new StringReader(xml));
|
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new StringReader(xml));
|
||||||
|
Supplier<StaxReader<?>> staxReaderSupplier = staxReaders.get(clazz);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
StaxReader<Z> staxProcessor = (StaxReader<Z>) staxReaders.get(clazz);
|
StaxReader<Z> staxProcessor = (StaxReader<Z>) staxReaderSupplier.get();
|
||||||
if (staxProcessor != null) {
|
if (staxProcessor != null) {
|
||||||
return staxProcessor.read(xmlStreamReader);
|
return staxProcessor.read(xmlStreamReader);
|
||||||
}
|
}
|
||||||
|
|
@ -62,8 +67,9 @@ public class XmlProcessorStaxImpl implements StaxXmlProcessor {
|
||||||
public <Z> Z read(byte[] xml, Class<Z> clazz) {
|
public <Z> Z read(byte[] xml, Class<Z> clazz) {
|
||||||
try {
|
try {
|
||||||
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(xml));
|
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(xml));
|
||||||
|
Supplier<StaxReader<?>> staxReaderSupplier = staxReaders.get(clazz);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
StaxReader<Z> staxProcessor = (StaxReader<Z>) staxReaders.get(clazz);
|
StaxReader<Z> staxProcessor = (StaxReader<Z>) staxReaderSupplier.get();
|
||||||
if (staxProcessor != null) {
|
if (staxProcessor != null) {
|
||||||
return staxProcessor.read(xmlStreamReader);
|
return staxProcessor.read(xmlStreamReader);
|
||||||
}
|
}
|
||||||
|
|
@ -81,8 +87,9 @@ public class XmlProcessorStaxImpl implements StaxXmlProcessor {
|
||||||
public <Z> Z read(InputStream inputStream, Class<Z> clazz) {
|
public <Z> Z read(InputStream inputStream, Class<Z> clazz) {
|
||||||
try {
|
try {
|
||||||
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(inputStream);
|
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(inputStream);
|
||||||
|
Supplier<StaxReader<?>> staxReaderSupplier = staxReaders.get(clazz);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
StaxReader<Z> staxProcessor = (StaxReader<Z>) staxReaders.get(clazz);
|
StaxReader<Z> staxProcessor = (StaxReader<Z>) staxReaderSupplier.get();
|
||||||
if (staxProcessor != null) {
|
if (staxProcessor != null) {
|
||||||
return staxProcessor.read(xmlStreamReader);
|
return staxProcessor.read(xmlStreamReader);
|
||||||
}
|
}
|
||||||
|
|
@ -100,8 +107,9 @@ public class XmlProcessorStaxImpl implements StaxXmlProcessor {
|
||||||
public <Z> Z read(InputStream inputStream, Class<Z> clazz, Consumer<Z> objProcessor, Function<Z, Boolean> emptyBatchCheckFunction, Integer batchSize, String endBatchElementPath) {
|
public <Z> Z read(InputStream inputStream, Class<Z> clazz, Consumer<Z> objProcessor, Function<Z, Boolean> emptyBatchCheckFunction, Integer batchSize, String endBatchElementPath) {
|
||||||
try {
|
try {
|
||||||
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(inputStream);
|
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(inputStream);
|
||||||
|
Supplier<StaxReader<?>> staxReaderSupplier = staxReaders.get(clazz);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
StaxReader<Z> staxProcessor = (StaxReader<Z>) staxReaders.get(clazz);
|
StaxReader<Z> staxProcessor = (StaxReader<Z>) staxReaderSupplier.get();
|
||||||
if (staxProcessor != null) {
|
if (staxProcessor != null) {
|
||||||
return staxProcessor.read(xmlStreamReader, objProcessor, emptyBatchCheckFunction, batchSize, endBatchElementPath);
|
return staxProcessor.read(xmlStreamReader, objProcessor, emptyBatchCheckFunction, batchSize, endBatchElementPath);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import javax.xml.stream.XMLStreamException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@SpringBootTest(classes = {StaxTest.TestConfig.class})
|
@SpringBootTest(classes = {StaxTest.TestConfig.class})
|
||||||
public class StaxTest {
|
public class StaxTest {
|
||||||
|
|
@ -31,9 +32,9 @@ public class StaxTest {
|
||||||
public static class TestConfig {
|
public static class TestConfig {
|
||||||
@Bean
|
@Bean
|
||||||
public StaxXmlProcessor xmlProcessor() {
|
public StaxXmlProcessor xmlProcessor() {
|
||||||
List<StaxReader<?>> staxReader = new ArrayList<>();
|
List<Supplier<StaxReader<?>>> staxReader = new ArrayList<>();
|
||||||
staxReader.add(new MonitoringRequestStaxReader());
|
staxReader.add(MonitoringRequestStaxReader::new);
|
||||||
staxReader.add(new OnlineDownloadReportPersonsStaxReader());
|
staxReader.add(OnlineDownloadReportPersonsStaxReader::new);
|
||||||
return new XmlProcessorStaxImpl(staxReader);
|
return new XmlProcessorStaxImpl(staxReader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
|
|
@ -41,8 +42,8 @@ public class ValidationUtilTest {
|
||||||
public static class TestConfig {
|
public static class TestConfig {
|
||||||
@Bean
|
@Bean
|
||||||
public StaxXmlProcessor xmlProcessor() {
|
public StaxXmlProcessor xmlProcessor() {
|
||||||
List<StaxReader<?>> staxReader = new ArrayList<>();
|
List<Supplier<StaxReader<?>>> staxReader = new ArrayList<>();
|
||||||
staxReader.add(new MonitoringRequestStaxReader());
|
staxReader.add(MonitoringRequestStaxReader::new);
|
||||||
return new XmlProcessorStaxImpl(staxReader);
|
return new XmlProcessorStaxImpl(staxReader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue