EIDSProductBuilder.java

package gov.usgs.earthquake.eids;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import gov.usgs.ansseqmsg.EQMessage;
import gov.usgs.earthquake.distribution.ProductBuilder;
import gov.usgs.earthquake.distribution.ProductSender;
import gov.usgs.earthquake.eidsutil.EIDSClient;
import gov.usgs.earthquake.eidsutil.EIDSListener;
import gov.usgs.earthquake.eidsutil.EIDSMessageEvent;
import gov.usgs.earthquake.product.Product;
import gov.usgs.util.Config;

/**
 * Convert messages from EIDS into products.
 *
 * Listens to messages from an EIDSClient. Uses EQXMLProductParser and
 * EventAddonParser to build products. Any built products are sent to all
 * configured productSenders.
 */
public class EIDSProductBuilder extends ProductBuilder implements EIDSListener {

	/** Logging object. */
	private static final Logger LOGGER = Logger
			.getLogger(EIDSProductBuilder.class.getName());

	/** Convert EventAddon to EQMessage objects. */
	private EventAddonParser addonParser = new EventAddonParser();

	/** Convert EQMessages to products. */
	private EQMessageProductCreator eqmessageProductCreator = new EQMessageProductCreator();

	/**
	 * Receive EIDS messages from an EIDSClient.
	 *
	 * Any received messages are parsed and sent to any ProductSenders. If the
	 * message is not EQXML, this method returns immediately.
	 */
	@Override
	public synchronized void onEIDSMessage(EIDSMessageEvent event) {
		List<Product> products = new LinkedList<Product>();

		// parse eids message into Products
		if (event.getRootElement().equals("EQMessage")) {
			try {
				products.addAll(eqmessageProductCreator
						.getEQMessageProducts(event.getMessage()));
			} catch (Exception e) {
				// unable to parse EQMessage
				LOGGER.log(Level.WARNING, "Error while parsing EQMessage", e);
				LOGGER.info(event.getMessage());
				return;
			}
		} else if (event.getRootElement().equals("eventaddon")) {
			try {
				EQMessage message = addonParser.parseMessage(event);
				if (message != null) {
					products.addAll(eqmessageProductCreator
							.getEQMessageProducts(message));
				} else {
					LOGGER.log(Level.WARNING, "Unable to parse eventaddon\n"
							+ event.getMessage());
				}
			} catch (Exception e) {
				// unable to parse eventaddon
				LOGGER.log(Level.WARNING, "Error while parsing eventaddon", e);
				LOGGER.info(event.getMessage());
				return;
			}
		} else {
			// not parseable
			LOGGER.info("Unexpected EIDS message {" + event.getRootNamespace()
					+ "}" + event.getRootElement());
			return;
		}

		LOGGER.finest("Received EIDS message " + event.getMessage());

		// add eids properties onto products
		String feederSource = event.getMessageSource();
		Long feederSequence = event.getMessageSequence();
		Iterator<Product> iter = products.iterator();
		while (iter.hasNext()) {
			Product product = iter.next();
			Map<String, String> properties = product.getProperties();
			if (feederSource != null) {
				properties.put("eids-feeder", feederSource);
			}
			if (feederSequence != null) {
				properties.put("eids-feeder-sequence",
						feederSequence.toString());
			}
		}

		try {
			// send products
			iter = products.iterator();
			while (iter.hasNext()) {
				Product product = iter.next();
				LOGGER.fine("Sending product id=" + product.getId()
						+ ", status=" + product.getStatus());

				Map<ProductSender, Exception> errors = sendProduct(product);
				Iterator<ProductSender> senders = errors.keySet().iterator();
				while (senders.hasNext()) {
					LOGGER.log(Level.WARNING, "Error sending product",
							errors.get(senders.next()));
					LOGGER.info(event.getMessage());
				}
			}
		} catch (Exception e) {
			LOGGER.log(Level.FINE, "Error sending products", e);
		}

	}

	/**
	 * Main method to test EQXMLProductBuilder.
	 *
	 * Connects an eids client to the product builder, and uses a dummy product
	 * sender that outputs to stderr.
	 *
	 * @param args arguments included in the running of main
	 */
	public static void main(final String[] args) {
		EIDSProductBuilder builder = new EIDSProductBuilder();
		builder.addProductSender(new ProductSender() {
			@Override
			public void configure(Config arg0) throws Exception {
			}

			@Override
			public void shutdown() throws Exception {
			}

			@Override
			public void startup() throws Exception {
			}

			@Override
			public void sendProduct(Product product) throws Exception {
				System.err.println("product id=" + product.getId().toString());

				Iterator<String> names = product.getProperties().keySet()
						.iterator();
				while (names.hasNext()) {
					String name = names.next();
					System.err.println("\t" + name + "="
							+ product.getProperties().get(name));
				}
			}

			@Override
			public String getName() {
				return null;
			}

			@Override
			public void setName(String arg0) {
			}
		});

		EIDSClient client = new EIDSClient("eids1.cr.usgs.gov", 39977);
		client.addListener(builder);
		client.startup();
	}

}