Пример #1
0
  /**
   * Join the federation of the given name. This will find the channel with the same name as the
   * federation and connect to it. It will then attempt to mark this execution as a federate within
   * that channel (as opposed to just a regular member).
   *
   * <p>== Federate Names == A federation can optionally require that each federate have a unique
   * name (RID option). If this is not the case, Portico will always ensure that federates do have
   * unique names by modifying newly joining duplicates. If unique names are enforced and we try to
   * join with an existing name, an exception is thrown.
   *
   * <p>== FOM Modules == If there are additional FOM modules, we attempt a dry-run merge first to
   * identify any issues. Should that be successful, we join and then apply the changes to our local
   * copy of the FOM. The Role Call semantics that executes outside of the connection after we join
   * handles the job of dispersing the new module information to everyone else (who then also apply
   * them locally).
   */
  public ConnectedRoster joinFederation(JoinFederation joinMessage) throws Exception {
    // connect to the federation channel if we are not already
    Federation federation = findFederation(joinMessage.getFederationName());

    // validate that our FOM modules can be merged successfully with the existing FOM first
    logger.debug(
        "Validate that ["
            + joinMessage.getJoinModules().size()
            + "] modules can merge successfully with the existing FOM");
    ModelMerger.mergeDryRun(federation.getManifest().getFom(), joinMessage.getJoinModules());
    logger.debug("Modules can be merged successfully, continue with join");

    // tell the channel that we're joining the federation
    String joinedName = federation.sendJoinFederation(joinMessage.getFederateName(), this.lrc);

    // the joined name could be different from what we asked for, so update the request
    // to make sure it is correct
    joinMessage.setFederateName(joinedName);

    // now that we've joined a federation, store it here so we can route messages to it
    this.joinedFederation = federation;

    // We have to merge the FOMs together here before we return to the Join handler and
    // a RoleCall is sent out. We do this because although we receive our own RoleCall
    // notice (with the additional modules) we won't process it as we can't tell if it's
    // one we sent out because we joined (and thus need to merge) or because someone else
    // joined. Additional modules will only be present if it is a new join, so
    // we could figure it out that way, but that will cause redundant merges for the JVM
    // binding (as all connections share the same object model reference). To cater to the
    // specifics of this connection it's better to put the logic in the connection rather than
    // in the generic-to-all-connections RoleCallHandler. Long way of saying we need to merge
    // in the additional join modules that were provided here. F*** IT! WE'LL DO IT LIVE!
    if (joinMessage.getJoinModules().size() > 0) {
      logger.debug(
          "Merging "
              + joinMessage.getJoinModules().size()
              + " additional FOM modules that we receive with join request");

      ObjectModel fom = federation.getManifest().getFom();
      fom.unlock();
      federation.getManifest().setFom(ModelMerger.merge(fom, joinMessage.getJoinModules()));
      fom.lock();
    }

    // create and return the roster
    return new Roster(
        federation.getManifest().getLocalFederateHandle(),
        federation.getManifest().getFederateHandles(),
        federation.getManifest().getFom());
  }
Пример #2
0
  /**
   * Resign ourselves from the federation we are currently connected to. This will not disconnect us
   * from the channel, but will rather just mark us as no longer being a federate (only a channel
   * member).
   *
   * <p>An exception is thrown if any of the checks we run (such as whether we are infact even
   * connected to a federation at all!) fail.
   */
  public void resignFederation(ResignFederation resignMessage) throws Exception {
    // make sure we're joined to the federation
    if (joinedFederation == null
        || joinedFederation.getManifest().isLocalFederateJoined() == false) {
      throw new JFederateNotExecutionMember(
          "Federate ["
              + resignMessage.getFederateName()
              + "] not joined to ["
              + resignMessage.getFederationName()
              + "]");
    }

    // send out the resign notification
    joinedFederation.sendResignFederation(resignMessage);

    // all happy, as we're no longer joined, set out joined channel to null
    joinedFederation = null;
  }