Исключение при разборе ответа Json от Swift API

У меня есть несколько файлов, загруженных в хранилище объектов openstacks. Этот фрагмент извлекает список контейнеров и объектов и распечатывает их.

private void listContainers() {
      ContainerApi containerApi = swiftApi.getContainerApiForRegion("region");
      Set<Container> containers = containerApi.list().toSet();

      for (Container container : containers) {
          ObjectApi objectApi = swiftApi.getObjectApiForRegionAndContainer("region", container.getName());

          ObjectList objects = objectApi.list();  // crashes here
          for (SwiftObject object: objects) {
             System.out.println("\t\t"+ object);
          }

          System.out.println("\t" + container);
      }
   }

вывод консоли:

DEBUG o.j.rest.internal.InvokeHttpMethod - >> invoking container:list
DEBUG o.j.h.i.JavaUrlHttpCommandExecutorService - Sending request -363056976: GET http://127.0.0.1/swift/v1/?format=json HTTP/1.1
DEBUG jclouds.headers - >> GET http://127.0.0.1/swift/v1/?format=json HTTP/1.1
DEBUG jclouds.headers - >> Accept: application/json
DEBUG jclouds.headers - >> X-Auth-Token: MIIQ...
DEBUG o.j.h.i.JavaUrlHttpCommandExecutorService - Receiving response -363056976: HTTP/1.1 200 OK
DEBUG jclouds.headers - << HTTP/1.1 200 OK
DEBUG jclouds.headers - << Transfer-Encoding: chunked
DEBUG jclouds.headers - << Date: Tue, 25 Nov 2014 07:39:44 GMT
DEBUG jclouds.headers - << Keep-Alive: timeout=5, max=98
DEBUG jclouds.headers - << Connection: Keep-Alive
DEBUG jclouds.headers - << Server: Apache/2.2.22 (Ubuntu)
DEBUG jclouds.headers - << Content-Type: application/json; charset=utf-8
DEBUG jclouds.wire - << "[{"name":"jclouds-example","count":1,"bytes":12},{"name":"test_name","count":3,"bytes":22008217}]"
DEBUG o.j.rest.internal.InvokeHttpMethod - >> invoking object:list
DEBUG o.j.h.i.JavaUrlHttpCommandExecutorService - Sending request -1472717862: GET http://127.0.0.1/swift/v1/jclouds-example/?format=json HTTP/1.1
DEBUG jclouds.headers - >> GET http://127.0.0.1/swift/v1/jclouds-example/?format=json HTTP/1.1
DEBUG jclouds.headers - >> Accept: application/json
DEBUG jclouds.headers - >> X-Auth-Token: MIIQ...
DEBUG o.j.h.i.JavaUrlHttpCommandExecutorService - Receiving response -1472717862: HTTP/1.1 200 OK
DEBUG jclouds.headers - << HTTP/1.1 200 OK
DEBUG jclouds.headers - << Transfer-Encoding: chunked
DEBUG jclouds.headers - << Date: Tue, 25 Nov 2014 07:39:44 GMT
DEBUG jclouds.headers - << Keep-Alive: timeout=5, max=97
DEBUG jclouds.headers - << Connection: Keep-Alive
DEBUG jclouds.headers - << Server: Apache/2.2.22 (Ubuntu)
DEBUG jclouds.headers - << Content-Type: application/json; charset=utf-8
DEBUG jclouds.wire - << "[{"name":"jclouds-example.txt","hash":"ed076287532e86365e841e92bfc50d8c","bytes":12,"content_type":"application\/unknown","last_modified":"2014-11-25T07:39:44.000Z"}]"
java.lang.NumberFormatException: null
    at java.lang.Long.parseLong(Long.java:404)
    at java.lang.Long.parseLong(Long.java:483)
    at org.jclouds.openstack.swift.v1.functions.ParseContainerFromHeaders.apply(ParseContainerFromHeaders.java:39)
    at org.jclouds.openstack.swift.v1.functions.ParseObjectListFromResponse.apply(ParseObjectListFromResponse.java:66)
    at org.jclouds.openstack.swift.v1.functions.ParseObjectListFromResponse.apply(ParseObjectListFromResponse.java:41)
    at org.jclouds.rest.internal.InvokeHttpMethod.invoke(InvokeHttpMethod.java:90)
    at org.jclouds.rest.internal.InvokeHttpMethod.apply(InvokeHttpMethod.java:73)
    at org.jclouds.rest.internal.InvokeHttpMethod.apply(InvokeHttpMethod.java:44)
    at org.jclouds.reflect.FunctionalReflection$FunctionalInvocationHandler.handleInvocation(FunctionalReflection.java:117)
    at com.google.common.reflect.AbstractInvocationHandler.invoke(AbstractInvocationHandler.java:87)
    at com.sun.proxy.$Proxy66.list(Unknown Source)
    at test.jcloud.JCloudsSwift.listContainers(JCloudsSwift.java:99)
    at test.jcloud.JCloudsSwift.main(JCloudsSwift.java:39)

