All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.vlingo.xoom.cluster.model.attribute.ConfirmingDistributor Maven / Gradle / Ivy

// Copyright © 2012-2022 VLINGO LABS. All rights reserved.
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL
// was not distributed with this file, You can obtain
// one at https://mozilla.org/MPL/2.0/.

package io.vlingo.xoom.cluster.model.attribute;

import io.vlingo.xoom.actors.Logger;
import io.vlingo.xoom.cluster.model.application.ClusterApplication;
import io.vlingo.xoom.cluster.model.attribute.Confirmables.Confirmable;
import io.vlingo.xoom.cluster.model.attribute.message.*;
import io.vlingo.xoom.cluster.model.message.ApplicationSays;
import io.vlingo.xoom.cluster.model.outbound.OperationalOutboundStream;
import io.vlingo.xoom.wire.node.Node;

import java.util.Collection;
import java.util.function.Supplier;

public final class ConfirmingDistributor {
  private final ClusterApplication application;
  private final Confirmables confirmables;

  private final Supplier> allOtherNodesSupplier;
  private final Logger logger;
  private final Node node;
  private final OperationalOutboundStream outbound;

  ConfirmingDistributor(final ClusterApplication application, final Node node, final OperationalOutboundStream outbound,
                        final Supplier> allOtherNodesSupplier, final Logger logger) {
    this.application = application;
    this.logger = logger;
    this.node = node;
    this.outbound = outbound;
    this.allOtherNodesSupplier = allOtherNodesSupplier;
    this.confirmables = new Confirmables(node, allOtherNodesSupplier);
  }

  void acknowledgeConfirmation(final String trackingId, final Node node) {
    confirmables.confirm(trackingId, node);
  }

  Collection allTrackingIds() {
    return confirmables.allTrackingIds();
  }

  void distributeCreate(final AttributeSet set) {
    distributeTo(set, allOtherNodesSupplier.get());
  }

  public void distributeRemove(final AttributeSet set) {
    distributeRemoveTo(set, allOtherNodesSupplier.get());
  }

  void distributeTo(final AttributeSet set, final Collection nodes) {
    final CreateAttributeSet create = new CreateAttributeSet(node, set);
    final Confirmable confirmable = confirmables.unconfirmedFor(create, nodes);
    outbound.application(ApplicationSays.from(node.id(), node.name(), create.toPayload()), confirmable.unconfirmedNodes());
    application.informAttributeSetCreated(set.name);
    
    for (final TrackedAttribute tracked : set.all()) {
      distributeTo(set, tracked, ApplicationMessageType.AddAttribute, nodes);
    }
  }

  void distributeRemoveTo(final AttributeSet set, final Collection nodes) {
    // remove attributes first, then the set
    for (final TrackedAttribute untracked : set.all()) {
      distributeTo(set, untracked, ApplicationMessageType.RemoveAttribute, nodes);
    }
    final RemoveAttributeSet removeSet = new RemoveAttributeSet(node, set);
    final Confirmable confirmable = confirmables.unconfirmedFor(removeSet, nodes);
    outbound.application(ApplicationSays.from(node.id(), node.name(), removeSet.toPayload()), confirmable.unconfirmedNodes());
    application.informAttributeSetRemoved(set.name);
  }

  void distribute(final AttributeSet set, final TrackedAttribute tracked, final ApplicationMessageType type) {
    distributeTo(set, tracked, type, allOtherNodesSupplier.get());
  }

