package com.linkedin.databus2.ggParser.staxparser;
import com.linkedin.databus.core.util.Base64;
import com.linkedin.databus2.ggParser.XmlStateMachine.StateMachine;
import com.linkedin.databus2.ggParser.XmlStateMachine.TransactionSuccessCallBack;
import com.linkedin.databus2.ggParser.XmlStateMachine.XmlStreamReaderHelper;
import com.linkedin.databus2.relay.config.ReplicationBitSetterStaticConfig;
import com.linkedin.databus2.schemas.SchemaRegistryService;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.apache.log4j.Logger;
public class XmlParser
{
XMLStreamReader _xmlStreamReader;
SchemaRegistryService _schemaRegistryService;
StateMachine _stateMachine;
AtomicBoolean _shutdownRequested = new AtomicBoolean(false);
InputStream _inputStream;
public static final Logger LOG = Logger.getLogger(XmlParser.class
.getName());
public XmlParser(XMLStreamReader xmlStreamReader,
SchemaRegistryService schemaRegistry,
HashMap<String, String> tableMap,
HashMap<String, Integer> tableToSourceId,
TransactionSuccessCallBack _transactionSuccessCallBack,
boolean errorOnMissingFields,
ReplicationBitSetterStaticConfig replicationBitConfig,
InputStream inputStream)
{
_xmlStreamReader = xmlStreamReader;
_schemaRegistryService = schemaRegistry;
_stateMachine = new StateMachine(schemaRegistry, tableMap, tableToSourceId, _transactionSuccessCallBack,errorOnMissingFields,replicationBitConfig);
_shutdownRequested.set(false);
//The reference to the inputstream is passed just for closing the stream on shutdown.`
_inputStream = inputStream;
}
public void start()
throws Exception
{
XmlStreamReaderHelper.checkAndMoveNext(_xmlStreamReader); // Point to the root element
try{
while(!_shutdownRequested.get() && _xmlStreamReader.hasNext())
{
_stateMachine.processElement(_xmlStreamReader);
}
}
catch (NoSuchElementException e)
{
/**
* This is an expected behavior during a shutdown, the parser was reading something and we decided to close the stream from another thread.
* We consume this exception and proceed to shutdown. (DDSDBUS-3267 for details)
*/
if(!_shutdownRequested.get())
{
throw e;
}
}
catch (XMLStreamException e)
{
/**
* This is an expected behavior during a shutdown, the parser was reading something and we decided to close the stream from another thread.
* We consume this exception and proceed to shutdown. We rethrow this exception (on non shutdown situation) because the event producer attempts to restart the parser with this
* information. (DDSDBUS-3267 for details)
*/
if(!_shutdownRequested.get())
{
throw e;
}
}
}
public void setShutDownRequested(boolean shutDownRequested)
{
_shutdownRequested.set(shutDownRequested);
try
{
_xmlStreamReader.close();
}
catch (XMLStreamException e)
{
LOG.error("Error while attempting to close the parser: ");
}
catch(NoSuchElementException e)
{
LOG.info("Concurrent stream access while shutdown, it's safe to ignore this.");
}
catch(RuntimeException e)
{
LOG.error("Runtime exception while attempting shutdown, ignoring the exception", e);
}
try
{
_inputStream.close();
}
catch (IOException e)
{
LOG.error("Error while attempting to close the input stream:", e);
}
catch(NoSuchElementException e)
{
LOG.info("Concurrent stream access while shutdown, it's safe to ignore this.");
}
catch(RuntimeException e)
{
LOG.error("Runtime exception while attempting shutdown, ignoring the exception", e);
}
}
}