@Test
  public void testPassingValidSubscriptionSendsOutExpectedNotifications() throws Exception {

    IQ request =
        toIq(
            readStanzaAsString("/iq/pubsub/subscribe/authorizationPendingGrantReply.stanza")
                .replaceFirst("subscription='subscribed'", "subscription='subscribed'"));

    NodeAffiliation subscriptionMockActor = Mockito.mock(NodeAffiliation.class);
    Mockito.when(subscriptionMockActor.getAffiliation()).thenReturn(Affiliations.owner);

    NodeSubscription subscriptionMockSubscriber = Mockito.mock(NodeSubscription.class);
    Mockito.when(subscriptionMockSubscriber.getSubscription()).thenReturn(Subscriptions.subscribed);

    Mockito.when(dataStore.nodeExists(node)).thenReturn(true);
    Mockito.when(dataStore.getUserAffiliation(node, jid)).thenReturn(subscriptionMockActor);

    Mockito.when(dataStore.getUserSubscription(node, new JID(subscriber)))
        .thenReturn(subscriptionMockSubscriber);

    event.setChannelManager(dataStore);

    ArrayList<NodeSubscription> subscribers = new ArrayList<NodeSubscription>();
    subscribers.add(new NodeSubscriptionMock(new JID("*****@*****.**")));
    subscribers.add(new NodeSubscriptionMock(new JID("*****@*****.**")));

    Mockito.doReturn(new ResultSetImpl<NodeSubscription>(subscribers))
        .when(dataStore)
        .getNodeSubscriptionListeners(Mockito.anyString());

    event.setChannelManager(dataStore);
    event.process(element, jid, request, null);

    Assert.assertEquals(2, queue.size());
    Packet notification = queue.poll(100, TimeUnit.MILLISECONDS);
    Assert.assertEquals("*****@*****.**", notification.getTo().toString());
    notification = queue.poll(100, TimeUnit.MILLISECONDS);
    Assert.assertEquals("*****@*****.**", notification.getTo().toString());

    Assert.assertEquals(
        node,
        notification.getElement().element("event").element("subscription").attributeValue("node"));
    Assert.assertTrue(notification.toXML().contains(JabberPubsub.NS_PUBSUB_EVENT));
    Assert.assertEquals(
        "subscribed",
        notification
            .getElement()
            .element("event")
            .element("subscription")
            .attributeValue("subscription"));
    Assert.assertEquals(
        subscriber,
        notification.getElement().element("event").element("subscription").attributeValue("jid"));
  }
Example #2
0
 /**
  * Make sure that the received packet has a TO and FROM values defined and that it was sent from a
  * previously validated domain. If the packet does not matches any of the above conditions then a
  * PacketRejectedException will be thrown.
  *
  * @param packet the received packet.
  * @throws PacketRejectedException if the packet does not include a TO or FROM or if the packet
  *     was sent from a domain that was not previously validated.
  */
 private void packetReceived(Packet packet) throws PacketRejectedException {
   if (packet.getTo() == null || packet.getFrom() == null) {
     Log.debug(
         "Closing IncomingServerSession due to packet with no TO or FROM: " + packet.toXML());
     // Send a stream error saying that the packet includes no TO or FROM
     StreamError error = new StreamError(StreamError.Condition.improper_addressing);
     connection.deliverRawText(error.toXML());
     // Close the underlying connection
     connection.close();
     open = false;
     throw new PacketRejectedException("Packet with no TO or FROM attributes");
   } else if (!((IncomingServerSession) session).isValidDomain(packet.getFrom().getDomain())) {
     Log.debug(
         "Closing IncomingServerSession due to packet with invalid domain: " + packet.toXML());
     // Send a stream error saying that the packet includes an invalid FROM
     StreamError error = new StreamError(StreamError.Condition.invalid_from);
     connection.deliverRawText(error.toXML());
     // Close the underlying connection
     connection.close();
     open = false;
     throw new PacketRejectedException("Packet with no TO or FROM attributes");
   }
 }
 /**
  * Processes packets that were sent to this service. Currently only packets that were sent from
  * registered components are being processed. In the future, we may also process packet of trusted
  * clients. Trusted clients may be able to execute ad-hoc commands such as adding or removing
  * components.
  *
  * @param packet the packet to process.
  */
 @Override
 public void process(Packet packet) throws PacketException {
   List<Component> components = getComponents(packet.getFrom());
   // Only process packets that were sent by registered components
   if (!components.isEmpty()) {
     if (packet instanceof IQ && IQ.Type.result == ((IQ) packet).getType()) {
       IQ iq = (IQ) packet;
       Element childElement = iq.getChildElement();
       if (childElement != null) {
         String namespace = childElement.getNamespaceURI();
         if ("http://jabber.org/protocol/disco#info".equals(namespace)) {
           // Add a disco item to the server for the component that supports disco
           Element identity = childElement.element("identity");
           if (identity == null) {
             // Do nothing since there are no identities in the disco#info packet
             return;
           }
           try {
             XMPPServer.getInstance()
                 .getIQDiscoItemsHandler()
                 .addComponentItem(packet.getFrom().toBareJID(), identity.attributeValue("name"));
             for (Component component : components) {
               if (component instanceof ComponentSession.ExternalComponent) {
                 ComponentSession.ExternalComponent externalComponent =
                     (ComponentSession.ExternalComponent) component;
                 externalComponent.setName(identity.attributeValue("name"));
                 externalComponent.setType(identity.attributeValue("type"));
                 externalComponent.setCategory(identity.attributeValue("category"));
               }
             }
           } catch (Exception e) {
             Log.error(
                 "Error processing disco packet of components: "
                     + components
                     + " - "
                     + packet.toXML(),
                 e);
           }
           // Store the IQ disco#info returned by the component
           addComponentInfo(iq);
           // Notify listeners that a component answered the disco#info request
           notifyComponentInfo(iq);
           // Alert other cluster nodes
           CacheFactory.doClusterTask(new NotifyComponentInfo(iq));
         }
       }
     }
   }
 }
