@Override public void run() { try { deserializer.notify( Collections.unmodifiableCollection(listenersCopy), topic, notification.getBody().array()); } catch (IOException ex) { LOG.error("Failed to process notification for topic {}", topic.getId(), ex); } } });
@Override public int compare(Notification o1, Notification o2) { return o1.getSeqNumber() - o2.getSeqNumber(); } });
private List<Notification> getUnicastNotifications(List<Notification> notifications) { List<Notification> result = new ArrayList<>(); for (Notification notification : notifications) { if (notification.getUid() != null) { result.add(notification); } } return result; }
@Test public void testFilterStaleNotification() throws Exception { KaaClientState clientState = Mockito.mock(KaaClientState.class); NotificationProcessor notificationProcessor = Mockito.mock(NotificationProcessor.class); Mockito.when(clientState.updateTopicSubscriptionInfo(Mockito.anyLong(), Mockito.anyInt())).thenReturn(Boolean.FALSE); NotificationSyncResponse response = new NotificationSyncResponse(); response.setResponseStatus(SyncResponseStatus.DELTA); KaaChannelManager channelManagerMock = Mockito.mock(KaaChannelManager.class); NotificationTransport transport = new DefaultNotificationTransport(); transport.setChannelManager(channelManagerMock); transport.setNotificationProcessor(notificationProcessor); transport.setClientState(clientState); Notification nf1 = new Notification(1l, NotificationType.CUSTOM, null, 3, ByteBuffer.wrap(new byte[]{1, 2, 3})); Notification nf2 = new Notification(1l, NotificationType.CUSTOM, null, 3, ByteBuffer.wrap(new byte[]{1, 2, 3})); response.setNotifications(Arrays.asList(nf1, nf2)); transport.onNotificationResponse(response); List<Notification> expectedNotifications = Collections.emptyList(); Mockito.verify(notificationProcessor, Mockito.times(1)).notificationReceived(expectedNotifications); }
if (acceptedUnicastNotificationIds.add(notification.getUid())) { newNotifications.add(notification); } else { LOG.info("Notification with uid [{}] was already received", notification.getUid()); if (clientState.updateTopicSubscriptionInfo(notification.getTopicId(), notification.getSeqNumber())) { newNotifications.add(notification); } else { LOG.info("Notification with seq number {} was already received", notification.getSeqNumber());
@Override public void notificationReceived(List<Notification> notifications) throws IOException { for (Notification notification : notifications) { try { Topic topic = findTopicById(notification.getTopicId()); boolean hasOwner = false; synchronized (optionalListeners) { List<NotificationListener> listeners = optionalListeners.get(topic.getId()); if (listeners != null && !listeners.isEmpty()) { hasOwner = true; notifyListeners(listeners, topic, notification); } } if (!hasOwner) { synchronized (mandatoryListeners) { notifyListeners(mandatoryListeners, topic, notification); } } } catch (UnavailableTopicException ex) { LOG.warn("Received notification for an unknown topic (id={}), exception catched: {}", notification.getTopicId(), ex); } } }
response.setAvailableTopics(topicList); Notification nf1 = new Notification(topicId2, NotificationType.CUSTOM, "uid", 5, ByteBuffer.wrap(new byte[]{1, 2, 3})); Notification nf2 = new Notification(topicId1, NotificationType.CUSTOM, null, 3, ByteBuffer.wrap(new byte[]{1, 2, 3})); Notification nf3 = new Notification(topicId1, NotificationType.CUSTOM, null, 6, ByteBuffer.wrap(new byte[]{1, 2, 3}));
private static NotificationSyncResponse convert(NotificationServerSync source) { if (source == null) { return null; } NotificationSyncResponse sync = new NotificationSyncResponse(); sync.setResponseStatus(convert(source.getResponseStatus())); if (source.getAvailableTopics() != null) { List<Topic> topics = new ArrayList<>(source.getAvailableTopics().size()); for (org.kaaproject.kaa.server.sync.Topic topic : source.getAvailableTopics()) { topics.add(new Topic( topic.getIdAsLong(), topic.getName(), convert(topic.getSubscriptionType()))); } sync.setAvailableTopics(topics); } if (source.getNotifications() != null) { List<Notification> notifications = new ArrayList<>(source.getNotifications().size()); for (org.kaaproject.kaa.server.sync.Notification notification : source.getNotifications()) { notifications.add(new Notification( notification.getTopicIdAsLong(), convert(notification.getType()), notification.getUid(), notification.getSeqNumber(), notification.getBody())); } sync.setNotifications(notifications); } return sync; }
private List<Notification> getMulticastNotifications(List<Notification> notifications) { List<Notification> result = new ArrayList<>(); for (Notification notification : notifications) { if (notification.getUid() == null) { result.add(notification); } } Collections.sort(result, new Comparator<Notification>() { @Override public int compare(Notification o1, Notification o2) { return o1.getSeqNumber() - o2.getSeqNumber(); } }); return result; }
private void notifyListeners(Collection<NotificationListener> listeners, final Topic topic, final Notification notification) { final Collection<NotificationListener> listenersCopy = new ArrayList<NotificationListener>(listeners); if (notification.getBody() != null) { executorContext.getCallbackExecutor().submit(new Runnable() { @Override public void run() { try { deserializer.notify( Collections.unmodifiableCollection(listenersCopy), topic, notification.getBody().array()); } catch (IOException ex) { LOG.error("Failed to process notification for topic {}", topic.getId(), ex); } } }); } }
@Test public void testAcceptedUnicastNotification() throws Exception { KaaClientState clientState = Mockito.mock(KaaClientState.class); NotificationProcessor notificationProcessor = Mockito.mock(NotificationProcessor.class); NotificationSyncResponse response1 = new NotificationSyncResponse(); response1.setResponseStatus(SyncResponseStatus.DELTA); KaaChannelManager channelManagerMock = Mockito.mock(KaaChannelManager.class); NotificationTransport transport = new DefaultNotificationTransport(); transport.setChannelManager(channelManagerMock); transport.setNotificationProcessor(notificationProcessor); transport.setClientState(clientState); Notification nf1 = new Notification(1l, NotificationType.CUSTOM, "uid_1", 5, ByteBuffer.wrap(new byte[]{1, 2, 3})); Notification nf2 = new Notification(2l, NotificationType.CUSTOM, "uid_2", 3, ByteBuffer.wrap(new byte[]{1, 2, 3})); Notification nf3 = new Notification(3l, NotificationType.CUSTOM, "uid_2", 5, ByteBuffer.wrap(new byte[]{1, 2, 3})); response1.setNotifications(Arrays.asList(nf1, nf2, nf3)); transport.onNotificationResponse(response1); NotificationSyncRequest request1 = transport.createNotificationRequest(); Assert.assertTrue(request1.getAcceptedUnicastNotifications().size() == 2); NotificationSyncResponse response2 = new NotificationSyncResponse(); response2.setResponseStatus(SyncResponseStatus.NO_DELTA); transport.onNotificationResponse(response2); NotificationSyncRequest request2 = transport.createNotificationRequest(); Assert.assertNull(request2.getAcceptedUnicastNotifications()); }
@Override public Notification build() { try { Notification record = new Notification(); record.topicId = fieldSetFlags()[0] ? this.topicId : (java.lang.Long) defaultValue(fields()[0]); record.type = fieldSetFlags()[1] ? this.type : (org.kaaproject.kaa.common.endpoint.gen.NotificationType) defaultValue(fields()[1]); record.uid = fieldSetFlags()[2] ? this.uid : (java.lang.String) defaultValue(fields()[2]); record.seqNumber = fieldSetFlags()[3] ? this.seqNumber : (java.lang.Integer) defaultValue(fields()[3]); record.body = fieldSetFlags()[4] ? this.body : (java.nio.ByteBuffer) defaultValue(fields()[4]); return record; } catch (Exception e) { throw new org.apache.avro.AvroRuntimeException(e); } } }
@Test public void testGlobalNotificationListeners() throws Exception { KaaClientPropertiesState state = new KaaClientPropertiesState( new FilePersistentStorage(), CommonsBase64.getInstance(), KaaClientPropertiesStateTest.getProperties()); NotificationTransport transport = mock(NotificationTransport.class); DefaultNotificationManager notificationManager = new DefaultNotificationManager(state, executorContext, transport); List<Topic> topicsUpdate = Arrays.asList( new Topic(1l, "topic_name1", SubscriptionType.MANDATORY_SUBSCRIPTION) , new Topic(2l, "topic_name1", SubscriptionType.MANDATORY_SUBSCRIPTION)); ByteBuffer notificationBody = ByteBuffer.wrap(new AvroByteArrayConverter<>(org.kaaproject.kaa.schema.base.Notification.class).toByteArray( new org.kaaproject.kaa.schema.base.Notification())); notificationManager.topicsListUpdated(topicsUpdate); List<Notification> notificationUpdate = Arrays.asList( new Notification(1l, NotificationType.CUSTOM, null, 1, notificationBody), new Notification(2l, NotificationType.CUSTOM, null, 1, notificationBody)); NotificationListener mandatoryListener = Mockito.mock(NotificationListener.class); NotificationListener globalListener = Mockito.mock(NotificationListener.class); notificationManager.addNotificationListener(mandatoryListener); notificationManager.notificationReceived(notificationUpdate); Thread.sleep(500); notificationManager.removeNotificationListener(mandatoryListener); notificationManager.addNotificationListener(globalListener); notificationManager.notificationReceived(notificationUpdate); notificationManager.notificationReceived(notificationUpdate); Mockito.verify(mandatoryListener, Mockito.timeout(1000).times(notificationUpdate.size())) .onNotification(Mockito.anyLong(), Mockito.any(org.kaaproject.kaa.schema.base.Notification.class)); Mockito.verify(globalListener, Mockito.timeout(1000).times(notificationUpdate.size() * 2)) .onNotification(Mockito.anyLong(), Mockito.any(org.kaaproject.kaa.schema.base.Notification.class)); }
@Test public void testNotificationListenerOnTopic() throws Exception { KaaClientPropertiesState state = new KaaClientPropertiesState( new FilePersistentStorage(), CommonsBase64.getInstance(), KaaClientPropertiesStateTest.getProperties()); NotificationTransport transport = mock(NotificationTransport.class); DefaultNotificationManager notificationManager = new DefaultNotificationManager(state, executorContext, transport); List<Topic> topicsUpdate = Arrays.asList( new Topic(1l, "topic_name1", SubscriptionType.MANDATORY_SUBSCRIPTION) , new Topic(2l, "topic_name1", SubscriptionType.MANDATORY_SUBSCRIPTION)); ByteBuffer notificationBody = ByteBuffer.wrap(new AvroByteArrayConverter<>(Topic.class).toByteArray( new Topic(3l, "name", SubscriptionType.MANDATORY_SUBSCRIPTION))); notificationManager.topicsListUpdated(topicsUpdate); List<Notification> notificationUpdate = Arrays.asList( new Notification(1l, NotificationType.CUSTOM, null, 1, notificationBody), new Notification(2l, NotificationType.CUSTOM, null, 1, notificationBody)); NotificationListener globalListener = Mockito.mock(NotificationListener.class); NotificationListener topicListener = Mockito.mock(NotificationListener.class); notificationManager.addNotificationListener(globalListener); notificationManager.addNotificationListener(2l, topicListener); notificationManager.notificationReceived(notificationUpdate); notificationManager.removeNotificationListener(2l, topicListener); notificationManager.notificationReceived(notificationUpdate); Mockito.verify(globalListener, Mockito.timeout(1000).times(notificationUpdate.size() * 2 - 1)) .onNotification(Mockito.anyLong(), Mockito.any(org.kaaproject.kaa.schema.base.Notification.class)); Mockito.verify(topicListener, Mockito.timeout(1000).times(1)) .onNotification(Mockito.anyLong(), Mockito.any(org.kaaproject.kaa.schema.base.Notification.class)); }