Верблюд Запрос / Ответ Корреляция - PullRequest
2 голосов
/ 07 февраля 2012

У меня есть конечная точка 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();
 }
}

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

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

1 Ответ

1 голос
/ 08 февраля 2012

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

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

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

...