  void distributeTo(final AttributeSet set, final TrackedAttribute tracked, final ApplicationMessageType type, final Collection nodes) {
    switch (type) {
    case AddAttribute:
      final AddAttribute add = AddAttribute.from(node, set, tracked);
      final Confirmable addConfirmable = confirmables.unconfirmedFor(add, nodes);
      outbound.application(ApplicationSays.from(node.id(), node.name(), add.toPayload()), addConfirmable.unconfirmedNodes());
      application.informAttributeAdded(set.name, tracked.attribute.name);
      break;
    case RemoveAttribute:
      final RemoveAttribute remove = RemoveAttribute.from(node, set, tracked);
      final Confirmable removeConfirmable = confirmables.unconfirmedFor(remove, nodes);
      outbound.application(ApplicationSays.from(node.id(), node.name(), remove.toPayload()), removeConfirmable.unconfirmedNodes());
      application.informAttributeRemoved(set.name, tracked.attribute.name);
      break;
    case RemoveAttributeSet:
      final RemoveAttributeSet removeSet = RemoveAttributeSet.from(node, set);
      final Confirmable removeSetConfirmable = confirmables.unconfirmedFor(removeSet, nodes);
      outbound.application(ApplicationSays.from(node.id(), node.name(), removeSet.toPayload()), removeSetConfirmable.unconfirmedNodes());
      application.informAttributeSetRemoved(set.name);
      break;
    case ReplaceAttribute:
      final ReplaceAttribute replace = ReplaceAttribute.from(node, set, tracked);
      final Confirmable replaceConfirmable = confirmables.unconfirmedFor(replace, nodes);
      outbound.application(ApplicationSays.from(node.id(), node.name(), replace.toPayload()), replaceConfirmable.unconfirmedNodes());
      application.informAttributeReplaced(set.name, tracked.attribute.name);
      break;
    default:
      throw new IllegalArgumentException("Cannot distribute unknown ApplicationMessageType.");
    }
  }

  void confirmCreate(
          final String correlatingMessageId,
          final AttributeSet set,
          final Node toOriginalSource) {
    
    final ConfirmCreateAttributeSet confirm = new ConfirmCreateAttributeSet(correlatingMessageId, node, set);
    outbound.application(ApplicationSays.from(node.id(), node.name(), confirm.toPayload()), toOriginalSource.collected());
    application.informAttributeSetCreated(set.name);
  }

  void confirmRemove(
          final String correlatingMessageId,
          final AttributeSet set,
          final Node toOriginalSource) {
    
    final ConfirmRemoveAttributeSet confirm = new ConfirmRemoveAttributeSet(correlatingMessageId, node, set);
    outbound.application(ApplicationSays.from(node.id(), node.name(), confirm.toPayload()), toOriginalSource.collected());
    application.informAttributeSetRemoved(set.name);
  }
  
  void confirm(
          final String correlatingMessageId,
          final AttributeSet set,
          final TrackedAttribute tracked,
          final ApplicationMessageType type,
          final Node toOriginalSource) {
    
    switch (type) {
    case AddAttribute:
      final ConfirmAttribute confirmAdd = ConfirmAttribute.from(correlatingMessageId, toOriginalSource, set, tracked, ApplicationMessageType.ConfirmAddAttribute);
      outbound.application(ApplicationSays.from(node.id(), node.name(), confirmAdd.toPayload()), toOriginalSource.collected());
      application.informAttributeAdded(set.name, tracked.attribute.name);
      break;
    case RemoveAttribute:
      final ConfirmAttribute confirmRemove = ConfirmAttribute.from(correlatingMessageId, toOriginalSource, set, tracked, ApplicationMessageType.ConfirmRemoveAttribute);
      outbound.application(ApplicationSays.from(node.id(), node.name(), confirmRemove.toPayload()), toOriginalSource.collected());
      application.informAttributeRemoved(set.name, tracked.attribute.name);
      break;
    case ReplaceAttribute:
      final ConfirmAttribute confirmReplace = ConfirmAttribute.from(correlatingMessageId, toOriginalSource, set, tracked, ApplicationMessageType.ConfirmReplaceAttribute);
      outbound.application(ApplicationSays.from(node.id(), node.name(), confirmReplace.toPayload()), toOriginalSource.collected());
      application.informAttributeReplaced(set.name, tracked.attribute.name);
      break;
    default:
      throw new IllegalArgumentException("Cannot confirm unknown ApplicationMessageType.");
    }
  }

  void redistributeUnconfirmed() {
    for (final Confirmable confirmable : confirmables.allRedistributable()) {
      if (confirmable.hasUnconfirmedNodes()) {
        logger.trace("REDIST ATTR: " + confirmable);
        outbound.application(ApplicationSays.from(
                node.id(), node.name(),
                confirmable.message().toPayload()),
                confirmable.unconfirmedNodes());
      }
    }
  }

  void synchronizeTo(final Collection sets, final Node targetNode) {
    final Collection onlyOneTargetNode = targetNode.collected();
    
    for (final AttributeSet set : sets) {
      this.distributeTo(set, onlyOneTargetNode);
    }
  }

  Collection unconfirmedNodesFor(final String trackingId) {
    return confirmables.confirmableOf(trackingId).unconfirmedNodes();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy