Lambda Expression to close my SocketConversation - java

I have a test application that spawns a number of SocketConversations with a server. In the old days, I would have added an interface called ClosedWhenDone or something that defined a close method and pass an instance in that would notify the calling class that the SocketConversation is complete.
I'm new to java 8 and want to teach myself lambda functions. I have looked at these: http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html, http://viralpatel.net/blogs/lambda-expressions-java-tutorial/, http://java.dzone.com/articles/why-we-need-lambda-expressions, http://java.dzone.com/articles/why-we-need-lambda-expressions-0, and http://java.dzone.com/articles/why-we-need-lambda-expressions.
So, based on my research, I added a parameter to my constructor:
private Predicate<SocketConversation> closePredicate;
private long delay;
private boolean done;
private int index;
public SocketConversation(URI uri, int idx, String line, long delay, Predicate<SocketConversation> predicate) {
index = idx;
socket = new AirSocketClient(uri, this);
closePredicate = predicate;
...
}
Then when my conversation is over, I do the following:
socket.close();
closePredicate.close(this);
The close here, though, generates an error:
The method close(SocketConversation) is undefined for the type Predicate<SocketConversation>
What am I missing?

It sounds like what you want is a callback that lets the caller know that the conversation is complete, by calling a bit of code that the caller has specified. This sounds like a perfect use of lambdas. In the "old" days (prior to Java 8) you'd specify some interface and the caller would pass in an instance of an anonymous inner class. This can easily be done with a lambda instead.
You could define your own interface, but you don't need to in this case because most of the simple interfaces have already been defined. In this case the callback is passed an instance of a SocketConversation and returns nothing. The functional interface for this is a Consumer, which is already defined in java.util.function package. It's generic, so you want a Consumer<SocketConversation>. Your class would look something like this:
private Consumer<SocketConversation> callback;
public SocketConversation(URI uri, int idx, String line, long delay, Consumer<SocketConversation> callback) {
this.callback = callback;
...
}
and later on, when the conversation is closed, you'd do this:
socket.close();
callback.accept(this);
Callers could pass a lambda expression as the callback like this:
SocketConversation conv = new SocketConversation(uri, idx, line, delay,
sc -> System.out.println("conversation " + sc + " is done"));

Related

Akka - AbstractBehaviorWithStash?

is there a way to start out an Akka Typed Behavior with a stash in Java? The reason is simple, during the first stage, the Behavior waits for a certain kind of message, initializes itself with it and should stash() every other message until it got that message, then unstash() them and proceed as normal.
With functional, this is easily doable, sure, but is there a way to do so with AbstractBehavior and it's createReceive() method, because that one doesn't allow me to return a stashed Behavior via Behaviors.withStash( stash -> ...), since it expects a Receive ?
In the OO API, I would expect that the approach would be to inject the stash through constructor args from a static create method.
// Apologies if this Java is atrocious
public class ActorWithAStash extends AbstractBehavior<ActorWithAStash.Command> {
public static Behavior<Command> create() {
Behaviors.setup(context ->
Behaviors.withStash(100, stash ->
new ActorWithAStash(context, stash)
)
);
}
public interface Command;
private ActorWithAStash(ActorContext<Command> context, StashBuffer<Command> stash) {
this.context = context;
this.stash = stash;
}
private ActorContext<Command> context;
private StashBuffer<Command> stash;
}

Using a loop to call different methods depending on which string is found

