Search in sources :

Example 6 with ApnsNotification

use of com.notnoop.apns.ApnsNotification in project camel by apache.

the class ApnsProducer method notify.

private void notify(Exchange exchange) throws ApnsException {
    MessageType messageType = getHeaderMessageType(exchange, MessageType.STRING);
    if (messageType == MessageType.APNS_NOTIFICATION) {
        ApnsNotification apnsNotification = exchange.getIn().getBody(ApnsNotification.class);
        getEndpoint().getApnsService().push(apnsNotification);
    } else {
        constructNotificationAndNotify(exchange, messageType);
    }
}
Also used : ApnsNotification(com.notnoop.apns.ApnsNotification) MessageType(org.apache.camel.component.apns.model.MessageType)

Example 7 with ApnsNotification

use of com.notnoop.apns.ApnsNotification in project java-apns by notnoop.

the class QueuedApnsService method start.

public void start() {
    if (started.getAndSet(true)) {
        // So it is returning immediately here
        return;
    }
    service.start();
    shouldContinue = true;
    thread = threadFactory.newThread(new Runnable() {

        public void run() {
            while (shouldContinue) {
                try {
                    ApnsNotification msg = queue.take();
                    service.push(msg);
                } catch (InterruptedException e) {
                // ignore
                } catch (NetworkIOException e) {
                // ignore: failed connect...
                } catch (Exception e) {
                    // weird if we reached here - something wrong is happening, but we shouldn't stop the service anyway!
                    logger.warn("Unexpected message caught... Shouldn't be here", e);
                }
            }
        }
    });
    thread.start();
}
Also used : ApnsNotification(com.notnoop.apns.ApnsNotification) NetworkIOException(com.notnoop.exceptions.NetworkIOException) NetworkIOException(com.notnoop.exceptions.NetworkIOException)

Example 8 with ApnsNotification

use of com.notnoop.apns.ApnsNotification in project java-apns by notnoop.

the class ApnsConnectionImpl method monitorSocket.

