I have the method:
public HTTPResult get(String url) throws Exception{
try {
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
return new HTTPResult(response.getBody(), response.getStatusCode().value());
}
catch (ResourceAccessException e) {
String responseBody = e.getCause().getMessage();
JSONObject obj = new JSONObject(responseBody);
return new HTTPResult(obj.getString("responseBody"), Integer.parseInt(obj.getString("statusCode")));
}
}
I want to do unit testing for it and i am not sure how to proceed:
public class MockHttpServerTest {
private static final int PORT = 51234;
private static final String baseUrl = "http://localhost:" + PORT;
private MockHttpServer server;
private SimpleHttpResponseProvider responseProvider;
private HttpClient client;
#Before
public void setUp() throws Exception {
responseProvider = new SimpleHttpResponseProvider();
server = new MockHttpServer(PORT, responseProvider);
server.start();
client = new DefaultHttpClient();
}
I am getting RED for MockHttpServer & SimpleHttpResponseProvider which should be part of org.apache.wink.client.*; which i am importing. so why do i have red ones? is there some simple way to unit test it?
HTTPResult return me response code and message.
I want to send rcon command to server using java, to do this I'm using the following library https://github.com/Kronos666/rkon-core
When i run command like this
Rcon rcon = new Rcon("127.0.0.1", 27015, "mypassword".getBytes());
// Example: On a minecraft server this will list the connected players
String result = rcon.command("list");
// Display the result in the console
System.out.println(result);
My server show response in console Gc connection established from... and so on
but in java app i have the empty result, it's not null, it's just empty
String result = rcon.command("list");
How can i take response from server using rcon protocol?
Try this:
try {
Rcon rcon = new Rcon("127.0.0.1", 27015, "mypassword".getBytes());
String result = rcon.command("list");
System.out.println(result);
} catch (AuthenticationException e) {
String result = "Authentication failed";
}
Finally I write my own implementation:
public final class RconClient implements AutoCloseable {
private static final int MAX_SIZE = 4096;
private final Socket socket;
private final RconData data;
private static final Logger LOG = LoggerFactory.getLogger(RconClient.class);
#SuppressWarnings("ConstructorShouldNotThrowExceptions")
public RconClient(final String host,
final int port,
final byte[] password) throws IOException {
this.socket = new Socket(host, port);
final RconData requst = request(new RconData(RconData.AUTH, password));
if (requst.getId() == -1) {
LOG.error("Wrong password or ip to connect to rcon");
throw new LoginException(host, port);
}
this.data = read();
}
public String command(String command) throws IOException {
command = "get5_status";
final RconData response = request(new RconData(command.getBytes()));
return new String(response.getPayload(), Charset.forName("UTF-8"));
}
public RconData request(RconData packet) throws IOException {
try {
write(packet);
return read();
} catch (final SocketException exception) {
socket.close();
throw exception;
}
}
private void write(RconData packet) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(packet.getPayload().length + 14);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.putInt(packet.getPayload().length + 10);
buffer.putInt(packet.getId());
buffer.putInt(packet.getType());
buffer.put(packet.getPayload());
buffer.put((byte)0);
buffer.put((byte)0);
socket.getOutputStream().write(buffer.array());
socket.getOutputStream().flush();
}
private RconData read() throws IOException {
byte[] packet = new byte[MAX_SIZE];
int packetSize = this.socket.getInputStream().read(packet);
ByteBuffer buffer = ByteBuffer.wrap(packet, 0, packetSize);
buffer.order(ByteOrder.LITTLE_ENDIAN);
if (buffer.remaining() < 4) {
throw new WrongPacketException();
}
int size = buffer.getInt();
if (buffer.remaining() < size) {
throw new WrongPacketException();
}
int id = buffer.getInt();
int type = buffer.getInt();
byte[] payload = new byte[size - 10];
buffer.get(payload);
buffer.get(new byte[2]);
return new RconData(id, type, payload);
}
#Override
public void close() throws IOException {
this.socket.close();
}
}
Where RconData it's simple POJO with byte[] password property,
I'm using KSOAP2, when sending request to the server and got java.io.IOException: HTTP request failed, HTTP status: 500 in the line httpTransport.call(SOAP_ACTION, envelope) , but server works, I have checked it using SoapUI. What can be the problem?
public class SOAPClient
{
private static final int TIMEOUT_SOCKET = 180000;
public static SoapObject get(Context context, String methodName, ArrayList<Pair<String, ?>> args) throws Exception
{
final String URL = PrefHelper.getSOAPUrl(context);
final String NAMESPACE = PrefHelper.getSOAPNamespace(context);
final String SOAP_ACTION = methodName; //NAMESPACE + "#" + "mapx" + ":" + methodName;
SoapObjectEve request = new SoapObjectEve(NAMESPACE, methodName);
if (args != null) {
for (Pair<String, ?> arg : args) {
if (arg.first != null) {
request.addProperty(arg.first, arg.second);
}
}
}
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
new MarshalBase64().register(envelope);
envelope.setOutputSoapObject(request);
envelope.implicitTypes = true;
HttpTransportSE httpTransport = new HttpTransportSE(URL, TIMEOUT_SOCKET);
httpTransport.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
try
{
httpTransport.call(SOAP_ACTION, envelope);
AppLog.e(httpTransport.requestDump+"requestDump");
}
catch (ConnectTimeoutException e) {
AppLog.e(e.getMessage());
throw new Exception(context.getString(R.string.node_unavailable));
}
catch (SocketTimeoutException e) {
AppLog.e(e.getMessage());
throw new Exception(context.getString(R.string.timeout));
}
catch (Exception e) {
e.printStackTrace();
AppLog.e(e.getMessage());
AppLog.e(httpTransport.requestDump+"requestDump");
throw new Exception(context.getString(R.string.warning_error_get_data) + e.getMessage() == null ? "" : " " + e.getMessage());
}
AppLog.i(httpTransport.requestDump+"requestDump");
SoapObject soapObj = null;
try {
soapObj = (SoapObject) envelope.getResponse();
}
catch (Exception e) {
String response = ((SoapPrimitive) envelope.getResponse()).toString();
boolean res = Boolean.valueOf(response);
soapObj = new SoapObject();
soapObj.addProperty("response", res);
soapObj.addProperty("msg", "");
soapObj.addProperty("data", null);
}
AppLog.e(httpTransport.responseDump+"responseDump");
return soapObj;
}
}
Make sure your NAMESPACE, METHODNAME, WSDL and SOAP_ACTION are correct.
Try this code,
private static final String NAMESPACE = "http://www.kltro.com";
private static final String METHODNAME = "getUser";
private static final String WSDL = "http://ap.kashkan.org:55555/tro/ws/kltro";
private static final String SOAP_ACTION = NAMESPACE + "#kltro:" + METHODNAME ;
private static String TAG = "soap";
public static String callWebservice() {
String responseDump = "";
try {
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
SoapObject request = new SoapObject(NAMESPACE, METHODNAME);
request.addProperty("login", login);
request.addProperty("pass", password);
request.addProperty("androidID", androidID);
request.addProperty("ver", version);
envelope.bodyOut = request;
HttpTransportSE transport = new HttpTransportSE(WSDL);
transport.debug = true;
try {
transport.call(SOAP_ACTION, envelope);
String requestDump = transport.requestDump;
responseDump = transport.responseDump;
Log.e(TAG, requestDump);
Log.e(TAG, responseDump);
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return responseDump;
}
Also make sure you have internet permission in the manifest,
<uses-permission android:name="android.permission.INTERNET" />
//Back end
#Path("/travelgood")
public class TravelgoodResource {
#POST
#Path("/{bookingNo}/{name}/{number}/{expMonth}/{expYear}")
public boolean bookingFlight(#PathParam("bookingNo") String bookingNo, #PathParam("name") String name, #PathParam("number") String number, #PathParam("expMonth") String expMonth, #PathParam("expYear") String expYear) {
ws.tg.BookType booking = new ws.tg.BookType();
booking.setBookingnumber(Integer.parseInt(bookingNo));
CreditCardInfoType cci = new CreditCardInfoType();
cci.setName(name);
cci.setNumber(number);
CreditCardInfoType.ExpirationDate ed = new CreditCardInfoType.ExpirationDate();
ed.setYear(Integer.parseInt(expYear));
ed.setMonth(Integer.parseInt(expMonth));
cci.setExpirationDate(ed);
booking.setCreditcardinformation(cci);
boolean myBooking = false;
try {
myBooking = bookFlight(booking);
} catch (BookFault ex) {
Logger.getLogger(TravelgoodResource.class.getName()).log(Level.SEVERE, null, ex);
}
return myBooking;
}
private static boolean bookFlight(ws.tg.BookType input2) throws BookFault {
ws.tg.Lameduck2Service service = new ws.tg.Lameduck2Service();
ws.tg.Lameduck2PortType port = service.getLameduck2PortTypeBindingPort();
return port.bookFlight(input2);
}
}
//TEST CLASS (Client)
public class TravelGoodRESTTest {
Client client = Client.create();
#Test
public void TestbookFlight() {
WebResource r = client.resource("htttp://localhost:8080/tg/webresources/travelgood/1/Donovan%20Jasper/50408818/6/9");
System.out.println("testBookFlight: "+r.post(String.class));
}
}
When running a Unit test it gives me the following error:
Caused an ERROR: POST htttp://localhost/8080/tg/webresources/travelgood/1/Donovan%20Jasper/50408818/6/9 returned a response status of 500 internal server error
I have tried all the things to connect Facebook with XMPP but i have faced only
one error all the time which is :
SASL authentication failed using mechanism DIGEST-MD5 I am implementing following method to perform this task :
public class MySASLDigestMD5Mechanism extends SASLMechanism {
public MySASLDigestMD5Mechanism(SASLAuthentication saslAuthentication) {
super(saslAuthentication);
}
protected void authenticate() throws IOException, XMPPException {
String[] mechanisms = { getName() };
Map<String, String> props = new HashMap<String, String>();
sc = Sasl.createSaslClient(mechanisms, null, "xmpp", hostname, props, this);
super.authenticate();
}
public void authenticate(String username, String host, String password) throws IOException, XMPPException {
this.authenticationId = username;
this.password = password;
this.hostname = host;
String[] mechanisms = { getName() };
Map<String,String> props = new HashMap<String,String>();
sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, this);
super.authenticate();
}
public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException {
String[] mechanisms = { getName() };
Map<String,String> props = new HashMap<String,String>();
sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, (org.apache.harmony.javax.security.auth.callback.CallbackHandler) cbh);
super.authenticate();
}
protected String getName() {
return "DIGEST-MD5";
}
/*public void challengeReceived1(String challenge) throws IOException {
// Build the challenge response stanza encoding the response text
StringBuilder stanza = new StringBuilder();
byte response[];
if (challenge != null) {
response = sc.evaluateChallenge(Base64.decode(challenge));
} else {
response = sc.evaluateChallenge(null);
}
String authenticationText="";
if (response != null) { // fix from 3.1.1
authenticationText = Base64.encodeBytes(response, Base64.DONT_BREAK_LINES);
if (authenticationText.equals("")) {
authenticationText = "=";
}
}
stanza.append("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
stanza.append(authenticationText);
stanza.append("</response>");
// Send the authentication to the server
getSASLAuthentication().send(stanza.toString());
}*/
public void challengeReceived(String challenge)
throws IOException {
byte response[];
if (challenge != null) {
response = sc.evaluateChallenge(Base64.decode(challenge));
} else {
response = sc.evaluateChallenge(new byte[0]);
}
Packet responseStanza;
if (response == null) {
responseStanza = new Response();
} else {
responseStanza = new Response(Base64.encodeBytes(response, Base64.DONT_BREAK_LINES));
}
getSASLAuthentication().send(responseStanza);
}
}
And Connection Function is :
try{
SASLAuthentication.registerSASLMechanism("DIGEST-MD5",MySASLDigestMD5Mechanism. class);
ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com",5222);
config.setSASLAuthenticationEnabled(true);
config.setRosterLoadedAtLogin (true);
connection = new XMPPConnection(config);
connection.connect();
Log.d("Connect...", "Afetr Connect");
connection.login("username#chat.facebook.com", "password");
Log.d("done","XMPP client logged in");
}
catch(XMPPException ex)
{
Log.d("not done","in catchhhhhhhhh");
System.out.println(ex.getMessage ());
connection.disconnect();
}
}
but "After connect" it gone to the ctach and give me error like :
SASL authentication failed using mechanism DIGEST-MD5
I searched all blog and find same thing but i dont know what am i doing wrong here..
If is there any other way or solution to connect Facebook XMPP then please Help me
ASAP
Finally, thanks to the no.good.at.coding code and the suggestion of harism, I've been able to connect to the Facebook chat. This code is the Mechanism for the Asmack library (the Smack port for Android). For the Smack library is necessary to use the no.good.at.coding mechanism.
SASLXFacebookPlatformMechanism.java:
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import org.apache.harmony.javax.security.auth.callback.CallbackHandler;
import org.apache.harmony.javax.security.sasl.Sasl;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.sasl.SASLMechanism;
import org.jivesoftware.smack.util.Base64;
public class SASLXFacebookPlatformMechanism extends SASLMechanism
{
private static final String NAME = "X-FACEBOOK-PLATFORM";
private String apiKey = "";
private String applicationSecret = "";
private String sessionKey = "";
/** * Constructor. */
public SASLXFacebookPlatformMechanism(SASLAuthentication saslAuthentication)
{
super(saslAuthentication);
}
#Override
protected void authenticate() throws IOException, XMPPException
{
getSASLAuthentication().send(new AuthMechanism(NAME, ""));
}
#Override
public void authenticate(String apiKeyAndSessionKey, String host, String applicationSecret) throws IOException, XMPPException
{
if (apiKeyAndSessionKey == null || applicationSecret == null)
{
throw new IllegalArgumentException("Invalid parameters");
}
String[] keyArray = apiKeyAndSessionKey.split("\\|", 2);
if (keyArray.length < 2)
{
throw new IllegalArgumentException( "API key or session key is not present"); }
this.apiKey = keyArray[0];
this.applicationSecret = applicationSecret;
this.sessionKey = keyArray[1];
this.authenticationId = sessionKey;
this.password = applicationSecret;
this.hostname = host;
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props,this);
authenticate();
}
#Override
public void authenticate(String username, String host, CallbackHandler cbh)throws IOException, XMPPException
{
String[] mechanisms = { "DIGEST-MD5" };
Map<String, String> props = new HashMap<String, String>();
this.sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props,cbh);
authenticate();
} #Override protected String getName()
{
return NAME;
}
#Override
public void challengeReceived(String challenge) throws IOException
{
byte[] response = null;
if (challenge != null)
{
String decodedChallenge = new String(Base64.decode(challenge));
Map<String, String> parameters = getQueryMap(decodedChallenge);
String version = "1.0";
String nonce = parameters.get("nonce");
String method = parameters.get("method");
long callId = new GregorianCalendar().getTimeInMillis();
String sig = "api_key=" + apiKey + "call_id=" + callId + "method=" + method + "nonce=" + nonce + "session_key=" + sessionKey + "v=" + version + applicationSecret;
try
{
sig = md5(sig);
}
catch (NoSuchAlgorithmException e)
{
throw new IllegalStateException(e);
}
String composedResponse = "api_key=" + URLEncoder.encode(apiKey, "utf-8") + "&call_id=" + callId + "&method="+ URLEncoder.encode(method, "utf-8") + "&nonce="+ URLEncoder.encode(nonce, "utf-8")+ "&session_key="+ URLEncoder.encode(sessionKey, "utf-8") + "&v="+ URLEncoder.encode(version, "utf-8") + "&sig="+ URLEncoder.encode(sig, "utf-8");response = composedResponse.getBytes("utf-8");
}
String authenticationText = "";
if (response != null)
{
authenticationText = Base64.encodeBytes(response, Base64.DONT_BREAK_LINES);
}
// Send the authentication to the server
getSASLAuthentication().send(new Response(authenticationText));
}
private Map<String, String> getQueryMap(String query)
{
Map<String, String> map = new HashMap<String, String>();
String[] params = query.split("\\&");
for (String param : params)
{
String[] fields = param.split("=", 2);
map.put(fields[0], (fields.length > 1 ? fields[1] : null));
}
return map;
}
private String md5(String text) throws NoSuchAlgorithmException,UnsupportedEncodingException
{
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(text.getBytes("utf-8"), 0, text.length());
return convertToHex(md.digest());
}
private String convertToHex(byte[] data)
{
StringBuilder buf = new StringBuilder();
int len = data.length;
for (int i = 0; i < len; i++)
{
int halfByte = (data[i] >>> 4) & 0xF;
int twoHalfs = 0;
do
{
if (0 <= halfByte && halfByte <= 9)
{
buf.append((char) ('0' + halfByte));
}
else
{
buf.append((char) ('a' + halfByte - 10));
}
halfByte = data[i] & 0xF;
}
while (twoHalfs++ < 1);
}
return buf.toString();
}
}
To use it:
ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com", 5222);
config.setSASLAuthenticationEnabled(true);
XMPPConnection xmpp = new XMPPConnection(config);
try
{
SASLAuthentication.registerSASLMechanism("X-FACEBOOK-PLATFORM", SASLXFacebookPlatformMechanism.class);
SASLAuthentication.supportSASLMechanism("X-FACEBOOK-PLATFORM", 0);
xmpp.connect();
xmpp.login(apiKey + "|" + sessionKey, sessionSecret, "Application");
}
catch (XMPPException e)
{
xmpp.disconnect();
e.printStackTrace();
}
apiKey is the API key given in the application settings page in Facebook. sessionKey is the second part of the access token. If the token is in this form, AAA|BBB|CCC, the BBB is the session key. sessionSecret is obtained using the old REST API with the method auth.promoteSession. To use it, it's needed to make a Http get to this url:
https://api.facebook.com/method/auth.promoteSession?access_token=yourAccessToken
Despite of the Facebook Chat documentation says that it's needed to use your application secret key, only when I used the key that returned that REST method I was able to make it works. To make that method works, you have to disable the Disable Deprecated Auth Methods option in the Advance tab in your application settings.
I solved this problem. I find solution that http://community.igniterealtime.org/thread/41080
Jerry Magill wrote this...
import java.io.IOException;
import java.util.HashMap;
import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.Sasl;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.sasl.SASLMechanism;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.util.Base64;
public class MySASLDigestMD5Mechanism extends SASLMechanism
{
public MySASLDigestMD5Mechanism(SASLAuthentication saslAuthentication)
{
super(saslAuthentication);
}
protected void authenticate()
throws IOException, XMPPException
{
String mechanisms[] = {
getName()
};
java.util.Map props = new HashMap();
sc = Sasl.createSaslClient(mechanisms, null, "xmpp", hostname, props, this);
super.authenticate();
}
public void authenticate(String username, String host, String password)
throws IOException, XMPPException
{
authenticationId = username;
this.password = password;
hostname = host;
String mechanisms[] = {
getName()
};
java.util.Map props = new HashMap();
sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, this);
super.authenticate();
}
public void authenticate(String username, String host, CallbackHandler cbh)
throws IOException, XMPPException
{
String mechanisms[] = {
getName()
};
java.util.Map props = new HashMap();
sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, cbh);
super.authenticate();
}
protected String getName()
{
return "DIGEST-MD5";
}
public void challengeReceived(String challenge)
throws IOException
{
//StringBuilder stanza = new StringBuilder();
byte response[];
if(challenge != null)
response = sc.evaluateChallenge(Base64.decode(challenge));
else
//response = sc.evaluateChallenge(null);
response = sc.evaluateChallenge(new byte[0]);
//String authenticationText = "";
Packet responseStanza;
//if(response != null)
//{
//authenticationText = Base64.encodeBytes(response, 8);
//if(authenticationText.equals(""))
//authenticationText = "=";
if (response == null){
responseStanza = new Response();
} else {
responseStanza = new Response(Base64.encodeBytes(response,Base64.DONT_BREAK_LINES));
}
//}
//stanza.append("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
//stanza.append(authenticationText);
//stanza.append("</response>");
//getSASLAuthentication().send(stanza.toString());
getSASLAuthentication().send(responseStanza);
}
}
It is then called thus from the JabberSmackAPI:
public void login(String userName, String password) throws XMPPException
{
SASLAuthentication.registerSASLMechanism("DIGEST-MD5",MySASLDigestMD5Mechanism. class);
ConnectionConfiguration config = new ConnectionConfiguration("chat.facebook.com",5222);
config.setSASLAuthenticationEnabled(true);
config.setRosterLoadedAtLogin (true);
connection = new XMPPConnection(config);
connection.connect();
connection.login(userName, password);
}