Issue
I am trying to do the class registry in java using the below code
public interface IServiceBus {
<C,R> R send(C c);
}
public interface IRequestHandler<C , R> {
R handler(C c);
default Class<C> getCmdType(){
return (Class<C>) this.getClass();
};
}
@Singleton
public class ServiceBus implements IServiceBus {
private final Map<Class<?>, IRequestHandler<?, ?>> handlerMap;
public ServiceBus(List<IRequestHandler<?, ?>> handlers) {
handlerMap = handlers.stream()
.collect(toMap(
IRequestHandler::getCmdType,
Function.identity()
));
}
@Override
public <C, R> R send(C c) {
IRequestHandler<C, R> handler = (IRequestHandler<C, R>) handlerMap.get(c.getClass());
if (handler == null)
throw new UnsupportedOperationException("Unsupported command: " + c.getClass());
return handler.handler(c);
}
}
controller
public Mono<MutableHttpResponse<?>> getById(@NotBlank String id) {
var item = _iserviceBus.<CreateProductCommand, CreateProductCommand>send(new CreateProductCommand());
return null;
}
On
handlerMap = handlers.stream()
.collect(toMap(
IRequestHandler::getCmdType,
Function.identity()
));
The return of getCmdType
is not correct and not sure about Function.identity()
. Threfore IRequestHandler<C, R> handler = (IRequestHandler<C, R>) handlerMap.get(c.getClass());
is always null
What is the best way to get the command and register with the handler
Solution
There are several things about your design that can't work and I am not sure what the real requirements are given what is in the question but the project at github.com/jeffbrown/sanjaisyinterfaces should help.
src/main/java/sanjaisyinterfaces/SomeReturnType.java
package sanjaisyinterfaces;
public class SomeReturnType {
}
src/main/java/sanjaisyinterfaces/SomeOtherReturnType.java
package sanjaisyinterfaces;
public class SomeOtherReturnType {
}
src/main/java/sanjaisyinterfaces/CommandType.java
package sanjaisyinterfaces;
public interface CommandType {
}
src/main/java/sanjaisyinterfaces/SomeCommandType.java
package sanjaisyinterfaces;
public class SomeCommandType implements CommandType {
}
src/main/java/sanjaisyinterfaces/SomeOtherCommandType.java
package sanjaisyinterfaces;
public class SomeOtherCommandType implements CommandType {
}
src/main/java/sanjaisyinterfaces/IRequestHandler.java
package sanjaisyinterfaces;
public interface IRequestHandler<C extends CommandType, R> {
R handler(C c);
Class<C> getCmdType();
}
src/main/java/sanjaisyinterfaces/SomeRequestHandler.java
package sanjaisyinterfaces;
import jakarta.inject.Singleton;
@Singleton
public class SomeRequestHandler implements IRequestHandler<SomeCommandType, SomeReturnType> {
@Override
public SomeReturnType handler(SomeCommandType someCommandType) {
System.out.println("SomeRequestHandler is handling a request for SomeCommandType");
// do whatever needs to be done here
return null;
}
@Override
public Class getCmdType() {
return SomeCommandType.class;
}
}
src/main/java/sanjaisyinterfaces/SomeOtherRequestHandler.java
package sanjaisyinterfaces;
import jakarta.inject.Singleton;
@Singleton
public class SomeOtherRequestHandler implements IRequestHandler<SomeOtherCommandType, SomeOtherReturnType> {
@Override
public SomeOtherReturnType handler(SomeOtherCommandType someCommandType) {
System.out.println("SomeOtherRequestHandler is handling a request for SomeOtherCommandType");
// do whatever needs to be done here
return null;
}
@Override
public Class getCmdType() {
return SomeOtherCommandType.class;
}
}
src/main/java/sanjaisyinterfaces/IServiceBus.java
package sanjaisyinterfaces;
public interface IServiceBus {
Object send(CommandType c);
}
src/main/java/sanjaisyinterfaces/ServiceBus.java
package sanjaisyinterfaces;
import jakarta.inject.Singleton;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import static java.util.stream.Collectors.toMap;
@Singleton
public class ServiceBus implements IServiceBus {
private final Map<Class<?>, IRequestHandler<?, ?>> handlerMap;
public ServiceBus(List<IRequestHandler<?, ?>> handlers) {
handlerMap = handlers.stream()
.collect(toMap(
IRequestHandler::getCmdType,
Function.identity()
));
}
@Override
public Object send(CommandType c) {
IRequestHandler handler = handlerMap.get(c.getClass());
if (handler == null)
throw new UnsupportedOperationException("Unsupported command: " + c.getClass());
return handler.handler(c);
}
}
src/main/java/sanjaisyinterfaces/SanjaisyinterfacesCommand.java
package sanjaisyinterfaces;
import io.micronaut.configuration.picocli.PicocliRunner;
import io.micronaut.context.ApplicationContext;
import jakarta.inject.Inject;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
@Command(name = "sanjaisyinterfaces", description = "...",
mixinStandardHelpOptions = true)
public class SanjaisyinterfacesCommand implements Runnable {
@Inject
ServiceBus serviceBus;
public static void main(String[] args) throws Exception {
PicocliRunner.run(SanjaisyinterfacesCommand.class, args);
}
public void run() {
CommandType firstCommand = new SomeCommandType();
CommandType secondCommand = new SomeOtherCommandType();
serviceBus.send(firstCommand);
serviceBus.send(secondCommand);
}
}
Running that project indicates that the relationships are being recognized as intended:
~ $ mkdir example
~ $ cd example
example $ git clone [email protected]:jeffbrown/sanjaisyinterfaces.git
Cloning into 'sanjaisyinterfaces'...
remote: Enumerating objects: 47, done.
remote: Counting objects: 100% (47/47), done.
remote: Compressing objects: 100% (35/35), done.
remote: Total 47 (delta 8), reused 44 (delta 5), pack-reused 0
Receiving objects: 100% (47/47), 63.88 KiB | 838.00 KiB/s, done.
Resolving deltas: 100% (8/8), done.
example $
example $ cd sanjaisyinterfaces
sanjaisyinterfaces (main)$ ./gradlew run
> Task :run
09:10:39.377 [main] INFO i.m.context.env.DefaultEnvironment - Established active environments: [cli]
SomeRequestHandler is handling a request for SomeCommandType
SomeOtherRequestHandler is handling a request for SomeOtherCommandType
sanjaisyinterfaces (main)$
Answered By - Jeff Scott Brown
Answer Checked By - Gilberto Lyons (JavaFixing Admin)