下面列出了io.grpc.Status#Code ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void respondWithHttpError(
ChannelHandlerContext ctx, int streamId, int code, Status.Code statusCode, String msg) {
Metadata metadata = new Metadata();
metadata.put(InternalStatus.CODE_KEY, statusCode.toStatus());
metadata.put(InternalStatus.MESSAGE_KEY, msg);
byte[][] serialized = InternalMetadata.serialize(metadata);
Http2Headers headers = new DefaultHttp2Headers(true, serialized.length / 2)
.status("" + code)
.set(CONTENT_TYPE_HEADER, "text/plain; encoding=utf-8");
for (int i = 0; i < serialized.length; i += 2) {
headers.add(new AsciiString(serialized[i], false), new AsciiString(serialized[i + 1], false));
}
encoder().writeHeaders(ctx, streamId, headers, 0, false, ctx.newPromise());
ByteBuf msgBuf = ByteBufUtil.writeUtf8(ctx.alloc(), msg);
encoder().writeData(ctx, streamId, msgBuf, 0, true, ctx.newPromise());
}
/**
* Determine whether the given status maps to the error that GRPC-Java throws when an Android
* device is missing required SSL Ciphers.
*
* <p>This error is non-recoverable and must be addressed by the app developer.
*/
public static boolean isMissingSslCiphers(Status status) {
Status.Code code = status.getCode();
Throwable t = status.getCause();
// Check for the presence of a cipher error in the event of an SSLHandshakeException. This is
// the special case of SSLHandshakeException that contains the cipher error.
boolean hasCipherError = false;
if (t instanceof SSLHandshakeException && t.getMessage().contains("no ciphers available")) {
hasCipherError = true;
}
return Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP
&& code.equals(Status.Code.UNAVAILABLE)
&& hasCipherError;
}
private static void checkEndTags(
MetricsRecord record, String methodName, Status.Code status, boolean clientSide) {
assertNotNull("record is not null", record);
TagKey methodNameTagKey = clientSide
? RpcMeasureConstants.GRPC_CLIENT_METHOD
: RpcMeasureConstants.GRPC_SERVER_METHOD;
TagValue methodNameTag = record.tags.get(methodNameTagKey);
assertNotNull("method name tagged", methodNameTag);
assertEquals("method names match", methodName, methodNameTag.asString());
TagKey statusTagKey = clientSide
? RpcMeasureConstants.GRPC_CLIENT_STATUS
: RpcMeasureConstants.GRPC_SERVER_STATUS;
TagValue statusTag = record.tags.get(statusTagKey);
assertNotNull("status tagged", statusTag);
assertEquals(status.toString(), statusTag.asString());
}
@SafeVarargs
StatusCategoryComparator(List<Status.Code>... statusCategories) {
for (int i = 0; i < statusCategories.length; i++) {
List<Status.Code> codes = statusCategories[i];
for (Status.Code code : codes) {
if (priorities.putIfAbsent(code, i) != null) {
throw new IllegalArgumentException(code + " has been already specified with a different priority");
}
}
}
}
static Set<Status.Code> getRetryableStatusCodesFromRetryPolicy(Map<String, ?> retryPolicy) {
String retryableStatusCodesKey = "retryableStatusCodes";
Set<Status.Code> codes = getListOfStatusCodesAsSet(retryPolicy, retryableStatusCodesKey);
verify(codes != null, "%s is required in retry policy", retryableStatusCodesKey);
verify(!codes.isEmpty(), "%s must not be empty", retryableStatusCodesKey);
verify(!codes.contains(Status.Code.OK), "%s must not contain OK", retryableStatusCodesKey);
return codes;
}
/**
* Wraps call to generateAndRegisterSshTunnelingKeyPair.
*
* @param requestId the request ID for the request
* @param accountId the account ID
* @param minaSshdServiceId the minasshd service ID
* @param keyId the key ID
* @return the response containing the key pair
* @throws CcmException if an exception occurs
*/
public GenerateAndRegisterSshTunnelingKeyPairResponse generateAndRegisterSshTunnelingKeyPair(
String requestId, String accountId, String minaSshdServiceId, String keyId) throws CcmException {
checkNotNull(requestId);
checkNotNull(accountId);
checkNotNull(minaSshdServiceId);
checkNotNull(keyId);
MinaSshdManagementBlockingStub blockingStub = newStub(requestId);
GenerateAndRegisterSshTunnelingKeyPairRequest.Builder requestBuilder = GenerateAndRegisterSshTunnelingKeyPairRequest.newBuilder()
.setAccountId(accountId)
.setMinaSshdServiceId(minaSshdServiceId)
.setKeyId(keyId);
try {
LOGGER.debug("Calling generateAndRegisterSshTunnelingKeyPair with requestId: {}, accountId: {}, minaSshdServiceId: {}, keyId: {}",
requestId, accountId, minaSshdServiceId, keyId);
GenerateAndRegisterSshTunnelingKeyPairResponse response = blockingStub.generateAndRegisterSshTunnelingKeyPair(requestBuilder.build());
if (response == null) {
throw new CcmException("Got null response from MinaSshdManagementService generateAndRegisterSshTunnelingKeyPair gRPC call", false);
} else {
return response;
}
} catch (StatusRuntimeException e) {
String message = "MinaSshdManagementService generateAndRegisterSshTunnelingKeyPair gRPC call failed: " + e.getMessage();
Status status = e.getStatus();
Status.Code code = status.getCode();
boolean retryable = GrpcUtil.isRetryable(code);
LOGGER.debug("Got status code: {}, retryable: {}", code, retryable);
throw new CcmException(message, e, retryable);
}
}
/**
* Wraps call to acquireMinaSshdService.
*
* @param requestId the request ID for the request
* @param accountId the account ID
* @return the minasshd service
* @throws CcmException if an exception occurs
*/
public MinaSshdService acquireMinaSshdService(String requestId, String accountId) throws CcmException {
checkNotNull(requestId);
checkNotNull(accountId);
MinaSshdManagementBlockingStub blockingStub = newStub(requestId);
AcquireMinaSshdServiceRequest.Builder requestBuilder = AcquireMinaSshdServiceRequest.newBuilder()
.setAccountId(accountId);
try {
LOGGER.debug("Calling acquireMinaSshdService with requestId: {}, accountId: {}",
requestId, accountId);
AcquireMinaSshdServiceResponse response = blockingStub.acquireMinaSshdService(requestBuilder.build());
if (response == null) {
throw new CcmException("Got null response from MinaSshdManagementService acquireMinaSshdService gRPC call", false);
} else {
MinaSshdService minaSshdService = response.getMinaSshdService();
if (minaSshdService == null) {
throw new CcmException("Got null minasshd service in MinaSshdManagementService acquireMinaSshdService gRPC response", false);
} else {
return minaSshdService;
}
}
} catch (StatusRuntimeException e) {
String message = "MinaSshdManagementService acquireMinaSshdService gRPC call failed: " + e.getMessage();
Status status = e.getStatus();
Status.Code code = status.getCode();
boolean retryable = GrpcUtil.isRetryable(code);
LOGGER.debug("Got status code: {}, retryable: {}", code, retryable);
throw new CcmException(message, e, retryable);
}
}
private void assertClientStatsTrace(String method, Status.Code code,
Collection<? extends MessageLite> requests, Collection<? extends MessageLite> responses) {
// Tracer-based stats
TestClientStreamTracer tracer = clientStreamTracers.poll();
assertNotNull(tracer);
assertTrue(tracer.getOutboundHeaders());
// assertClientStatsTrace() is called right after application receives status,
// but streamClosed() may be called slightly later than that. So we need a timeout.
try {
assertTrue(tracer.await(5, TimeUnit.SECONDS));
} catch (InterruptedException e) {
throw new AssertionError(e);
}
assertEquals(code, tracer.getStatus().getCode());
if (requests != null && responses != null) {
checkTracers(tracer, requests, responses);
}
if (metricsExpected()) {
// CensusStreamTracerModule records final status in interceptor, which is guaranteed to be
// done before application receives status.
MetricsRecord clientStartRecord = clientStatsRecorder.pollRecord();
checkStartTags(clientStartRecord, method, true);
MetricsRecord clientEndRecord = clientStatsRecorder.pollRecord();
checkEndTags(clientEndRecord, method, code, true);
if (requests != null && responses != null) {
checkCensus(clientEndRecord, false, requests, responses);
}
}
}
void assertException(Throwable t, Status.Code status, String message) {
assertThat(t).isNotNull()
.isInstanceOf(StatusRuntimeException.class)
.hasMessageContaining(message);
StatusRuntimeException statusRuntimeException = (StatusRuntimeException) t;
assertThat(statusRuntimeException.getStatus().getCode()).isEqualTo(status);
}
private boolean errorIsInteresting(Status error) {
Status.Code code = error.getCode();
String description = error.getDescription() != null ? error.getDescription() : "";
if (code == Status.Code.FAILED_PRECONDITION && description.contains("requires an index")) {
return true;
} else if (code == Status.Code.PERMISSION_DENIED) {
return true;
}
return false;
}
public static Status assertFutureThrowsStatus(final Status.Code code, final ListenableFuture<?> future,
final int timeout, final TimeUnit timeoutUnit) {
final StatusRuntimeException exception =
assertFutureThrows(StatusRuntimeException.class, future, timeout, timeoutUnit);
return assertStatus(code, exception);
}
/**
* Wraps calls to listMinaSshdServices with an account ID.
*
* @param requestId the request ID for the request
* @param accountId the account ID
* @param serviceIds the minasshd services to list. if null or empty then all minasshd services will be listed
* @return the list of minasshd services
*/
public List<MinaSshdService> listMinaSshdServices(String requestId, String accountId, List<String> serviceIds) throws CcmException {
checkNotNull(requestId);
checkNotNull(accountId);
List<MinaSshdService> groups = new ArrayList<>();
MinaSshdManagementBlockingStub minaSshdManagementBlockingStub = newStub(requestId);
ListMinaSshdServicesRequest.Builder requestBuilder = ListMinaSshdServicesRequest.newBuilder()
.setAccountId(accountId)
.setPageSize(minaSshdManagementClientConfig.getListMinaSshdServicesPageSize());
if (serviceIds != null && !serviceIds.isEmpty()) {
requestBuilder.addAllId(serviceIds);
}
ListMinaSshdServicesResponse response;
do {
try {
LOGGER.debug("Calling listMinaSshdServices with requestId: {}, accountId: {}, serviceIds: [{}]",
requestId, accountId, serviceIds);
response = minaSshdManagementBlockingStub.listMinaSshdServices(requestBuilder.build());
if (response == null) {
throw new CcmException("Got null response from MinaSshdManagementService listMinaSshdServices gRPC call", false);
} else {
List<MinaSshdService> minaSshdServices = response.getMinaSshdServiceList();
if (minaSshdServices == null) {
throw new CcmException("Got null minasshd services in MinaSshdManagementService listMinaSshdServices gRPC response", false);
} else {
groups.addAll(minaSshdServices);
}
}
} catch (StatusRuntimeException e) {
String message = "MinaSshdManagementService listMinaSshdServices gRPC call failed: " + e.getMessage();
Status status = e.getStatus();
Status.Code code = status.getCode();
boolean retryable = GrpcUtil.isRetryable(code);
LOGGER.debug("Got status code: {}, retryable: {}", code, retryable);
throw new CcmException(message, e, retryable);
}
requestBuilder.setPageToken(response.getNextPageToken());
} while (response.hasNextPageToken());
return groups;
}
/** This assumes the client limits metadata size to GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE. */
@Test
public void clientChecksInboundMetadataSize_trailer() throws Exception {
server.start(serverListener);
client = newClientTransport(server);
startTransport(client, mockClientTransportListener);
MockServerTransportListener serverTransportListener
= serverListener.takeListenerOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
serverTransport = serverTransportListener.transport;
Metadata.Key<String> tellTaleKey
= Metadata.Key.of("tell-tale", Metadata.ASCII_STRING_MARSHALLER);
Metadata tooLargeMetadata = new Metadata();
tooLargeMetadata.put(tellTaleKey, "true");
tooLargeMetadata.put(
Metadata.Key.of("foo-bin", Metadata.BINARY_BYTE_MARSHALLER),
new byte[GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE]);
ClientStream clientStream =
client.newStream(methodDescriptor, new Metadata(), callOptions);
ClientStreamListenerBase clientStreamListener = new ClientStreamListenerBase();
clientStream.start(clientStreamListener);
clientStream.writeMessage(methodDescriptor.streamRequest("foo"));
clientStream.halfClose();
clientStream.request(1);
StreamCreation serverStreamCreation
= serverTransportListener.takeStreamOrFail(TIMEOUT_MS, TimeUnit.MILLISECONDS);
serverStreamCreation.stream.request(1);
serverStreamCreation.stream.writeHeaders(new Metadata());
serverStreamCreation.stream.writeMessage(methodDescriptor.streamResponse("response"));
serverStreamCreation.stream.close(Status.OK, tooLargeMetadata);
Status status = clientStreamListener.status.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
List<Status.Code> codeOptions = Arrays.asList(
Status.Code.UNKNOWN, Status.Code.RESOURCE_EXHAUSTED, Status.Code.INTERNAL);
if (!codeOptions.contains(status.getCode())) {
fail("Status code was not expected: " + status);
}
Metadata metadata = clientStreamListener.trailers.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
assertNull(metadata.get(tellTaleKey));
}
private void unpackP4Error(int index, Any any, boolean reconcilable) {
final P4RuntimeOuterClass.Error p4Error;
try {
p4Error = any.unpack(P4RuntimeOuterClass.Error.class);
} catch (InvalidProtocolBufferException e) {
final String unpackErr = format(
"P4Runtime Error message format not recognized [%s]",
TextFormat.shortDebugString(any));
if (reconcilable) {
setFailure(index, unpackErr, EntityUpdateStatus.OTHER_ERROR);
} else {
log.warn(unpackErr);
}
return;
}
// Map gRPC status codes to our WriteResponseStatus codes.
final Status.Code p4Code = Status.fromCodeValue(
p4Error.getCanonicalCode()).getCode();
final EntityUpdateStatus ourCode;
switch (p4Code) {
case OK:
if (reconcilable) {
setSuccess(index);
}
return;
case NOT_FOUND:
ourCode = EntityUpdateStatus.NOT_FOUND;
break;
case ALREADY_EXISTS:
ourCode = EntityUpdateStatus.ALREADY_EXIST;
break;
default:
ourCode = EntityUpdateStatus.OTHER_ERROR;
break;
}
// Put the p4Code in the explanation only if ourCode is OTHER_ERROR.
final String explanationCode = ourCode == EntityUpdateStatus.OTHER_ERROR
? p4Code.name() + " " : "";
final String details = p4Error.hasDetails()
? ", " + p4Error.getDetails().toString() : "";
final String explanation = format(
"%s%s%s (%s:%d)", explanationCode, p4Error.getMessage(),
details, p4Error.getSpace(), p4Error.getCode());
if (reconcilable) {
setFailure(index, explanation, ourCode);
} else {
log.warn("P4Runtime write error: {}", explanation);
}
}
@ParameterizedTest(name = "{0}")
@MethodSource("fromThrowableDataProvider")
void fromThrowableTest(String testCaseName, Status.Code code, IdbmmsOperationErrorStatus errorStatusExpected) {
assertThat(IdbmmsOperationErrorStatus.fromThrowable(createStatusRuntimeException(code))).isEqualTo(errorStatusExpected);
}
public ListenableFutureAssert<ACTUAL> failsWithGrpcStatusCode(Status.Code code) {
checkNotNull(code, "code");
assertThat(getFailureGrpcStatus().getCode()).isEqualTo(code);
return this;
}
public static Status assertFutureThrowsStatus(final Status.Code code, final ListenableFuture<?> future,
final int timeout, final TimeUnit timeoutUnit) {
final StatusRuntimeException exception =
assertFutureThrows(StatusRuntimeException.class, future, timeout, timeoutUnit);
return assertStatus(code, exception);
}
/**
* Evaluates a throwable to determine if it has a gRPC status, and then if so, evaluates the throwable's
* status code.
*
* @param t A throwable to evaluate
* @param code A {@code Status.Code} to look for
* @return {@code true} if {@code t} is a {@code StatusException} or a {@code StatusRuntimeException} with
* {@code Status.Code} equal to {@code code}
*/
public static boolean hasStatusCode(Throwable t, Status.Code code) {
if (!hasStatus(t)) {
return false;
} else {
return doWithStatus(t, (status, metadata) -> status.getCode() == code);
}
}
/**
* Poll the next metrics record and check it against the provided information, without checking
* the message sizes.
*/
private void assertStatsTrace(String method, Status.Code status) {
assertStatsTrace(method, status, null, null);
}
/**
* Returns whether the specified status code indicates a transient problem.
*
* @param statusCode the status code
* @return whether the specified status code indicates a transient problem
*/
public static boolean isRetryable(Status.Code statusCode) {
return RETRYABLE_STATUS_CODES.contains(statusCode);
}