private void monitorSocket(final Socket socketToMonitor) {
    logger.debug("Launching Monitoring Thread for socket {}", socketToMonitor);
    Thread t = threadFactory.newThread(new Runnable() {

        static final int EXPECTED_SIZE = 6;

        @SuppressWarnings("InfiniteLoopStatement")
        @Override
        public void run() {
            logger.debug("Started monitoring thread");
            try {
                InputStream in;
                try {
                    in = socketToMonitor.getInputStream();
                } catch (IOException ioe) {
                    logger.warn("The value of socket is null", ioe);
                    in = null;
                }
                byte[] bytes = new byte[EXPECTED_SIZE];
                while (in != null && readPacket(in, bytes)) {
                    logger.debug("Error-response packet {}", Utilities.encodeHex(bytes));
                    // Quickly close socket, so we won't ever try to send push notifications
                    // using the defective socket.
                    Utilities.close(socketToMonitor);
                    int command = bytes[0] & 0xFF;
                    if (command != 8) {
                        throw new IOException("Unexpected command byte " + command);
                    }
                    int statusCode = bytes[1] & 0xFF;
                    DeliveryError e = DeliveryError.ofCode(statusCode);
                    int id = Utilities.parseBytes(bytes[2], bytes[3], bytes[4], bytes[5]);
                    logger.debug("Closed connection cause={}; id={}", e, id);
                    delegate.connectionClosed(e, id);
                    Queue<ApnsNotification> tempCache = new LinkedList<ApnsNotification>();
                    ApnsNotification notification = null;
                    boolean foundNotification = false;
                    while (!cachedNotifications.isEmpty()) {
                        notification = cachedNotifications.poll();
                        logger.debug("Candidate for removal, message id {}", notification.getIdentifier());
                        if (notification.getIdentifier() == id) {
                            logger.debug("Bad message found {}", notification.getIdentifier());
                            foundNotification = true;
                            break;
                        }
                        tempCache.add(notification);
                    }
                    if (foundNotification) {
                        logger.debug("delegate.messageSendFailed, message id {}", notification.getIdentifier());
                        delegate.messageSendFailed(notification, new ApnsDeliveryErrorException(e));
                    } else {
                        cachedNotifications.addAll(tempCache);
                        int resendSize = tempCache.size();
                        logger.warn("Received error for message that wasn't in the cache...");
                        if (autoAdjustCacheLength) {
                            cacheLength = cacheLength + (resendSize / 2);
                            delegate.cacheLengthExceeded(cacheLength);
                        }
                        logger.debug("delegate.messageSendFailed, unknown id");
                        delegate.messageSendFailed(null, new ApnsDeliveryErrorException(e));
                    }
                    int resendSize = 0;
                    while (!cachedNotifications.isEmpty()) {
                        resendSize++;
                        final ApnsNotification resendNotification = cachedNotifications.poll();
                        logger.debug("Queuing for resend {}", resendNotification.getIdentifier());
                        notificationsBuffer.add(resendNotification);
                    }
                    logger.debug("resending {} notifications", resendSize);
                    delegate.notificationsResent(resendSize);
                }
                logger.debug("Monitoring input stream closed by EOF");
            } catch (IOException e) {
                // An exception when reading the error code is non-critical, it will cause another retry
                // sending the message. Other than providing a more stable network connection to the APNS
                // server we can't do much about it - so let's not spam the application's error log.
                logger.info("Exception while waiting for error code", e);
                delegate.connectionClosed(DeliveryError.UNKNOWN, -1);
            } finally {
                Utilities.close(socketToMonitor);
                drainBuffer();
            }
        }

        /**
             * Read a packet like in.readFully(bytes) does - but do not throw an exception and return false if nothing
             * could be read at all.
             * @param in the input stream
             * @param bytes the array to be filled with data
             * @return true if a packet as been read, false if the stream was at EOF right at the beginning.
             * @throws IOException When a problem occurs, especially EOFException when there's an EOF in the middle of the packet.
             */
        private boolean readPacket(final InputStream in, final byte[] bytes) throws IOException {
            final int len = bytes.length;
            int n = 0;
            while (n < len) {
                try {
                    int count = in.read(bytes, n, len - n);
                    if (count < 0) {
                        throw new EOFException("EOF after reading " + n + " bytes of new packet.");
                    }
                    n += count;
                } catch (IOException ioe) {
                    if (n == 0)
                        return false;
                    throw new IOException("Error after reading " + n + " bytes of packet", ioe);
                }
            }
            return true;
        }
    });
    t.start();
}
Also used : InputStream(java.io.InputStream) ApnsNotification(com.notnoop.apns.ApnsNotification) EnhancedApnsNotification(com.notnoop.apns.EnhancedApnsNotification) NetworkIOException(com.notnoop.exceptions.NetworkIOException) IOException(java.io.IOException) DeliveryError(com.notnoop.apns.DeliveryError) EOFException(java.io.EOFException) Queue(java.util.Queue) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) ApnsDeliveryErrorException(com.notnoop.exceptions.ApnsDeliveryErrorException)

Example 9 with ApnsNotification

use of com.notnoop.apns.ApnsNotification in project java-apns by notnoop.

the class ApnsConnectionCacheTest method handleReTransmissionError5Good1Bad7Good.

/**
     * Test1 to make sure that after rejected notification
     * in-flight notifications are re-transmitted
     *
     * @throws InterruptedException
     */
