Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.belio.mq; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.MessageProperties; import java.io.IOException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Level; import java.util.logging.Logger; import org.belio.Launcher; import org.belio.domain.tix.Alert; import org.belio.domain.tix.Outbox; import org.belio.domain.tix.OutboxList; import org.belio.model.MessagePublisher; import org.belio.model.Queuable; import org.belio.model.QueueType; import org.belio.model.Status; import org.belio.service.producer.DbReader; /** * * @author dena */ public class RabbitPublisher extends EndPoint implements MessagePublisher, Status { final List<? extends Queuable> messageQueue; final List<Queuable> failedMessageQueue; DbReader dbReader; Alert alert; String[] hosts; public RabbitPublisher(DbReader dbReader, final Properties properties, List<? extends Queuable> messageQueue, final QueueType queuetype, Alert alert) { super(properties, queuetype); this.dbReader = dbReader; this.messageQueue = messageQueue; this.alert = alert; this.failedMessageQueue = new ArrayList<>(); } @Override public void open() throws IOException { synchronized (RabbitPublisher.class) { try { // Create a connection factory and hosts = mqproperties.getProperty("host").split(","); ConnectionFactory factory = new ConnectionFactory(); factory.setHost(mqproperties.getProperty("host")); factory.setVirtualHost(mqproperties.getProperty("vhost")); factory.setUsername(mqproperties.getProperty("username")); factory.setPassword(mqproperties.getProperty("password")); factory.setPort(Integer.parseInt(mqproperties.getProperty("port"))); // Create a new connection to MQ connection = factory.newConnection(); // Create a new channel and declare it's type and exhange as well channel = connection.createChannel(); channel.queueDeclare(queueType.name().concat(QUEUE_SUFFIX), true, false, false, null); channel.exchangeDeclare(queueType.name().concat(EXCHANGE_SUFFIX), mqproperties.getProperty("type")); channel.queueBind(queueType.name().concat(QUEUE_SUFFIX), queueType.name().concat(EXCHANGE_SUFFIX), ""); } catch (Exception ex) { ex.printStackTrace(); } } } @Override public void publish() { try { open(); } catch (IOException ex) { Logger.getLogger(RabbitPublisher.class.getName()).log(Level.SEVERE, null, ex); } // synchronized (this) { OutboxList outboxList = new OutboxList(queueType); outboxList.setOutboxes((ArrayList<Outbox>) messageQueue); Long startTime = System.currentTimeMillis(); int MQTHREADS = 3; ExecutorService executor = Executors.newFixedThreadPool(MQTHREADS); try { channel.txSelect(); dbReader.insertSublistBatch(messageQueue); // check that insert is complete int alertsSaved = dbReader.saveAlertsToOutboxCount(alert); if (alertsSaved == messageQueue.size()) { Launcher.LOG.info("publishing " + alert + " to " + alert.getType().name()); // create a map that will hold the outbox lists of different networks Map<String, OutboxList> map = new HashMap<>(); // loop through the messages to add them onto outbox lists in batches of 10 for (Outbox outbox : outboxList.getOutboxes()) { // check if the map contains an outbox list of the network if (map.containsKey(outbox.getNetwork())) { // check if the max of 10 has been reached in the size of the outboxlist if (map.get(outbox.getNetwork()).getOutboxes().size() < Integer .parseInt(threadproperties.getProperty("batch_size"))) { // add the outbox to the outboxlist if the size is less than 10 map.get(outbox.getNetwork()).add(outbox); } else { // publish the outboxlist to MQ and reset the outboxlist OutboxList ol = map.get(outbox.getNetwork()); final String message = xStream.toXML(ol); Runnable worker = new Runnable() { @Override public void run() { try { channel.basicPublish(alert.getType().name().concat(EXCHANGE_SUFFIX), alert.getType().name().concat(QUEUE_SUFFIX), MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes()); } catch (IOException ex) { Logger.getLogger(RabbitPublisher.class.getName()).log(Level.SEVERE, null, ex); } } }; executor.execute(worker); // clear the outboxlist of the network map.get(outbox.getNetwork()).getOutboxes().clear(); } } else { // create the outbox list for the network map.put(outbox.getNetwork(), new OutboxList(queueType)); // add an outbox to the outboxlist map.get(outbox.getNetwork()).add(outbox); } } // get the iterator of the entries in the map for publishing for (Map.Entry<String, OutboxList> entry : map.entrySet()) { // publish the outboxlist to MQ and reset the outboxlist OutboxList ol = entry.getValue(); final String message = xStream.toXML(ol); Runnable worker = new Runnable() { @Override public void run() { try { channel.basicPublish(alert.getType().name().concat(EXCHANGE_SUFFIX), alert.getType().name().concat(QUEUE_SUFFIX), MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes()); } catch (IOException ex) { Logger.getLogger(RabbitPublisher.class.getName()).log(Level.SEVERE, null, ex); } } }; executor.execute(worker); // clear the outboxlist of the network entry.getValue().getOutboxes().clear(); } channel.txCommit(); dbReader.updateAlertStatus(alert, "SENT", messageQueue.size(), new Timestamp(Calendar.getInstance().getTimeInMillis())); dbReader.deleteCSVFile(alert); } else { channel.txRollback(); Launcher.LOG.info("unable to publish " + alert + " to " + alert.getType().name() + " " + alertsSaved + " - " + messageQueue.size()); dbReader.updateAlertStatus(alert, "UNSENT", null, null); //TO:DO //delete from outboxes where alert dbReader.deleteCSVFile(alert); } } catch (IOException exception) { Launcher.LOG.error("Error publishing", exception); //TODO log exception dbReader.updateAlertStatus(alert, "UNSENT", null, null); dbReader.deleteCSVFile(alert); //TO:DO //delete from outboxes where alert // reset message to unsent //failedMessageQueue.add(queuable); try { channel.txRollback(); } catch (IOException ioe) { //TODO log message } } Long endTime = System.currentTimeMillis(); Long timeTaken = endTime - startTime; Launcher.LOG.info("Took " + timeTaken + " to publish"); try { // System.exit(0); close(); } catch (IOException ex) { Logger.getLogger(RabbitPublisher.class.getName()).log(Level.SEVERE, null, ex); } } @Override public int queueSize() { return failedMessageQueue.size(); } }