Example #4
0
  public void deliver(Packet packet) throws UnauthorizedException {
    if (isClosed()) {
      // OF-857: Do not allow the backup deliverer to recurse
      if (backupDeliverer == null) {
        Log.error("Failed to deliver packet: " + packet.toXML());
        throw new IllegalStateException("Connection closed");
      }
      // attempt to deliver via backup only once
      PacketDeliverer backup = backupDeliverer;
      backupDeliverer = null;
      backup.deliver(packet);
    } else {
      boolean errorDelivering = false;
      IoBuffer buffer = IoBuffer.allocate(4096);
      buffer.setAutoExpand(true);
      try {
        // OF-464: if the connection has been dropped, fail over to backupDeliverer (offline)
        if (!ioSession.isConnected()) {
          throw new IOException("Connection reset/closed by peer");
        }
        XMLWriter xmlSerializer =
            new XMLWriter(new ByteBufferWriter(buffer, encoder.get()), new OutputFormat());
        xmlSerializer.write(packet.getElement());
        xmlSerializer.flush();
        if (flashClient) {
          buffer.put((byte) '\0');
        }
        buffer.flip();

        ioSessionLock.lock();
        try {
          ioSession.write(buffer);
        } finally {
          ioSessionLock.unlock();
        }
      } catch (Exception e) {
        Log.debug("Error delivering packet:\n" + packet, e);
        errorDelivering = true;
      }
      if (errorDelivering) {
        close();
        // Retry sending the packet again. Most probably if the packet is a
        // Message it will be stored offline
        backupDeliverer.deliver(packet);
      } else {
        session.incrementServerPacketCount();
      }
    }
  }
 private void extractNodeDetails(Packet packet) {
   try {
     String packetXml = packet.toXML();
     if (!packetXml.contains("node=")) {
       return;
     }
     nodeMap.put(packet.getID(), packetXml.split("node=\"")[1].split("\"")[0]);
   } catch (NullPointerException e) {
     logger.info("No node details found in federated packet");
     logger.error(e);
   } catch (ArrayIndexOutOfBoundsException e) {
     logger.info("Error extracting node information from federated packet");
     logger.error(e);
   }
 }
Example #6
0
  /* @see org.xmpp.component.Component#processPacket(org.xmpp.packet.Packet) */
  public void processPacket(Packet packet) {
    try {
      debug("Service.processPacket: %s", packet.toXML());
      List<Packet> replies = null;
      if (packet instanceof IQ) replies = processIQ((IQ) packet);
      else if (packet instanceof Presence) replies = processPresence((Presence) packet);
      else if (packet instanceof Message) replies = processMessage((Message) packet);
      else {
        debug("ignoring unknown packet: %s", packet);
      }

      if (replies != null) for (Packet p : replies) send(p);
    } catch (Exception e) {
      Log.error("Interop:" + getName() + " - exception in processPacket", e);
    }
  }
  public void process(Packet packet) throws ComponentException {

    logger.debug("Packet payload " + packet.toXML() + " going to federation.");

    String to = packet.getTo().toString();

    String uniqueId = generateUniqueId(packet);
    idMap.put(uniqueId, packet.getID());
    packet.setID(uniqueId);

    sentRemotePackets.put(uniqueId, packet.getFrom());
    try {
      extractNodeDetails(packet);
      // Do we have a map already?
      if (discoveredServers.containsKey(to)) {
        packet.setTo(new JID(discoveredServers.get(to)));
        sendPacket(packet.createCopy());
        return;
      }
      // Are we already discovering a remote server?
      if (!remoteChannelDiscoveryStatus.containsKey(to)) {
        discoverRemoteChannelServer(to, packet.getID());
      } else if (remoteChannelDiscoveryStatus.get(to).equals(NO_CHANNEL_SERVER)) {
        logger.error("No remote channel server for " + to);
        IQ reply = IQ.createResultIQ((IQ) packet);
        reply.setError(
            new PacketError(
                PacketError.Condition.remote_server_not_found, PacketError.Type.cancel));
        component.sendPacket(reply);
        return;
      }
      // Add packet to list
      if (!waitingStanzas.containsKey(to)) {
        waitingStanzas.put(to, new ArrayList<Packet>());
      }
      waitingStanzas.get(to).add(packet);
      logger.debug(
          "Adding packet to waiting stanza list for "
              + to
              + " (size "
              + waitingStanzas.get(to).size()
              + ")");
    } catch (Exception e) {
      logger.error(e);
    }
  }