private Set<Ack> rowsToAcks(final List<Row> rows) { if (rows.isEmpty()) { return Collections.emptySet(); } final Set<Ack> unacks = new HashSet<Ack>(rows.size()); for (Row row : rows) { final JsonNode json = row.getValueAsNode().get(DOC_FIELD); unacks.add(new AckImpl(json.get(CHID_FIELD).asText(), json.get(VERSION_FIELD).asLong())); } return unacks; }
@Override public AckMessageImpl deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException { final ObjectCodec oc = jp.getCodec(); final JsonNode node = oc.readTree(jp); final JsonNode acksNode = node.get(AckMessage.UPDATES_FIELD); final Set<Ack> acks = new HashSet<Ack>(); if (acksNode.isArray()) { for (JsonNode ackNode : acksNode) { acks.add(new AckImpl(ackNode.get("channelID").asText(), ackNode.get("version").asLong())); } } return new AckMessageImpl(acks); } }
private Set<Ack> rowsToAcks(final List<Row> rows) { if (rows.isEmpty()) { return Collections.emptySet(); } final Set<Ack> unacks = new HashSet<Ack>(rows.size()); for (Row row : rows) { final JsonNode json = row.getValueAsNode().get(DOC_FIELD); unacks.add(new AckImpl(json.get(CHID_FIELD).asText(), json.get(VERSION_FIELD).asLong())); } return unacks; }
@Override public AckMessageImpl deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException { final ObjectCodec oc = jp.getCodec(); final JsonNode node = oc.readTree(jp); final JsonNode acksNode = node.get(AckMessage.UPDATES_FIELD); final Set<Ack> acks = new HashSet<Ack>(); if (acksNode.isArray()) { for (JsonNode ackNode : acksNode) { acks.add(new AckImpl(ackNode.get("channelID").asText(), ackNode.get("version").asLong())); } } return new AckMessageImpl(acks); } }
@Override public NotificationMessageImpl deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException { final ObjectCodec oc = jp.getCodec(); final JsonNode node = oc.readTree(jp); final JsonNode updatesNode = node.get(NotificationMessage.UPDATES_FIELD); final Set<Ack> acks = new HashSet<Ack>(); if (updatesNode.isArray()) { for (JsonNode channelNode : updatesNode) { final JsonNode versionNode = channelNode.get(NotificationMessage.VERSION_FIELD); final JsonNode channelIdNode = channelNode.get(RegisterMessage.CHANNEL_ID_FIELD); acks.add(new AckImpl(channelIdNode.asText(), versionNode.asLong())); } } return new NotificationMessageImpl(acks); } }
@Override public NotificationMessageImpl deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException { final ObjectCodec oc = jp.getCodec(); final JsonNode node = oc.readTree(jp); final JsonNode updatesNode = node.get(NotificationMessage.UPDATES_FIELD); final Set<Ack> acks = new HashSet<Ack>(); if (updatesNode.isArray()) { for (JsonNode channelNode : updatesNode) { final JsonNode versionNode = channelNode.get(NotificationMessage.VERSION_FIELD); final JsonNode channelIdNode = channelNode.get(RegisterMessage.CHANNEL_ID_FIELD); acks.add(new AckImpl(channelIdNode.asText(), versionNode.asLong())); } } return new NotificationMessageImpl(acks); } }
@Override public Set<Ack> perform(final EntityManager em) { final UserAgentDTO userAgent = em.find(UserAgentDTO.class, uaid); if (userAgent == null) { return Collections.emptySet(); } final HashSet<Ack> acks = new HashSet<Ack>(); for (AckDTO ackDTO : userAgent.getAcks()) { acks.add(new AckImpl(ackDTO.getChannelId(), ackDTO.getVersion())); } return acks; } };
@Override public Set<Ack> perform(final EntityManager em) { final UserAgentDTO userAgent = em.find(UserAgentDTO.class, uaid); if (userAgent == null) { return Collections.emptySet(); } final HashSet<Ack> acks = new HashSet<Ack>(); for (AckDTO ackDTO : userAgent.getAcks()) { acks.add(new AckImpl(ackDTO.getChannelId(), ackDTO.getVersion())); } return acks; } };
@Override public Set<Ack> perform(final EntityManager em) { final List<String> channelIds = new ArrayList<String>(acked.size()); for (Ack ack : acked) { channelIds.add(ack.getChannelId()); } final Query delete = em.createQuery("DELETE from AckDTO c where c.channelId in (:channelIds)"); delete.setParameter("channelIds", channelIds); delete.executeUpdate(); final UserAgentDTO userAgent = em.find(UserAgentDTO.class, uaid); final Set<AckDTO> acks = userAgent.getAcks(); final Set<Ack> unacked = new HashSet<Ack>(acks.size()); for (AckDTO ackDto : acks) { unacked.add(new AckImpl(ackDto.getChannelId(), ackDto.getVersion())); } return unacked; } };
@Override public Set<Ack> perform(final EntityManager em) { final List<String> channelIds = new ArrayList<String>(acked.size()); for (Ack ack : acked) { channelIds.add(ack.getChannelId()); } final Query delete = em.createQuery("DELETE from AckDTO c where c.channelId in (:channelIds)"); delete.setParameter("channelIds", channelIds); delete.executeUpdate(); final UserAgentDTO userAgent = em.find(UserAgentDTO.class, uaid); final Set<AckDTO> acks = userAgent.getAcks(); final Set<Ack> unacked = new HashSet<Ack>(acks.size()); for (AckDTO ackDto : acks) { unacked.add(new AckImpl(ackDto.getChannelId(), ackDto.getVersion())); } return unacked; } };
@Override public Set<Ack> getUnacknowledged(final String uaid) { final Jedis jedis = jedisPool.getResource(); try { final Set<String> unacks = jedis.smembers(acksLookupKey(uaid)); if (unacks.isEmpty()) { return Collections.emptySet(); } final Set<Ack> acks = new HashSet<Ack>(unacks.size()); for (String channelId : unacks) { acks.add(new AckImpl(channelId, Long.valueOf(jedis.get(ackLookupKey(channelId))))); } return acks; } finally { jedisPool.returnResource(jedis); } }
@Override public String saveUnacknowledged(final String channelId, final long version) throws ChannelNotFoundException { checkNotNull(channelId, "channelId"); checkNotNull(version, "version"); final Channel channel = channels.get(channelId); if (channel == null) { throw new ChannelNotFoundException("Could not find channel", channelId); } final String uaid = channel.getUAID(); final Set<Ack> newAcks = Collections.newSetFromMap(new ConcurrentHashMap<Ack, Boolean>()); newAcks.add(new AckImpl(channelId, version)); while (true) { final Set<Ack> currentAcks = unacked.get(uaid); if (currentAcks == null) { final Set<Ack> previous = unacked.putIfAbsent(uaid, newAcks); if (previous != null) { newAcks.addAll(previous); if (unacked.replace(uaid, previous, newAcks)) { break; } } } else { newAcks.addAll(currentAcks); if (unacked.replace(uaid, currentAcks, newAcks)) { break; } } } return uaid; }
@Override public String saveUnacknowledged(final String channelId, final long version) throws ChannelNotFoundException { checkNotNull(channelId, "channelId"); checkNotNull(version, "version"); final Channel channel = channels.get(channelId); if (channel == null) { throw new ChannelNotFoundException("Could not find channel", channelId); } final String uaid = channel.getUAID(); final Set<Ack> newAcks = Collections.newSetFromMap(new ConcurrentHashMap<Ack, Boolean>()); newAcks.add(new AckImpl(channelId, version)); while (true) { final Set<Ack> currentAcks = unacked.get(uaid); if (currentAcks == null) { final Set<Ack> previous = unacked.putIfAbsent(uaid, newAcks); if (previous != null) { newAcks.addAll(previous); if (unacked.replace(uaid, previous, newAcks)) { break; } } } else { newAcks.addAll(currentAcks); if (unacked.replace(uaid, currentAcks, newAcks)) { break; } } } return uaid; }
@Override public Notification handleNotification(final String endpointToken, final String body) throws ChannelNotFoundException { final Long version = Long.valueOf(VersionExtractor.extractVersion(body)); final String channelId = store.updateVersion(endpointToken, version); if (channelId == null) { throw new ChannelNotFoundException("Could not find channel for endpoint [" + endpointToken + "]", null); } final Ack ack = new AckImpl(channelId, version); final String uaid = store.saveUnacknowledged(channelId, ack.getVersion()); return new Notification(uaid, ack); }
@Override public Notification handleNotification(final String endpointToken, final String body) throws ChannelNotFoundException { final Long version = Long.valueOf(VersionExtractor.extractVersion(body)); final String channelId = store.updateVersion(endpointToken, version); if (channelId == null) { throw new ChannelNotFoundException("Could not find channel for endpoint [" + endpointToken + "]", null); } final Ack ack = new AckImpl(channelId, version); final String uaid = store.saveUnacknowledged(channelId, ack.getVersion()); return new Notification(uaid, ack); }