I'm using listeners provided by Pircbotx (https://github.com/pircbotx/pircbotx/wiki/Documentation) to detect when a command is found in Twitch chat, and I am trying to use a different method depending on which Command is called (format is !command). Classes used: Listeners, Command.
Commands are stored in an array of Command objects, comprised of one String (name). Each Command object will ultimately use its own method that will be defined in the Command class. The Listeners object when instantiated will immediately place every element of the array into a hash table (commands).
When Listeners detects a message, it is stored using a local String variable (msg). When this happens, a loop iterates through the Command object array, and then.... is supposed to call the method that corresponds to that particular object, in this case Command.addDeath(). That's where I'm stuck.
I was previously using a bunch of if statements for my listeners, but when there's a bunch of commands things will get really, really messy. Apologies in advance if the formatting in my code block is weird, I'm pretty new to utilizing Stackverflow, and I'm also a Java novice that's learning as I go along. After looking at the code again, it would appear I don't really need the hash table - but I'm leaving it in there just in case you guys have any better ideas for what to do with them.
public class Listeners {
String name;
String message;
private static MessageEvent event;
Command [] commandNames = {new Command("!clearchat", new Command("!addDeath")};
Hashtable<String, Command> commands = new Hashtable<String, Command>();
public Listeners() {
for (int i = 0; i < commandNames.length; i++) {
commands.put(commandNames[i].name, new Command(commandNames[i].name));
}
if (event.getMessage() != null) {
String msg = event.getMessage();
for (int x = 0; x < commandNames.length; x++ ) {
if (msg.startsWith(commandNames[x].name)) {
// call Command method here
}
}
}
}
And here is the Command class:
public class Command {
String name;
public Command(String name) {
this.name = name;
}
public static void addDeath() {
DeathCounter.addDeath();
Listeners.sendMessage("Death Counter: " + DeathCounter.getDeaths());
}
}
You can use an interface for your commands:
public interface Command {
public abstract void execute();
}
Then have your commands implement the interface:
public class DeathCommand implements Command {
#Override
public void execute() {
DeathCounter.addDeath();
Listeners.sendMessage("Death Counter: " + DeathCounter.getDeaths());
}
}
In your listener class, map the command strings to instances of the corresponding command:
public class Listeners {
String name;
String message;
private static MessageEvent event;
static Map<String, Command> commands = new HashMap<>();
static {
commands.put("!addDeath", new DeathCommand());
}
public Listeners() {
if (event.getMessage() != null) {
String msg = event.getMessage();
Optional<String> key = commands.keySet().stream().filter(k -> msg.startsWith(k)).findFirst();
key.ifPresent(s -> commands.get(s).execute());
}
}
}
I replaced your Hashtable with a HashMap which is better in most ways (but is used the same way).
I'm a bit skeptical about having the map as a static member, but since I'm not familiar with your use case I leave that bit as is.
Edit
All Java classes have a default constructor (with no parameters) unless you write your own constructor (you have to write the default one yourself if you still want it). Interfaces don't have constructors since they can't be instantiated directly. They just specify methods that implementing classes must have. This allows you to have references (named fields/variables) of the interface type and be able to call the methods without knowing, or having to know, which implementation it is.
Example:
Command com = new DeathCommand();
com.execute(); // <- this will run the execute() code in the DeathCommand class
Command com2 = new SomeOtherCommand();
com2.execute(); // <- this will run the execute() code in the SomeOtherCommand class
The above code for Command is complete. There is nothing more. As for DeathCommand, and other implementations, you'll need to add what code is needed.
Each class and interface goes in it's own file named as the type:
Command.java
DeathCommand.java
Regarding HashTable vs HashMap. I should have said that it's better to use Map and it's implementations. If you need thread safety, use ConcurrentHashMap as agilob pointed out since regular HashMap is not thread safe.

Matching mutable object without ArgumentCaptor

I have to test a method which uses a mutable object
private final List<LogMessage> buffer;
...
flushBuffer() {
sender.send(buffer);
buffer.clear();
}
I need to test that it sends buffers with exact size.
ArgumentCaptor is not applicable because the captured collection is clear by the time of assertion.
Is there a kind of matcher which can reuse Hamcrest's hasSize() and does check right in time of method call?
I would prefer something like this hypothetical collectionWhich matcher:
bufferedSender.flushBuffer();
verify(sender).send(collectionWhich(hasSize(5)));
A lightweight alternative to David's idea: Use an Answer to make a copy at the time of the call. Untested code, but this should be pretty close:
final List<LogMessage> capturedList = new ArrayList<>();
// This uses a lambda, but you could also do it with an anonymous inner class:
// new Answer<Void>() {
// #Override public Void answer(InvocationOnMock invocation) { /* ... */ }
// }
when(sender.send(any())).thenAnswer(invocation -> {
List<LogMessage> argument = (List<LogMessage>) invocation.getArguments()[0];
capturedList.addAll(argument);
});
bufferedSender.flushBuffer();
assertThat(capturedList).hasSize(5);
The Jeff Bowman answer is fine but I think that we can improve it by inlining the assertion in the Answer object itself. It avoids creating unnecessary copy objects and additional local variable(s).
Besides in cases of we need to copy the state of custom objects (by performing a deep copy of it), this way is much simpler. Indeed, it doesn't require any custom code or library to perform the copies as the assertion is done on the fly.
In Java 8, it would give :
import static org.mockito.Mockito.*;
when(sender.send(any())).thenAnswer(invocation -> {
List<LogMessage> listAtMockTime = invocation.getArguments()[0];
Assert.assertEquals(5, listAtMockTime.getSize());
});
bufferedSender.flushBuffer();
Note that InvocationOnMock.getArgument(int index) returns an unbounded wildcard (?). So no cast is required from the caller as the returned type is defined by the target : here the declared variable for which one we assign the result.
You would have the same issue than with ArgumenCaptor as the verify() method checks the invocation with the state of the object after the execution. No capture is performed to keep only the state at the invocation time.
So with a mutable object I think that a better way would be to not use Mockito and instead create a stub of the Sender class where you capture the actual size of the collection as send() is invoked.
Here is a sample stub class (minimal example that you could of course enrich/adapt) :
class SenderStub extends Sender {
private int bufferSize;
private boolean isSendInvoked;
public int getBufferSize() {
return bufferSize;
}
public boolean isSendInvoked(){
return isSendInvoked;
}
#Override
public void send(List<LogMessage> buffer ) {
this.isSendInvoked = true;
this.bufferSize = buffer.size();
}
}
Now you have a way to check whether the Sender was invoked and the size (or even more) of that.
And so put aside Mockito to create this mock and verify its behavior :
SenderStub sender = new SenderStub();
MyClassToTest myClass = new MyClassToTest(sender);
// action
myClass.flushBuffer();
// assertion
Assert.assertTrue(sender.isInvoked());
Assert.assertEquals(5, sender.getBufferSize());

AWS Java Lambda local variables vs object variables

I am trying to find answer to a very specific question. Trying to go through documentation but so far no luck.
Imagine this piece of code
#Override
public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
Request request = parseRequest(input);
List<String> validationErrors = validate(request);
if (validationErrors.size() == 0){
ordersManager.getOrderStatusForStore(orderId, storeId);
} else {
generateBadRequestResponse(output, "Invalid Request", null);
}
}
private List<String> validate(Request request) {
orderId = request.getPathParameters().get(PATH_PARAM_ORDER_ID);
programId = request.getPathParameters().get(PATH_PARAM_STORE_ID);
return new ArrayList<>();
}
Here, I am storing orderId and storeId in field variables. Is this okay? I am not sure if AWS will cache this function and hence cache the field variables or would it initiate a new Java object for every request. If its a new object, then storing in field variable is fine but not sure.
AWS will spin up a JVM and instantiate an instance of your code on the first request. AWS has an undocumented spin down time, where if you do not invoke your Lambda again within this time limit, it will shut down the JVM. You will notice these initial requests can take significantly longer but once your function is "warmed up", then it will be much quicker.
So to directly answer your question, your instance will be reused if the next request comes in quick enough. Otherwise, a new instance will be stood up.
A simple Lambda function that can illustrate this point:
/**
* A Lambda handler to see where this runs and when instances are reused.
*/
public class LambdaStatus {
private String hostname;
private AtomicLong counter;
public LambdaStatus() throws UnknownHostException {
this.counter = new AtomicLong(0L);
this.hostname = InetAddress.getLocalHost().getCanonicalHostName();
}
public void handle(Context context) {
counter.getAndIncrement();
context.getLogger().log("hostname=" + hostname + ",counter=" + counter.get());
}
}
Logs from invoking the above.
22:49:20 hostname=ip-10-12-169-156.ec2.internal,counter=1
22:49:27 hostname=ip-10-12-169-156.ec2.internal,counter=2
22:49:39 hostname=ip-10-12-169-156.ec2.internal,counter=3
01:19:05 hostname=ip-10-33-101-18.ec2.internal,counter=1
Strongly not recommended.
Multiple invocations may use the same Lambda function instance and this will break your current functionality.
You need to ensure your instance variables are thread safe and can be accessed by multiple threads when it comes to Lambda. Limit your instance variable writes to initialization - once only.

what's a good pattern for registering a Class to execute a specific task later on?

I'm writing a test suite, and I'm thinking about how to mock certain request/response flows. For example, I want to test a method that makes multiple RESTful calls:
getCounts() {
...
Promise<Integer> count1 = getCount1();
Promise<Integer> count2 = getCount2();
// returns a DataModel containing all counts when the Promises redeem
}
getCount1() {
...
Request<Foo> request = new Request<Foo>();
sendRequest(request);
...
}
getCount2() {
...
Request<Bar> request = new Request<Bar>();
sendRequest(request);
...
}
sendRequest(Request<T> request) {...}
However, each getCount() method creates a different Request<T> object, where <T> describes the type of request being made in regards to the count being retrieved. This means I can't simply "mock" the sendRequest() method since it is being called with a different type each time.
I was thinking about an approach where I register a "handler"... when sendRequest() is called, it determines which handler to call, and the handler would know the appropriate type of mock data to return. The registration would be something like storing the handler class type or an instance of the handler class along with the mock data it needs, and when sendRequest() is called, it would look for and invoke the correct handler.
However, I'm not sure if this a good pattern, and I'm wondering if there is a better way of approaching this problem. What is a good pattern for registering a Class or a particular method to execute a specific task later on?
Hard to answer without more context, but the general approach is to use Inversion Of Control (IOC). For example, put the getCountXXX methods into a class of their own, which may be a good idea for better reuse, readability, encapsulation, testability, etc:
public class CountFetcher {
getCount1() { ... }
getCount2() { ... }
}
The original code now gets an instance of CountFetcher using whatever "injection" mechanism is available to you. Simplest is just a constructor:
public class Counter {
private final CountFetcher fetcher;
public Counter(CountFetcher fetcher) {
this.fetcher = fetcher;
}
public getCounts() {
Promise<Integer> count1 = fetcher.getCount1();
Promise<Integer> count2 = fetcher.getCount2();
...
}
}
In your production code, you instantiate Counter with a real CountFetcher. In test code, you inject a mock version of CountFetcher which can have each individual getCountXXX method return whatever you want:
public class MockCountFetcher extends CountFetcher {
#Override
getCount1() { return mockCount1; }
}
public class TestCounter {
#Test
public void smokeTest() {
CountFetcher mockFetcher = new MockCountFetcher();
Counter counter = new Counter(mockFetcher);
assertEquals(someExpectedValue, counter.getCounts());
}
}

Categories