Если я укажу имя файла и получу его метаданные, все будет работать нормально:

...
for (Container container : containers) {
    ObjectApi objectApi = swiftApi.getObjectApiForRegionAndContainer("region", container.getName());
    SwiftObject obj = objectApi.get("jclouds-example.txt");
    System.out.println("--  "+obj.getMetadata());
    ObjectList objects = objectApi.list();
...

вывод консоли:

DEBUG o.j.rest.internal.InvokeHttpMethod - >> invoking object:get
DEBUG o.j.h.i.JavaUrlHttpCommandExecutorService - Sending request -614124758: GET http://127.0.0.1/swift/v1/jclouds-example/jclouds-example.txt HTTP/1.1
DEBUG jclouds.headers - >> GET http://127.0.0.1/swift/v1/jclouds-example/jclouds-example.txt HTTP/1.1
DEBUG jclouds.headers - >> Accept: application/json
DEBUG jclouds.headers - >> X-Auth-Token: MIIQ...
DEBUG o.j.h.i.JavaUrlHttpCommandExecutorService - Receiving response -614124758: HTTP/1.1 200 OK
DEBUG jclouds.headers - << HTTP/1.1 200 OK
DEBUG jclouds.headers - << etag: ed076287532e86365e841e92bfc50d8c
DEBUG jclouds.headers - << Date: Tue, 25 Nov 2014 07:48:49 GMT
DEBUG jclouds.headers - << Last-Modified: Tue, 25 Nov 2014 07:48:49 GMT
DEBUG jclouds.headers - << Keep-Alive: timeout=5, max=97
DEBUG jclouds.headers - << X-Object-Meta-key4: blu
DEBUG jclouds.headers - << X-Object-Meta-key3: value3
DEBUG jclouds.headers - << Connection: Keep-Alive
DEBUG jclouds.headers - << Accept-Ranges: bytes
DEBUG jclouds.headers - << Server: Apache/2.2.22 (Ubuntu)
DEBUG jclouds.headers - << Content-Type: application/unknown
DEBUG jclouds.headers - << Content-Length: 12
DEBUG jclouds.wire - << "Hello World!"
--  {key4=blu, key3=value3}

Код основан на этом примере и получении информации об объекте на это пример

Проблема

Я получаю NumberFormatException, когда jclouds преобразует данные json, содержащие список объектов, в объект java.

Вопрос

Как я могу получить список файлов для каждого контейнера и получить их метаданные?


person gkiko    schedule 25.11.2014    source источник


Ответы (1)


Я только что попробовал это на OpenStack Juno с jclouds 1.8.1, и у меня это работает. Какие версии OpenStack и jclouds вы используете?

Я также заметил, что в ответе со списком объектов отсутствуют заголовки X-Container-Object-Count и X-Container-Bytes-Used. Странно, согласно этому справочнику по API, они должны быть там. Возможно, ваш сервер Apache манипулирует или фильтрует заголовки?

Если вы хотите попробовать jclouds 1.8.1, прочтите эти примечания к выпуску первый.

person Everett Toews    schedule 03.12.2014
comment
Я использую jclouds 1.8.1 и openstack 2014.1. - person gkiko; 04.12.2014
comment
Swift действительно должен перенастраивать заголовки X-Container-Object-Count и X-Container-Bytes-Used, они существовали задолго до 2014.1 (см. server.py). Возможно, ваш сервер Apache манипулирует или фильтрует заголовки? - person Everett Toews; 04.12.2014
comment
Кроме того, как вы заставили запрос заканчиваться на ?format=json GET http://127.0.0.1/swift/v1/jclouds-example/?format=json? Это невозможно сделать при вызове ObjectApi.list() в версии 1.8.1 (см. ObjectApi.java). - person Everett Toews; 04.12.2014
comment
Я скачал исходник jclouds 1.8.1, и он отличается от копии на github. Например, метод ObjectApi ObjectList list(); имеет тег @QueryParams(keys = format, values ​​= json) - person gkiko; 05.12.2014
comment
Не могли бы вы прислать ссылку на точно то, что вы скачали? - person Everett Toews; 05.12.2014
comment
Я использую пример maven с веб-сайта jclouds. Исходники скачивал через maven - person gkiko; 06.12.2014
comment
Если это так, то канонические источники поступают из sources.jar в хранилище.apache.org (также в sources.jar в Maven Central). Оба согласны с GitHub ObjectApi.java. - person Everett Toews; 08.12.2014
comment
Мне бы тоже хотелось узнать об этом несоответствии, так как я думаю, что это имеет отношение к моей проблеме, когда JClouds не добавит этот параметр в строку запроса, и поэтому Swift вернет ответ в обычном/текстовом формате, поэтому я получить сообщение об ошибке: stackoverflow.com/questions/35439056/ - person krause; 18.02.2016