Search in sources :

Example 1 with EventReceipt

use of org.opennms.netmgt.xml.event.EventReceipt in project opennms by OpenNMS.

the class UdpUuidSender method run.

/**
     * <p>run</p>
     */
@Override
public void run() {
    // get the context
    m_context = Thread.currentThread();
    Logging.putPrefix(m_logPrefix);
    if (m_stop) {
        LOG.debug("Stop flag set before thread started, exiting");
        return;
    } else {
        LOG.debug("Thread context started");
    }
    /*
         * This loop is labeled so that it can be
         * exited quickly when the thread is interrupted.
         */
    List<UdpReceivedEvent> eventHold = new ArrayList<UdpReceivedEvent>(30);
    Map<UdpReceivedEvent, EventReceipt> receipts = new HashMap<UdpReceivedEvent, EventReceipt>();
    RunLoop: while (!m_stop) {
        LOG.debug("Waiting on event receipts to be generated");
        synchronized (m_eventUuidsOut) {
            // wait for an event to show up.  wait in 1 second intervals
            while (m_eventUuidsOut.isEmpty()) {
                try {
                    // use wait instead of sleep to release the lock!
                    m_eventUuidsOut.wait(1000);
                } catch (InterruptedException ie) {
                    LOG.debug("Thread context interrupted");
                    break RunLoop;
                }
            }
            eventHold.addAll(m_eventUuidsOut);
            m_eventUuidsOut.clear();
        }
        LOG.debug("Received {} event receipts to process", eventHold.size());
        LOG.debug("Processing receipts");
        // build an event-receipt
        for (UdpReceivedEvent re : eventHold) {
            for (Event e : re.getAckedEvents()) {
                if (e.getUuid() != null) {
                    EventReceipt receipt = receipts.get(re);
                    if (receipt == null) {
                        receipt = new EventReceipt();
                        receipts.put(re, receipt);
                    }
                    receipt.addUuid(e.getUuid());
                }
            }
        }
        eventHold.clear();
        LOG.debug("Event receipts sorted, transmitting receipts");
        // turn them into XML and send it out the socket
        for (Map.Entry<UdpReceivedEvent, EventReceipt> entry : receipts.entrySet()) {
            UdpReceivedEvent re = entry.getKey();
            EventReceipt receipt = entry.getValue();
            StringWriter writer = new StringWriter();
            try {
                JaxbUtils.marshal(receipt, writer);
            } catch (DataAccessException e) {
                LOG.warn("Failed to build event receipt for agent {}:{}", InetAddressUtils.str(re.getSender()), re.getPort(), e);
            }
            String xml = writer.getBuffer().toString();
            try {
                byte[] xml_bytes = xml.getBytes(StandardCharsets.US_ASCII);
                DatagramPacket pkt = new DatagramPacket(xml_bytes, xml_bytes.length, re.getSender(), re.getPort());
                LOG.debug("Transmitting receipt to destination {}:{}", InetAddressUtils.str(re.getSender()), re.getPort());
                m_dgSock.send(pkt);
                synchronized (m_handlers) {
                    for (EventHandler handler : m_handlers) {
                        try {
                            handler.receiptSent(receipt);
                        } catch (Throwable t) {
                            LOG.warn("Error processing event receipt", t);
                        }
                    }
                }
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Receipt transmitted OK {");
                    LOG.debug(xml);
                    LOG.debug("}");
                }
            } catch (IOException e) {
                LOG.warn("Failed to send packet to host {}:{}", InetAddressUtils.str(re.getSender()), re.getPort(), e);
            }
        }
        receipts.clear();
    }
    LOG.debug("Context finished, returning");
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) EventHandler(org.opennms.netmgt.eventd.adaptors.EventHandler) IOException(java.io.IOException) EventReceipt(org.opennms.netmgt.xml.event.EventReceipt) StringWriter(java.io.StringWriter) DatagramPacket(java.net.DatagramPacket) Event(org.opennms.netmgt.xml.event.Event) DataAccessException(org.springframework.dao.DataAccessException)

Example 2 with EventReceipt

use of org.opennms.netmgt.xml.event.EventReceipt in project opennms by OpenNMS.

the class TcpStreamHandler method run.

/**
     * The main execution context for processing a remote XML document. Once the
     * document is processed and an event receipt is returned to the client the
     * thread will exit.
     */
