Проблемы с рестлетом HTTP в OSGi - PullRequest
2 голосов
/ 02 августа 2011

Я увлеченный пользователь фреймворка Restlet (версия 2.08).Вот почему я сейчас пытаюсь использовать Restlet в среде OSGi для практической части моей диссертации.Наконец, я пришел, чтобы создать серверный комплект (который запускается Активатором в моей среде Felix OSGi) и показать сообщение в ответ на простой вызов, такой как http://localhost:8888/.

Но я неудалось получить другой ресурс из моего рестлета.Представьте себе случай, когда мне нужны данные от http://localhost:808​0/tripleStore/triple​s/5, чтобы вычислить результат http://localhost:8888/test.(фрагмент кода следует ...)

public void startServer() throws Exception {
   component = new Component();
   Server server = new Server ( Protocol.HTTP, 8888);
   component.getServers​().add(server);
   Client client = new Client (Protocol.HTTP);
   component.getClients​().add(client);

   Restlet restlet = new Restlet() {
      @Override
      public void handle(Request request, Response response) {
         response.setEntity("Container Resource is active!", MediaType.TEXT_PLAIN);
      }
   };

   Restlet restletTest = new Restlet() {
      @Override
      public void handle(Request request, Response response) {
         RdfClientResource cli = new RdfClientResource("http://localhost:808​0/tripleStore/triples/5");
         cli.setFollowingRedi​rects(false);
         Representation repri = cli.get();
         response.setEntity(repri);
      }
   };

   component.getDefault​Host().attach("/cont​ainer",new Sink());
   component.getDefault​Host().attach("/test​",restletTest);
   component.getDefault​Host().attach(restle​t);
   component.getClients​().add(Protocol.HTTP​);
   component.start();
}

В настоящее время я получаю ошибку "неверный запрос", когда я вызываю http://localhost:808​0/tripleStore/triple​s/5 в моем рестлете, и ошибку "запрещенный", когда я звоню http://127.0.0.1:808​0/tripleStore/triple​s/5 из моего рестлета.

Дальнейшие исследования показали, что причина этих ошибок довольно проста.Рестлет пытается получить результаты напрямую от сетевого прокси, который не знает localhost и запрещает вызов 127.0.0.1.

Еще один критический момент заключается в том, что ошибка всегда была реплицируемой, за исключениемво время одной попыткиВ этом случае все работало нормально.Вот почему я предполагаю отношение к порядку запуска OSGi.(Что не является исправлением и зависит от структуры эфира Sonatype.)

Вам уже известна ошибка, подобная этой?И можете ли вы предложить мне какое-либо исправление, позволяющее избежать попытки запуска всех заказов OSGi вручную?Когда я пытаюсь сделать это за пределами OSGi, все работает вполне нормально.

Заранее спасибо!Marcus

1 Ответ

1 голос
/ 03 августа 2011

Ваша проблема напоминает мне проблему, которая у меня была. Вы должны иметь в виду, что клиентские соединители автоматически регистрируются в движке Restlet. Проблема здесь заключается в порядке загрузки пакета.

Моя проблема была связана с разъемом HTTPS. Вы должны быть уверены, что пакет, предоставляющий соединитель, уже загружен при попытке добавить соединитель клиента. Иначе я увижу что-то подобное в следе:

Internal Connector Error (1002) - No available client connector supports the required
protocol: 'HTTPS'. Please add the JAR of a matching connector to your classpath.

Возможно, перед добавлением клиентского соединителя вы можете проверить загруженные пакеты и перед выполнением запроса REST зарегистрированный клиентский соединитель?

Вот код для просмотра зарегистрированных клиентских коннекторов:

List<ConnectorHelper<Client>> clients = Engine.getInstance().getRegisteredClients();
System.out.println("Connectors - "+clients.size());
for (ConnectorHelper<Client> connectorHelper : clients) {
    System.out.println("connector = "+connectorHelper.getClass());
}

Вы можете использовать прослушиватели комплектов OSGi, чтобы увидеть, загружены ли необходимые комплекты. Вот пример кода:

// Checking the bundle loading in the future
bundleContext.addBundleListener(new BundleListener() {
    public void bundleChanged(BundleEvent event) {
        if (event.getBundle().getSymbolicName().equals("org.restlet.ext.ssl")
                       & event.getBundle().getState()==BundleEvent.RESOLVED) {
            registerClientConnector();
        }
    }
});

// Checking if the bundle is already present
Bundle[] bundles = bundleContext.getBundles();
for (Bundle bundle : bundles) {
    if (bundle.getSymbolicName().equals("org.restlet.ext.ssl")
              && bundle.getState()==BundleEvent.RESOLVED) {
        registerClientConnector();
    }
}

Метод registerClientConnector просто делает что-то подобное: component.getClients (). Add (Protocol.HTTPS);.

Надеюсь, это поможет вам. Не стесняйтесь, присылайте мне минимальный проект, чтобы воспроизвести проблему, чтобы я мог помочь более точно. Thierry

...