@Override
  public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
    NodeId master = mastershipService.getMasterFor(deviceId);

    if (master == null) {
      log.debug("Failed to getFlowEntries: No master for {}", deviceId);
      return Collections.emptyList();
    }

    if (Objects.equal(local, master)) {
      return flowTable.getFlowEntries(deviceId);
    }

    log.trace(
        "Forwarding getFlowEntries to {}, which is the primary (master) for device {}",
        master,
        deviceId);

    return Tools.futureGetOrElse(
        clusterCommunicator.sendAndReceive(
            deviceId,
            FlowStoreMessageSubjects.GET_DEVICE_FLOW_ENTRIES,
            SERIALIZER::encode,
            SERIALIZER::decode,
            master),
        FLOW_RULE_STORE_TIMEOUT_MILLIS,
        TimeUnit.MILLISECONDS,
        Collections.emptyList());
  }
  @Override
  public FlowEntry getFlowEntry(FlowRule rule) {
    NodeId master = mastershipService.getMasterFor(rule.deviceId());

    if (master == null) {
      log.debug("Failed to getFlowEntry: No master for {}", rule.deviceId());
      return null;
    }

    if (Objects.equal(local, master)) {
      return flowTable.getFlowEntry(rule);
    }

    log.trace(
        "Forwarding getFlowEntry to {}, which is the primary (master) for device {}",
        master,
        rule.deviceId());

    return Tools.futureGetOrElse(
        clusterCommunicator.sendAndReceive(
            rule,
            FlowStoreMessageSubjects.GET_FLOW_ENTRY,
            SERIALIZER::encode,
            SERIALIZER::decode,
            master),
        FLOW_RULE_STORE_TIMEOUT_MILLIS,
        TimeUnit.MILLISECONDS,
        null);
  }
  @Override
  public void storeBatch(FlowRuleBatchOperation operation) {
    if (operation.getOperations().isEmpty()) {
      notifyDelegate(
          FlowRuleBatchEvent.completed(
              new FlowRuleBatchRequest(operation.id(), Collections.emptySet()),
              new CompletedBatchOperation(true, Collections.emptySet(), operation.deviceId())));
      return;
    }

    DeviceId deviceId = operation.deviceId();
    NodeId master = mastershipService.getMasterFor(deviceId);

    if (master == null) {
      log.warn("No master for {} : flows will be marked for removal", deviceId);

      updateStoreInternal(operation);

      notifyDelegate(
          FlowRuleBatchEvent.completed(
              new FlowRuleBatchRequest(operation.id(), Collections.emptySet()),
              new CompletedBatchOperation(true, Collections.emptySet(), operation.deviceId())));
      return;
    }

    if (Objects.equal(local, master)) {
      storeBatchInternal(operation);
      return;
    }

    log.trace(
        "Forwarding storeBatch to {}, which is the primary (master) for device {}",
        master,
        deviceId);

    clusterCommunicator
        .unicast(operation, APPLY_BATCH_FLOWS, SERIALIZER::encode, master)
        .whenComplete(
            (result, error) -> {
              if (error != null) {
                log.warn("Failed to storeBatch: {} to {}", operation, master, error);

                Set<FlowRule> allFailures =
                    operation
                        .getOperations()
                        .stream()
                        .map(op -> op.target())
                        .collect(Collectors.toSet());

                notifyDelegate(
                    FlowRuleBatchEvent.completed(
                        new FlowRuleBatchRequest(operation.id(), Collections.emptySet()),
                        new CompletedBatchOperation(false, allFailures, deviceId)));
              }
            });
  }
  @Override
  public FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) {
    NodeId master = mastershipService.getMasterFor(rule.deviceId());
    if (Objects.equal(local, master)) {
      return addOrUpdateFlowRuleInternal(rule);
    }

    log.warn("Tried to update FlowRule {} state," + " while the Node was not the master.", rule);
    return null;
  }
  @Override
  public Iterable<TableStatisticsEntry> getTableStatistics(DeviceId deviceId) {
    NodeId master = mastershipService.getMasterFor(deviceId);

    if (master == null) {
      log.debug("Failed to getTableStats: No master for {}", deviceId);
      return Collections.emptyList();
    }

    List<TableStatisticsEntry> tableStats = deviceTableStats.get(deviceId);
    if (tableStats == null) {
      return Collections.emptyList();
    }
    return ImmutableList.copyOf(tableStats);
  }
  @Override
  public Set<FlowEntry> getPreviousFlowStatistic(ConnectPoint connectPoint) {
    final DeviceId deviceId = connectPoint.deviceId();

    NodeId master = mastershipService.getMasterFor(deviceId);
    if (master == null) {
      log.warn("No master for {}", deviceId);
      return Collections.emptySet();
    }

    if (Objects.equal(local, master)) {
      return getPreviousStatisticInternal(connectPoint);
    } else {
      return Tools.futureGetOrElse(
          clusterCommunicator.sendAndReceive(
              connectPoint, GET_PREVIOUS, SERIALIZER::encode, SERIALIZER::decode, master),
          STATISTIC_STORE_TIMEOUT_MILLIS,
          TimeUnit.MILLISECONDS,
          Collections.emptySet());
    }
  }
  @Override
  public void emit(OutboundPacket packet) {
    NodeId myId = clusterService.getLocalNode().id();
    NodeId master = mastershipService.getMasterFor(packet.sendThrough());

    if (master == null) {
      return;
    }

    if (myId.equals(master)) {
      notifyDelegate(new PacketEvent(Type.EMIT, packet));
      return;
    }

    communicationService
        .unicast(packet, PACKET_OUT_SUBJECT, SERIALIZER::encode, master)
        .whenComplete(
            (r, error) -> {
              if (error != null) {
                log.warn("Failed to send packet-out to {}", master, error);
              }
            });
  }
Esempio n. 8
-1
  @Override
  public FlowRuleEvent removeFlowRule(FlowEntry rule) {
    final DeviceId deviceId = rule.deviceId();
    NodeId master = mastershipService.getMasterFor(deviceId);

    if (Objects.equal(local, master)) {
      // bypass and handle it locally
      return removeFlowRuleInternal(rule);
    }

    if (master == null) {
      log.warn("Failed to removeFlowRule: No master for {}", deviceId);
      // TODO: revisit if this should be null (="no-op") or Exception
      return null;
    }

    log.trace(
        "Forwarding removeFlowRule to {}, which is the master for device {}", master, deviceId);

    return Futures.get(
        clusterCommunicator.sendAndReceive(
            rule, REMOVE_FLOW_ENTRY, SERIALIZER::encode, SERIALIZER::decode, master),
        FLOW_RULE_STORE_TIMEOUT_MILLIS,
        TimeUnit.MILLISECONDS,
        RuntimeException.class);
  }