@Test(timeout = 5000)
public void handleReTransmissionError5Good1Bad7Good() throws InterruptedException {
    server = new ApnsServerStub(FixedCertificates.serverContext().getServerSocketFactory());
    //5 success 1 fail 7 success 7 resent
    final CountDownLatch sync = new CountDownLatch(20);
    final AtomicInteger numResent = new AtomicInteger();
    final AtomicInteger numSent = new AtomicInteger();
    final AtomicInteger numStartSend = new AtomicInteger();
    int EXPECTED_RESEND_COUNT = 7;
    int EXPECTED_SEND_COUNT = 12;
    server.getWaitForError().acquire();
    server.start();
    ApnsService service = APNS.newService().withSSLContext(clientContext()).withGatewayDestination(LOCALHOST, server.getEffectiveGatewayPort()).withDelegate(new StartSendingApnsDelegate() {

        public void startSending(final ApnsNotification message, final boolean resent) {
            if (!resent) {
                numStartSend.incrementAndGet();
            }
        }

        public void messageSent(ApnsNotification message, boolean resent) {
            if (!resent) {
                numSent.incrementAndGet();
            }
            sync.countDown();
        }

        public void messageSendFailed(ApnsNotification message, Throwable e) {
            numSent.decrementAndGet();
        }

        public void connectionClosed(DeliveryError e, int messageIdentifier) {
        }

        public void cacheLengthExceeded(int newCacheLength) {
        }

        public void notificationsResent(int resendCount) {
            numResent.set(resendCount);
        }
    }).build();
    server.stopAt(eMsg1.length() * 5 + eMsg2.length() + eMsg3.length() * 14);
    for (int i = 0; i < 5; ++i) {
        service.push(eMsg1);
    }
    service.push(eMsg2);
    for (int i = 0; i < 7; ++i) {
        service.push(eMsg3);
    }
    server.sendError(8, eMsg2.getIdentifier());
    server.getWaitForError().release();
    server.getMessages().acquire();
    sync.await();
    Assert.assertEquals(EXPECTED_RESEND_COUNT, numResent.get());
    Assert.assertEquals(EXPECTED_SEND_COUNT, numSent.get());
    Assert.assertEquals(EXPECTED_SEND_COUNT + 1, numStartSend.get());
}
Also used : StartSendingApnsDelegate(com.notnoop.apns.StartSendingApnsDelegate) ApnsServerStub(com.notnoop.apns.utils.ApnsServerStub) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) DeliveryError(com.notnoop.apns.DeliveryError) ApnsNotification(com.notnoop.apns.ApnsNotification) SimpleApnsNotification(com.notnoop.apns.SimpleApnsNotification) EnhancedApnsNotification(com.notnoop.apns.EnhancedApnsNotification) CountDownLatch(java.util.concurrent.CountDownLatch) ApnsService(com.notnoop.apns.ApnsService)

Example 10 with ApnsNotification

use of com.notnoop.apns.ApnsNotification in project java-apns by notnoop.

the class BatchApnsServiceTest method simpleBatchWait_one.

@Test
public void simpleBatchWait_one() throws IOException, InterruptedException {
    // send message
    ApnsNotification message = service.push("1234", "{}");
    // make sure no message was send yet
    verify(prototype, times(0)).copy();
    verify(prototype, times(0)).sendMessage(message);
    verify(prototype, times(0)).close();
    Thread.sleep(delayTimeInSec_millis + /* for sure */
    250);
    // verify batch sends and close the connection
    verify(prototype, times(1)).copy();
    verify(prototype, times(1)).sendMessage(message);
    verify(prototype, times(1)).close();
}
Also used : ApnsNotification(com.notnoop.apns.ApnsNotification) Test(org.junit.Test)

Aggregations

ApnsNotification (com.notnoop.apns.ApnsNotification)12 EnhancedApnsNotification (com.notnoop.apns.EnhancedApnsNotification)7 DeliveryError (com.notnoop.apns.DeliveryError)6 ApnsService (com.notnoop.apns.ApnsService)5 SimpleApnsNotification (com.notnoop.apns.SimpleApnsNotification)5 StartSendingApnsDelegate (com.notnoop.apns.StartSendingApnsDelegate)5 ApnsServerStub (com.notnoop.apns.utils.ApnsServerStub)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 CountDownLatch (java.util.concurrent.CountDownLatch)4 Test (org.junit.Test)3 ApnsDelegate (com.notnoop.apns.ApnsDelegate)2 NetworkIOException (com.notnoop.exceptions.NetworkIOException)2 ApnsDeliveryErrorException (com.notnoop.exceptions.ApnsDeliveryErrorException)1 EOFException (java.io.EOFException)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 Queue (java.util.Queue)1 ConcurrentLinkedQueue (java.util.concurrent.ConcurrentLinkedQueue)1 MessageType (org.apache.camel.component.apns.model.MessageType)1