private static CommandInterfaceInfo forInterfaceUncached(Class<?> iface) { checkNotNull(iface, "iface must not be null"); checkArgument(iface.isInterface(), "iface must be interface"); checkArgument(iface.isAnnotationPresent(HandlesCommandsFor.class), "Interface %s is not annotated with @HandlesCommandsFor", iface); String aggregateType = iface.getAnnotation(HandlesCommandsFor.class).value(); Map<Method, CommandMethodMapping> commandMappers = getCommandMappers(iface, aggregateType); Map<CommandType, CommandTypeInfo> typeInfoMap = commandMappers.values().stream().collect(Collectors.toMap( CommandMethodMapping::getCommandType, CommandMethodMapping::getCommandTypeInfo )); MultiTypeCommandDispatcher commandDispatcher = CommandDispatchers.dispatchingCommandsByType(commandMappers); return new CommandInterfaceInfo(typeInfoMap, commandMappers, CommandTypeMatcher.matchingAgainst(typeInfoMap), commandDispatcher); }
/** * Convert this {@link CommandJson} to an {@link Command}, using the supplied {@link CommandTypeMatcher} and * {@link ObjectMapper}. * @param typeMatcher The {@link CommandTypeMatcher} to use to resolve {@link CommandType}s to * {@link com.opencredo.concursus.domain.commands.CommandTypeInfo}. * @param objectMapper The {@link ObjectMapper} to use to deserialise event parameters. * @return The converted {@link Command}, iff the {@link CommandTypeMatcher} matches its type. */ public Optional<Command> toCommand(CommandTypeMatcher typeMatcher, ObjectMapper objectMapper) { CommandType commandType = getCommandType(); BiFunction<JsonNode, Type, Object> deserialiser = makeDeserialiser(objectMapper); return typeMatcher.match(commandType).map(typeInfo -> commandType.makeCommand( aggregateId, StreamTimestamp.of(streamId, Instant.ofEpochMilli(commandTimestamp)), typeInfo.getTupleSchema().deserialise(deserialiser, parameters), typeInfo.getReturnType() )) .map(command -> processingId.isEmpty() ? command : command.processed(UUID.fromString(processingId)) ); }