Верблюжья корреляция запроса/ответа

У меня есть конечная точка CXFRS, где такой запрос, как «GET /files/x», должен вернуть файл «x» из определенного каталога, а затем удалить его. Файлы выводятся из другого процесса, а затем быстро потребляются по этому маршруту. Таким образом, было бы приемлемо, если бы они были опрошены и временно сохранены в памяти.

Ниже мой веб-сервис.

@Component
@Path("/")
public class WebService {
 @GET
 @Path("files/{id}")
 public String getFile(@PathParam("id") String id) {
  return null;
 }
}

Ниже неполный маршрут.

<route>
 <from uri="cxfrs://bean:webService"/>
 <choice>
  <when>
   <simple>${in.headers.operationName} == 'getFile'</simple>
   <setHeader headerName="correlationId">
    <simple>mandatoryBodyAs(java.lang.String)</simple>
   </setHeader>
   ???
  </when>
 <choice>
</route>

Я исследовал шаблон обогащения контента, но это не поможет, потому что потребитель не может получить доступ к исходному обмену внутри расширителя. Таким образом, имя файла не может быть динамически определено из входного сообщения. Другими словами, в приведенном ниже примере файл «x» не будет прочитан, потому что конечная точка файла никогда не увидит заголовок.

...setHeader(Exchange.FILE_NAME, "x").pollEnrich("file://dir")...

Я также попытался использовать шаблон агрегатора между маршрутом веб-службы и отдельным файловым маршрутом со стратегией агрегации, показанной ниже.

@Component
public class Aggregator implements AggregationStrategy {
 public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
  if (oldExchange == null) {
   return newExchange;
  } else {
   oldExchange.getOut().setBody(newExchange.getIn().getBody());
   return oldExchange;
  }
 } 
}

Это не работает, потому что шаблон агрегатора, по-видимому, предназначен для обменов «только внутри»; при обмене «in out» ответ возвращается клиенту, как только сообщение достигает агрегатора, а не после завершения агрегирования. Впоследствии я перешел к написанию описанного ниже процесса.

@Component
public class FileEnricher implements Processor {

 @Value("${folder}")
 private String folder;

 public void process(Exchange exchange) throws Exception {

  Endpoint endpoint = exchange.getContext().getEndpoint(String.format(
   "file://%s?fileName=%s",
   folder,
   exchange.getIn().getHeader("correlationId")
  ));
  PollingConsumer consumer = endpoint.createPollingConsumer();
  PollEnricher enricher = new PollEnricher(consumer);
  enricher.setTimeout(10000);

  consumer.start();
  enricher.process(exchange);
  enricher.shutdown();
  consumer.stop();
 }
}

Этот процесс не делает ничего, кроме как позволяет мне динамически настраивать средство обогащения контента. Мне трудно поверить, что нет лучшего способа сделать это. В частности, меня беспокоит многопоточность и постоянное добавление/удаление компонентов/конечных точек в контексте.

Может ли кто-нибудь предложить лучшее решение этой проблемы?


person Jared O'Connor    schedule 07.02.2012    source источник
comment
Существует билет JIRA для улучшения pollEnrich в будущем выпуске Camel: issues.apache.org/ jira/browse/CAMEL-4163   -  person Claus Ibsen    schedule 08.02.2012


Ответы (1)


Просто установите тело сообщения с помощью java.io.File для файла, который будет обогащен, например, из java bean. А затем направьте сообщение на bean-компонент:

public File whichFileToPick(@Header("id") String id) {
   return new File("somedir/" + id");
}

В будущем pollEnrich будет улучшен, поэтому его будет проще делать непосредственно на маршруте Camel. Кристиану пришла в голову хорошая идея разрешить указывать выражение Camel в качестве uri для pollEnrich.

person Claus Ibsen    schedule 08.02.2012