У меня есть приложение
A на
Tomcat, приложение
B на
WildFly. Задача такая: приложение
A имеет три REST-контроллера, которые:
- Выдают список всех расписаний на сегодня
- Выдают конкретное расписание по id
- Выдают список всех станций
Когда я запускаю оба приложения, приложение
B вытаскивает сначала список всех расписаний поездов на сегодня.
Но теперь рассмотрим такой use-case. В приложении
A меняется расписание (добавляется новая запись).
A шлёт сообщение через брокер (RabbitMQ)
B. Приложение
B принимает сообщение и пытается вытащить новое расписание через REST-контроллер первого приложения по id-шнику. И вот именно тут происходят проблемы.
Итак, давайте сначала покажу код самого REST-контроллера:
@RestController
public class BoardScheduleController {
private static final Logger LOGGER = Logger.getLogger(BoardScheduleController.class);
@Autowired
ScheduleService scheduleService;
@Autowired
StationService stationService;
@GetMapping("/api/board/schedule/today")
public ResponseEntity<?> getSchedulesForToday() {
List<ScheduleDTO> schedules = null;
try {
schedules = scheduleService.getAllForToday();
} catch (ParseException e) {
e.printStackTrace();
}
LOGGER.info("RETRIEVED " + schedules.size() + " RECORDS");
return ResponseEntity.ok(schedules);
}
@GetMapping("/api/board/stations")
public ResponseEntity<?> getStationList() {
List<StationDTO> stations = stationService.getAll();
LOGGER.info("RETRIEVED " + stations.size() + " RECORDS");
return ResponseEntity.ok(stations);
}
@GetMapping("/api/board/schedule/{id}")
public ResponseEntity<?> getScheduleById(@PathVariable Long id) {
ScheduleDTO schedule = scheduleService.getByIdScheduleDTO(id);
LOGGER.info("DTO: " + schedule.getStationDepartureName() + " -> " + schedule.getStationArrivalName() + " (" + schedule.getDateDeparture() + " --> " + schedule.getDateArrival() + ")");
LOGGER.info("RETRIEVED " + schedule + " SCHEDULER");
return ResponseEntity.ok(schedule);
}
}
Итак, когда в
service-слое первого приложения отправляется сообщение о том, что появилось изменение в расписании (создалось новое). Затем, когда это сообщение успешно читает
Listener
, второе приложение пытается вытащить оное по id (id новой записи у меня передаётся в самом сообщении в виде строки).
В логах видно, что оно читается:
INFO 2018-10-12 22:49:33,799 [pool-9-thread-4] com.slandshow.helpers.Listener - [x] Received 'create id=46'
INFO 2018-10-12 22:49:33,800 [pool-9-thread-4] com.slandshow.helpers.Listener - create id=46
Теперь пытаемся вытащить данную запись через REST по
id = 46:
public Schedule getById(Long id) {
String response = getResultResponse(Utils.URL_SCHEDULE_BY_ID + id);
Schedule schedule = null;
try {
log.info(response);
schedule = objectMapper.readValue(response, new TypeReference<Schedule>() {
});
} catch (IOException e) {
log.error("ERROR, CAN'T LOAD SCHEDULE BY ID " + e.getMessage());
}
return schedule;
}
...
// Внутри класса Loader использую эту функцию для того, чтобы вытащить JSON по REST'у
private String getResultResponse(String URL) {
WebResource webResource = client.resource(URL);
return webResource.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class).getEntity(String.class);
}
Ну и да, внутри второго приложения используется балванка Schedule:
public class Schedule implements Serializable {
private Long id;
private String dateDeparture;
private String dateArrival;
private String trainName;
private String stationDepartureName;
private String stationArrivalName;
private Integer price;
/* Getters & setters */
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getDateDeparture() { return dateDeparture; }
public void setDateDeparture(String dateDeparture) { this.dateDeparture = dateDeparture; }
public String getDateArrival() { return dateArrival; }
public void setDateArrival(String dateArrival) { this.dateArrival = dateArrival; }
public String getTrainName() { return trainName; }
public void setTrainName(String train) { this.trainName = trainName; }
public String getStationDepartureName() { return stationDepartureName; }
public void setStationDepartureName(String stationDeparture) { this.stationDepartureName = stationDeparture; }
public String getStationArrivalName() { return stationArrivalName; }
public void setStationArrival(String stationArrival) { this.stationArrivalName = stationArrival; }
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
}
Так вот, когда выполняется ретривинг данных через REST, я получаю реквестом
500-ку. Вернее, я получаю строковое представление странички с 500-ой, где написано это:
java.lang.IllegalArgumentException: source cannot be null
Не понимаю, что не так? REST-контроллер должен работать верно, ведь список поездов и расписаний он отправляет, а по id не может найти (вручную проверял и он возвращает действительно валидный JSON).