blob: 134315c73d40537aad3a393a74619cf7a091e8b8 [file] [log] [blame]
/*
* 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 flex.messaging.io.amf.client;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import flex.messaging.util.TestServerWrapper;
import junit.extensions.TestSetup;
import org.junit.Assert;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import amfclient.ClientCustomType;
import flex.messaging.MessageException;
import flex.messaging.messages.RemotingMessage;
import flex.messaging.io.amf.ASObject;
import flex.messaging.io.amf.AmfTrace;
import flex.messaging.io.amf.client.AMFConnection.HttpResponseInfo;
import flex.messaging.io.amf.client.exceptions.ClientStatusException;
import flex.messaging.io.amf.client.exceptions.ServerStatusException;
import flex.messaging.io.MessageIOConstants;
/**
* JUnit tests for AMFConnection. Note that most of the tests require a running
* server with the specified destination.
*/
public class AMFConnectionIT extends TestCase
{
private static final String DEFAULT_DESTINATION_ID = "amfConnectionTestService";
private static final String DEFAULT_METHOD_NAME = "echoString";
private static final String DEFAULT_METHOD_ARG = "echo me";
private static final String DEFAULT_URL = "http://localhost:%s/qa-regress/messagebroker/amf";
private static final String DEFAULT_AMF_OPERATION = getOperationCall(DEFAULT_METHOD_NAME);
private static final String FOO_STRING = "foo";
private static final String BAR_STRING = "bar";
private static final String UNEXPECTED_EXCEPTION_STRING = "Unexpected exception: ";
private static TestServerWrapper serverWrapper;
private static int serverPort;
/**
* Given a remote method name, returns the AMF connection call needed using
* the default destination id.
*/
private static String getOperationCall(String method)
{
return DEFAULT_DESTINATION_ID + "." + method;
}
protected String getConnectionUrl() {
return String.format(DEFAULT_URL, serverPort);
}
public AMFConnectionIT(String name)
{
super(name);
}
public static Test suite()
{
//TestSuite suite = new TestSuite(AMFConnectionIT.class);
TestSuite suite = new TestSuite();
suite.addTest(new AMFConnectionIT("testConnect"));
suite.addTest(new AMFConnectionIT("testConnectAndClose"));
suite.addTest(new AMFConnectionIT("testConnectBadUrl"));
suite.addTest(new AMFConnectionIT("testCallMultipleTimes"));
suite.addTest(new AMFConnectionIT("testCallNoConnect"));
suite.addTest(new AMFConnectionIT("testCallNoConnectStringMsg"));
suite.addTest(new AMFConnectionIT("testCallUnreachableConnectUrl"));
suite.addTest(new AMFConnectionIT("testCallNonexistantMethod"));
suite.addTest(new AMFConnectionIT("testHttpResponseInfoWithNonexistantMethod"));
suite.addTest(new AMFConnectionIT("testCloseNoConnect"));
suite.addTest(new AMFConnectionIT("testSetGetObjectEncoding"));
suite.addTest(new AMFConnectionIT("testSetGetDefaultObjectEncoding"));
suite.addTest(new AMFConnectionIT("testSetGetAMFHeaderProcessor"));
suite.addTest(new AMFConnectionIT("testAddRemoveAMFHeaderTwoParam"));
suite.addTest(new AMFConnectionIT("testAddRemoveAMFHeader"));
suite.addTest(new AMFConnectionIT("testAddRemoveAllAMFHeaders"));
suite.addTest(new AMFConnectionIT("testAddRemoveHTTPRequestHeader"));
suite.addTest(new AMFConnectionIT("testAddRemoveAllHTTPRequestHeaders"));
suite.addTest(new AMFConnectionIT("testRemoveAMFHeader"));
suite.addTest(new AMFConnectionIT("testRemoveAllAMFHeaders"));
suite.addTest(new AMFConnectionIT("testRemoveHTTPRequestHeader"));
suite.addTest(new AMFConnectionIT("testRemoveAllHTTPRequestHeaders"));
suite.addTest(new AMFConnectionIT("testInstantiateTypes"));
suite.addTest(new AMFConnectionIT("testSetGetAMFTrace"));
suite.addTest(new AMFConnectionIT("testHTTPProxy"));
return new TestSetup(suite) {
protected void setUp() throws Exception {
serverWrapper = new TestServerWrapper();
serverPort = serverWrapper.startServer("classpath:/WEB-INF/flex/services-config.xml");
if(serverPort == -1) {
Assert.fail("Couldn't start server process");
}
AMFConnection.registerAlias(
"remoting.amfclient.ServerCustomType" /* server type */,
"amfclient.ClientCustomType" /* client type */);
}
protected void tearDown() throws Exception {
serverWrapper.stopServer();
serverWrapper = null;
}
};
}
// Not a test, just an example to show how to use AMFConnection.
public void example()
{
// Create the AMF connection.
AMFConnection amfConnection = new AMFConnection();
// Connect to the remote url.
try
{
amfConnection.connect(getConnectionUrl());
}
catch (ClientStatusException cse)
{
return;
}
// Make a remoting call and retrieve the result.
try
{
Object result = amfConnection.call(DEFAULT_AMF_OPERATION, DEFAULT_METHOD_ARG);
Assert.assertEquals(DEFAULT_METHOD_ARG, result);
}
catch (ClientStatusException cse)
{
// Ignore.
}
catch (ServerStatusException sse)
{
// Ignore.
}
// Close the connection.
amfConnection.close();
}
public void testConnect()
{
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(getConnectionUrl());
Assert.assertEquals(getConnectionUrl(), amfConnection.getUrl());
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
finally
{
amfConnection.close();
}
}
public void testConnectAndClose()
{
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(getConnectionUrl());
Assert.assertEquals(getConnectionUrl(), amfConnection.getUrl());
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
finally
{
amfConnection.close();
Assert.assertEquals(null, amfConnection.getUrl());
}
}
public void testConnectBadUrl()
{
String badUrl = "badUrl";
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(badUrl);
fail("ClientStatusException expected");
}
catch (ClientStatusException cse)
{
Assert.assertEquals(ClientStatusException.AMF_CONNECT_FAILED_CODE, cse.getCode());
}
finally
{
amfConnection.close();
}
}
public void testCallMultipleTimes()
{
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(getConnectionUrl());
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
// Make a remoting call and retrieve the result.
try
{
for (int i = 1; i < 4; i++)
{
String stringToEcho = DEFAULT_METHOD_ARG + i;
Object result = amfConnection.call(DEFAULT_AMF_OPERATION, stringToEcho);
Assert.assertEquals(stringToEcho, result);
}
}
catch (Exception e)
{
fail(UNEXPECTED_EXCEPTION_STRING + e);
}
finally
{
amfConnection.close();
}
}
public void testCallNoConnect()
{
AMFConnection amfConnection = new AMFConnection();
// Make a remoting call without connect.
try
{
Object result = amfConnection.call(DEFAULT_AMF_OPERATION, DEFAULT_METHOD_ARG);
Assert.assertEquals(DEFAULT_METHOD_ARG, result);
}
catch (ClientStatusException cse)
{
Assert.assertEquals(ClientStatusException.AMF_CALL_FAILED_CODE, cse.getCode());
}
catch (Exception e)
{
fail(UNEXPECTED_EXCEPTION_STRING + e);
}
finally
{
amfConnection.close();
}
}
public void testCallNoConnectStringMsg()
{
AMFConnection amfConnection = new AMFConnection();
// Make a remoting call without connect.
try
{
Object result = amfConnection.call(DEFAULT_AMF_OPERATION, DEFAULT_METHOD_ARG);
Assert.assertEquals(DEFAULT_METHOD_ARG, result);
}
catch (ClientStatusException cse)
{
Assert.assertEquals(ClientStatusException.AMF_CALL_FAILED_CODE, cse.getCode());
}
catch (Exception e)
{
fail(UNEXPECTED_EXCEPTION_STRING + e);
}
finally
{
amfConnection.close();
}
}
public void testCallUnreachableConnectUrl()
{
String unreachableUrl = "http://localhost:8400/team/messagebroker/unreachable";
AMFConnection amfConnection = new AMFConnection();
try
{
// Connect does not actually connect but simply sets the url.
amfConnection.connect(unreachableUrl);
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
// Make a remoting call and retrieve the result.
try
{
Object result = amfConnection.call(DEFAULT_AMF_OPERATION, DEFAULT_METHOD_ARG);
Assert.assertEquals(DEFAULT_METHOD_ARG, result);
}
catch (ClientStatusException cse)
{
Assert.assertEquals(ClientStatusException.AMF_CALL_FAILED_CODE, cse.getCode());
}
catch (Exception e)
{
fail(UNEXPECTED_EXCEPTION_STRING + e);
}
finally
{
amfConnection.close();
}
}
public void testCallNonexistantMethod()
{
String method = "nonExistantMethod";
final ClientCustomType methodArg = new ClientCustomType();
methodArg.setId(1);
try
{
internalTestCall(getOperationCall(method), methodArg, new CallResultHandler(){
public void onResult(Object result)
{
fail("Unexcepted result: " + result);
}
});
}
catch (ServerStatusException sse)
{
ASObject status = (ASObject)sse.getData();
String code = (String)status.get("code");
Assert.assertEquals(MessageException.CODE_SERVER_RESOURCE_UNAVAILABLE, code);
HttpResponseInfo info = sse.getHttpResponseInfo();
// AMF status messages are reported as HTTP_OK still.
Assert.assertEquals(HttpURLConnection.HTTP_OK, info.getResponseCode());
Assert.assertEquals("OK", info.getResponseMessage());
}
catch (Exception e)
{
fail(UNEXPECTED_EXCEPTION_STRING + e);
}
}
public void testHttpResponseInfoWithNonexistantMethod()
{
String method = "nonExistantMethod";
final ClientCustomType methodArg = new ClientCustomType();
methodArg.setId(1);
try
{
internalTestCall(getOperationCall(method), methodArg, new CallResultHandler(){
public void onResult(Object result)
{
fail("Unexcepted result: " + result);
}
});
}
catch (ServerStatusException sse)
{
HttpResponseInfo info = sse.getHttpResponseInfo();
// AMF status messages are reported as HTTP_OK still.
Assert.assertEquals(HttpURLConnection.HTTP_OK, info.getResponseCode());
Assert.assertEquals("OK", info.getResponseMessage());
}
catch (Exception e)
{
fail(UNEXPECTED_EXCEPTION_STRING + e);
}
}
public void testCloseNoConnect()
{
AMFConnection amfConnection = new AMFConnection();
// Closing with no connection or call.
try
{
amfConnection.close();
Assert.assertEquals(null, amfConnection.getUrl());
}
catch (Exception e)
{
fail(UNEXPECTED_EXCEPTION_STRING + e);
}
}
public void testSetGetObjectEncoding()
{
int retAMF;
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(getConnectionUrl());
Assert.assertEquals(getConnectionUrl(), amfConnection.getUrl());
amfConnection.setObjectEncoding(MessageIOConstants.AMF0);
retAMF = amfConnection.getObjectEncoding();
Assert.assertEquals(MessageIOConstants.AMF0, retAMF);
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
finally
{
amfConnection.close();
}
}
public void testSetGetDefaultObjectEncoding()
{
int retAMF;
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(getConnectionUrl());
Assert.assertEquals(getConnectionUrl(), amfConnection.getUrl());
AMFConnection.setDefaultObjectEncoding(MessageIOConstants.AMF3);
retAMF = AMFConnection.getDefaultObjectEncoding();
Assert.assertEquals(MessageIOConstants.AMF3, retAMF);
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
finally
{
amfConnection.close();
}
}
/**
* There doesn't seem to be a single implementation of AMFHeaderProcessor therefore this test
* is pretty useless.
*/
public void testSetGetAMFHeaderProcessor()
{
AMFHeaderProcessor setAMF = null;
AMFHeaderProcessor retAMF;
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(getConnectionUrl());
Assert.assertEquals(getConnectionUrl(), amfConnection.getUrl());
amfConnection.setAMFHeaderProcessor(setAMF);
retAMF = amfConnection.getAMFHeaderProcessor();
Assert.assertEquals(setAMF, retAMF);
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
finally
{
amfConnection.close();
}
}
public void testAddRemoveAMFHeaderTwoParam()
{
boolean retAMF;
Object val = 1;
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(getConnectionUrl());
Assert.assertEquals(getConnectionUrl(), amfConnection.getUrl());
amfConnection.addAmfHeader(FOO_STRING,val);
retAMF = amfConnection.removeAmfHeader(FOO_STRING);
Assert.assertTrue(retAMF);
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
finally
{
amfConnection.close();
}
}
public void testAddRemoveAMFHeader()
{
boolean retAMF;
Object val = 1;
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(getConnectionUrl());
Assert.assertEquals(getConnectionUrl(), amfConnection.getUrl());
amfConnection.addAmfHeader(FOO_STRING,true,val);
retAMF = amfConnection.removeAmfHeader(FOO_STRING);
Assert.assertTrue(retAMF);
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
finally
{
amfConnection.close();
}
}
public void testAddRemoveAllAMFHeaders()
{
Object val1 = 1;
Object val2 = 2;
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(getConnectionUrl());
Assert.assertEquals(getConnectionUrl(), amfConnection.getUrl());
amfConnection.addAmfHeader(FOO_STRING,true,val1);
amfConnection.addAmfHeader(BAR_STRING,true,val2);
amfConnection.removeAllAmfHeaders();
Assert.assertTrue(true);
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
finally
{
amfConnection.close();
}
}
public void testAddRemoveHTTPRequestHeader()
{
boolean retHttp;
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(getConnectionUrl());
Assert.assertEquals(getConnectionUrl(), amfConnection.getUrl());
amfConnection.addHttpRequestHeader(FOO_STRING,BAR_STRING);
retHttp = amfConnection.removeHttpRequestHeader(FOO_STRING);
Assert.assertTrue(retHttp);
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
finally
{
amfConnection.close();
}
}
public void testAddRemoveAllHTTPRequestHeaders()
{
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(getConnectionUrl());
Assert.assertEquals(getConnectionUrl(), amfConnection.getUrl());
amfConnection.addHttpRequestHeader(FOO_STRING,BAR_STRING);
amfConnection.addHttpRequestHeader(BAR_STRING,FOO_STRING);
amfConnection.removeAllHttpRequestHeaders();
Assert.assertTrue(true);
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
finally
{
amfConnection.close();
}
}
public void testRemoveAMFHeader()
{
boolean retAMF;
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(getConnectionUrl());
Assert.assertEquals(getConnectionUrl(), amfConnection.getUrl());
retAMF = amfConnection.removeAmfHeader(FOO_STRING);
Assert.assertFalse(retAMF);
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
finally
{
amfConnection.close();
}
}
public void testRemoveAllAMFHeaders()
{
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(getConnectionUrl());
Assert.assertEquals(getConnectionUrl(), amfConnection.getUrl());
amfConnection.removeAllAmfHeaders();
Assert.assertTrue(true);
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
finally
{
amfConnection.close();
}
}
public void testRemoveHTTPRequestHeader()
{
boolean retHttp;
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(getConnectionUrl());
Assert.assertEquals(getConnectionUrl(), amfConnection.getUrl());
retHttp = amfConnection.removeHttpRequestHeader(FOO_STRING);
Assert.assertFalse(retHttp);
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
finally
{
amfConnection.close();
}
}
public void testRemoveAllHTTPRequestHeaders()
{
AMFConnection amfConnection = new AMFConnection();
try
{
amfConnection.connect(getConnectionUrl());
Assert.assertEquals(getConnectionUrl(), amfConnection.getUrl());
amfConnection.removeAllHttpRequestHeaders();
Assert.assertTrue(true);
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
finally
{
amfConnection.close();
}
}
public void testInstantiateTypes()
{
String method = "getObject2";
try
{
AMFConnection amfConnection = new AMFConnection();
amfConnection.connect(getConnectionUrl());
// First, make sure we get the strong type.
Object result = amfConnection.call(getOperationCall(method));
Assert.assertTrue(result instanceof ClientCustomType);
// Now, call again with instantiateTypes=false and expect an Object.
amfConnection.setInstantiateTypes(false);
result = amfConnection.call(getOperationCall(method));
Assert.assertTrue(!(result instanceof ClientCustomType));
amfConnection.close();
}
catch (Exception e)
{
fail(UNEXPECTED_EXCEPTION_STRING + e);
}
}
public void testSetGetAMFTrace()
{
AMFConnection amfConnection = new AMFConnection();
try
{
AmfTrace trace = new AmfTrace();
amfConnection.connect(getConnectionUrl());
amfConnection.setAmfTrace(trace);
String stringToEcho = DEFAULT_METHOD_ARG + 1;
Object result = amfConnection.call(DEFAULT_AMF_OPERATION, stringToEcho);
Assert.assertEquals(stringToEcho, result);
if (trace.toString().length() > 0) Assert.assertTrue(true);
else fail("AmfTrace did not get anything: " + trace.toString() + " " + trace.toString().length());
amfConnection.close();
}
catch (ClientStatusException cse)
{
fail(UNEXPECTED_EXCEPTION_STRING + cse);
}
catch (Exception e)
{
fail(UNEXPECTED_EXCEPTION_STRING + e);
}
finally
{
amfConnection.close();
}
}
public void testHTTPProxy()
{
AMFConnection amfconn = new AMFConnection();
try
{
amfconn.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 8888)));
amfconn.connect("http://localhost:8400/team/messagebroker/amf");
RemotingMessage call = new RemotingMessage();
call.setHeader("DSId", "" + System.identityHashCode(amfconn));
call.setClientId("ro");
call.setDestination("remoting_AMF");
call.setMessageId("12345");
call.setOperation("echo");
call.setBody("hello");
amfconn.call("foo", call);
fail("ClientStatusException expected");
}
catch (ClientStatusException cse)
{
Assert.assertEquals(ClientStatusException.AMF_CALL_FAILED_CODE, cse.getCode());
}
catch (Exception e)
{
fail(UNEXPECTED_EXCEPTION_STRING + e);
}
finally
{
amfconn.close();
}
}
// A simple interface to handle AMF call results.
private interface CallResultHandler
{
void onResult(Object result);
}
// Helper method used by JUnit tests to pass in an operation and method argument
// When the AMF call returns, CallResultHandler.onResult is called to Assert things.
private void internalTestCall(String operation, Object methodArg, CallResultHandler resultHandler) throws ClientStatusException, ServerStatusException
{
AMFConnection amfConnection = new AMFConnection();
// Connect.
amfConnection.connect(getConnectionUrl());
// Make a remoting call and retrieve the result.
Object result;
if (methodArg == null)
result = amfConnection.call(operation);
else
result = amfConnection.call(operation, methodArg);
resultHandler.onResult(result);
amfConnection.close();
}
}