
org.apache.servicemix.xmpp.XMPPReceiverEndpoint Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.servicemix.xmpp;
import org.apache.servicemix.common.endpoints.ConsumerEndpoint;
import org.apache.servicemix.xmpp.marshaler.XMPPMarshalerSupport;
import org.apache.servicemix.xmpp.marshaler.impl.DefaultXMPPMarshaler;
import org.jivesoftware.smack.AccountManager;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.proxy.ProxyInfo;
import org.jivesoftware.smackx.muc.MultiUserChat;
import javax.jbi.management.DeploymentException;
import javax.jbi.messaging.InOnly;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.MessagingException;
import javax.jbi.messaging.NormalizedMessage;
/**
* This endpoint receives XMPP messages and events and sends them as xml message into
* the NMR to the defined target
*
* @org.apache.xbean.XBean element="receiver"
*
* @author lhein
*/
public class XMPPReceiverEndpoint extends ConsumerEndpoint implements XMPPEndpointType, PacketListener {
private XMPPMarshalerSupport marshaler = new DefaultXMPPMarshaler();
private XMPPConnection connection;
private String host;
private int port = -1;
private String user;
private String password;
private String resource;
private String room;
private String proxyHost;
private String proxyPort;
private String proxyUser;
private String proxyPass;
private String proxyType;
private boolean login = true;
private PacketFilter filter;
private boolean createAccount;
private ConnectionConfiguration connectionConfig;
private ProxyInfo proxyInfo;
@Override
public void validate() throws DeploymentException {
super.validate();
if (this.host == null || this.host.trim().length() < 1) {
// invalid host name
throw new DeploymentException("Missing host name!");
}
if (this.port < 0) {
this.port = XMPPConstants.DEFAULT_XMPP_PORT;
}
}
@Override
public void start() throws Exception {
super.start();
// create a proxy info object if needed
if (this.proxyInfo == null && XMPPConstants.isSet(this.proxyHost)) {
ProxyInfo.ProxyType pType = null;
if (XMPPConstants.isSet(this.proxyType)) {
pType = ProxyInfo.ProxyType.valueOf(this.proxyType.toUpperCase());
}
this.proxyInfo = new ProxyInfo(pType,
this.proxyHost,
XMPPConstants.isSet(this.proxyPort) ? Integer.parseInt(this.proxyPort) : XMPPConstants.DEFAULT_PROXY_PORT,
this.proxyUser,
this.proxyPass);
}
// create the connection config
if (this.connectionConfig == null) {
if (this.proxyInfo != null) {
this.connectionConfig = new ConnectionConfiguration(this.host, this.port, this.proxyInfo);
} else {
this.connectionConfig = new ConnectionConfiguration(this.host, this.port);
}
this.connectionConfig.setCompressionEnabled(true);
this.connectionConfig.setReconnectionAllowed(true);
this.connectionConfig.setSASLAuthenticationEnabled(true);
}
if (this.connection == null) {
this.connection = new XMPPConnection(this.connectionConfig);
this.logger.debug("Connecting to server {}", this.host);
this.connection.connect();
}
if (this.login && !this.connection.isAuthenticated()) {
if (this.user != null) {
this.logger.debug("Logging into Jabber as user: {} on connection: {}", this.user, this.connection);
if (this.password == null) {
this.logger.warn("No password configured for user: {}", this.user);
}
if (this.createAccount) {
AccountManager accountManager = new AccountManager(this.connection);
accountManager.createAccount(this.user, this.password);
}
if (this.resource != null) {
this.connection.login(this.user, this.password, this.resource);
} else {
this.connection.login(this.user, this.password);
}
} else {
this.logger.debug("Logging in anonymously to Jabber on connection: {}", this.connection);
this.connection.loginAnonymously();
}
// now lets send a presence we are available
this.connection.sendPacket(new Presence(Presence.Type.available));
}
// now register listener for new packets
if (this.connection != null && this.connection.isConnected()) {
// if the user specified a chat room to join we do this here
if (this.room != null) {
MultiUserChat chatRoom = new MultiUserChat(this.connection, this.room);
chatRoom.join(this.user);
}
this.connection.addPacketListener(this, this.filter);
}
}
@Override
public void stop() throws Exception {
if (this.connection != null && this.connection.isConnected()) {
this.logger.debug("Disconnecting from server {}", this.host);
this.connection.disconnect();
this.connection = null;
}
super.stop();
}
@Override
public void process(MessageExchange exchange) throws Exception {
// only DONE and ERROR states will be received here and this
// endpoint is not interested in such messages at all
}
public void processPacket(Packet packet) {
if (packet instanceof Message == false ||
((Message)packet).getBody() == null) {
// we do only process messages for now, so skip it
return;
}
try {
InOnly exchange = getExchangeFactory().createInOnlyExchange();
NormalizedMessage in = exchange.createMessage();
configureExchangeTarget(exchange);
exchange.setInMessage(in);
this.marshaler.toJBI(in, packet);
getChannel().send(exchange);
} catch (MessagingException e) {
this.logger.error("Unable to send exchange for packet {}", packet.toXML(), e);
}
}
public XMPPMarshalerSupport getMarshaler() {
return marshaler;
}
/**
* With this method you can specify a marshaler class which provides the
* logic for converting an xmpp message into a normalized message. This class has
* to implement the interface XMPPMarshalerSupport
or another class which
* implements it. If you don't specify a marshaler, the
* DefaultXMPPMarshaler
will be used.
*
* @param marshaler
* a class which implements XMPPMarshalerSupport
*/
public void setMarshaler(XMPPMarshalerSupport marshaler) {
this.marshaler = marshaler;
}
public String getHost() {
return host;
}
/**
* With that method you can specify the host name of the XMPP server as
* hostname or ip address.
*
* @param host the hostname or ip address of the XMPP server
*/
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
/**
* This method will set the port number for the XMPP connection. If nothing
* is defined the default XMPP port number 5222 will be used.
*
* @param port the port number of the XMPP server
*/
public void setPort(int port) {
this.port = port;
}
public String getUser() {
return user;
}
/**
* This method if used to specify the user name to use for connecting to
* the XMPP server. It is not required that this user already exists but if
* not then the server should allow registration of new users and this user
* should not already exist with another password.
*
* @param user the name of the user to use for connecting. for example: joe
*/
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
/**
* This method sets the password for connecting to the XMPP server.
*
* @param password the password for connecting to the XMPP server
*/
public void setPassword(String password) {
this.password = password;
}
public String getResource() {
return resource;
}
/**
* Specify here the resource string to submit to the XMPP server. Usually you define
* the identifier of the XMPP client here.
*
* @param resource the resource identifier (for example: servicemix-xmpp)
*/
public void setResource(String resource) {
this.resource = resource;
}
public String getProxyHost() {
return proxyHost;
}
/**
* Here you can specify the hostname or ip address of a proxy to be used to connect
* to the XMPP server. If you don't define this no proxy is used.
*
* @param proxyHost the hostname or ip address of the proxy to use
*/
public void setProxyHost(String proxyHost) {
this.proxyHost = proxyHost;
}
public String getProxyPort() {
return proxyPort;
}
/**
* Here you can specify the port of the proxy server. If you do not define this the
* default port (3128) will be used.
*
* @param proxyPort the default proxy port number (default: 3128)
*/
public void setProxyPort(String proxyPort) {
this.proxyPort = proxyPort;
}
public String getProxyUser() {
return proxyUser;
}
/**
*
If your proxy needs authentication you can specify here the user name. Leave this
* undefined if your proxy does not need authentication.
*
* @param proxyUser the name of the user to authenticate with the proxy
*/
public void setProxyUser(String proxyUser) {
this.proxyUser = proxyUser;
}
public String getProxyPass() {
return proxyPass;
}
/**
* If your proxy needs authentication you can specify here the user password. Leave this
* undefined if your proxy does not need authentication.
*
* @param proxyPass the password of the user to authenticate with the proxy
*/
public void setProxyPass(String proxyPass) {
this.proxyPass = proxyPass;
}
public String getProxyType() {
return proxyType;
}
/**
* Here you can specify the type of proxy you have. Possible values are:
* NONE
, HTTP
, SOCKS4
, SOCKS5
*
* @param proxyType the type of proxy (NONE
, HTTP
, SOCKS4
, SOCKS5
)
*/
public void setProxyType(String proxyType) {
this.proxyType = proxyType;
}
public boolean isLogin() {
return login;
}
/**
*
Here you can specify if the user should login to the server or not. Not logging in means that endpoint
* itself will be created but it will be inactive.
*
* @param login a flag if the process should login to the XMPP account (true / false)
*/
public void setLogin(boolean login) {
this.login = login;
}
public PacketFilter getFilter() {
return filter;
}
/**
* Here you can define a PacketFilter
to use for filtering XMPP packets.
*
* @param filter a PacketFilter
to use for filtering XMPP packets
*/
public void setFilter(PacketFilter filter) {
this.filter = filter;
}
public boolean isCreateAccount() {
return createAccount;
}
/**
*
Specify here if you want to create an account for the user if
* the user is currently not existing on the XMPP server.
*
* @param createAccount flag if an account should be created if the user doesn't exist (true / false)
*/
public void setCreateAccount(boolean createAccount) {
this.createAccount = createAccount;
}
public String getRoom() {
return room;
}
/**
* Specify here an optional room to join. If set, the user
* will join that room and listens to messages there.
*
* @param room the room to join or null if no room should be joined
*/
public void setRoom(String room) {
this.room = room;
}
}