private void processIQ(IQ iq) { long start = System.currentTimeMillis(); Element childElement = iq.getChildElement(); String namespace = childElement.getNamespaceURI(); // 构造返回dom IQ reply = IQ.createResultIQ(iq); Element childElementCopy = childElement.createCopy(); reply.setChildElement(childElementCopy); if (XConstants.PROTOCOL_DISCO_INFO.equals(namespace)) { generateDisco(childElementCopy); // 构造disco反馈信息 if (LOG.isInfoEnabled()) { LOG.info( "[spend time:{}ms],reqId: {},IRComponent服务发现,response:{}", System.currentTimeMillis() - start, iq.getID(), reply.toXML()); } } try { ComponentManagerFactory.getComponentManager().sendPacket(this, reply); } catch (Throwable t) { LOG.error( "[spend time:{}ms],reqId: {},IRComponent IQ处理异常! iq:{},replay:{}", System.currentTimeMillis() - start, iq.getID(), reply.toXML(), t); } }
public String getRelatedNodeForRemotePacket(IQ packet) { String id = null; if (nodeMap.containsKey(packet.getID())) { id = (String) nodeMap.get(packet.getID()); nodeMap.remove(packet.getID()); } return id; }
public void passResponseToRequester(IQ packet) throws Exception { if (!sentRemotePackets.containsKey(packet.getID())) { throw new UnknownFederatedPacketException( "Can not find original requesting packet! (ID:" + packet.getID() + ")"); } String uniqueId = packet.getID(); packet.setID(idMap.get(uniqueId)); packet.setTo((JID) sentRemotePackets.get(uniqueId)); packet.setFrom(localServer); sentRemotePackets.remove(packet.getID()); idMap.remove(uniqueId); component.sendPacket(packet); }
public void receivedAnswer(IQ packet) { String packetId = packet.getID(); if (isValid(packet)) { // The packet was validated, so it can be added to the Entity // Capabilities cache map. // Add the resolved identities and features to the entity // EntityCapabilitiesManager.capabilities object and add it // to the cache map... EntityCapabilities caps = verAttributes.get(packetId); // Store identities. List<String> identities = getIdentitiesFrom(packet); for (String identity : identities) { caps.addIdentity(identity); } // Store features. List<String> features = getFeaturesFrom(packet); for (String feature : features) { caps.addFeature(feature); } entityCapabilitiesMap.put(caps.getVerAttribute(), caps); entityCapabilitiesUserMap.put(packet.getFrom(), caps.getVerAttribute()); } // Remove cached 'ver' attribute. verAttributes.remove(packetId); }
@Override public IQ query(Component component, IQ packet, long timeout) throws ComponentException { final LinkedBlockingQueue<IQ> answer = new LinkedBlockingQueue<>(8); XMPPServer.getInstance() .getIQRouter() .addIQResultListener( packet.getID(), new IQResultListener() { @Override public void receivedAnswer(IQ packet) { answer.offer(packet); } @Override public void answerTimeout(String packetId) { Log.warn( "An answer to a previously sent IQ stanza was never received. Packet id: " + packetId); } }); sendPacket(component, packet); IQ reply = null; try { reply = answer.poll(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { // Ignore } return reply; }
public void process(Presence packet) { // Ignore unavailable presences if (Presence.Type.unavailable == packet.getType()) { return; } // Examine the packet and check if it has caps info, // if not -- do nothing by returning. Element capsElement = packet.getChildElement("c", "http://jabber.org/protocol/caps"); if (capsElement == null) { return; } // Examine the packet and check if it's in legacy format (pre version 1.4 // of XEP-0115). If so, do nothing by returning. // TODO: if this packet is in legacy format, we SHOULD check the 'node', // 'ver', and 'ext' combinations as specified in the archived version // 1.3 of the specification, and cache the results. See JM-1447 final String hashAttribute = capsElement.attributeValue("hash"); if (hashAttribute == null || hashAttribute.trim().length() == 0) { return; } // Examine the packet and check if it has and a 'ver' hash // if not -- do nothing by returning. final String newVerAttribute = capsElement.attributeValue("ver"); if (newVerAttribute == null || newVerAttribute.trim().length() == 0) { return; } // Check to see if the 'ver' hash is already in our cache. if (isInCapsCache(newVerAttribute)) { // The 'ver' hash is in the cache already, so let's update the // entityCapabilitiesUserMap for the user that sent the caps // packet. entityCapabilitiesUserMap.put(packet.getFrom(), newVerAttribute); } else { // The 'ver' hash is not in the cache so send out a disco#info query // so that we may begin recognizing this 'ver' hash. IQ iq = new IQ(IQ.Type.get); iq.setTo(packet.getFrom()); String serverName = XmppServer.getInstance().getServerInfo().getXMPPDomain(); iq.setFrom(serverName); iq.setChildElement("query", "http://jabber.org/protocol/disco#info"); String packetId = iq.getID(); final EntityCapabilities caps = new EntityCapabilities(); caps.setHashAttribute(hashAttribute); caps.setVerAttribute(newVerAttribute); verAttributes.put(packetId, caps); final IQRouter iqRouter = XmppServer.getInstance().getIQRouter(); iqRouter.addIQResultListener(packetId, this); iqRouter.route(iq); } }
/** * Determines whether or not the packet received from a disco#info result was valid by comparing * its 'ver' hash (identites+features encapsulated hash) with the 'ver' hash of the original caps * packet that the disco#info query was sent on behalf of. * * @param packet the disco#info result packet. * @return true if the packet's generated 'ver' hash matches the 'ver' hash of the original caps * packet. */ private boolean isValid(IQ packet) { final EntityCapabilities original = verAttributes.get(packet.getID()); if (original == null) { return false; } final String newVerHash = generateVerHash(packet, original.getHashAttribute()); return newVerHash.equals(original.getVerAttribute()); }
/** * Creates an error response for a given IQ request. * * @param request * @param message * @param condition * @param type * @return */ public static IQ createErrorResponse( final IQ request, final String message, Condition condition, Type type) { final IQ result = request.createCopy(); result.setID(request.getID()); result.setFrom(request.getTo()); result.setTo(request.getFrom()); PacketError e = new PacketError(condition, type); if (message != null) { e.setText(message); } result.setError(e); return result; }
/** * Sends an IQ packet to the Clearspace external component and returns the IQ packet returned by * CS or <tt>null</tt> if no answer was received before the specified timeout. * * @param packet IQ packet to send. * @param timeout milliseconds to wait before timing out. * @return IQ packet returned by Clearspace responsing the packet we sent. */ public IQ query(final IQ packet, int timeout) { // Complain if FROM is empty if (packet.getFrom() == null) { throw new IllegalStateException("IQ packets with no FROM cannot be sent to Clearspace"); } // If CS is not connected then return null if (clearspaces.isEmpty()) { return null; } // Set the target address to the IQ packet. Roate list so we distribute load String component; synchronized (clearspaces) { component = clearspaces.get(0); Collections.rotate(clearspaces, 1); } packet.setTo(component); final LinkedBlockingQueue<IQ> answer = new LinkedBlockingQueue<IQ>(8); final IQRouter router = XMPPServer.getInstance().getIQRouter(); router.addIQResultListener( packet.getID(), new IQResultListener() { public void receivedAnswer(IQ packet) { answer.offer(packet); } public void answerTimeout(String packetId) { Log.warn("No answer from Clearspace was received for IQ stanza: " + packet); } }); XMPPServer.getInstance().getIQRouter().route(packet); IQ reply = null; try { reply = answer.poll(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { // Ignore } return reply; }
@Override public void query(Component component, IQ packet, IQResultListener listener) throws ComponentException { XMPPServer.getInstance().getIQRouter().addIQResultListener(packet.getID(), listener); sendPacket(component, packet); }