Hey, have been trying to work this out for last day or so but hitting brick wall. Trying to unit test this bit of code. But not sure if need to use EasyMock or not?? Seem few examples online but seem to be using older techniques.
public boolean verifyConnection(final String url) {
boolean result;
final int timeout = getConnectionTimeout();
if (timeout < 0) {
log.info("No need to verify connection to client. Supplied timeout = {}", timeout);
result = true;
} else {
try {
log.debug("URL: {} Timeout: {} ", url, timeout);
final URL targetUrl = new URL(url);
final HttpURLConnection connection = (HttpURLConnection) targetUrl.openConnection();
connection.setConnectTimeout(timeout);
connection.connect();
result = true;
} catch (ConnectException e) {
log.warn("Could not connect to client supplied url: " + url, e);
result = false;
} catch (MalformedURLException e) {
log.error("Malformed client supplied url: " + url, e);
result = false;
} catch (IOException e) {
log.warn("Could not connect to client supplied url: " + url, e);
result = false;
}
}
return result;
}
It just take's in a url checks its valid and returns T or F.
I have always observed that Mocking Can be avoided as much as possible because it can lead to difficult to maintain JUnit tests and defeat the whole purpose.
My suggestion would be to create a temporary server on your local machine from a JUnit itself.
At the beginning of JUnit you can create a server(not more than 10-15 lines of coding required) using Java sockets and then in your code pass the URL for the local server. This way you are reducing mocking and ensuring maximum code coverage.
Something like this -
public class SimpleServer extends Thread {
public void run() {
try {
serverSocket = new ServerSocket(port);
while (true) {
Socket s = serverSocket.accept();
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
serverSocket = null;
}
}
}
If you want to mock this method, I'd recommend passing in the URL rather than the String. Don't have your method create the URL it needs; let the client create the URL for you and pass it in. That way your test can substitute a mock if it needs to.
It's almost a dependency injection idea - your method should be given its dependencies and not create them on its own. The call to "new" is the dead giveaway.
It's not a drastic change. You could overload the method and have two signatures: one that accepts a URL string and another that accepts the URL itself. Have the first method create the URL and call the second. That way you can test it and still have the method with the String signature in your API for convenience.
Trying to set up mock implementation of the HttpURLConnection. Like
public class MockHttpURLConnection extends HttpURLConnection {'
then added method to class to override
' protected HttpURLConnection createHttpURLConnection(URL url)
throws IOException {
return (HttpURLConnection) url.openConnection();
}
So test looking something like this:
#Test
public void testGetContentOk() throws Exception
{
String url = "http://localhost";
MockHttpURLConnection mockConnection = new MockHttpURLConnection();
TestableWebClient client = new TestableWebClient();
client.setHttpURLConnection(mockConnection);
boolean result = client.verify(url);
assertEquals(true, result);
}
#Test
public void testDoesNotGetContentOk() throws Exception
{
String url = "http://1.2.3.4";
MockHttpURLConnection mockConnection = new MockHttpURLConnection();
TestableWebClient client = new TestableWebClient();
client.setHttpURLConnection(mockConnection);
boolean result = client.verify(url);
assertEquals(false, result);
}
/**
* An inner, private class that extends WebClient and allows us
* to override the createHttpURLConnection method.
*/
private class TestableWebClient extends WebClient1 {
private HttpURLConnection connection;
/**
* Setter method for the HttpURLConnection.
*
* #param connection
*/
public void setHttpURLConnection(HttpURLConnection connection)
{
this.connection = connection;
}
/**
* A method that we overwrite to create the URL connection.
*/
#Override
public HttpURLConnection createHttpURLConnection(URL url) throws IOException
{
return this.connection;
}
}
First part passed but is getting true for false dummy test, thanks for feedback back so far best site I have found for help. So let me know if think on right track
Related
I'm very new in openfire and first time using java, I got stuck when I trying to develop plugin for crud. Could you give me some sample to make crud plugin ability? Thanks for your help before...
You can start from this answer: Mapping Openfire Custom plugin with aSmack Client
and follow the official tutorial with first 3 points of the answer.
About CRUD:
Let's assume you want to audit all your messages as XML in your database, so you'll implement a PacketInterceptor just to keep an easy scenario.
Your class plugin will looks like:
public class MyCustomPlugin implements Plugin, PacketInterceptor {//foo}
in method initializePlugin you'll have an invokation like:
public void initializePlugin(PluginManager manager, File pluginDirectory)
{
InterceptorManager.getInstance().addInterceptor(this);
}
and in method interceptPacket something like that:
#Override
public void interceptPacket(Packet packet, Session session,
boolean incoming, boolean processed) throws PacketRejectedException {
if (!processed)
{
boolean done = doMyCRUDAction(packet);
}
if (!done)
{ //do something if error occourred}
}
now let's write on database:
private static final String AUDIT_CHAT =
"INSERT INTO MYTABLE(MESSAGEASXML) VALUES (?)";
private boolean doMyCRUDAction(Packet packet)
{
if ((packet instanceof Message))
{
Message message = (Message) packet.createCopy();
boolean isAudited = false;
Connection con = null;
PreparedStatement statement = null;
try {
con = DbConnectionManager.getConnection();
statement = con.prepareStatement(AUDIT_CHAT);
statement.setString(1, message.toString());
statement.executeQuery();
isAudited = true;
}
catch (SQLException e) {
Log.error(e.getMessage(), e);
}
catch (Exception ex)
{
Log.error(ex.getMessage(), ex);
}
finally {
DbConnectionManager.closeConnection(statement, con);
}
return isAudited;
}
}
please keep in mind this is a reduced snippet of a working code, so there can be some sintax to fix
If your CRUD must follow an explicit IQ request, you'll have to extends an IQHandler and create a custom IQ and send to the client in handleIQ(IQ packet) method. You can check in Openfire sourcecode about detailed and complex implementations.
I'm trying to establish a https connection between an android app (client) an my laptop (server).
My https server is running as python script (with a letsencrypt certificate) which works fine as long as I try to connect it with chrome or another python script.
Now I wanted to implement the client in my android app. Therefore I added the permission to the AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
and added following lines to my MainActivity.java (based on HttpURLConnection Reference on Android Developers!:
public void onButtonClicked(String message) {
try {
URL url = new URL("https://foo.bar.com/");
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
OutputStream output = new BufferedOutputStream(urlConnection.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
mSecondFragment.updateMessage(message);
}
At the moment I just want to establish a connection to my https server and send a simple GET request without receiving any data. But my goal would be to parse an additional key value pair together with the GET request that will be processed by the server:
"https://foo.bar.com?a=1"
I tried to keep it as simple as possible (that's the reason why I wanted to use java.net.HttpURLConnection) but I assume the problem is not as trivial as I expected.
Maybe someone ran into the same problem and can help my with that :)
EDIT (Thanks to #atomicrat2552 and #petey):
I added an additional class that handles the request as an AsyncTask:
public class NetworkConnection extends AsyncTask<String, Void, NetworkConnection.Result> {
static class Result {
public String mResultValue;
public Exception mException;
public Result(String resultValue) {
mResultValue = resultValue;
}
public Result(Exception exception){
mException = exception;
}
}
protected NetworkConnection.Result doInBackground(String... urls) {
Result result = null;
HttpsURLConnection urlConnection = null;
try {
URL url = new URL(urls[0]);
urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
//urlConnection.connect();
result = new Result("Done");
}catch(Exception e) {
result = new Result(e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return result;
}
}
This leads to a simplified onButtonClick method in MainActivity.java:
NetworkConnection nwConn = new NetworkConnection();
public void onButtonClicked(String message) {
nwConn.execute("https://foo.bar.com");
mSecondFragment.updateMessage(message);
}
Again I tried to simplify the code in order to get a small working code a can extend later.
The app doesn't crash anymore but my server still doesn't show any requests. If I'm using the browser on my phone everything works just fine. Any idea?
The most common pitfall I see here is that network code cannot run on the UI thread, so you must use some sort of background worker to do your network calls. The developer site has a basic guide on how to do this.
Now i'm working with Apache Kafka and have task:
We have some csv-files in directory, it's a mini-batch files, each file is about 25-30 mb. All i need - parse file and put it to kafka.
As I can see, Kafka have some interesting thing like Connector.
I can create Source-Connector and SourceTask, but i don't understand one thing:
when i handle file, how i can stop or delete my task?
For example i have dummy connector:
public class DummySourceConnector extends SourceConnector {
private static final Logger logger = LogManager.getLogger();
#Override
public String version() {
logger.info("version");
return "1";
}
#Override
public ConfigDef config() {
logger.info("config");
return null;
}
#Override
public Class<? extends Task> taskClass() {
return DummySourceTask.class;
}
#Override
public void start(Map<String, String> props) {
logger.info("start {}", props);
}
#Override
public void stop() {
logger.info("stop");
}
#Override
public List<Map<String, String>> taskConfigs(int maxTasks) {
logger.info("taskConfigs {}", maxTasks);
return ImmutableList.of(ImmutableMap.of("key", "value"));
}
And Task:
public class DummySourceTask extends SourceTask {
private static final Logger logger = LogManager.getLogger();
private long offset = 0;
#Override
public String version() {
logger.info("version");
return "1";
}
#Override
public void start(Map<String, String> props) {
logger.info("start {}", props);
}
#Override
public List<SourceRecord> poll() throws InterruptedException {
Thread.sleep(3000);
final String value = "Offset " + offset++ + " Timestamp " + Instant.now().toString();
logger.info("poll value {}", value);
return ImmutableList.of(new SourceRecord(
ImmutableMap.of("partition", 0),
ImmutableMap.of("offset", offset),
"topic-dummy",
SchemaBuilder.STRING_SCHEMA,
value
));
}
public void stop() {
logger.info("stop");
}
But how i can close my task when it's all done?
Or maybe you can help me with another idea for this task.
Thanx for your help!
First, I encourage you to have a look at existing connectors here. I feel like the spooldir connector would be helpful to you. It may even be possible for you to just download and install it without having to write any code at all.
Second, if I'm understanding correctly, you want to stop a task. I believe this discussion is what you want.
A not so elegant solution of terminating a Task when an event happens is to check for the event in the source of the task and call System.exit(1).
Nevertheless the most elegant solution I have found is this:
When the event occurs the Connector Task apply a REST call to the broker in order to stop the Connector that runs the Task.
To do this the Task itself should know the name of the Connector that runs the task which you can find following the steps of this discussion.
So the name of the connector it is in properties argument of Task, there exists a property with "name" key, and whose value is the name of the Connector which executes the Task ( which we want to stop if an event occurs).
Finally, we make a REST call and we get a 204 answer with no content if the task stops.
The code of the call is this:
try {
URL url = new URL("url/" + connectorName);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("DELETE");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 204) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
System.out.println("Task Stopped \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Now all the Connector Tasks stop.
(Of course as it is mentioned previously you have to keep in mind that the logic of each SourceTask and each SinkTask is neverending. They are supposed to never stop if an event occurs but instead to continuously seaching for new entries in the files you provide them. So usually you stop them with a REST call and if you want them to stop when an event occurs you put that REST call in their own code.)
I am debugging an issue in my android app. I found the root cause is file descriptors went beyond the limit. After further investigation I found that the app has too many sockets open. I use OkHttpClient 2.5 for all of my network communication, thus I am wondering how should I limit my connection pool size. Below is my code snippet:
OkHttpClient okHttpClient = new OkHttpClient().setConnectTimeout(TIMEOUT);
ConnectionPool connectionPool = new ConnectionPool(MAX_IDLE_CONNECTIONS,
KEEP_ALIVE_DURATION_MS);
okHttpClient.set(connectionPool);
#RequireArgsConstructor
public HttpEngineCallable implements Callable<IHttpResponse>
{
private final String url;
public IHttpResponse call () throws Exception
{
try
{
Request request = Request.Builder().url(url).build();
Call call = okHttpClient.newCall(request);
Response rawResponse = call.execute();
return new OkHttpResponse(rawResponse);
}
catch (Exception e)
{
throw new IllegalStateException(e);
}
}
private final Function<IHttpResponse, T> httpResponseParser = new Function<IHttpResponse, T>()
{
#Nullable
#Override
public T apply(#Nullable IHttpResponse httpResponse)
{
if(httpResponse == null)
{
return null;
}
InputStream stream = httpResponse.getBody();
JsonParser parser = null;
T result = null;
try
{
parser = jsonFactory.createParser(stream);
result = strategy.parseData(parser);
}
catch (Exception e)
{
log.error("Unable to convert {} with {}.", stream, strategy, e);
}
finally
{
IOUtils.closeQuietly(parser);
IOUtils.closeQuietly(stream);
}
return result;
}
};
Future<T> future = executorService.submit(new HttpEngineCallable(url));
Future<V> finalFuture = Futures.transform(future, httpResponseParser, executorService);
T result = timeoutExecutorService.submit(new Runnable()
{
try
{
T result = finalFuture.get(CLIENT_TIMEOUT, TIMEUNIT)
if (result == null)
{
notify onFailure listeners
}
else
{
notify onSuccess Listeners
}
}
catch(Exception ex)
{
notify onFailure listeners
}
}
So I have a few questions regarding this implementation:
My CLIENT_TIMEOUT is shorter than OkHttp ConnectTimeout. If my finalFuture.get(CLINT_TIMEOUT, TIMEUNIT) throws timeout exception, would my finally block in the Parser Function still be executed? I am counting on it to close my connection.
How can limits the size of my ConnectionPool? Is there way I can auto-recycle oldest connections if connection went beyond limit?
We had a similar issue with too many open file descriptors crashing our app.
The problem was that we created one OkHttpClient per request. By default each OkHttpClient comes with its own connection pool, which of course blows up the number of connections/threads/file handles and prevents proper reuse in the pool.
We solved the problem by manually creating a global ConnectionPool in a singleton, and then passing that to the OkHttpClient.Builder object which builds the actual OkHttpClient.
...
builder.connectionPool(GLOBAL_CONNECTION_POOL);
OkHttpClient client = builder.build();
...
This still allows for per-request configuration using the OkHttpClient.Builder and makes sure all OkHttpClient instances are still using a common connection pool.
We were then able to properly size the global connection pool.
I have a class FTPOperation that I use as a base class to regroup methods that are common to FTP operations. One of these methods is connect().
public abstract class FtpOperation {
protected static final Log log = LogFactory.getLog(FtpOperation.class);
/**
* Hostname or IP address of the FTP server (e.g. localhost, 127.0.0.1).
*/
private String hostName;
private String username;
private String password;
protected FTPClient ftpClient = getFTPClient();
public void setHostName(String hostName) {
this.hostName = hostName;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
/**
* Connect to the specified FTP server.
*
* #throws Exception
*/
protected void connect() throws Exception {
int reply;
// Connect to the FTP server
ftpClient.connect(hostName);
if (!ftpClient.login(username, password))
throw new Exception("Fail to log in with the given credentials.");
log.info("Connected to " + hostName + ".");
log.info(ftpClient.getReplyString());
// Check if the connection succeeded
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply))
throw new Exception("Connection to FTP server failed with code "
+ reply + ".");
}
/**
* Used for mocking.
*
* #return
*/
protected FTPClient getFTPClient() {
if (this.ftpClient == null)
this.ftpClient = new FTPClient();
return ftpClient;
}
}
I want to write unit test for testing this method but I don't know how to test it. I use Mockito to create a mock object for the FTPClient instance.
First, I thought about testing the different cases where the ftpClient.connect() call returns a certain exception, but I think it's wrong since I'm testing by knowing the implementation of the connect() method and not trough the API.
On example of test I've done:
#Test(expected = SocketException.class)
public void testConnectSocketException() throws Exception {
downloadInitialFileTasklet.setHostName("hostname");
doThrow(new SocketException()).when(mockFtpClient).connect("hostname");
downloadInitialFileTasklet.connect();
}
Could someone explain me the right way to test this method?
Thanks
What is your test meant to be testing? If you're simply seeing that SocketException is not caught it seems a bit of a peculiar test.
If you were to wrap the exception then it makes a little bit more sense.
eg.
protected void connect() throws FTPException {
int reply;
// Connect to the FTP server
try {
ftpClient.connect(hostName);
} catch (IOException e) {
throw new FTPException(e, "unable to connect to: "+hostname);
}
...
}
With the test we're testing that connect correctly terminates early and throws an FTPException if the underlying client cannot connect
#Test(expected = FTPException.class)
public void ConnectFailsIfExceptionOnClientConnect() throws FTPException {
// setup
downloadInitialFileTasklet.setHostName("hostname");
when(mockFtpClient).connect(any(String.class)).doThrow(new SocketException());
// verify -- if something else throws an FTP exception later then the verify
// statements should fail the test because either connect was not called
// because or login was
verify(mockFtpClient).connect(any(String.class));
verify(mockFtpClient, never()).login(any(String.class), any(String.class));
downloadInitialFileTasklet.connect();
}
Create an interface for the FtpClient class, than wrap it into a new class that you will use in the production environment.
For tests instead you can implement a stub (a fake class) or a mock object of the wrapped FtpClient (I prefer the first way).
Pass the IFtpClient interface to the constructor of the FtpOperation class.