下面列出了怎么用 io.netty.handler.codec.http.HttpMethod 的API类实例代码及写法,或者点击链接到github查看源代码。
private void testPredictionsDecodeRequest(Channel inferChannel, Channel mgmtChannel)
throws InterruptedException, NoSuchFieldException, IllegalAccessException {
setConfiguration("decode_input_request", "true");
loadTests(mgmtChannel, "noop-v1.0-config-tests", "noop-config");
result = null;
latch = new CountDownLatch(1);
DefaultFullHttpRequest req =
new DefaultFullHttpRequest(
HttpVersion.HTTP_1_1, HttpMethod.POST, "/predictions/noop-config");
req.content().writeCharSequence("{\"data\": \"test\"}", CharsetUtil.UTF_8);
HttpUtil.setContentLength(req, req.content().readableBytes());
req.headers().set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON);
inferChannel.writeAndFlush(req);
latch.await();
Assert.assertEquals(httpStatus, HttpResponseStatus.OK);
Assert.assertFalse(result.contains("bytearray"));
unloadTests(mgmtChannel, "noop-config");
}
public static void unregisterModel(
Channel channel, String modelName, String version, boolean syncChannel)
throws InterruptedException {
String requestURL = "/models/" + modelName;
if (version != null) {
requestURL += "/" + version;
}
HttpRequest req =
new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.DELETE, requestURL);
if (syncChannel) {
channel.writeAndFlush(req).sync();
channel.closeFuture().sync();
} else {
channel.writeAndFlush(req);
}
}
/**
* Returns all methods that this router handles. For {@code OPTIONS *}.
*/
public Set<HttpMethod> allAllowedMethods() {
if (anyMethodRouter.size() > 0) {
Set<HttpMethod> ret = new HashSet<HttpMethod>(9);
ret.add(HttpMethod.CONNECT);
ret.add(HttpMethod.DELETE);
ret.add(HttpMethod.GET);
ret.add(HttpMethod.HEAD);
ret.add(HttpMethod.OPTIONS);
ret.add(HttpMethod.PATCH);
ret.add(HttpMethod.POST);
ret.add(HttpMethod.PUT);
ret.add(HttpMethod.TRACE);
return ret;
} else {
return new HashSet<HttpMethod>(routers.keySet());
}
}
@Test
public void disableChunkForced() {
AtomicReference<HttpHeaders> headers = new AtomicReference<>();
Tuple2<HttpResponseStatus, String> r =
HttpClient.newConnection()
.host("localhost")
.port(getPort())
.headers(h -> h.set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED))
.wiretap(true)
.doAfterRequest((req, connection) -> headers.set(req.requestHeaders()))
.request(HttpMethod.GET)
.uri("/status/400")
.send(ByteBufFlux.fromString(Flux.just("hello")))
.responseSingle((res, conn) -> Mono.just(res.status())
.zipWith(conn.asString()))
.block(Duration.ofSeconds(30));
assertThat(r).isNotNull();
assertThat(r.getT1()).isEqualTo(HttpResponseStatus.BAD_REQUEST);
assertThat(headers.get().get("Content-Length")).isEqualTo("5");
assertThat(headers.get().get("Transfer-Encoding")).isNull();
}
@Test(
alwaysRun = true,
dependsOnMethods = {"testPredictionsBinary"})
public void testPredictionsJson() throws InterruptedException {
Channel channel = TestUtils.getInferenceChannel(configManager);
TestUtils.setResult(null);
TestUtils.setLatch(new CountDownLatch(1));
DefaultFullHttpRequest req =
new DefaultFullHttpRequest(
HttpVersion.HTTP_1_1, HttpMethod.POST, "/predictions/noop");
req.content().writeCharSequence("{\"data\": \"test\"}", CharsetUtil.UTF_8);
HttpUtil.setContentLength(req, req.content().readableBytes());
req.headers().set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON);
channel.writeAndFlush(req);
TestUtils.getLatch().await();
Assert.assertEquals(TestUtils.getResult(), "OK");
}
@Test
public void testDowngradeFullHeaders() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new Http2StreamFrameToHttpObjectCodec(true));
Http2Headers headers = new DefaultHttp2Headers();
headers.path("/");
headers.method("GET");
assertTrue(ch.writeInbound(new DefaultHttp2HeadersFrame(headers, true)));
FullHttpRequest request = ch.readInbound();
try {
assertThat(request.uri(), is("/"));
assertThat(request.method(), is(HttpMethod.GET));
assertThat(request.protocolVersion(), is(HttpVersion.HTTP_1_1));
assertThat(request.content().readableBytes(), is(0));
assertTrue(request.trailingHeaders().isEmpty());
assertFalse(HttpUtil.isTransferEncodingChunked(request));
} finally {
request.release();
}
assertThat(ch.readInbound(), is(nullValue()));
assertFalse(ch.finish());
}
private void testRegisterModelMalformedUrl() throws InterruptedException {
Channel channel = connect(true);
Assert.assertNotNull(channel);
HttpRequest req =
new DefaultFullHttpRequest(
HttpVersion.HTTP_1_1,
HttpMethod.POST,
"/models?url=http%3A%2F%2Flocalhost%3Aaaaa");
channel.writeAndFlush(req).sync();
channel.closeFuture().sync();
ErrorResponse resp = JsonUtils.GSON.fromJson(result, ErrorResponse.class);
Assert.assertEquals(resp.getCode(), HttpResponseStatus.NOT_FOUND.code());
Assert.assertEquals(resp.getMessage(), "Invalid model url: http://localhost:aaaa");
}
/**
* Creates a {@link NettyRequest} with the given parameters.
* @param httpMethod the {@link HttpMethod} desired.
* @param uri the URI desired.
* @param headers {@link HttpHeaders} that need to be a part of the request.
* @param channel the {@link Channel} that the request arrived over.
* @return {@link NettyRequest} encapsulating a {@link HttpRequest} with the given parameters.
* @throws RestServiceException if the {@code httpMethod} is not recognized by {@link NettyRequest}.
*/
private NettyRequest createNettyRequest(HttpMethod httpMethod, String uri, HttpHeaders headers, Channel channel)
throws RestServiceException {
MetricRegistry metricRegistry = new MetricRegistry();
RestRequestMetricsTracker.setDefaults(metricRegistry);
HttpRequest httpRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, httpMethod, uri, false);
if (headers != null) {
httpRequest.headers().set(headers);
}
NettyRequest nettyRequest =
new NettyRequest(httpRequest, channel, new NettyMetrics(metricRegistry), BLACKLISTED_QUERY_PARAM_SET);
assertEquals("Auto-read is in an invalid state",
(!httpMethod.equals(HttpMethod.POST) && !httpMethod.equals(HttpMethod.PUT))
|| NettyRequest.bufferWatermark <= 0, channel.config().isAutoRead());
return nettyRequest;
}
@Test
public void testSuggestPostWithValidTypeAndQuery() throws Exception {
// @formatter:off
String content =
"{\n" +
" \"type\": \"metrics\",\n" +
" \"q\": \"sys.cpu.user\"\n" +
"}";
// @formatter:on
decoder = new TestHttpQueryDecoder(config);
DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST,
"/api/suggest");
request.content().writeBytes(content.getBytes());
addCookie(request);
decoder.decode(null, request, results);
Assert.assertEquals(1, results.size());
Assert.assertEquals(SuggestRequest.class, results.iterator().next().getClass());
SuggestRequest suggest = (SuggestRequest) results.iterator().next();
Assert.assertEquals("metrics", suggest.getType());
Assert.assertEquals("sys.cpu.user", suggest.getQuery().get());
Assert.assertEquals(25, suggest.getMax());
suggest.validate();
}
@Override
public AbstractHttpDownBootstrap update(UpdateInfo updateInfo)
throws Exception {
HttpRequestInfo requestInfo = new HttpRequestInfo(HttpVer.HTTP_1_1, HttpMethod.GET.toString(),
updateInfo.getUrl(), buildHead(), null);
requestInfo.setRequestProto(new RequestProto(HOST, 80, false));
TaskInfo taskInfo = HttpDownUtil
.getTaskInfo(requestInfo, null, null, HttpDownConstant.clientSslContext,
HttpDownConstant.clientLoopGroup)
.setConnections(64)
.setFileName("proxyee-down-core.jar.bak")
.setFilePath(HttpDownConstant.MAIN_PATH);
HttpDownInfo httpDownInfo = new HttpDownInfo(taskInfo, requestInfo, null);
AbstractHttpDownBootstrap bootstrap = HttpDownBootstrapFactory.create(httpDownInfo, 5,
HttpDownConstant.clientSslContext, HttpDownConstant.clientLoopGroup, null);
bootstrap.startDown();
return bootstrap;
}
/**
* Tests for failure when {@link NettyRequest#getDigest()} is called without a call to
* {@link NettyRequest#setDigestAlgorithm(String)}.
* @throws RestServiceException
*/
private void getDigestWithoutSettingAlgorithmTest() throws RestServiceException {
List<HttpContent> httpContents = new ArrayList<HttpContent>();
generateContent(httpContents);
Channel channel = new MockChannel();
NettyRequest nettyRequest = createNettyRequest(HttpMethod.POST, "/", null, channel);
ByteBufferAsyncWritableChannel writeChannel = new ByteBufferAsyncWritableChannel();
ReadIntoCallback callback = new ReadIntoCallback();
nettyRequest.readInto(writeChannel, callback);
for (HttpContent httpContent : httpContents) {
nettyRequest.addContent(httpContent);
}
assertNull("Digest should be null because no digest algorithm was set", nettyRequest.getDigest());
closeRequestAndValidate(nettyRequest, channel);
}
private RequestMatcher createMatcher() {
HttpGet[] gets = this.getClass().getAnnotationsByType(HttpGet.class);
HttpPost[] posts = this.getClass().getAnnotationsByType(HttpPost.class);
if ((gets.length + posts.length) > 0) {
List<RequestMatcher> matchers = new ArrayList<>(gets.length + posts.length);
for (HttpGet get : gets) {
matchers.add(new WildcardMatcher(get.value(), HttpMethod.GET));
}
for (HttpPost post : posts) {
matchers.add(new WildcardMatcher(post.value(), HttpMethod.POST));
}
return new MultiMatcher(matchers);
}
else {
return new NeverMatcher();
}
}
@Test(
alwaysRun = true,
dependsOnMethods = {"testDescribeModelNotFound"})
public void testRegisterModelMissingUrl() throws InterruptedException {
Channel channel = TestUtils.connect(true, configManager);
Assert.assertNotNull(channel);
HttpRequest req =
new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/models");
channel.writeAndFlush(req).sync();
channel.closeFuture().sync();
ErrorResponse resp = JsonUtils.GSON.fromJson(TestUtils.getResult(), ErrorResponse.class);
Assert.assertEquals(resp.getCode(), HttpResponseStatus.BAD_REQUEST.code());
Assert.assertEquals(resp.getMessage(), "Parameter url is required.");
}
@Test(
alwaysRun = true,
dependsOnMethods = {"testRegisterModelMissingUrl"})
public void testRegisterModelInvalidRuntime() throws InterruptedException {
Channel channel = TestUtils.connect(true, configManager);
Assert.assertNotNull(channel);
HttpRequest req =
new DefaultFullHttpRequest(
HttpVersion.HTTP_1_1,
HttpMethod.POST,
"/models?url=InvalidUrl&runtime=InvalidRuntime");
channel.writeAndFlush(req).sync();
channel.closeFuture().sync();
ErrorResponse resp = JsonUtils.GSON.fromJson(TestUtils.getResult(), ErrorResponse.class);
Assert.assertEquals(resp.getCode(), HttpResponseStatus.BAD_REQUEST.code());
Assert.assertEquals(resp.getMessage(), "Invalid RuntimeType value: InvalidRuntime");
}
@Test
public void testLookupPostWithNoLimit() throws Exception {
// @formatter:off
String content =
"{\n" +
" \"metric\": \"sys.cpu.user\"\n" +
"}";
// @formatter:on
decoder = new TestHttpQueryDecoder(config);
DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST,
"/api/search/lookup");
request.content().writeBytes(content.getBytes());
addCookie(request);
decoder.decode(null, request, results);
Assert.assertEquals(1, results.size());
Assert.assertEquals(SearchLookupRequest.class, results.iterator().next().getClass());
SearchLookupRequest lookup = (SearchLookupRequest) results.iterator().next();
Assert.assertEquals("sys.cpu.user", lookup.getQuery());
Assert.assertEquals(25, lookup.getLimit());
Assert.assertEquals(0, lookup.getTags().size());
}
@Test(
alwaysRun = true,
dependsOnMethods = {"testRegisterModelInvalidPath"})
public void testScaleModelNotFound() throws InterruptedException {
Channel channel = TestUtils.connect(true, configManager);
Assert.assertNotNull(channel);
HttpRequest req =
new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.PUT, "/models/fake");
channel.writeAndFlush(req).sync();
channel.closeFuture().sync();
ErrorResponse resp = JsonUtils.GSON.fromJson(TestUtils.getResult(), ErrorResponse.class);
Assert.assertEquals(resp.getCode(), HttpResponseStatus.NOT_FOUND.code());
Assert.assertEquals(resp.getMessage(), "Model not found: fake");
}
@Test
public void should_return_expected_response_when_chunked_request_not_exceeding_global_request_size() throws Exception {
NettyHttpClientRequestBuilder request = request()
.withMethod(HttpMethod.POST)
.withUri(BasicEndpoint.MATCHING_PATH)
.withPaylod(generatePayloadOfSizeInBytes(GLOBAL_MAX_REQUEST_SIZE))
.withHeader(HttpHeaders.Names.TRANSFER_ENCODING, CHUNKED);
// when
NettyHttpClientResponse serverResponse = request.execute(serverConfig.endpointsPort(),
incompleteCallTimeoutMillis);
// then
assertThat(serverResponse.statusCode).isEqualTo(HttpResponseStatus.OK.code());
assertThat(serverResponse.payload).isEqualTo(BasicEndpoint.RESPONSE_PAYLOAD);
}
@Override
public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
// for POST requests, check Content-Type header
if ( request.getMethod() == HttpMethod.POST ) {
if (!mediaTypeChecker.isContentTypeValid(request.headers())) {
DefaultHandler.sendErrorResponse(ctx, request,
String.format("Unsupported media type for Content-Type: %s", request.headers().get(HttpHeaders.Names.CONTENT_TYPE)),
HttpResponseStatus.UNSUPPORTED_MEDIA_TYPE
);
return;
}
}
// for GET or POST requests, check Accept header
if ( request.getMethod() == HttpMethod.GET || request.getMethod() == HttpMethod.POST ) {
if (!mediaTypeChecker.isAcceptValid(request.headers())) {
DefaultHandler.sendErrorResponse(ctx, request,
String.format("Unsupported media type for Accept: %s", request.headers().get(HttpHeaders.Names.ACCEPT)),
HttpResponseStatus.UNSUPPORTED_MEDIA_TYPE
);
return;
}
}
router.route(ctx, HttpRequestWithDecodedQueryParams.create(request));
}
/**
* Tests for POST request that has no content.
* @throws Exception
*/
@Test
public void zeroSizeContentTest() throws Exception {
Channel channel = new MockChannel();
NettyRequest nettyRequest = createNettyRequest(HttpMethod.POST, "/", null, channel);
HttpContent httpContent = new DefaultLastHttpContent();
nettyRequest.addContent(httpContent);
assertEquals("Reference count is not as expected", 2, httpContent.refCnt());
ByteBufferAsyncWritableChannel writeChannel = new ByteBufferAsyncWritableChannel();
ReadIntoCallback callback = new ReadIntoCallback();
Future<Long> future = nettyRequest.readInto(writeChannel, callback);
assertEquals("There should be no content", 0, writeChannel.getNextChunk().remaining());
writeChannel.resolveOldestChunk(null);
closeRequestAndValidate(nettyRequest, channel);
writeChannel.close();
assertEquals("Reference count of http content has changed", 1, httpContent.refCnt());
callback.awaitCallback();
if (callback.exception != null) {
throw callback.exception;
}
long futureBytesRead = future.get();
assertEquals("Total bytes read does not match (callback)", 0, callback.bytesRead);
assertEquals("Total bytes read does not match (future)", 0, futureBytesRead);
}
@Before
public void setUp() throws Exception {
super.setUp();
builder = buildParameters(null);
FieldUtils.writeField(handler, "twilioAccountAuth", "AUTHKEY", true);
sig = Base64.encodeToString(HmacUtils.hmacSha1 ("AUTHKEY", TwilioHelper.PROTOCOL_HTTPS + "somehost" + builder.toString()));
EasyMock.expect(request.getUri()).andReturn(builder.toString()).anyTimes();
EasyMock.expect(request.getMethod()).andReturn(HttpMethod.GET);
EasyMock.expect(request.headers()).andReturn(httpHeaders).anyTimes();
EasyMock.expect(httpHeaders.contains(TwilioHelper.SIGNATURE_HEADER_KEY)).andReturn(true).anyTimes();
EasyMock.expect(httpHeaders.get(TwilioHelper.SIGNATURE_HEADER_KEY)).andReturn(sig).anyTimes();
EasyMock.expect(httpHeaders.get(TwilioHelper.HOST_HEADER_KEY)).andReturn("somehost").anyTimes();
EasyMock.expect(personDAO.findById(personID)).andReturn(person);
EasyMock.expect(placeDAO.findById(placeId)).andReturn(place);
EasyMock.expect(populationCacheMgr.getPopulationByPlaceId(EasyMock.anyObject(UUID.class))).andReturn(Population.NAME_GENERAL).anyTimes();
}
@PostConstruct
public void init() {
exposeRequest = split(exposeRequestHeaders, false);
allowRequest = split(allowRequestHeaders, false);
String[] splitMethods = split(allowRequestMethods, false);
allowMethods = new HttpMethod[splitMethods.length];
for(int i = 0; i < splitMethods.length; i++) {
allowMethods[i] = new HttpMethod(splitMethods[i]);
}
origins = split(corsOrigins ,true);
logger.info("cors configured expose headers: {}", Arrays.toString(exposeRequest));
logger.info("cors configured allow headers: {}", Arrays.toString(allowRequest));
logger.info("cors configured allow methods: {}", Arrays.toString(allowMethods));
logger.info("cors configured to allow origins: {}", Arrays.toString(origins));
}
private Timer expectedRequestTimer(HttpMethod m, EndpointMetricsHandlerDefaultImpl impl) {
if (m == null) {
return impl.otherRequests;
}
else {
if (m.equals(HttpMethod.GET))
return impl.getRequests;
else if (m.equals(HttpMethod.POST))
return impl.postRequests;
else if (m.equals(HttpMethod.PUT))
return impl.putRequests;
else if (m.equals(HttpMethod.DELETE))
return impl.deleteRequests;
else
return impl.otherRequests;
}
}
/**
* Gets the blob info of the blob with blob ID {@code blobId} and verifies them against what is expected.
* @param blobId the blob ID of the blob to HEAD.
* @param getOption the options to use while getting the blob.
* @param expectedHeaders the expected headers in the response.
* @param isPrivate {@code true} if the blob is expected to be private
* @param accountName the expected account name in the response.
* @param containerName the expected container name in response.
* @param usermetadata if non-null, this is expected to come as the body.
* @throws ExecutionException
* @throws InterruptedException
*/
private void getBlobInfoAndVerify(String blobId, GetOption getOption, HttpHeaders expectedHeaders, boolean isPrivate,
String accountName, String containerName, byte[] usermetadata) throws ExecutionException, InterruptedException {
HttpHeaders headers = new DefaultHttpHeaders();
if (getOption != null) {
headers.add(RestUtils.Headers.GET_OPTION, getOption.toString());
}
FullHttpRequest httpRequest =
buildRequest(HttpMethod.GET, blobId + "/" + RestUtils.SubResource.BlobInfo, headers, null);
ResponseParts responseParts = nettyClient.sendRequest(httpRequest, null, null).get();
HttpResponse response = getHttpResponse(responseParts);
assertEquals("Unexpected response status", HttpResponseStatus.OK, response.status());
checkCommonGetHeadHeaders(response.headers());
verifyTrackingHeaders(response);
verifyBlobProperties(expectedHeaders, isPrivate, response);
verifyAccountAndContainerHeaders(accountName, containerName, response);
verifyUserMetadata(expectedHeaders, response, usermetadata, responseParts.queue);
if (usermetadata == null) {
assertEquals("Content-Length is not 0", 0, HttpUtil.getContentLength(response));
assertNoContent(responseParts.queue, 1);
}
assertTrue("Channel should be active", HttpUtil.isKeepAlive(response));
assertEquals(RestUtils.Headers.LIFE_VERSION + " does not match", expectedHeaders.get(RestUtils.Headers.LIFE_VERSION),
response.headers().get(RestUtils.Headers.LIFE_VERSION));
}
private static void setContent(IHttpRequest request, HttpMethod httpMethod, HttpEntityEnclosingRequestBase httpRequest) {
if (httpMethod != HttpMethod.POST && httpMethod != HttpMethod.PUT) return;
httpRequest.setEntity(request.getContent());
if (request.getContentType() != null && request.getContent() != null) {
httpRequest.setHeader("ContentType", request.getContentType());
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");
request.headers().set(HttpHeaderNames.HOST, host);
request.headers().set(HttpHeaderNames.USER_AGENT, "netty-ocsp-example/1.0");
ctx.writeAndFlush(request).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
ctx.fireChannelActive();
}
/**
* {@inheritDoc}
*/
@Override
public synchronized @Nullable List<InterfaceHttpData> getMultipartParts() {
if (!isMultipartRequest() || !isCompleteRequestWithAllChunks())
return null;
if (multipartData == null) {
byte[] contentBytes = getRawContentBytes();
HttpVersion httpVersion = getProtocolVersion();
HttpMethod httpMethod = getMethod();
// HttpVersion and HttpMethod cannot be null because DefaultFullHttpRequest doesn't allow them to be
// null, but our getProtocolVersion() and getMethod() methods might return null (i.e. due to an
// invalid request). They shouldn't be null in practice by the time this getMultipartParts() method
// is called, but since they don't seem to be used by the Netty code we delegate to, we can just
// default them to something if null somehow slips through.
if (httpVersion == null) {
httpVersion = HttpVersion.HTTP_1_0;
}
if (httpMethod == null) {
httpMethod = HttpMethod.POST;
}
HttpRequest fullHttpRequestForMultipartDecoder =
(contentBytes == null)
? new DefaultFullHttpRequest(httpVersion, httpMethod, getUri())
: new DefaultFullHttpRequest(httpVersion, httpMethod, getUri(),
Unpooled.wrappedBuffer(contentBytes));
fullHttpRequestForMultipartDecoder.headers().add(getHeaders());
multipartData = new HttpPostMultipartRequestDecoder(
new DefaultHttpDataFactory(false), fullHttpRequestForMultipartDecoder, getContentCharset()
);
}
return multipartData.getBodyHttpDatas();
}
@Test
public void testUnauthenticatedWebLaunch() throws Exception {
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/web/launch");
expectGetUnauthenticatedClient();
replay();
FullHttpResponse response = handler.respond(request, mockContext());
assertRedirectTo(response, config.getWebUrl());
}
private CompletableFuture<Void> delete(String uri, UserCredentials userCredentials, HttpResponseStatus expectedStatus) {
FullHttpRequest request = newRequest(HttpMethod.DELETE, uri, defaultOr(userCredentials));
return client.send(request).thenAccept(response -> {
if (response.status().code() == HttpResponseStatus.NOT_FOUND.code()) {
throw new ProjectionNotFoundException(request, response);
} else if (response.status().code() != expectedStatus.code()) {
throw new ProjectionException(request, response);
}
});
}
/**
* Call the {@code POST /accounts} API to update account metadata and verify that the update succeeded.
* @param accounts the accounts to replace or add using the {@code POST /accounts} call.
*/
private void updateAccountsAndVerify(Account... accounts) throws Exception {
JSONObject accountUpdateJson = AccountCollectionSerde.toJson(Arrays.asList(accounts));
FullHttpRequest request = buildRequest(HttpMethod.POST, Operations.ACCOUNTS, null,
ByteBuffer.wrap(accountUpdateJson.toString().getBytes(StandardCharsets.UTF_8)));
ResponseParts responseParts = nettyClient.sendRequest(request, null, null).get();
HttpResponse response = getHttpResponse(responseParts);
assertEquals("Unexpected response status", HttpResponseStatus.OK, response.status());
verifyTrackingHeaders(response);
assertNoContent(responseParts.queue, 1);
for (Account account : accounts) {
assertEquals("Update not reflected in AccountService", account, ACCOUNT_SERVICE.getAccountById(account.getId()));
}
}
@Test
public void assertChannelReadProgress() {
fullHttpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/scaling/job/progress/2");
httpServerHandler.channelRead0(channelHandlerContext, fullHttpRequest);
ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(FullHttpResponse.class);
verify(channelHandlerContext).writeAndFlush(argumentCaptor.capture());
FullHttpResponse fullHttpResponse = (FullHttpResponse) argumentCaptor.getValue();
assertTrue(fullHttpResponse.content().toString(CharsetUtil.UTF_8).contains("Can't find scaling job id 2"));
}