@Override
public void run() {
    // get the context and stop if necessary
    m_context = Thread.currentThread();
    synchronized (m_context) {
        m_context.notifyAll();
    }
    // check the stop flag
    if (m_stop) {
        LOG.debug("The stop flag was set prior to thread entry, closing connection");
        try {
            m_connection.close();
        } catch (final IOException e) {
            LOG.error("An error occured while closing the connection.", e);
        }
        LOG.debug("Thread context exiting");
        return;
    }
    // Log the startup of this stream handler
    final InetAddress sender = m_connection.getInetAddress();
    LOG.debug("Event Log Stream Handler Started for {}", sender);
    /*
         * This linked list is used to exchange
         * instances of PipedOutputStreams. Whenever a
         * pipe output stream is recovered it must be
         * signaled to inform the EOT thread of the
         * ability to write to the pipe. Also, when
         * the descriptor is close a EOFException is
         * passed on the list.
         */
    final LinkedList<Object> pipeXchange = new LinkedList<Object>();
    final TcpRecordHandler chunker = new TcpRecordHandler(m_connection, pipeXchange);
    final Thread tchunker = new Thread(chunker, "TCPRecord Chunker[" + InetAddressUtils.str(m_connection.getInetAddress()) + ":" + m_connection.getPort() + "]");
    synchronized (tchunker) {
        tchunker.start();
        try {
            tchunker.wait();
        } catch (final InterruptedException e) {
            LOG.error("The thread was interrupted.", e);
        }
    }
    MAINLOOP: while (!m_stop && m_parent.getStatus() != Fiber.STOP_PENDING && m_parent.getStatus() != Fiber.STOPPED && m_recsPerConn != 0) {
        // get a new pipe input stream
        PipedInputStream pipeIn = null;
        synchronized (pipeXchange) {
            while (pipeXchange.isEmpty()) {
                if (chunker.isAlive()) {
                    try {
                        pipeXchange.wait(500);
                    } catch (final InterruptedException e) {
                        LOG.error("The thread was interrupted.", e);
                        break MAINLOOP;
                    }
                } else {
                    break MAINLOOP;
                }
            }
            // if an exception occured then just exit the BAL (Big Ass Loop)
            final Object o = pipeXchange.removeFirst();
            if (o instanceof Throwable) {
                break MAINLOOP;
            }
            // construct the other end of the pipe
            try {
                pipeIn = new PipedInputStream((PipedOutputStream) o);
            } catch (final IOException e) {
                LOG.error("An I/O exception occured construction a record reader.", e);
                break MAINLOOP;
            }
            // signal that we got the stream
            synchronized (o) {
                o.notify();
            }
        }
        // decrement the record count if greater than zero
        m_recsPerConn -= (m_recsPerConn > 0 ? 1 : 0);
        // convert the pipe input stream into a buffered input stream
        final InputStream stream = new BufferedInputStream(pipeIn);
        // Unmarshal the XML document
        Log eLog = null;
        boolean doCleanup = false;
        try {
            eLog = JaxbUtils.unmarshal(Log.class, new InputSource(stream));
            LOG.debug("Event record converted");
        } catch (final Exception e) {
            LOG.error("Could not unmarshall the XML record.", e);
            doCleanup = true;
        } finally {
            if (stream != null) {
                IOUtils.closeQuietly(stream);
            }
        }
        // clean up the data on the current pipe if necessary
        if (doCleanup) {
            /*
                 * Cleanup a failed record. Need to read
                 * the remaining bytes from the other thread
                 * to synchronize up. The other thread might
                 * be blocked writing.
                 */
            try {
                while (stream.read() != -1) {
                    /* do nothing */
                    ;
                }
            } catch (final IOException e) {
            // do nothing
            }
            // start from the top!
            continue MAINLOOP;
        }
        // Now that we have a list of events, process them
        final Event[] events = eLog.getEvents().getEvent();
        // sort the events by time
        Arrays.sort(events, new Comparator<Event>() {

            @Override
            public int compare(final Event e1, final Event e2) {
                final boolean e1t = (e1.getTime() != null);
                final boolean e2t = (e2.getTime() != null);
                if (e1t && !e2t) {
                    return 1;
                } else if (!e1t && e2t) {
                    return -1;
                } else if (!e1t && !e2t) {
                    return 0;
                }
                Date de1 = e1.getTime();
                Date de2 = e2.getTime();
                if (de1 != null && de2 != null) {
                    return (int) (de1.getTime() - de2.getTime());
                } else if (de1 == null && de2 != null) {
                    return -1;
                } else if (de1 != null && de2 == null) {
                    return 1;
                } else {
                    return 0;
                }
            }
        });
        // process the events
        if (events != null && events.length != 0) {
            final Collection<Event> okEvents = new LinkedHashSet<>(events.length);
            /*
                 * This synchronization loop will hold onto the lock
                 * for a while. If the handlers are going to change
                 * often, which is shouldn't then might want to consider
                 * duplicating the handlers into an array before processing
                 * the events.
                 *
                 * Doing the synchronization in the outer loop prevents spending
                 * lots of cycles doing synchronization when it should not
                 * normally be necesary.
                 */
            synchronized (m_handlers) {
                for (final EventHandler hdl : m_handlers) {
                    /*
                         * get the handler and then have it process all
                         * the events in the document before moving to the
                         * next event handler.
                         */
                    for (final Event event : events) {
                        /*
                             * Process the event and log any errors,
                             *  but don't die on these errors
                             */
                        try {
                            LOG.debug("handling event: {}", event);
                            // shortcut and BOTH parts MUST execute!
                            if (hdl.processEvent(event)) {
                                if (!okEvents.contains(event)) {
                                    okEvents.add(event);
                                }
                            }
                        } catch (final Throwable t) {
                            LOG.warn("An exception occured while processing an event.", t);
                        }
                    }
                }
            }
            // Now process the good events and send a receipt message
            boolean hasReceipt = false;
            final EventReceipt receipt = new EventReceipt();
            for (final Event event : okEvents) {
                if (event.getUuid() != null) {
                    receipt.addUuid(event.getUuid());
                    hasReceipt = true;
                }
            }
            if (hasReceipt) {
                // Transform it to XML and send it to the socket in one call
                try {
                    final Writer writer = new BufferedWriter(new OutputStreamWriter(m_connection.getOutputStream(), StandardCharsets.UTF_8));
                    JaxbUtils.marshal(receipt, writer);
                    writer.flush();
                    synchronized (m_handlers) {
                        for (final EventHandler hdl : m_handlers) {
                            /*
                                 * Get the handler and then have it process all
                                 * the events in the document before moving to
                                 * the next event hander.
                                 */
                            try {
                                hdl.receiptSent(receipt);
                            } catch (final Throwable t) {
                                LOG.warn("An exception occured while processing an event receipt.", t);
                            }
                        }
                    }
                    if (LOG.isDebugEnabled()) {
                        try {
                            final StringWriter swriter = new StringWriter();
                            JaxbUtils.marshal(receipt, swriter);
                            LOG.debug("Sent Event Receipt {");
                            LOG.debug(swriter.getBuffer().toString());
                            LOG.debug("}");
                        } catch (final Throwable e) {
                            LOG.error("An error occured during marshalling of event receipt for the log.", e);
                        }
                    }
                } catch (final IOException e) {
                    LOG.warn("Failed to send event-receipt XML document.", e);
                    break MAINLOOP;
                }
            }
        } else {
            LOG.debug("The agent sent an empty event stream");
        }
    }
    try {
        LOG.debug("stopping record handler");
        chunker.stop();
        LOG.debug("record handler stopped");
    } catch (final InterruptedException e) {
        LOG.warn("The thread was interrupted while trying to close the record handler.", e);
    }
    // regardless of any errors, be sure to release the socket.
    try {
        LOG.debug("closing connnection");
        m_connection.close();
        LOG.debug("connnection closed ");
    } catch (final IOException e) {
        LOG.warn("An I/O exception occured while closing the TCP/IP connection.", e);
    }
    LOG.debug("Thread exiting");
}
Also used : InputSource(org.xml.sax.InputSource) EventHandler(org.opennms.netmgt.eventd.adaptors.EventHandler) Comparator(java.util.Comparator) BufferedWriter(java.io.BufferedWriter) StringWriter(java.io.StringWriter) BufferedInputStream(java.io.BufferedInputStream) Log(org.opennms.netmgt.xml.event.Log) BufferedInputStream(java.io.BufferedInputStream) PipedInputStream(java.io.PipedInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) PipedInputStream(java.io.PipedInputStream) LinkedList(java.util.LinkedList) IOException(java.io.IOException) Date(java.util.Date) EventReceipt(org.opennms.netmgt.xml.event.EventReceipt) Event(org.opennms.netmgt.xml.event.Event) Collection(java.util.Collection) OutputStreamWriter(java.io.OutputStreamWriter) InetAddress(java.net.InetAddress) OutputStreamWriter(java.io.OutputStreamWriter) BufferedWriter(java.io.BufferedWriter) StringWriter(java.io.StringWriter) Writer(java.io.Writer)

Aggregations

IOException (java.io.IOException)2 StringWriter (java.io.StringWriter)2 EventHandler (org.opennms.netmgt.eventd.adaptors.EventHandler)2 Event (org.opennms.netmgt.xml.event.Event)2 EventReceipt (org.opennms.netmgt.xml.event.EventReceipt)2 BufferedInputStream (java.io.BufferedInputStream)1 BufferedWriter (java.io.BufferedWriter)1 InputStream (java.io.InputStream)1 OutputStreamWriter (java.io.OutputStreamWriter)1 PipedInputStream (java.io.PipedInputStream)1 Writer (java.io.Writer)1 DatagramPacket (java.net.DatagramPacket)1 InetAddress (java.net.InetAddress)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 Comparator (java.util.Comparator)1 Date (java.util.Date)1 HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 Log (org.opennms.netmgt.xml.event.Log)1