@Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof SourcedModifyNotification)) return false; if (!super.equals(o)) return false; SourcedModifyNotification that = (SourcedModifyNotification) o; if (source != null ? !source.equals(that.source) : that.source != null) return false; return true; }
@Override public int hashCode() { int result = super.hashCode(); result = 31 * result + (source != null ? source.hashCode() : 0); return result; } }
@Override public String toString() { return "SourcedModifyNotification{" + "source=" + source + "} " + super.toString(); }
public static AuditRecord forChangeNotification(String auditServerId, long timestamp, boolean userTriggered, ChangeNotification<InstanceInfo> changeNotification) { switch (changeNotification.getKind()) { case Add: return forInstanceAdd(auditServerId, timestamp, userTriggered, changeNotification.getData()); case Modify: ModifyNotification<InstanceInfo> modifyNotification = (ModifyNotification<InstanceInfo>) changeNotification; return forInstanceUpdate(auditServerId, timestamp, userTriggered, modifyNotification.getData(), modifyNotification.getDelta()); case Delete: return forInstanceDelete(auditServerId, timestamp, userTriggered, changeNotification.getData()); } throw new IllegalStateException("unhadled enum value " + changeNotification.getKind()); }
public static ChangeNotification<InstanceInfo> addTimeStamp(ChangeNotification<InstanceInfo> notification, long timeStamp) { InstanceInfo timeStamped = addTimeStamp(notification.getData(), timeStamp); switch (notification.getKind()) { case Add: case Delete: return new ChangeNotification<>(notification.getKind(), timeStamped); case Modify: return new ModifyNotification<>(timeStamped, ((ModifyNotification) notification).getDelta()); default: throw new IllegalArgumentException("Unexpected enum value " + notification.getKind()); } }
public ModifyNotification<T> toBaseNotification() { return new ModifyNotification<>(getData(), getDelta()); }
public Observable<Void> sendNotification(ChangeNotification<InstanceInfo> notification) { switch (notification.getKind()) { case Add: return transport.submitWithAck(new AddInstance(notification.getData())); case Delete: return transport.submitWithAck(new DeleteInstance(notification.getData().getId())); case Modify: final ModifyNotification<InstanceInfo> modifyNotification = (ModifyNotification<InstanceInfo>) notification; /** * Below will only work correctly if {@link MessageBroker#submitWithAck(Object)} is a lazy submit i.e. * the message is only sent over the wire when subscribed. If it is eager i.e. the message is written * to the underlying connection without subscription then {@link Observable#concatWith(Observable)} * will eagerly write all the messages without waiting for an ack. */ Observable<Void> toReturn = null; for (final Delta<?> delta : modifyNotification.getDelta()) { if (null == toReturn) { toReturn = transport.submitWithAck(new UpdateInstanceInfo(delta)); } else { toReturn.concatWith(transport.submitWithAck(new UpdateInstanceInfo(delta))); } } return toReturn; } return Observable.error(new IllegalArgumentException("Unknown change notification type: " + notification.getKind())); }
public static AuditRecord forChangeNotification(String auditServerId, long timestamp, boolean userTriggered, ChangeNotification<InstanceInfo> changeNotification) { switch (changeNotification.getKind()) { case Add: return forInstanceAdd(auditServerId, timestamp, userTriggered, changeNotification.getData()); case Modify: ModifyNotification<InstanceInfo> modifyNotification = (ModifyNotification<InstanceInfo>) changeNotification; return forInstanceUpdate(auditServerId, timestamp, userTriggered, modifyNotification.getData(), modifyNotification.getDelta()); case Delete: return forInstanceDelete(auditServerId, timestamp, userTriggered, changeNotification.getData()); } throw new IllegalStateException("unhadled enum value " + changeNotification.getKind()); }
/** * For an UpdateInstanceInfo msg, * - if it does not exist in cache, we ignore this message as we do not have enough information to restore it * - if it exist in cache but is different, this is a modify notification to the store. * We only apply changes to cached instance if it has a version number GREATER THAN the cached * version number. */ @SuppressWarnings("unchecked") private ChangeNotification<InstanceInfo> updateMessageToChangeNotification(UpdateInstanceInfo msg) { ModifyNotification<InstanceInfo> notification = null; Delta delta = msg.getDelta(); InstanceInfo cached = idVsInstance.get(delta.getId()); if (cached == null) { if (logger.isWarnEnabled()) { logger.warn("Update notification received for non-existent instance id " + delta.getId()); } } else { InstanceInfo updatedInfo = cached.applyDelta(delta); idVsInstance.put(updatedInfo.getId(), updatedInfo); notification = new ModifyNotification(updatedInfo, Collections.singleton(delta)); } return notification; }
private Observable<Void> sendNotification(ChangeNotification<InstanceInfo> notification) { switch (notification.getKind()) { case Add: return transport.submitWithAck(new AddInstance(notification.getData())); case Delete: return transport.submitWithAck(new DeleteInstance(notification.getData().getId())); case Modify: final ModifyNotification<InstanceInfo> modifyNotification = (ModifyNotification<InstanceInfo>) notification; /** * Below will only work correctly if {@link MessageBroker#submitWithAck(Object)} is a lazy submit i.e. * the message is only sent over the wire when subscribed. If it is eager i.e. the message is written * to the underlying connection without subscription then {@link Observable#concatWith(Observable)} * will eagerly write all the messages without waiting for an ack. */ Observable<Void> toReturn = null; for (final Delta<?> delta : modifyNotification.getDelta()) { if (null == toReturn) { toReturn = transport.submitWithAck(new UpdateInstanceInfo(delta)); } else { toReturn.concatWith(transport.submitWithAck(new UpdateInstanceInfo(delta))); } } return toReturn; case BufferSentinel: return transport.submitWithAck(new StreamStateUpdate((StreamStateNotification<InstanceInfo>) notification)); } return Observable.error(new IllegalArgumentException("Unknown change notification type: " + notification.getKind())); }
@Override public void onNext(ChangeNotification<InstanceInfo> notification) { switch (notification.getKind()) { // these are in-mem blocking ops case Add: registry.register(notification.getData()); break; case Modify: ModifyNotification<InstanceInfo> modifyNotification = (ModifyNotification<InstanceInfo>) notification; registry.update(modifyNotification.getData(), modifyNotification.getDelta()); break; case Delete: registry.unregister(notification.getData()); break; default: logger.error("Unrecognized notification kind"); } } });
/** * For an UpdateInstanceInfo msg, * - if it does not exist in cache, we ignore this message as we do not have enough information to restore it * - if it exist in cache but is different, this is a modify notification to the store. * We only apply changes to cached instance if it has a version number GREATER THAN the cached * version number. */ @SuppressWarnings("unchecked") private ChangeNotification<InstanceInfo> updateMessageToChangeNotification(UpdateInstanceInfo msg) { ModifyNotification<InstanceInfo> notification = null; Delta delta = msg.getDelta(); InstanceInfo cached = idVsInstance.get(delta.getId()); if (cached == null) { if (logger.isWarnEnabled()) { logger.warn("Update notification received for non-existent instance id " + delta.getId()); } } else if (delta.getVersion() <= cached.getVersion()) { logger.debug("Skipping <= version of the delta. Cached: {}, Delta: {}", cached, delta); } else { InstanceInfo updatedInfo = cached.applyDelta(delta); idVsInstance.put(updatedInfo.getId(), updatedInfo); notification = new ModifyNotification(updatedInfo, Collections.singleton(delta)); } return notification; }
@Override public String toString() { return "SourcedModifyNotification{" + "source=" + source + "} " + super.toString(); }
@Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof SourcedModifyNotification)) return false; if (!super.equals(o)) return false; SourcedModifyNotification that = (SourcedModifyNotification) o; if (source != null ? !source.equals(that.source) : that.source != null) return false; return true; }
@Override public int hashCode() { int result = super.hashCode(); result = 31 * result + (source != null ? source.hashCode() : 0); return result; } }
@Override public Observable<Void> update(InstanceInfo updatedInfo, Set<Delta<?>> deltas) { InstanceInfo previous = internalStore.put(updatedInfo.getId(), updatedInfo); if (previous == null) { notificationSubject.onNext(new ChangeNotification<>(Kind.Add, updatedInfo)); } else { notificationSubject.onNext(new ModifyNotification<>(updatedInfo, deltas)); } return Observable.empty(); }