Как я могу использовать HttpBuilder с частичным путем в URL? - PullRequest
1 голос
/ 07 мая 2019

В моем приложении Grails у меня есть свойство config, которое включает частичный путь URL, например: http://apis.mycompany.com/my-api/v1/

Я хочу вызвать конечные точки, используя этот URL с HttpBuilder:

class MyApiService {
    @Value('${myApiUrl}')
    String myApiUrl

    def http

    @PostConstruct()
    init() {
        http = HttpBuilder.configure {
            request.uri = myApiUrl
        }
    }

    def getData() {
        http.get() {
            // This doesn't work!!
            request.uri.path = 'resource/data'
        }
    }
}

request.uri.path стирает существующий сегмент пути:

java.lang.RuntimeException: java.net.URISyntaxException: Relative path in absolute URI: http://apis.mycompany.comresource/data

Мне удалось обойти это:

request.raw = "${myApiUrl}resource/data"

... но я не могу заставить Эрзаца работать с raw в моем тесте Спока:

def setup() {
    ersatz = new ErsatzServer()
    service.myApiUrl = ersatz.httpUrl + '/'
}

void "getData() - should call the endpoint"() {
    given:
    def jsonData = '[{"person": "Someone"}]'

    ersatz.expectations {
        get("/resource/data") {
            called 1
            responder {
                content jsonData, 'application/json;chartset=UTF-8'
            }
        }
    }

    when:
    def result = service.getData()

    then:
    result == jsonData
}

URL, назначаемый для raw: http://localhost:-1/resources/data

Это приводит к исключению:

java.lang.IllegalArgumentException: protocol = http host = null

    at sun.net.spi.DefaultProxySelector.select(DefaultProxySelector.java:176)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1132)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1032)
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:966)
    at groovyx.net.http.JavaHttpBuilder$Action.lambda$execute$2(JavaHttpBuilder.java:147)
    at groovyx.net.http.JavaHttpBuilder$ThreadLocalAuth.with(JavaHttpBuilder.java:331)
    at groovyx.net.http.JavaHttpBuilder$Action.execute(JavaHttpBuilder.java:122)
    at groovyx.net.http.JavaHttpBuilder.createAndExecute(JavaHttpBuilder.java:374)
    at groovyx.net.http.JavaHttpBuilder.doGet(JavaHttpBuilder.java:381)
    at groovyx.net.http.HttpObjectConfigImpl.nullInterceptor(HttpObjectConfigImpl.java:47)
    at groovyx.net.http.HttpBuilder.get(HttpBuilder.java:346)
    at groovyx.net.http.HttpBuilder.get(HttpBuilder.java:1297)
    at com.mycompany.MyApiService.getData(...)
    at com.mycompany.MyApiServiceSpec.getData(...)

Это ошибка в HttpBuilder или я делаю это неправильно? Помощь оценена!

Обновление:

Я думал, что Эрзац начнется, когда его построят, но, оказывается, я ошибся. Вызов start() перед использованием URL исправил номер порта -1:

def setup() {
    ersatz = new ErsatzServer()
    ersatz.start()
    service.myApiUrl = ersatz.httpUrl + '/'
}

Теперь разработчик получает, казалось бы, действительный URL: http://localhost:52180/resources/data

... но сервер Ersatz выдает сообщение о том, что ожидание не соответствует.

java.lang.AssertionError: Expectations for Expectations (ErsatzRequest): <GET>, "/resources/data" were not met.. Expression: (com.stehno.ersatz.impl.ErsatzRequest -> com.stehno.ersatz.impl.ErsatzRequest) r.verify()

    at com.stehno.ersatz.impl.ExpectationsImpl.verify_closure2(ExpectationsImpl.groovy:365)
    at com.stehno.ersatz.impl.ExpectationsImpl.verify(ExpectationsImpl.groovy:364)
    at com.stehno.ersatz.ErsatzServer.verify(ErsatzServer.groovy:522)
    at com.mycompany.MyApiServiceSpec.cleanup(...)

В документах Ersatz указано, что несопоставленный запрос должен быть распечатан, но он печатает только вышеуказанную трассировку стека (и исключение HttpNotFoundException).

...