private String apiVersionToText(ApiVersion apiVersion) { StringBuilder bld = new StringBuilder(); ApiKeys apiKey = null; if (ApiKeys.hasId(apiVersion.apiKey)) { apiKey = ApiKeys.forId(apiVersion.apiKey); bld.append(apiKey.name).append("(").append(apiKey.id).append("): "); } else { bld.append("UNKNOWN(").append(apiVersion.apiKey).append("): "); } if (apiVersion.minVersion == apiVersion.maxVersion) { bld.append(apiVersion.minVersion); } else { bld.append(apiVersion.minVersion).append(" to ").append(apiVersion.maxVersion); } if (apiKey != null) { ApiVersion supportedVersion = supportedVersions.get(apiKey); if (apiKey.latestVersion() < supportedVersion.minVersion) { bld.append(" [unusable: node too new]"); } else if (supportedVersion.maxVersion < apiKey.oldestVersion()) { bld.append(" [unusable: node too old]"); } else { short latestUsableVersion = Utils.min(apiKey.latestVersion(), supportedVersion.maxVersion); bld.append(" [usable: ").append(latestUsableVersion).append("]"); } } return bld.toString(); }
public static WriteTxnMarkersResponse parse(ByteBuffer buffer, short version) { return new WriteTxnMarkersResponse(ApiKeys.WRITE_TXN_MARKERS.parseResponse(version, buffer)); } }
@Override protected Struct toStruct() { return new Struct(ApiKeys.LIST_GROUPS.requestSchema(version())); } }
/** * Construct a new builder which allows any supported version */ public Builder(ApiKeys apiKey) { this(apiKey, apiKey.oldestVersion(), apiKey.latestVersion()); }
public NodeApiVersions(Collection<ApiVersion> nodeApiVersions) { for (ApiVersion nodeApiVersion : nodeApiVersions) { if (ApiKeys.hasId(nodeApiVersion.apiKey)) { ApiKeys nodeApiKey = ApiKeys.forId(nodeApiVersion.apiKey); supportedVersions.put(nodeApiKey, nodeApiVersion); } else { // Newer brokers may support ApiKeys we don't know about unknownApis.add(nodeApiVersion); } } }
@Test public void testVersionsToString() { List<ApiVersion> versionList = new ArrayList<>(); for (ApiKeys apiKey : ApiKeys.values()) { if (apiKey == ApiKeys.DELETE_TOPICS) { versionList.add(new ApiVersion(apiKey.id, (short) 10000, (short) 10001)); StringBuilder bld = new StringBuilder(); String prefix = "("; for (ApiKeys apiKey : ApiKeys.values()) { bld.append(prefix); if (apiKey == ApiKeys.DELETE_TOPICS) { bld.append(apiKey.name).append("("). append(apiKey.id).append("): "); if (apiKey.oldestVersion() == apiKey.latestVersion()) { bld.append(apiKey.oldestVersion()); } else { bld.append(apiKey.oldestVersion()). append(" to "). append(apiKey.latestVersion()); bld.append(" [usable: ").append(apiKey.latestVersion()). append("]");
protected void saslAuthenticateVersion(ApiVersionsResponse apiVersionsResponse) { ApiVersion authenticateVersion = apiVersionsResponse.apiVersion(ApiKeys.SASL_AUTHENTICATE.id); if (authenticateVersion != null) this.saslAuthenticateVersion = (short) Math.min(authenticateVersion.maxVersion, ApiKeys.SASL_AUTHENTICATE.latestVersion()); }
private Set<ApiKeys> apiKeysInResponse(final ApiVersionsResponse apiVersions) { final Set<ApiKeys> apiKeys = new HashSet<>(); for (final ApiVersionsResponse.ApiVersion version : apiVersions.apiVersions()) { apiKeys.add(ApiKeys.forId(version.apiKey)); } return apiKeys; }
/** * All valid client responses which may be throttled should have a field named * 'throttle_time_ms' to return the throttle time to the client. Exclusions are * <ul> * <li> Cluster actions used only for inter-broker are throttled only if unauthorized * <li> SASL_HANDSHAKE and SASL_AUTHENTICATE are not throttled when used for authentication * when a connection is established or for re-authentication thereafter; these requests * return an error response that may be throttled if they are sent otherwise. * </ul> */ @Test public void testResponseThrottleTime() { List<ApiKeys> authenticationKeys = Arrays.asList(ApiKeys.SASL_HANDSHAKE, ApiKeys.SASL_AUTHENTICATE); for (ApiKeys apiKey: ApiKeys.values()) { Schema responseSchema = apiKey.responseSchema(apiKey.latestVersion()); BoundField throttleTimeField = responseSchema.get(CommonFields.THROTTLE_TIME_MS.name); if (apiKey.clusterAction || authenticationKeys.contains(apiKey)) assertNull("Unexpected throttle time field: " + apiKey, throttleTimeField); else assertNotNull("Throttle time field missing: " + apiKey, throttleTimeField); } } }
protected Struct parseResponse(short version, ByteBuffer buffer, short fallbackVersion) { int bufferPosition = buffer.position(); try { return responseSchema(version).read(buffer); } catch (SchemaException e) { if (version != fallbackVersion) { buffer.position(bufferPosition); return responseSchema(fallbackVersion).read(buffer); } else throw e; } }
@Test public void testUsableVersionLatestVersions() { List<ApiVersion> versionList = new LinkedList<>(); for (ApiVersion apiVersion: ApiVersionsResponse.defaultApiVersionsResponse().apiVersions()) { versionList.add(apiVersion); } // Add an API key that we don't know about. versionList.add(new ApiVersion((short) 100, (short) 0, (short) 1)); NodeApiVersions versions = new NodeApiVersions(versionList); for (ApiKeys apiKey: ApiKeys.values()) { assertEquals(apiKey.latestVersion(), versions.latestUsableVersion(apiKey)); } } }
private static String toHtml() { final StringBuilder b = new StringBuilder(); b.append("<table class=\"data-table\"><tbody>\n"); b.append("<tr>"); b.append("<th>Name</th>\n"); b.append("<th>Key</th>\n"); b.append("</tr>"); for (ApiKeys key : ApiKeys.values()) { b.append("<tr>\n"); b.append("<td>"); b.append("<a href=\"#The_Messages_" + key.name + "\">" + key.name + "</a>"); b.append("</td>"); b.append("<td>"); b.append(key.id); b.append("</td>"); b.append("</tr>\n"); } b.append("</table>\n"); return b.toString(); }
public boolean isVersionSupported(short apiVersion) { return apiVersion >= oldestVersion() && apiVersion <= latestVersion(); }
@Test public void shouldHaveCorrectDefaultApiVersionsResponse() { Collection<ApiVersionsResponse.ApiVersion> apiVersions = ApiVersionsResponse.defaultApiVersionsResponse().apiVersions(); assertEquals("API versions for all API keys must be maintained.", apiVersions.size(), ApiKeys.values().length); for (ApiKeys key : ApiKeys.values()) { ApiVersionsResponse.ApiVersion version = ApiVersionsResponse.defaultApiVersionsResponse().apiVersion(key.id); assertNotNull("Could not find ApiVersion for API " + key.name, version); assertEquals("Incorrect min version for Api " + key.name, version.minVersion, key.oldestVersion()); assertEquals("Incorrect max version for Api " + key.name, version.maxVersion, key.latestVersion()); // Check if versions less than min version are indeed set as null, i.e., deprecated. for (int i = 0; i < version.minVersion; ++i) { assertNull("Request version " + i + " for API " + version.apiKey + " must be null", key.requestSchemas[i]); assertNull("Response version " + i + " for API " + version.apiKey + " must be null", key.responseSchemas[i]); } // Check if versions between min and max versions are non null, i.e., valid. for (int i = version.minVersion; i <= version.maxVersion; ++i) { assertNotNull("Request version " + i + " for API " + version.apiKey + " must not be null", key.requestSchemas[i]); assertNotNull("Response version " + i + " for API " + version.apiKey + " must not be null", key.responseSchemas[i]); } } }
public static Builder forConsumer(boolean requireTimestamp, IsolationLevel isolationLevel) { short minVersion = 0; if (isolationLevel == IsolationLevel.READ_COMMITTED) minVersion = 2; else if (requireTimestamp) minVersion = 1; return new Builder(minVersion, ApiKeys.LIST_OFFSETS.latestVersion(), CONSUMER_REPLICA_ID, isolationLevel); }
@Test(expected = IllegalArgumentException.class) public void testForIdWithInvalidIdLow() { ApiKeys.forId(-1); }
public static ElectPreferredLeadersResponse parse(ByteBuffer buffer, short version) { return new ElectPreferredLeadersResponse( ApiKeys.ELECT_PREFERRED_LEADERS.responseSchema(version).read(buffer), version); }
public RequestHeader(Struct struct) { short apiKey = struct.getShort(API_KEY_FIELD_NAME); if (!ApiKeys.hasId(apiKey)) throw new InvalidRequestException("Unknown API key " + apiKey); this.apiKey = ApiKeys.forId(apiKey); apiVersion = struct.getShort(API_VERSION_FIELD_NAME); // only v0 of the controlled shutdown request is missing the clientId if (struct.hasField(CLIENT_ID_FIELD_NAME)) clientId = struct.getString(CLIENT_ID_FIELD_NAME); else clientId = ""; correlationId = struct.getInt(CORRELATION_ID_FIELD_NAME); }
/** * Verify that the JSON files support the same message versions as the * schemas accessible through the ApiKey class. */ @Test public void testMessageVersions() throws Exception { for (ApiKeys apiKey : ApiKeys.values()) { Message message = null; try { message = ApiMessageFactory.newRequest(apiKey.id); } catch (UnsupportedVersionException e) { fail("No request message spec found for API " + apiKey); } assertTrue("Request message spec for " + apiKey + " only " + "supports versions up to " + message.highestSupportedVersion(), apiKey.latestVersion() <= message.highestSupportedVersion()); try { message = ApiMessageFactory.newResponse(apiKey.id); } catch (UnsupportedVersionException e) { fail("No response message spec found for API " + apiKey); } assertTrue("Response message spec for " + apiKey + " only " + "supports versions up to " + message.highestSupportedVersion(), apiKey.latestVersion() <= message.highestSupportedVersion()); } }
public static ApiVersionsResponse createApiVersionsResponse(int throttleTimeMs, final byte minMagic) { List<ApiVersionsResponse.ApiVersion> versionList = new ArrayList<>(); for (ApiKeys apiKey : ApiKeys.values()) { if (apiKey.minRequiredInterBrokerMagic <= minMagic) { versionList.add(new ApiVersionsResponse.ApiVersion(apiKey)); } } return new ApiVersionsResponse(throttleTimeMs, Errors.NONE, versionList); }